All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.spy.memcached.KetamaIterator Maven / Gradle / Ivy

The newest version!
package net.spy.memcached;

import java.util.Iterator;
import java.util.SortedMap;
import java.util.TreeMap;
import net.spy.memcached.compat.SpyObject;

/**
 * Implements an Iterator which the KetamaNodeLoctaor may return to a client for
 * iterating through alternate nodes for a given key.
 */
class KetamaIterator extends SpyObject implements Iterator {

    final String key;
    long hashVal;
    int remainingTries;
    int numTries = 0;
    final HashAlgorithm hashAlg;
    final TreeMap ketamaNodes;

    /**
     * Create a new KetamaIterator to be used by a client for an operation.
     *
     * @param k the key to iterate for
     * @param t the number of tries until giving up
     * @param ketamaNodes the continuum in the form of a TreeMap to be used when selecting a node
     * @param hashAlg the hash algorithm to use when selecting within the continuumq
     */
    protected KetamaIterator(final String k, final int t, TreeMap ketamaNodes, final HashAlgorithm hashAlg) {
	super();
	this.ketamaNodes = ketamaNodes;
	this.hashAlg = hashAlg;
	hashVal = hashAlg.hash(k);
	remainingTries = t;
	key = k;
    }

    private void nextHash() {
	// this.calculateHash(Integer.toString(tries)+key).hashCode();
	long tmpKey = hashAlg.hash((numTries++) + key);
	// This echos the implementation of Long.hashCode()
	hashVal += (int) (tmpKey ^ (tmpKey >>> 32));
	hashVal &= 0xffffffffL; /* truncate to 32-bits */
	remainingTries--;
    }

    public boolean hasNext() {
	return remainingTries > 0;
    }

    public MemcachedNode next() {
	try {
	    return getNodeForKey(hashVal);
	} finally {
	    nextHash();
	}
    }

    public void remove() {
	throw new UnsupportedOperationException("remove not supported");
    }

    private MemcachedNode getNodeForKey(long hash) {
	final MemcachedNode rv;
	if (!ketamaNodes.containsKey(hash)) {
	    // Java 1.6 adds a ceilingKey method, but I'm still stuck in 1.5
	    // in a lot of places, so I'm doing this myself.
	    SortedMap tailMap = ketamaNodes.tailMap(hash);
	    if (tailMap.isEmpty()) {
		hash = ketamaNodes.firstKey();
	    } else {
		hash = tailMap.firstKey();
	    }
	}
	rv = ketamaNodes.get(hash);
	return rv;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy