ConsistentHash { public List<T> getNUniqueBinsFor(Object key, int n) { if (circle.isEmpty()) { return Collections.<T> emptyList(); } List<T> list = new ArrayList<T>(n); int hash = hashFunction.hash(key); int duped = 0; for (int i = 0; i < n; i++) { if (!circle.containsKey(hash)) { SortedMap<Integer, T> tailMap = circle.tailMap(hash); hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey(); } T candidate = circle.get(hash); if (!list.contains(candidate)) { duped = 0; list.add(candidate); } else { duped++; i--; if (duped > MAX_DUPES) { i++; } } hash++; } return list; } ConsistentHash(int numberOfReplicas, Collection<T> nodes);  ConsistentHash(HashFunction hashFunction, int numberOfReplicas,
      Collection<T> nodes); void addBin(T bin); void removeBin(T bin); T getBinFor(Object key); List<T> getNBinsFor(Object key, int n); List<T> getNUniqueBinsFor(Object key, int n); final static int MAX_DUPES; }
@Test public void testConsistentHashNUniqTooFew() { int replicas = 100; ConsistentHash<String> hash = new ConsistentHash<String>(replicas, Arrays .asList("single machine")); StringBuilder sb = new StringBuilder(); List<String> orig = new ArrayList<String>(20); LOG.info("Before: "); for (int i = 0; i < 20; i++) { String s = "this is a the key " + i; List<String> l = hash.getNUniqueBinsFor(s, 3); String bin = l.toString(); sb.append(bin + ", "); orig.add(l.get(0).toString()); Set<String> set = new HashSet<String>(l); assertEquals(1, set.size()); } LOG.info(sb.toString()); }