package com.rubiconproject.oss.kv.distributed.hashing; import java.util.Collection; import java.util.Map; import java.util.TreeMap; public class HashRing<K, V> { private int nodeCount = 0; private TreeMap<K, V> map = new TreeMap<K, V>(); public HashRing(int nodeCount) { this.nodeCount = nodeCount; } /** * Return the node count. Node count is independent from the ring as is * saved here merely as a convenience. It needs to be atomically assigned at * the same time as the switch to a new hash ring. * * @return */ public int getNodeCount() { return nodeCount; } /** * Place the given key on the ring, returning the matching key/value pair. * * @param key * @return */ public Map.Entry<K, V> place(K key) { assert map.size() > 0; Map.Entry<K, V> entry = map.ceilingEntry(key); if (entry == null) entry = map.firstEntry(); return entry; } /** * Returns the number of key-value mappings in this map. * * @return */ public int size() { return map.size(); } /** * Returns the value to which the specified key is mapped, or null if this * map contains no mapping for the key. * * @param key * @return */ public V get(K key) { return map.get(key); } /** * Associates the specified value with the specified key in this map. * * @param key * @param value */ public void put(K key, V value) { map.put(key, value); } /** * Returns a key-value mapping associated with the least key in this map, or * null if the map is empty. * * @return */ public Map.Entry<K, V> firstEntry() { assert map.size() > 0; return map.firstEntry(); } /** * Returns a key-value mapping associated with the greatest key in this map, * or null if the map is empty. * * @return */ public Map.Entry<K, V> lastEntry() { assert map.size() > 0; return map.lastEntry(); } /** * Returns a key-value mapping associated with the greatest key strictly * less than the given key, or null if there is no such key. * * @param key * @return */ public Map.Entry<K, V> lowerEntry(K key) { assert map.size() > 0; return map.lowerEntry(key); } /** * Returns a key-value mapping associated with the least key strictly * greater than the given key, or null if there is no such key. * * @param key * @return */ public Map.Entry<K, V> higherEntry(K key) { assert map.size() > 0; return map.higherEntry(key); } /** * Returns a Collection view of the values contained in this map. * * @return */ public Collection<V> values() { return map.values(); } }