Merge lp://qastaging/~trond-norbye/libmemcached/ketama_compat into lp://qastaging/~tangent-org/libmemcached/trunk

Proposed by Trond Norbye
Status: Merged
Merged at revision: not available
Proposed branch: lp://qastaging/~trond-norbye/libmemcached/ketama_compat
Merge into: lp://qastaging/~tangent-org/libmemcached/trunk
Diff against target: 1153 lines
8 files modified
docs/memcached_behavior.pod (+23/-16)
libmemcached/memcached_behavior.c (+39/-12)
libmemcached/memcached_constants.h (+8/-3)
libmemcached/memcached_hash.c (+15/-14)
libmemcached/memcached_hosts.c (+88/-41)
tests/function.c (+199/-16)
tests/ketama_test_cases.h (+113/-0)
tests/ketama_test_cases_spy.h (+89/-87)
To merge this branch: bzr merge lp://qastaging/~trond-norbye/libmemcached/ketama_compat
Reviewer Review Type Date Requested Status
Libmemcached-developers Pending
Review via email: mp+14355@code.qastaging.launchpad.net
To post a comment you must log in.
Revision history for this message
Trond Norbye (trond-norbye) wrote :

Hi,

I have merged https://code.launchpad.net/~mtsai/libmemcached/ketamahashing/+merge/13977https://code.launchpad.net/~mtsai/libmemcached/ketamahashing/+merge/13977 into my branch and created a new behavior setting to let the user specify if he wants a hashing compatible with libmemcached or spy memcached

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'docs/memcached_behavior.pod'
2--- docs/memcached_behavior.pod 2009-06-09 19:36:39 +0000
3+++ docs/memcached_behavior.pod 2009-11-03 13:30:25 +0000
4@@ -32,7 +32,7 @@
5
6 memcached_behavior_set() changes the value of a particular option of the
7 client. It takes both a flag (listed below) and a value. For simple on or
8-off options you just need to pass in a value of 1. Calls to
9+off options you just need to pass in a value of 1. Calls to
10 memcached_behavior_set() will flush and reset all connections.
11
12 =over 4
13@@ -40,7 +40,7 @@
14 =item MEMCACHED_BEHAVIOR_USE_UDP
15
16 Causes libmemcached(3) to use the UDP transport when communicating
17-with a memcached server. Not all I/O operations are supported
18+with a memcached server. Not all I/O operations are supported
19 when this behavior is enababled. The following operations will return
20 C<MEMCACHED_NOT_SUPPORTED> when executed with the MEMCACHED_BEHAVIOR_USE_UDP
21 enabled: memcached_version(), memcached_stat(), memcached_get(),
22@@ -50,7 +50,7 @@
23 All other operations are supported but are executed in a 'fire-and-forget'
24 mode, in which once the client has executed the operation, no attempt
25 will be made to ensure the operation has been received and acted on by the
26-server.
27+server.
28
29 libmemcached(3) does not allow TCP and UDP servers to be shared within
30 the same libmemached(3) client 'instance'. An attempt to add a TCP server
31@@ -82,19 +82,19 @@
32 =item MEMCACHED_BEHAVIOR_HASH
33
34 Makes the default hashing algorithm for keys use MD5. The value can be set
35-to either MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32, MEMCACHED_HASH_FNV1A_32, MEMCACHED_HASH_JENKINS, MEMCACHED_HASH_HSIEH, and MEMCACHED_HASH_MURMUR.
36+to either MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32, MEMCACHED_HASH_FNV1A_32, MEMCACHED_HASH_JENKINS, MEMCACHED_HASH_HSIEH, and MEMCACHED_HASH_MURMUR.
37 Each hash has it's advantages and it's weaknesses. If you dont know or dont care, just go with the default.
38-Support for MEMCACHED_HASH_HSIEH is a compile time option that is disabled by default. To enable support for this hashing algorithm, configure and build libmemcached with the --enable-hash_hsieh.
39+Support for MEMCACHED_HASH_HSIEH is a compile time option that is disabled by default. To enable support for this hashing algorithm, configure and build libmemcached with the --enable-hash_hsieh.
40
41 =item MEMCACHED_BEHAVIOR_DISTRIBUTION
42
43 Using this you can enable different means of distributing values to servers.
44 The default method is MEMCACHED_DISTRIBUTION_MODULA. You can enable
45-consistent hashing by setting MEMCACHED_DISTRIBUTION_CONSISTENT.
46-Consistent hashing delivers better distribution and allows servers to be
47+consistent hashing by setting MEMCACHED_DISTRIBUTION_CONSISTENT.
48+Consistent hashing delivers better distribution and allows servers to be
49 added to the cluster with minimal cache losses. Currently
50 MEMCACHED_DISTRIBUTION_CONSISTENT is an alias for the value
51-MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA.
52+MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA.
53
54 =item MEMCACHED_BEHAVIOR_CACHE_LOOKUPS
55
56@@ -117,7 +117,14 @@
57 =item MEMCACHED_BEHAVIOR_KETAMA_HASH
58
59 Sets the hashing algorithm for host mapping on continuum. The value can be set
60-to either MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32, and MEMCACHED_HASH_FNV1A_32.
61+to either MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32, and MEMCACHED_HASH_FNV1A_32.
62+
63+=item MEMCACHED_BEHAVIOR_KETAMA_COMPAT
64+
65+Sets the compatibility mode. The value can be set to either
66+MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED (this is the default) or
67+MEMCACHED_KETAMA_COMPAT_SPY to be compatible with the SPY Memcached client
68+for Java.
69
70 =item MEMCACHED_BEHAVIOR_POLL_TIMEOUT
71
72@@ -136,16 +143,16 @@
73 Enabling buffered IO causes commands to "buffer" instead of being sent. Any
74 action that gets data causes this buffer to be be sent to the remote
75 connection. Quiting the connection or closing down the connection will also
76-cause the buffered data to be pushed to the remote connection.
77+cause the buffered data to be pushed to the remote connection.
78
79 =item MEMCACHED_BEHAVIOR_VERIFY_KEY
80
81-Enabling this will cause libmemcached(3) to test all keys to verify that they
82+Enabling this will cause libmemcached(3) to test all keys to verify that they
83 are valid keys.
84
85 =item MEMCACHED_BEHAVIOR_SORT_HOSTS
86
87-Enabling this will cause hosts that are added to be placed in the host list in
88+Enabling this will cause hosts that are added to be placed in the host list in
89 sorted order. This will defeat consisten hashing.
90
91 =item MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT
92@@ -165,7 +172,7 @@
93
94 =item MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK
95
96-Set this value to tune the number of messages that may be sent before
97+Set this value to tune the number of messages that may be sent before
98 libmemcached should start to automatically drain the input queue. Setting
99 this value to high, may cause libmemcached to deadlock (trying to send data,
100 but the send will block because the input buffer in the kernel is full).
101@@ -175,7 +182,7 @@
102 Set this value to tune the number of bytes that may be sent before
103 libmemcached should start to automatically drain the input queue (need
104 at least 10 IO requests sent without reading the input buffer). Setting
105-this value to high, may cause libmemcached to deadlock (trying to send
106+this value to high, may cause libmemcached to deadlock (trying to send
107 data, but the send will block because the input buffer in the kernel is full).
108
109 =item MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH
110@@ -192,7 +199,7 @@
111 =item MEMCACHED_BEHAVIOR_NOREPLY
112
113 Set this value to specify that you really don't care about the result
114-from your storage commands (set, add, replace, append, prepend).
115+from your storage commands (set, add, replace, append, prepend).
116
117 =item MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS
118
119@@ -213,7 +220,7 @@
120 =head1 NOTES
121
122 memcached_behavior_set() in version .17 was changed from taking a pointer
123-to data value, to taking a uin64_t.
124+to data value, to taking a uin64_t.
125
126 =head1 HOME
127
128
129=== modified file 'libmemcached/memcached_behavior.c'
130--- libmemcached/memcached_behavior.c 2009-09-15 21:09:32 +0000
131+++ libmemcached/memcached_behavior.c 2009-11-03 13:30:25 +0000
132@@ -1,10 +1,10 @@
133-#include "common.h"
134+#include "common.h"
135 #include <time.h>
136 #include <sys/types.h>
137 #include <sys/socket.h>
138 #include <netinet/tcp.h>
139
140-/*
141+/*
142 This function is used to modify the behavior of running client.
143
144 We quit all connections so we can reset the sockets.
145@@ -18,8 +18,8 @@
146 ptr->flags&= ~temp_flag;
147 }
148
149-memcached_return memcached_behavior_set(memcached_st *ptr,
150- memcached_behavior flag,
151+memcached_return memcached_behavior_set(memcached_st *ptr,
152+ memcached_behavior flag,
153 uint64_t data)
154 {
155 switch (flag)
156@@ -38,18 +38,18 @@
157 break;
158 case MEMCACHED_BEHAVIOR_SND_TIMEOUT:
159 ptr->snd_timeout= (int32_t)data;
160- break;
161+ break;
162 case MEMCACHED_BEHAVIOR_RCV_TIMEOUT:
163 ptr->rcv_timeout= (int32_t)data;
164- break;
165+ break;
166 case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT:
167 ptr->server_failure_limit= (uint32_t)data;
168- break;
169+ break;
170 case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
171 if (data)
172 set_behavior_flag(ptr, MEM_VERIFY_KEY, 0);
173 set_behavior_flag(ptr, MEM_BINARY_PROTOCOL, data);
174- break;
175+ break;
176 case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
177 set_behavior_flag(ptr, MEM_SUPPORT_CAS, data);
178 break;
179@@ -105,6 +105,22 @@
180 run_distribution(ptr);
181 break;
182 }
183+ case MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE:
184+ switch (data)
185+ {
186+ case MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED:
187+ ptr->hash= MEMCACHED_HASH_MD5;
188+ ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA;
189+ break;
190+ case MEMCACHED_KETAMA_COMPAT_SPY:
191+ ptr->hash= MEMCACHED_HASH_MD5;
192+ ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY;
193+ break;
194+ default:
195+ return MEMCACHED_FAILURE;
196+ }
197+ run_distribution(ptr);
198+ break;
199 case MEMCACHED_BEHAVIOR_HASH:
200 #ifndef HAVE_HSIEH_HASH
201 if ((memcached_hash)(data) == MEMCACHED_HASH_HSIEH)
202@@ -169,7 +185,7 @@
203 return MEMCACHED_SUCCESS;
204 }
205
206-uint64_t memcached_behavior_get(memcached_st *ptr,
207+uint64_t memcached_behavior_get(memcached_st *ptr,
208 memcached_behavior flag)
209 {
210 memcached_flags temp_flag= MEM_NO_BLOCK;
211@@ -186,7 +202,7 @@
212 return ptr->io_key_prefetch;
213 case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
214 temp_flag= MEM_BINARY_PROTOCOL;
215- break;
216+ break;
217 case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
218 temp_flag= MEM_SUPPORT_CAS;
219 break;
220@@ -215,6 +231,17 @@
221 return ptr->distribution;
222 case MEMCACHED_BEHAVIOR_KETAMA:
223 return (ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) ? (uint64_t) 1 : 0;
224+ case MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE:
225+ switch (ptr->distribution)
226+ {
227+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
228+ return MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED;
229+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
230+ return MEMCACHED_KETAMA_COMPAT_SPY;
231+ default:
232+ return (uint64_t)-1;
233+ }
234+ /* NOTREACHED */
235 case MEMCACHED_BEHAVIOR_HASH:
236 return ptr->hash;
237 case MEMCACHED_BEHAVIOR_KETAMA_HASH:
238@@ -244,7 +271,7 @@
239 if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS)
240 return 0;
241
242- if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
243+ if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
244 SO_SNDBUF, &sock_size, &sock_length))
245 return 0; /* Zero means error */
246
247@@ -260,7 +287,7 @@
248 if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS)
249 return 0;
250
251- if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
252+ if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
253 SO_RCVBUF, &sock_size, &sock_length))
254 return 0; /* Zero means error */
255
256
257=== modified file 'libmemcached/memcached_constants.h'
258--- libmemcached/memcached_constants.h 2009-09-22 08:26:38 +0000
259+++ libmemcached/memcached_constants.h 2009-11-03 13:30:25 +0000
260@@ -17,7 +17,7 @@
261 #define MEMCACHED_MAX_HOST_SORT_LENGTH 86 /* Used for Ketama */
262 #define MEMCACHED_POINTS_PER_SERVER 100
263 #define MEMCACHED_POINTS_PER_SERVER_KETAMA 160
264-#define MEMCACHED_CONTINUUM_SIZE MEMCACHED_POINTS_PER_SERVER*100 /* This would then set max hosts to 100 */
265+#define MEMCACHED_CONTINUUM_SIZE MEMCACHED_POINTS_PER_SERVER*100 /* This would then set max hosts to 100 */
266 #define MEMCACHED_STRIDE 4
267 #define MEMCACHED_DEFAULT_TIMEOUT 1000
268 #define MEMCACHED_CONTINUUM_ADDITION 10 /* How many extra slots we should build for in the continuum */
269@@ -70,7 +70,8 @@
270 MEMCACHED_DISTRIBUTION_MODULA,
271 MEMCACHED_DISTRIBUTION_CONSISTENT,
272 MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA,
273- MEMCACHED_DISTRIBUTION_RANDOM
274+ MEMCACHED_DISTRIBUTION_RANDOM,
275+ MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY
276 } memcached_server_distribution;
277
278 typedef enum {
279@@ -103,9 +104,13 @@
280 MEMCACHED_BEHAVIOR_NOREPLY,
281 MEMCACHED_BEHAVIOR_USE_UDP,
282 MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS,
283- MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS
284+ MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
285+ MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE
286 } memcached_behavior;
287
288+#define MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED 0
289+#define MEMCACHED_KETAMA_COMPAT_SPY 1
290+
291 typedef enum {
292 MEMCACHED_CALLBACK_PREFIX_KEY = 0,
293 MEMCACHED_CALLBACK_USER_DATA = 1,
294
295=== modified file 'libmemcached/memcached_hash.c'
296--- libmemcached/memcached_hash.c 2009-08-11 18:56:12 +0000
297+++ libmemcached/memcached_hash.c 2009-11-03 13:30:25 +0000
298@@ -31,13 +31,13 @@
299 hash= 1;
300 break;
301 /* FNV hash'es lifted from Dustin Sallings work */
302- case MEMCACHED_HASH_FNV1_64:
303+ case MEMCACHED_HASH_FNV1_64:
304 {
305 /* Thanks to pierre@demartines.com for the pointer */
306 uint64_t temp_hash;
307
308 temp_hash= FNV_64_INIT;
309- for (x= 0; x < key_length; x++)
310+ for (x= 0; x < key_length; x++)
311 {
312 temp_hash *= FNV_64_PRIME;
313 temp_hash ^= (uint64_t)key[x];
314@@ -45,10 +45,10 @@
315 hash= (uint32_t)temp_hash;
316 }
317 break;
318- case MEMCACHED_HASH_FNV1A_64:
319+ case MEMCACHED_HASH_FNV1A_64:
320 {
321 hash= (uint32_t) FNV_64_INIT;
322- for (x= 0; x < key_length; x++)
323+ for (x= 0; x < key_length; x++)
324 {
325 uint32_t val= (uint32_t)key[x];
326 hash ^= val;
327@@ -56,10 +56,10 @@
328 }
329 }
330 break;
331- case MEMCACHED_HASH_FNV1_32:
332+ case MEMCACHED_HASH_FNV1_32:
333 {
334 hash= FNV_32_INIT;
335- for (x= 0; x < key_length; x++)
336+ for (x= 0; x < key_length; x++)
337 {
338 uint32_t val= (uint32_t)key[x];
339 hash *= FNV_32_PRIME;
340@@ -67,10 +67,10 @@
341 }
342 }
343 break;
344- case MEMCACHED_HASH_FNV1A_32:
345+ case MEMCACHED_HASH_FNV1A_32:
346 {
347 hash= FNV_32_INIT;
348- for (x= 0; x < key_length; x++)
349+ for (x= 0; x < key_length; x++)
350 {
351 uint32_t val= (uint32_t)key[x];
352 hash ^= val;
353@@ -121,10 +121,11 @@
354
355 static uint32_t dispatch_host(memcached_st *ptr, uint32_t hash)
356 {
357- switch (ptr->distribution)
358+ switch (ptr->distribution)
359 {
360 case MEMCACHED_DISTRIBUTION_CONSISTENT:
361 case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
362+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
363 {
364 uint32_t num= ptr->continuum_points_counter;
365 WATCHPOINT_ASSERT(ptr->continuum);
366@@ -145,7 +146,7 @@
367 if (right == end)
368 right= begin;
369 return right->index;
370- }
371+ }
372 case MEMCACHED_DISTRIBUTION_MODULA:
373 return hash % ptr->number_of_hosts;
374 case MEMCACHED_DISTRIBUTION_RANDOM:
375@@ -158,8 +159,8 @@
376 /* NOTREACHED */
377 }
378
379-/*
380- One day make this public, and have it return the actual memcached_server_st
381+/*
382+ One day make this public, and have it return the actual memcached_server_st
383 to the calling application.
384 */
385 uint32_t memcached_generate_hash(memcached_st *ptr, const char *key, size_t key_length)
386@@ -206,7 +207,7 @@
387 const char *ptr= key;
388 uint32_t value= 0;
389
390- while (key_length--)
391+ while (key_length--)
392 {
393 uint32_t val= (uint32_t) *ptr++;
394 value += val;
395@@ -215,7 +216,7 @@
396 }
397 value += (value << 3);
398 value ^= (value >> 11);
399- value += (value << 15);
400+ value += (value << 15);
401
402 return value == 0 ? 1 : (uint32_t) value;
403 }
404
405=== modified file 'libmemcached/memcached_hosts.c'
406--- libmemcached/memcached_hosts.c 2009-10-10 11:57:03 +0000
407+++ libmemcached/memcached_hosts.c 2009-11-03 13:30:25 +0000
408@@ -40,6 +40,7 @@
409 {
410 case MEMCACHED_DISTRIBUTION_CONSISTENT:
411 case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
412+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
413 return update_continuum(ptr);
414 case MEMCACHED_DISTRIBUTION_MODULA:
415 if (ptr->flags & MEM_USE_SORT_HOSTS)
416@@ -198,47 +199,93 @@
417 pointer_per_server);
418 #endif
419 }
420- for (pointer_index= 1;
421- pointer_index <= pointer_per_server / pointer_per_hash;
422- ++pointer_index)
423- {
424- char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
425- size_t sort_host_length;
426-
427- if (list[host_index].port == MEMCACHED_DEFAULT_PORT)
428- {
429- sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
430- "%s-%d",
431- list[host_index].hostname,
432- pointer_index - 1);
433-
434- }
435- else
436- {
437- sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
438- "%s:%d-%d",
439- list[host_index].hostname,
440- list[host_index].port, pointer_index - 1);
441- }
442- WATCHPOINT_ASSERT(sort_host_length);
443-
444- if (is_ketama_weighted)
445- {
446- unsigned int i;
447- for (i = 0; i < pointer_per_hash; i++)
448- {
449- value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i);
450- ptr->continuum[continuum_index].index= host_index;
451- ptr->continuum[continuum_index++].value= value;
452- }
453- }
454- else
455- {
456- value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum);
457- ptr->continuum[continuum_index].index= host_index;
458- ptr->continuum[continuum_index++].value= value;
459- }
460- }
461+
462+
463+ if (ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY)
464+ {
465+ for (pointer_index= 0;
466+ pointer_index < pointer_per_server / pointer_per_hash;
467+ pointer_index++)
468+ {
469+ char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
470+ size_t sort_host_length;
471+
472+ // Spymemcached ketema key format is: hostname/ip:port-index
473+ // If hostname is not available then: /ip:port-index
474+ sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
475+ "/%s:%d-%d",
476+ list[host_index].hostname,
477+ list[host_index].port,
478+ pointer_index);
479+#ifdef DEBUG
480+ printf("update_continuum: key is %s\n", sort_host);
481+#endif
482+
483+ WATCHPOINT_ASSERT(sort_host_length);
484+
485+ if (is_ketama_weighted)
486+ {
487+ unsigned int i;
488+ for (i = 0; i < pointer_per_hash; i++)
489+ {
490+ value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i);
491+ ptr->continuum[continuum_index].index= host_index;
492+ ptr->continuum[continuum_index++].value= value;
493+ }
494+ }
495+ else
496+ {
497+ value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum);
498+ ptr->continuum[continuum_index].index= host_index;
499+ ptr->continuum[continuum_index++].value= value;
500+ }
501+ }
502+ }
503+ else
504+ {
505+ for (pointer_index= 1;
506+ pointer_index <= pointer_per_server / pointer_per_hash;
507+ pointer_index++)
508+ {
509+ char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
510+ size_t sort_host_length;
511+
512+ if (list[host_index].port == MEMCACHED_DEFAULT_PORT)
513+ {
514+ sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
515+ "%s-%d",
516+ list[host_index].hostname,
517+ pointer_index - 1);
518+ }
519+ else
520+ {
521+ sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
522+ "%s:%d-%d",
523+ list[host_index].hostname,
524+ list[host_index].port, pointer_index - 1);
525+ }
526+
527+ WATCHPOINT_ASSERT(sort_host_length);
528+
529+ if (is_ketama_weighted)
530+ {
531+ unsigned int i;
532+ for (i = 0; i < pointer_per_hash; i++)
533+ {
534+ value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i);
535+ ptr->continuum[continuum_index].index= host_index;
536+ ptr->continuum[continuum_index++].value= value;
537+ }
538+ }
539+ else
540+ {
541+ value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum);
542+ ptr->continuum[continuum_index].index= host_index;
543+ ptr->continuum[continuum_index++].value= value;
544+ }
545+ }
546+ }
547+
548 pointer_counter+= pointer_per_server;
549 }
550
551
552=== modified file 'tests/function.c'
553--- tests/function.c 2009-10-14 18:50:03 +0000
554+++ tests/function.c 2009-11-03 13:30:25 +0000
555@@ -1463,7 +1463,7 @@
556 memc->number_of_hosts= 1;
557
558 int max_keys= binary ? 20480 : 1;
559-
560+
561
562 char **keys= calloc((size_t)max_keys, sizeof(char*));
563 size_t *key_length=calloc((size_t)max_keys, sizeof(size_t));
564@@ -2590,9 +2590,9 @@
565 /* verify the standard ketama set. */
566 for (x= 0; x < 99; x++)
567 {
568- uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
569+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
570 char *hostname = memc->hosts[server_idx].hostname;
571- assert(strcmp(hostname, test_cases[x].server) == 0);
572+ assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
573 }
574
575 memcached_server_list_free(server_pool);
576@@ -2735,7 +2735,7 @@
577
578 for (int x= 0; x < 99; x++)
579 {
580- uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
581+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
582 assert(server_idx != 2);
583 }
584
585@@ -2745,16 +2745,72 @@
586 run_distribution(memc);
587 for (int x= 0; x < 99; x++)
588 {
589- uint32_t server_idx = memcached_generate_hash(memc, test_cases[x].key, strlen(test_cases[x].key));
590- char *hostname = memc->hosts[server_idx].hostname;
591- assert(strcmp(hostname, test_cases[x].server) == 0);
592- }
593-
594- memcached_server_list_free(server_pool);
595- memcached_free(memc);
596-
597- return TEST_SUCCESS;
598-}
599+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
600+ char *hostname = memc->hosts[server_idx].hostname;
601+ assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
602+ }
603+
604+ memcached_server_list_free(server_pool);
605+ memcached_free(memc);
606+
607+ return TEST_SUCCESS;
608+}
609+
610+static test_return_t output_ketama_weighted_keys(memcached_st *trash)
611+{
612+ (void) trash;
613+
614+ memcached_return rc;
615+ memcached_st *memc= memcached_create(NULL);
616+ assert(memc);
617+
618+
619+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
620+ assert(rc == MEMCACHED_SUCCESS);
621+
622+ uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
623+ assert(value == 1);
624+
625+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
626+ assert(rc == MEMCACHED_SUCCESS);
627+
628+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
629+ assert(value == MEMCACHED_HASH_MD5);
630+
631+
632+ assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
633+ MEMCACHED_KETAMA_COMPAT_SPY) == MEMCACHED_SUCCESS);
634+
635+ memcached_server_st *server_pool;
636+ server_pool = memcached_servers_parse("10.0.1.1:11211,10.0.1.2:11211,10.0.1.3:11211,10.0.1.4:11211,10.0.1.5:11211,10.0.1.6:11211,10.0.1.7:11211,10.0.1.8:11211,192.168.1.1:11211,192.168.100.1:11211");
637+ memcached_server_push(memc, server_pool);
638+
639+ FILE *fp;
640+ if ((fp = fopen("ketama_keys.txt", "w")))
641+ {
642+ // noop
643+ } else {
644+ printf("cannot write to file ketama_keys.txt");
645+ return TEST_FAILURE;
646+ }
647+
648+ for (int x= 0; x < 10000; x++)
649+ {
650+ char key[10];
651+ sprintf(key, "%d", x);
652+
653+ uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
654+ char *hostname = memc->hosts[server_idx].hostname;
655+ unsigned int port = memc->hosts[server_idx].port;
656+ fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
657+ }
658+ fclose(fp);
659+ memcached_server_list_free(server_pool);
660+ memcached_free(memc);
661+
662+ return TEST_SUCCESS;
663+}
664+
665
666 static test_return_t result_static(memcached_st *memc)
667 {
668@@ -4623,6 +4679,125 @@
669 return TEST_SUCCESS;
670 }
671
672+
673+static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
674+{
675+ memcached_return rc;
676+ uint64_t value;
677+ int x;
678+ memcached_server_st *server_pool;
679+ memcached_st *memc;
680+
681+ (void)trash;
682+
683+ memc= memcached_create(NULL);
684+ assert(memc);
685+
686+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
687+ assert(rc == MEMCACHED_SUCCESS);
688+
689+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
690+ assert(value == 1);
691+
692+ assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
693+ MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED) == MEMCACHED_SUCCESS);
694+
695+ assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE) ==
696+ MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED);
697+
698+ server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
699+ memcached_server_push(memc, server_pool);
700+
701+ /* verify that the server list was parsed okay. */
702+ assert(memc->number_of_hosts == 8);
703+ assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
704+ assert(server_pool[0].port == 11211);
705+ assert(server_pool[0].weight == 600);
706+ assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
707+ assert(server_pool[2].port == 11211);
708+ assert(server_pool[2].weight == 200);
709+ assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
710+ assert(server_pool[7].port == 11211);
711+ assert(server_pool[7].weight == 100);
712+
713+ /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
714+ * us test the boundary wraparound.
715+ */
716+ assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
717+
718+ /* verify the standard ketama set. */
719+ for (x= 0; x < 99; x++)
720+ {
721+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
722+ char *hostname = memc->hosts[server_idx].hostname;
723+ assert(strcmp(hostname, ketama_test_cases[x].server) == 0);
724+ }
725+
726+ memcached_server_list_free(server_pool);
727+ memcached_free(memc);
728+
729+ return TEST_SUCCESS;
730+}
731+
732+static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
733+{
734+ memcached_return rc;
735+ uint64_t value;
736+ int x;
737+ memcached_server_st *server_pool;
738+ memcached_st *memc;
739+
740+ (void)trash;
741+
742+ memc= memcached_create(NULL);
743+ assert(memc);
744+
745+ rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
746+ assert(rc == MEMCACHED_SUCCESS);
747+
748+ value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
749+ assert(value == 1);
750+
751+ assert(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE,
752+ MEMCACHED_KETAMA_COMPAT_SPY) == MEMCACHED_SUCCESS);
753+
754+ assert(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE) ==
755+ MEMCACHED_KETAMA_COMPAT_SPY);
756+
757+ server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
758+ memcached_server_push(memc, server_pool);
759+
760+ /* verify that the server list was parsed okay. */
761+ assert(memc->number_of_hosts == 8);
762+ assert(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
763+ assert(server_pool[0].port == 11211);
764+ assert(server_pool[0].weight == 600);
765+ assert(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
766+ assert(server_pool[2].port == 11211);
767+ assert(server_pool[2].weight == 200);
768+ assert(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
769+ assert(server_pool[7].port == 11211);
770+ assert(server_pool[7].weight == 100);
771+
772+ /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
773+ * us test the boundary wraparound.
774+ */
775+ assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
776+
777+ /* verify the standard ketama set. */
778+ for (x= 0; x < 99; x++)
779+ {
780+ uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
781+ char *hostname = memc->hosts[server_idx].hostname;
782+ assert(strcmp(hostname, ketama_test_cases_spy[x].server) == 0);
783+ }
784+
785+ memcached_server_list_free(server_pool);
786+ memcached_free(memc);
787+
788+ return TEST_SUCCESS;
789+}
790+
791 static test_return_t regression_bug_434484(memcached_st *memc)
792 {
793 if (pre_binary(memc) != MEMCACHED_SUCCESS)
794@@ -4834,8 +5009,8 @@
795 ** to do this ;-)
796 */
797 memcached_quit(memc);
798-
799- /* Verify that all messages are stored, and we didn't stuff too much
800+
801+ /* Verify that all messages are stored, and we didn't stuff too much
802 * into the servers
803 */
804 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
805@@ -5175,6 +5350,12 @@
806 {0, 0, 0}
807 };
808
809+test_st ketama_compatibility[]= {
810+ {"libmemcached", 1, ketama_compatibility_libmemcached },
811+ {"spymemcached", 1, ketama_compatibility_spymemcached },
812+ {0, 0, 0}
813+};
814+
815 test_st generate_tests[] ={
816 {"generate_pairs", 1, generate_pairs },
817 {"generate_data", 1, generate_data },
818@@ -5217,6 +5398,7 @@
819
820 test_st ketama_auto_eject_hosts[] ={
821 {"auto_eject_hosts", 1, auto_eject_hosts },
822+ {"output_ketama_weighted_keys", 1, output_ketama_weighted_keys },
823 {0, 0, 0}
824 };
825
826@@ -5280,6 +5462,7 @@
827 {"consistent_not", 0, 0, consistent_tests},
828 {"consistent_ketama", pre_behavior_ketama, 0, consistent_tests},
829 {"consistent_ketama_weighted", pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
830+ {"ketama_compat", 0, 0, ketama_compatibility},
831 {"test_hashes", 0, 0, hash_tests},
832 {"replication", pre_replication, 0, replication_tests},
833 {"replication_noblock", pre_replication_noblock, 0, replication_tests},
834
835=== added file 'tests/ketama_test_cases.h'
836--- tests/ketama_test_cases.h 1970-01-01 00:00:00 +0000
837+++ tests/ketama_test_cases.h 2009-11-03 13:30:25 +0000
838@@ -0,0 +1,113 @@
839+#ifndef TESTS_KETAMA_TEST_CASES_H
840+#define TESTS_KETAMA_TEST_CASES_H
841+
842+static struct {
843+ const char *key;
844+ unsigned long hash1;
845+ unsigned long hash2;
846+ const char *server;
847+} ketama_test_cases[99]= {
848+ { "SVa_]_V41)", 443691461UL, 445379617UL, "10.0.1.7" },
849+ { "*/Z;?V(.\\8", 1422915503UL, 1428303028UL, "10.0.1.1" },
850+ { "30C1*Z*S/_", 1473165754UL, 1480075959UL, "10.0.1.2" },
851+ { "ERR:EC58G>", 2148406511UL, 2168579133UL, "10.0.1.7" },
852+ { "1I=cTMNTKF", 2882686667UL, 2885206587UL, "10.0.1.5" },
853+ { "]VG<`I*Z8)", 1103544263UL, 1104827657UL, "10.0.1.5" },
854+ { "UUTC`-V159", 3716288206UL, 3727224240UL, "10.0.1.5" },
855+ { "@7RU6C6T+Z", 3862737685UL, 3871917949UL, "10.0.1.5" },
856+ { "/XLN0@+36;", 1623269830UL, 1627683651UL, "10.0.1.1" },
857+ { "4(`X;\\V.^c", 373546328UL, 383925769UL, "10.0.1.1" },
858+ { "726bW=9*a4", 4213440020UL, 4213950705UL, "10.0.1.7" },
859+ { "\\`)<B)UE,c", 951096736UL, 955226069UL, "10.0.1.1" },
860+ { "P1[Ma3=K1/", 1989324036UL, 1994028240UL, "10.0.1.8" },
861+ { "C89I.-V?cT", 1604239957UL, 1606398093UL, "10.0.1.8" },
862+ { "D[HE+cFXDK", 2117036136UL, 2117124014UL, "10.0.1.3" },
863+ { "P1L?NAB[)K", 2129972569UL, 2132542634UL, "10.0.1.1" },
864+ { "cDT0)Z5P6,", 176485284UL, 178675413UL, "10.0.1.5" },
865+ { "@JW`+[WAO8", 2720940826UL, 2743975456UL, "10.0.1.5" },
866+ { "\\39DKW^)N_", 3548879868UL, 3550704865UL, "10.0.1.3" },
867+ { "EM75N0+[X1", 1558531507UL, 1559308507UL, "10.0.1.4" },
868+ { "`,SS]NBP,b", 1883545960UL, 1884847278UL, "10.0.1.1" },
869+ { "XX1a9LT+F?", 653487707UL, 656410408UL, "10.0.1.5" },
870+ { "Zc\\-,F-c6V", 1160802451UL, 1171575728UL, "10.0.1.5" },
871+ { "1*RTMC7,03", 1602398012UL, 1606398093UL, "10.0.1.8" },
872+ { "*Xc+V0P>32", 536016577UL, 539988520UL, "10.0.1.7" },
873+ { "U))Fb-(`,.", 4128682289UL, 4136854163UL, "10.0.1.7" },
874+ { "R-08RNTaRT", 3718170086UL, 3727224240UL, "10.0.1.5" },
875+ { "(LHcO203I3", 1007779411UL, 1014643570UL, "10.0.1.5" },
876+ { "=256P+;Qc8", 3976201210UL, 3976304873UL, "10.0.1.5" },
877+ { "OI5XZ_BBT(", 2155922164UL, 2168579133UL, "10.0.1.7" },
878+ { "2TLRL/UL;:", 1086800909UL, 1095659802UL, "10.0.1.7" },
879+ { "WHD\\O1`ZRW", 3087923411UL, 3095471560UL, "10.0.1.5" },
880+ { ".=54)_c;=T", 2497691631UL, 2502731301UL, "10.0.1.1" },
881+ { ";G<W-XWZ@b", 2888169733UL, 2888728739UL, "10.0.1.5" },
882+ { "(,>E`)FT\\4", 580747448UL, 581063326UL, "10.0.1.2" },
883+ { "HZAU*;P*N]", 2564670474UL, 2565697267UL, "10.0.1.7" },
884+ { "NZ@ZE=O84_", 533335275UL, 539988520UL, "10.0.1.7" },
885+ { "6,cEI`F_P>", 3972869246UL, 3974773167UL, "10.0.1.6" },
886+ { "c,5AQ/T5)6", 2835605783UL, 2847870057UL, "10.0.1.8" },
887+ { ".O,>>BT)RX", 3857978174UL, 3871917949UL, "10.0.1.5" },
888+ { "XY\\X::LX50", 1749241099UL, 1752196488UL, "10.0.1.6" },
889+ { "+550F^/.01", 3781824099UL, 3783248219UL, "10.0.1.6" },
890+ { "<.X9E2S5+9", 3232479481UL, 3234387706UL, "10.0.1.7" },
891+ { "]\\.UH8_0a1", 2419699252UL, 2423002920UL, "10.0.1.4" },
892+ { "8(6=(T0/Z0", 728266737UL, 729026070UL, "10.0.1.7" },
893+ { "8*6a;Sc*X+", 4223431086UL, 4230156966UL, "10.0.1.2" },
894+ { "<QW:;3K6;H", 2731158143UL, 2743975456UL, "10.0.1.5" },
895+ { "7C@EY@-Y?_", 760770733UL, 761576669UL, "10.0.1.5" },
896+ { "aPb3E1WD4K", 2500489218UL, 2502731301UL, "10.0.1.1" },
897+ { "?@12R<=1BH", 1494795329UL, 1502505505UL, "10.0.1.8" },
898+ { "QR(a+Q=1FU", 3238535074UL, 3238996435UL, "10.0.1.6" },
899+ { "`C9^FV,960", 2628553463UL, 2628733766UL, "10.0.1.6" },
900+ { "UNHVP..^8H", 977096483UL, 977319837UL, "10.0.1.4" },
901+ { ":Y.2W2[(35", 2777083668UL, 2784182515UL, "10.0.1.7" },
902+ { "M/HV^_HZ4O", 3623390946UL, 3624445007UL, "10.0.1.7" },
903+ { "ZY16KQ<ICD", 1831153193UL, 1838563516UL, "10.0.1.4" },
904+ { "bV2,`a.PY9", 1962228869UL, 1962648654UL, "10.0.1.1" },
905+ { "U;9:-+5N]9", 269504649UL, 277560877UL, "10.0.1.1" },
906+ { "1S/:aJ[1(;", 578069729UL, 581063326UL, "10.0.1.2" },
907+ { "Nb-X^]M)I:", 330865696UL, 331009896UL, "10.0.1.6" },
908+ { "2;M;ES>J5/", 2776949824UL, 2784182515UL, "10.0.1.7" },
909+ { "[>RZHG97Q9", 71954686UL, 72034069UL, "10.0.1.6" },
910+ { "J3/G[)9<^Z", 2799896459UL, 2805183696UL, "10.0.1.7" },
911+ { "N-)88>[O`,", 50404102UL, 51792557UL, "10.0.1.5" },
912+ { "NP:=FR\\OaA", 3837333776UL, 3837792034UL, "10.0.1.7" },
913+ { "`@L+W;a,O[", 1512157148UL, 1522285852UL, "10.0.1.6" },
914+ { "W2`P:-+1T[", 2945171975UL, 2946196424UL, "10.0.1.5" },
915+ { "-6G7K^YDIN", 3168617340UL, 3170513015UL, "10.0.1.7" },
916+ { "U>*>9ZI6V5", 668514946UL, 674097631UL, "10.0.1.6" },
917+ { ".I?^6Ic9RK", 938419020UL, 942832691UL, "10.0.1.6" },
918+ { "0OZH^9BKM[", 3682518606UL, 3686781297UL, "10.0.1.8" },
919+ { "5?50UGZ:ML", 868610882UL, 869425986UL, "10.0.1.5" },
920+ { "?K2NF@3=IU", 381218851UL, 383925769UL, "10.0.1.1" },
921+ { "YI@G-2X?UB", 3688706179UL, 3693197681UL, "10.0.1.5" },
922+ { "7cY</BSaL=", 3976870223UL, 3978903843UL, "10.0.1.6" },
923+ { "A(`KF:[RH8", 3292979676UL, 3294849139UL, "10.0.1.6" },
924+ { ";=ZT\\W^P+H", 1401102653UL, 1416290674UL, "10.0.1.4" },
925+ { "b2?WFF56;R", 480494704UL, 486971192UL, "10.0.1.4" },
926+ { "CTR74,J+N.", 137446045UL, 146633907UL, "10.0.1.8" },
927+ { "<b;*R+QDST", 1304985302UL, 1308223778UL, "10.0.1.5" },
928+ { "\\R^7=9UCG`", 126218373UL, 129199837UL, "10.0.1.5" },
929+ { "1bQS5]WOXB", 1853470245UL, 1855329369UL, "10.0.1.4" },
930+ { "M(@X^b[L:K", 3019630308UL, 3022260113UL, "10.0.1.1" },
931+ { "431cBF8,YO", 1679726993UL, 1685224295UL, "10.0.1.7" },
932+ { "(bEIQJ:E./", 2922607787UL, 2925521819UL, "10.0.1.6" },
933+ { "WS/3H*)7F;", 419488232UL, 422140585UL, "10.0.1.5" },
934+ { "ZJF[Ia6Q)+", 3960568056UL, 3962489998UL, "10.0.1.7" },
935+ { "<]*QCK8U,>", 2590140172UL, 2598117636UL, "10.0.1.7" },
936+ { "\\[a\\^=V_M0", 689410119UL, 698690782UL, "10.0.1.6" },
937+ { "7;RM+8J9YC", 1530175299UL, 1531107082UL, "10.0.1.7" },
938+ { "4*=.SPR[AV", 3928582722UL, 3928853792UL, "10.0.1.1" },
939+ { "-2F+^88P4U", 3023552752UL, 3025823613UL, "10.0.1.7" },
940+ { "X;-F`(N?9D", 570465234UL, 572485994UL, "10.0.1.7" },
941+ { "R=F_D-K2a]", 1287750228UL, 1290935562UL, "10.0.1.7" },
942+ { "X*+2aaC.EG", 3200948713UL, 3201088518UL, "10.0.1.5" },
943+ { "[1ZXONX2]a", 4108881567UL, 4109865744UL, "10.0.1.4" },
944+ { "FL;\\GWacaV", 458449508UL, 467374054UL, "10.0.1.4" },
945+ { "\\MQ_XNT7L-", 1259349383UL, 1259509450UL, "10.0.1.7" },
946+ { "VD6D0]ba_\\", 3842502950UL, 3842588691UL, "10.0.1.1" },
947+};
948+
949+#include "ketama_test_cases_spy.h"
950+
951+#endif
952
953=== renamed file 'tests/ketama_test_cases.h' => 'tests/ketama_test_cases_spy.h'
954--- tests/ketama_test_cases.h 2009-07-08 13:38:34 +0000
955+++ tests/ketama_test_cases_spy.h 2009-11-03 13:30:25 +0000
956@@ -1,108 +1,110 @@
957-typedef struct {
958+#ifndef TESTS_KETAMA_TEST_CASES_SPY_H
959+#define TESTS_KETAMA_TEST_CASES_SPY_H
960+
961+static struct {
962 const char *key;
963 unsigned long hash1;
964 unsigned long hash2;
965 const char *server;
966-} TestCase;
967-
968-static TestCase test_cases[99] = {
969- { "SVa_]_V41)", 443691461UL, 445379617UL, "10.0.1.7" },
970- { "*/Z;?V(.\\8", 1422915503UL, 1428303028UL, "10.0.1.1" },
971+} ketama_test_cases_spy[99]= {
972+ { "SVa_]_V41)", 443691461UL, 445379617UL, "10.0.1.2" },
973+ { "*/Z;?V(.\\8", 1422915503UL, 1428303028UL, "10.0.1.4" },
974 { "30C1*Z*S/_", 1473165754UL, 1480075959UL, "10.0.1.2" },
975 { "ERR:EC58G>", 2148406511UL, 2168579133UL, "10.0.1.7" },
976- { "1I=cTMNTKF", 2882686667UL, 2885206587UL, "10.0.1.5" },
977+ { "1I=cTMNTKF", 2882686667UL, 2885206587UL, "10.0.1.4" },
978 { "]VG<`I*Z8)", 1103544263UL, 1104827657UL, "10.0.1.5" },
979- { "UUTC`-V159", 3716288206UL, 3727224240UL, "10.0.1.5" },
980- { "@7RU6C6T+Z", 3862737685UL, 3871917949UL, "10.0.1.5" },
981- { "/XLN0@+36;", 1623269830UL, 1627683651UL, "10.0.1.1" },
982- { "4(`X;\\V.^c", 373546328UL, 383925769UL, "10.0.1.1" },
983- { "726bW=9*a4", 4213440020UL, 4213950705UL, "10.0.1.7" },
984- { "\\`)<B)UE,c", 951096736UL, 955226069UL, "10.0.1.1" },
985- { "P1[Ma3=K1/", 1989324036UL, 1994028240UL, "10.0.1.8" },
986- { "C89I.-V?cT", 1604239957UL, 1606398093UL, "10.0.1.8" },
987- { "D[HE+cFXDK", 2117036136UL, 2117124014UL, "10.0.1.3" },
988- { "P1L?NAB[)K", 2129972569UL, 2132542634UL, "10.0.1.1" },
989- { "cDT0)Z5P6,", 176485284UL, 178675413UL, "10.0.1.5" },
990- { "@JW`+[WAO8", 2720940826UL, 2743975456UL, "10.0.1.5" },
991- { "\\39DKW^)N_", 3548879868UL, 3550704865UL, "10.0.1.3" },
992- { "EM75N0+[X1", 1558531507UL, 1559308507UL, "10.0.1.4" },
993+ { "UUTC`-V159", 3716288206UL, 3727224240UL, "10.0.1.7" },
994+ { "@7RU6C6T+Z", 3862737685UL, 3871917949UL, "10.0.1.6" },
995+ { "/XLN0@+36;", 1623269830UL, 1627683651UL, "10.0.1.7" },
996+ { "4(`X;\\V.^c", 373546328UL, 383925769UL, "10.0.1.6" },
997+ { "726bW=9*a4", 4213440020UL, 4213950705UL, "10.0.1.3" },
998+ { "\\`)<B)UE,c", 951096736UL, 955226069UL, "10.0.1.8" },
999+ { "P1[Ma3=K1/", 1989324036UL, 1994028240UL, "10.0.1.1" },
1000+ { "C89I.-V?cT", 1604239957UL, 1606398093UL, "10.0.1.5" },
1001+ { "D[HE+cFXDK", 2117036136UL, 2117124014UL, "10.0.1.5" },
1002+ { "P1L?NAB[)K", 2129972569UL, 2132542634UL, "10.0.1.7" },
1003+ { "cDT0)Z5P6,", 176485284UL, 178675413UL, "10.0.1.1" },
1004+ { "@JW`+[WAO8", 2720940826UL, 2743975456UL, "10.0.1.2" },
1005+ { "\\39DKW^)N_", 3548879868UL, 3550704865UL, "10.0.1.6" },
1006+ { "EM75N0+[X1", 1558531507UL, 1559308507UL, "10.0.1.5" },
1007 { "`,SS]NBP,b", 1883545960UL, 1884847278UL, "10.0.1.1" },
1008- { "XX1a9LT+F?", 653487707UL, 656410408UL, "10.0.1.5" },
1009- { "Zc\\-,F-c6V", 1160802451UL, 1171575728UL, "10.0.1.5" },
1010- { "1*RTMC7,03", 1602398012UL, 1606398093UL, "10.0.1.8" },
1011+ { "XX1a9LT+F?", 653487707UL, 656410408UL, "10.0.1.6" },
1012+ { "Zc\\-,F-c6V", 1160802451UL, 1171575728UL, "10.0.1.6" },
1013+ { "1*RTMC7,03", 1602398012UL, 1606398093UL, "10.0.1.5" },
1014 { "*Xc+V0P>32", 536016577UL, 539988520UL, "10.0.1.7" },
1015 { "U))Fb-(`,.", 4128682289UL, 4136854163UL, "10.0.1.7" },
1016 { "R-08RNTaRT", 3718170086UL, 3727224240UL, "10.0.1.5" },
1017- { "(LHcO203I3", 1007779411UL, 1014643570UL, "10.0.1.5" },
1018- { "=256P+;Qc8", 3976201210UL, 3976304873UL, "10.0.1.5" },
1019- { "OI5XZ_BBT(", 2155922164UL, 2168579133UL, "10.0.1.7" },
1020- { "2TLRL/UL;:", 1086800909UL, 1095659802UL, "10.0.1.7" },
1021- { "WHD\\O1`ZRW", 3087923411UL, 3095471560UL, "10.0.1.5" },
1022- { ".=54)_c;=T", 2497691631UL, 2502731301UL, "10.0.1.1" },
1023- { ";G<W-XWZ@b", 2888169733UL, 2888728739UL, "10.0.1.5" },
1024- { "(,>E`)FT\\4", 580747448UL, 581063326UL, "10.0.1.2" },
1025- { "HZAU*;P*N]", 2564670474UL, 2565697267UL, "10.0.1.7" },
1026+ { "(LHcO203I3", 1007779411UL, 1014643570UL, "10.0.1.1" },
1027+ { "=256P+;Qc8", 3976201210UL, 3976304873UL, "10.0.1.3" },
1028+ { "OI5XZ_BBT(", 2155922164UL, 2168579133UL, "10.0.1.5" },
1029+ { "2TLRL/UL;:", 1086800909UL, 1095659802UL, "10.0.1.2" },
1030+ { "WHD\\O1`ZRW", 3087923411UL, 3095471560UL, "10.0.1.1" },
1031+ { ".=54)_c;=T", 2497691631UL, 2502731301UL, "10.0.1.6" },
1032+ { ";G<W-XWZ@b", 2888169733UL, 2888728739UL, "10.0.1.7" },
1033+ { "(,>E`)FT\\4", 580747448UL, 581063326UL, "10.0.1.5" },
1034+ { "HZAU*;P*N]", 2564670474UL, 2565697267UL, "10.0.1.1" },
1035 { "NZ@ZE=O84_", 533335275UL, 539988520UL, "10.0.1.7" },
1036- { "6,cEI`F_P>", 3972869246UL, 3974773167UL, "10.0.1.6" },
1037- { "c,5AQ/T5)6", 2835605783UL, 2847870057UL, "10.0.1.8" },
1038- { ".O,>>BT)RX", 3857978174UL, 3871917949UL, "10.0.1.5" },
1039- { "XY\\X::LX50", 1749241099UL, 1752196488UL, "10.0.1.6" },
1040- { "+550F^/.01", 3781824099UL, 3783248219UL, "10.0.1.6" },
1041+ { "6,cEI`F_P>", 3972869246UL, 3974773167UL, "10.0.1.3" },
1042+ { "c,5AQ/T5)6", 2835605783UL, 2847870057UL, "10.0.1.7" },
1043+ { ".O,>>BT)RX", 3857978174UL, 3871917949UL, "10.0.1.7" },
1044+ { "XY\\X::LX50", 1749241099UL, 1752196488UL, "10.0.1.7" },
1045+ { "+550F^/.01", 3781824099UL, 3783248219UL, "10.0.1.2" },
1046 { "<.X9E2S5+9", 3232479481UL, 3234387706UL, "10.0.1.7" },
1047- { "]\\.UH8_0a1", 2419699252UL, 2423002920UL, "10.0.1.4" },
1048- { "8(6=(T0/Z0", 728266737UL, 729026070UL, "10.0.1.7" },
1049- { "8*6a;Sc*X+", 4223431086UL, 4230156966UL, "10.0.1.2" },
1050- { "<QW:;3K6;H", 2731158143UL, 2743975456UL, "10.0.1.5" },
1051+ { "]\\.UH8_0a1", 2419699252UL, 2423002920UL, "10.0.1.6" },
1052+ { "8(6=(T0/Z0", 728266737UL, 729026070UL, "10.0.1.6" },
1053+ { "8*6a;Sc*X+", 4223431086UL, 4230156966UL, "10.0.1.5" },
1054+ { "<QW:;3K6;H", 2731158143UL, 2743975456UL, "10.0.1.7" },
1055 { "7C@EY@-Y?_", 760770733UL, 761576669UL, "10.0.1.5" },
1056- { "aPb3E1WD4K", 2500489218UL, 2502731301UL, "10.0.1.1" },
1057- { "?@12R<=1BH", 1494795329UL, 1502505505UL, "10.0.1.8" },
1058- { "QR(a+Q=1FU", 3238535074UL, 3238996435UL, "10.0.1.6" },
1059- { "`C9^FV,960", 2628553463UL, 2628733766UL, "10.0.1.6" },
1060- { "UNHVP..^8H", 977096483UL, 977319837UL, "10.0.1.4" },
1061- { ":Y.2W2[(35", 2777083668UL, 2784182515UL, "10.0.1.7" },
1062- { "M/HV^_HZ4O", 3623390946UL, 3624445007UL, "10.0.1.7" },
1063- { "ZY16KQ<ICD", 1831153193UL, 1838563516UL, "10.0.1.4" },
1064- { "bV2,`a.PY9", 1962228869UL, 1962648654UL, "10.0.1.1" },
1065- { "U;9:-+5N]9", 269504649UL, 277560877UL, "10.0.1.1" },
1066- { "1S/:aJ[1(;", 578069729UL, 581063326UL, "10.0.1.2" },
1067- { "Nb-X^]M)I:", 330865696UL, 331009896UL, "10.0.1.6" },
1068- { "2;M;ES>J5/", 2776949824UL, 2784182515UL, "10.0.1.7" },
1069- { "[>RZHG97Q9", 71954686UL, 72034069UL, "10.0.1.6" },
1070- { "J3/G[)9<^Z", 2799896459UL, 2805183696UL, "10.0.1.7" },
1071- { "N-)88>[O`,", 50404102UL, 51792557UL, "10.0.1.5" },
1072+ { "aPb3E1WD4K", 2500489218UL, 2502731301UL, "10.0.1.2" },
1073+ { "?@12R<=1BH", 1494795329UL, 1502505505UL, "10.0.1.1" },
1074+ { "QR(a+Q=1FU", 3238535074UL, 3238996435UL, "10.0.1.5" },
1075+ { "`C9^FV,960", 2628553463UL, 2628733766UL, "10.0.1.3" },
1076+ { "UNHVP..^8H", 977096483UL, 977319837UL, "10.0.1.6" },
1077+ { ":Y.2W2[(35", 2777083668UL, 2784182515UL, "10.0.1.6" },
1078+ { "M/HV^_HZ4O", 3623390946UL, 3624445007UL, "10.0.1.4" },
1079+ { "ZY16KQ<ICD", 1831153193UL, 1838563516UL, "10.0.1.7" },
1080+ { "bV2,`a.PY9", 1962228869UL, 1962648654UL, "10.0.1.7" },
1081+ { "U;9:-+5N]9", 269504649UL, 277560877UL, "10.0.1.2" },
1082+ { "1S/:aJ[1(;", 578069729UL, 581063326UL, "10.0.1.5" },
1083+ { "Nb-X^]M)I:", 330865696UL, 331009896UL, "10.0.1.3" },
1084+ { "2;M;ES>J5/", 2776949824UL, 2784182515UL, "10.0.1.6" },
1085+ { "[>RZHG97Q9", 71954686UL, 72034069UL, "10.0.1.4" },
1086+ { "J3/G[)9<^Z", 2799896459UL, 2805183696UL, "10.0.1.6" },
1087+ { "N-)88>[O`,", 50404102UL, 51792557UL, "10.0.1.2" },
1088 { "NP:=FR\\OaA", 3837333776UL, 3837792034UL, "10.0.1.7" },
1089- { "`@L+W;a,O[", 1512157148UL, 1522285852UL, "10.0.1.6" },
1090- { "W2`P:-+1T[", 2945171975UL, 2946196424UL, "10.0.1.5" },
1091- { "-6G7K^YDIN", 3168617340UL, 3170513015UL, "10.0.1.7" },
1092- { "U>*>9ZI6V5", 668514946UL, 674097631UL, "10.0.1.6" },
1093+ { "`@L+W;a,O[", 1512157148UL, 1522285852UL, "10.0.1.5" },
1094+ { "W2`P:-+1T[", 2945171975UL, 2946196424UL, "10.0.1.7" },
1095+ { "-6G7K^YDIN", 3168617340UL, 3170513015UL, "10.0.1.5" },
1096+ { "U>*>9ZI6V5", 668514946UL, 674097631UL, "10.0.1.5" },
1097 { ".I?^6Ic9RK", 938419020UL, 942832691UL, "10.0.1.6" },
1098- { "0OZH^9BKM[", 3682518606UL, 3686781297UL, "10.0.1.8" },
1099- { "5?50UGZ:ML", 868610882UL, 869425986UL, "10.0.1.5" },
1100- { "?K2NF@3=IU", 381218851UL, 383925769UL, "10.0.1.1" },
1101- { "YI@G-2X?UB", 3688706179UL, 3693197681UL, "10.0.1.5" },
1102- { "7cY</BSaL=", 3976870223UL, 3978903843UL, "10.0.1.6" },
1103+ { "0OZH^9BKM[", 3682518606UL, 3686781297UL, "10.0.1.2" },
1104+ { "5?50UGZ:ML", 868610882UL, 869425986UL, "10.0.1.6" },
1105+ { "?K2NF@3=IU", 381218851UL, 383925769UL, "10.0.1.6" },
1106+ { "YI@G-2X?UB", 3688706179UL, 3693197681UL, "10.0.1.6" },
1107+ { "7cY</BSaL=", 3976870223UL, 3978903843UL, "10.0.1.7" },
1108 { "A(`KF:[RH8", 3292979676UL, 3294849139UL, "10.0.1.6" },
1109- { ";=ZT\\W^P+H", 1401102653UL, 1416290674UL, "10.0.1.4" },
1110- { "b2?WFF56;R", 480494704UL, 486971192UL, "10.0.1.4" },
1111- { "CTR74,J+N.", 137446045UL, 146633907UL, "10.0.1.8" },
1112+ { ";=ZT\\W^P+H", 1401102653UL, 1416290674UL, "10.0.1.6" },
1113+ { "b2?WFF56;R", 480494704UL, 486971192UL, "10.0.1.7" },
1114+ { "CTR74,J+N.", 137446045UL, 146633907UL, "10.0.1.7" },
1115 { "<b;*R+QDST", 1304985302UL, 1308223778UL, "10.0.1.5" },
1116- { "\\R^7=9UCG`", 126218373UL, 129199837UL, "10.0.1.5" },
1117- { "1bQS5]WOXB", 1853470245UL, 1855329369UL, "10.0.1.4" },
1118- { "M(@X^b[L:K", 3019630308UL, 3022260113UL, "10.0.1.1" },
1119- { "431cBF8,YO", 1679726993UL, 1685224295UL, "10.0.1.7" },
1120- { "(bEIQJ:E./", 2922607787UL, 2925521819UL, "10.0.1.6" },
1121- { "WS/3H*)7F;", 419488232UL, 422140585UL, "10.0.1.5" },
1122- { "ZJF[Ia6Q)+", 3960568056UL, 3962489998UL, "10.0.1.7" },
1123- { "<]*QCK8U,>", 2590140172UL, 2598117636UL, "10.0.1.7" },
1124- { "\\[a\\^=V_M0", 689410119UL, 698690782UL, "10.0.1.6" },
1125+ { "\\R^7=9UCG`", 126218373UL, 129199837UL, "10.0.1.6" },
1126+ { "1bQS5]WOXB", 1853470245UL, 1855329369UL, "10.0.1.7" },
1127+ { "M(@X^b[L:K", 3019630308UL, 3022260113UL, "10.0.1.4" },
1128+ { "431cBF8,YO", 1679726993UL, 1685224295UL, "10.0.1.1" },
1129+ { "(bEIQJ:E./", 2922607787UL, 2925521819UL, "10.0.1.7" },
1130+ { "WS/3H*)7F;", 419488232UL, 422140585UL, "10.0.1.3" },
1131+ { "ZJF[Ia6Q)+", 3960568056UL, 3962489998UL, "10.0.1.5" },
1132+ { "<]*QCK8U,>", 2590140172UL, 2598117636UL, "10.0.1.5" },
1133+ { "\\[a\\^=V_M0", 689410119UL, 698690782UL, "10.0.1.7" },
1134 { "7;RM+8J9YC", 1530175299UL, 1531107082UL, "10.0.1.7" },
1135- { "4*=.SPR[AV", 3928582722UL, 3928853792UL, "10.0.1.1" },
1136+ { "4*=.SPR[AV", 3928582722UL, 3928853792UL, "10.0.1.3" },
1137 { "-2F+^88P4U", 3023552752UL, 3025823613UL, "10.0.1.7" },
1138- { "X;-F`(N?9D", 570465234UL, 572485994UL, "10.0.1.7" },
1139- { "R=F_D-K2a]", 1287750228UL, 1290935562UL, "10.0.1.7" },
1140- { "X*+2aaC.EG", 3200948713UL, 3201088518UL, "10.0.1.5" },
1141- { "[1ZXONX2]a", 4108881567UL, 4109865744UL, "10.0.1.4" },
1142- { "FL;\\GWacaV", 458449508UL, 467374054UL, "10.0.1.4" },
1143- { "\\MQ_XNT7L-", 1259349383UL, 1259509450UL, "10.0.1.7" },
1144- { "VD6D0]ba_\\", 3842502950UL, 3842588691UL, "10.0.1.1" },
1145+ { "X;-F`(N?9D", 570465234UL, 572485994UL, "10.0.1.5" },
1146+ { "R=F_D-K2a]", 1287750228UL, 1290935562UL, "10.0.1.1" },
1147+ { "X*+2aaC.EG", 3200948713UL, 3201088518UL, "10.0.1.3" },
1148+ { "[1ZXONX2]a", 4108881567UL, 4109865744UL, "10.0.1.7" },
1149+ { "FL;\\GWacaV", 458449508UL, 467374054UL, "10.0.1.7" },
1150+ { "\\MQ_XNT7L-", 1259349383UL, 1259509450UL, "10.0.1.5" },
1151+ { "VD6D0]ba_\\", 3842502950UL, 3842588691UL, "10.0.1.7" },
1152 };
1153+#endif

Subscribers

People subscribed via source and target branches

to all changes: