Continuum { public RawMemcacheClient findClient(final byte[] key) { final int keyHash = Hasher.hash(key).asInt(); Entry<Integer, RawMemcacheClient> entry = ringOfFire.ceilingEntry(keyHash); if (entry == null) { entry = ringOfFire.firstEntry(); } for (int i = 0; i < ringOfFire.size(); i++) { final RawMemcacheClient client = findClient(entry); if (client.isConnected()) { return client; } entry = ringOfFire.higherEntry(entry.getKey()); if (entry == null) { entry = ringOfFire.firstEntry(); } } return ringOfFire.firstEntry().getValue(); } Continuum(final Collection<AddressAndClient> clients); RawMemcacheClient findClient(final byte[] key);  }
@Test public void testSingleClient() { List<AddressAndClient> clients = ImmutableList.of(AAC1); Continuum c = new Continuum(clients); List<RawMemcacheClient> actual = Arrays.asList( c.findClient(bytes(KEY1)), c.findClient(bytes(KEY2)), c.findClient(bytes(KEY3))); List<RawMemcacheClient> expected = Arrays.asList(CLIENT1, CLIENT1, CLIENT1); assertEquals(expected, actual); }
@Test public void testMultipleClients() { List<AddressAndClient> clients = ImmutableList.of(AAC1, AAC2, AAC3); Continuum c = new Continuum(clients); List<RawMemcacheClient> actual = Arrays.asList( c.findClient(bytes(KEY1)), c.findClient(bytes(KEY2)), c.findClient(bytes(KEY3)), c.findClient(bytes(KEY4)), c.findClient(bytes(KEY5)), c.findClient(bytes(KEY6))); List<RawMemcacheClient> expected = Arrays.asList(CLIENT1, CLIENT1, CLIENT2, CLIENT3, CLIENT2, CLIENT1); assertEquals(expected, actual); }
@Test public void testMultipleClientsOneDisconnected() { List<AddressAndClient> clients = ImmutableList.of(AAC1, AAC2, AAC3, AAC4, AAC5); Continuum c = new Continuum(clients); List<RawMemcacheClient> actual = Arrays.asList( c.findClient(bytes(KEY1)), c.findClient(bytes(KEY2)), c.findClient(bytes(KEY3)), c.findClient(bytes(KEY4)), c.findClient(bytes(KEY5)), c.findClient(bytes(KEY6)), c.findClient(bytes(KEY7)), c.findClient(bytes(KEY8)), c.findClient(bytes(KEY9)), c.findClient(bytes(KEY10))); List<RawMemcacheClient> expected = Arrays.asList( CLIENT1, CLIENT5, CLIENT2, CLIENT4, CLIENT2, CLIENT1, CLIENT5, CLIENT1, CLIENT1, CLIENT4); assertEquals(expected, actual); when(CLIENT1.isConnected()).thenReturn(false); actual = Arrays.asList( c.findClient(bytes(KEY1)), c.findClient(bytes(KEY2)), c.findClient(bytes(KEY3)), c.findClient(bytes(KEY4)), c.findClient(bytes(KEY5)), c.findClient(bytes(KEY6)), c.findClient(bytes(KEY7)), c.findClient(bytes(KEY8)), c.findClient(bytes(KEY9)), c.findClient(bytes(KEY10))); expected = Arrays.asList( CLIENT4, CLIENT5, CLIENT2, CLIENT4, CLIENT2, CLIENT5, CLIENT5, CLIENT2, CLIENT5, CLIENT4); assertEquals(expected, actual); }
@Test public void testWrap() { final List<AddressAndClient> clients = ImmutableList.of(AAC1, AAC2, AAC3); final Continuum c = new Continuum(clients); List<RawMemcacheClient> actual = Arrays.asList(c.findClient(bytes("key321")), c.findClient(bytes("key477"))); List<RawMemcacheClient> expected = Arrays.asList(CLIENT2, CLIENT3); assertEquals(expected, actual); }
@Test public void testWrapDisconnected() { final List<AddressAndClient> clients = ImmutableList.of(AAC1, AAC2, AAC3); final Continuum c = new Continuum(clients); assertSame(CLIENT1, c.findClient(bytes("key1561"))); when(CLIENT1.isConnected()).thenReturn(false); assertSame(CLIENT2, c.findClient(bytes("key1561"))); }