diff --git a/core/src/main/java/hudson/util/ConsistentHash.java b/core/src/main/java/hudson/util/ConsistentHash.java index 9bbddbbd82d5e61f36916d8912b3df7e26b79d92..4878305fab94406df492e371946add439356137b 100644 --- a/core/src/main/java/hudson/util/ConsistentHash.java +++ b/core/src/main/java/hudson/util/ConsistentHash.java @@ -120,7 +120,9 @@ public class ConsistentHash { } T lookup(int queryPoint) { - return (T)owner[index(queryPoint)]; + int i = index(queryPoint); + if(i<0) return null; + return (T)owner[i]; } /** @@ -153,6 +155,7 @@ public class ConsistentHash { int idx = Arrays.binarySearch(hash, queryPoint); if(idx<0) { idx = -idx-1; // idx is now 'insertion point' + if(hash.length==0) return -1; idx %= hash.length; // make it a circle } return idx; @@ -204,6 +207,7 @@ public class ConsistentHash { public ConsistentHash(Hash hash, int defaultReplication) { this.hash = hash; this.defaultReplication = defaultReplication; + this.table = new Table(); // initial empty table } public int countAllPoints() { @@ -293,7 +297,7 @@ public class ConsistentHash { * or the # of replicas for the given node is changed. * * @return - * never null. + * null if the consistent hash is empty. Otherwise always non-null. */ public T lookup(int queryPoint) { return table.lookup(queryPoint); diff --git a/core/src/test/java/hudson/util/ConsistentHashTest.java b/core/src/test/java/hudson/util/ConsistentHashTest.java index 685b9aba2a1532f12da76d7c0fc4ed05b5742314..4c39c8554aaebb5c9c415850d138d732576dedfa 100644 --- a/core/src/test/java/hudson/util/ConsistentHashTest.java +++ b/core/src/test/java/hudson/util/ConsistentHashTest.java @@ -112,4 +112,11 @@ public class ConsistentHashTest extends TestCase { assertTrue(e.getValue()==0 || e.getValue()==m); } } + + public void testEmptyBehavior() { + ConsistentHash hash = new ConsistentHash(); + assertFalse(hash.list(0).iterator().hasNext()); + assertNull(hash.lookup(0)); + assertNull(hash.lookup(999)); + } }