Merge lp:~jake-moilanen/libmemcached/ubuntu32-build into lp:~tangent-org/libmemcached/trunk
- ubuntu32-build
- Merge into trunk
Proposed by
Jake Moilanen
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~jake-moilanen/libmemcached/ubuntu32-build |
Merge into: | lp:~tangent-org/libmemcached/trunk |
Diff against target: |
4999 lines (+2532/-1181) 48 files modified
.bzrignore (+1/-0) Makefile.am (+1/-1) clients/ms_atomic.h (+4/-0) clients/ms_conn.c (+13/-13) clients/ms_memslap.h (+3/-0) clients/ms_stats.c (+21/-0) clients/ms_stats.h (+13/-0) clients/ms_task.c (+6/-6) clients/ms_thread.c (+2/-2) configure.ac (+45/-0) libhashkit/Makefile.am (+43/-0) libhashkit/algorithm.h (+49/-0) libhashkit/behavior.c (+89/-0) libhashkit/behavior.h (+68/-0) libhashkit/common.h (+32/-0) libhashkit/crc32.c (+2/-3) libhashkit/default.c (+28/-0) libhashkit/fnv.c (+75/-0) libhashkit/hashkit.c (+255/-226) libhashkit/hashkit.h (+117/-0) libhashkit/hsieh.c (+2/-2) libhashkit/jenkins.c (+4/-4) libhashkit/ketama.c (+113/-473) libhashkit/md5.c (+12/-1) libhashkit/murmur.c (+2/-2) libhashkit/types.h (+85/-0) libhashkit/visibility.h (+51/-0) libmemcached/Makefile.am (+4/-13) libmemcached/common.h (+13/-26) libmemcached/memcached.c (+55/-4) libmemcached/memcached.h (+6/-11) libmemcached/memcached_behavior.c (+43/-10) libmemcached/memcached_constants.h (+4/-7) libmemcached/memcached_hash.c (+46/-0) libmemcached/memcached_hash.h (+9/-0) libmemcached/memcached_server.c (+298/-0) libmemcached/memcached_types.h (+4/-5) m4/pandora_have_libhashkit.m4 (+51/-0) tests/Makefile.am (+22/-15) tests/atomsmasher.c (+4/-4) tests/function.c (+290/-319) tests/hash_results.h (+115/-0) tests/hashkit_functions.c (+363/-0) tests/output_plus.res (+0/-5) tests/plus.cpp (+17/-11) tests/test.c (+38/-16) tests/test.h (+13/-1) tests/udp.c (+1/-1) |
To merge this branch: | bzr merge lp:~jake-moilanen/libmemcached/ubuntu32-build |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Libmemcached-developers | Pending | ||
Review via email: mp+16045@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Jake Moilanen (jake-moilanen) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2009-10-01 13:45:12 +0000 |
3 | +++ .bzrignore 2009-12-11 17:27:14 +0000 |
4 | @@ -65,3 +65,4 @@ |
5 | libmemcached-0.31-1.src.rpm |
6 | libmemcached-0.31-1.x86_64.rpm |
7 | libmemcached-?.??/ |
8 | +tests/testhashkit |
9 | |
10 | === modified file 'Makefile.am' |
11 | --- Makefile.am 2009-10-05 18:37:05 +0000 |
12 | +++ Makefile.am 2009-12-11 17:27:14 +0000 |
13 | @@ -1,6 +1,6 @@ |
14 | ACLOCAL_AMFLAGS = -I m4 |
15 | |
16 | -SUBDIRS = docs libmemcached support clients tests example |
17 | +SUBDIRS = docs ${PANDORA_BUNDLED_SUBDIRS} libmemcached support clients tests example |
18 | EXTRA_dist = README.FIRST |
19 | |
20 | check-local: test-no-outputdiff |
21 | |
22 | === modified file 'clients/ms_atomic.h' |
23 | --- clients/ms_atomic.h 2009-12-03 19:26:03 +0000 |
24 | +++ clients/ms_atomic.h 2009-12-11 17:27:14 +0000 |
25 | @@ -23,6 +23,10 @@ |
26 | # define atomic_dec_16_nv(X) __sync_fetch_and_sub((X), 1) |
27 | # define atomic_dec_32_nv(X) __sync_fetch_and_sub((X), 1) |
28 | # define atomic_dec_64_nv(X) __sync_fetch_and_sub((X), 1) |
29 | + |
30 | +# define spin_lock(l) while (__sync_lock_test_and_set(l, (void *) 1) == 1) {} |
31 | +# define spin_unlock(l) { asm volatile ("sfence":::"memory"); *(l) = 0;} |
32 | + |
33 | #endif /* defined(__SUNPRO_C) */ |
34 | |
35 | #endif /* CLIENTS_MS_ATOMIC_H */ |
36 | |
37 | === modified file 'clients/ms_conn.c' |
38 | --- clients/ms_conn.c 2009-12-06 09:02:23 +0000 |
39 | +++ clients/ms_conn.c 2009-12-11 17:27:14 +0000 |
40 | @@ -371,7 +371,7 @@ |
41 | |
42 | if (! (ms_setting.facebook_test && is_udp)) |
43 | { |
44 | - atomic_add_32(&ms_stats.active_conns, 1); |
45 | + ms_update_conns(&ms_stats, &ms_stats.active_conns, 1); |
46 | } |
47 | |
48 | return 0; |
49 | @@ -691,7 +691,7 @@ |
50 | close(c->udpsfd); |
51 | } |
52 | |
53 | - atomic_dec_32(&ms_stats.active_conns); |
54 | + ms_update_conns(&ms_stats, &ms_stats.active_conns, -1); |
55 | |
56 | ms_conn_free(c); |
57 | |
58 | @@ -1589,7 +1589,7 @@ |
59 | |
60 | if (res > 0) |
61 | { |
62 | - atomic_add_64(&ms_stats.bytes_read, res); |
63 | + ms_update_stats(&ms_stats, &ms_stats.bytes_read, res); |
64 | c->rudpbytes+= res; |
65 | rbytes+= res; |
66 | if (res == avail) |
67 | @@ -1623,7 +1623,7 @@ |
68 | |
69 | if (copybytes == -1) |
70 | { |
71 | - atomic_add_64(&ms_stats.pkt_disorder, 1); |
72 | + ms_update_stats(&ms_stats, (uint64_t *)&ms_stats.pkt_disorder, 1); |
73 | } |
74 | |
75 | return copybytes; |
76 | @@ -1701,7 +1701,7 @@ |
77 | { |
78 | if (! c->udp) |
79 | { |
80 | - atomic_add_64(&ms_stats.bytes_read, res); |
81 | + ms_update_stats(&ms_stats, &ms_stats.bytes_read, res); |
82 | } |
83 | gotdata= 1; |
84 | c->rbytes+= res; |
85 | @@ -1765,7 +1765,7 @@ |
86 | if (curr_time.tv_sec - c->curr_task.item->client_time |
87 | > c->curr_task.item->exp_time + EXPIRE_TIME_ERROR) |
88 | { |
89 | - atomic_add_64(&ms_stats.exp_get, 1); |
90 | + ms_update_stats(&ms_stats, &ms_stats.exp_get, 1); |
91 | |
92 | if (ms_setting.verbose) |
93 | { |
94 | @@ -1806,7 +1806,7 @@ |
95 | if ((c->curr_task.item->value_size != vlen) |
96 | || (memcmp(orignval, value, (size_t)vlen) != 0)) |
97 | { |
98 | - atomic_add_64(&ms_stats.vef_failed, 1); |
99 | + ms_update_stats(&ms_stats, &ms_stats.vef_failed, 1); |
100 | |
101 | if (ms_setting.verbose) |
102 | { |
103 | @@ -2254,7 +2254,7 @@ |
104 | res= sendmsg(c->sfd, m, 0); |
105 | if (res > 0) |
106 | { |
107 | - atomic_add_64(&ms_stats.bytes_written, res); |
108 | + ms_update_stats(&ms_stats, &ms_stats.bytes_written, (int)res); |
109 | |
110 | /* We've written some of the data. Remove the completed |
111 | * iovec entries from the list of pending writes. */ |
112 | @@ -2997,9 +2997,9 @@ |
113 | } |
114 | } |
115 | |
116 | - atomic_add_64(&ms_stats.obj_bytes, |
117 | - item->key_size + item->value_size); |
118 | - atomic_add_64(&ms_stats.cmd_set, 1); |
119 | + ms_update_stats(&ms_stats, &ms_stats.obj_bytes, |
120 | + item->key_size + item->value_size); |
121 | + ms_update_stats(&ms_stats, &ms_stats.cmd_set, 1); |
122 | |
123 | return 0; |
124 | } /* ms_mcd_set */ |
125 | @@ -3083,7 +3083,7 @@ |
126 | } |
127 | } |
128 | |
129 | - atomic_add_64(&ms_stats.cmd_get, 1); |
130 | + ms_update_stats(&ms_stats, &ms_stats.cmd_get, 1); |
131 | |
132 | return 0; |
133 | } /* ms_mcd_get */ |
134 | @@ -3182,7 +3182,7 @@ |
135 | for (int i= 0; i < c->mlget_task.mlget_num; i++) |
136 | { |
137 | item= c->mlget_task.mlget_item[i].item; |
138 | - atomic_add_64(&ms_stats.cmd_get, 1); |
139 | + ms_update_stats(&ms_stats, &ms_stats.cmd_get, 1); |
140 | } |
141 | |
142 | return 0; |
143 | |
144 | === modified file 'clients/ms_memslap.h' |
145 | --- clients/ms_memslap.h 2009-12-03 19:26:03 +0000 |
146 | +++ clients/ms_memslap.h 2009-12-11 17:27:14 +0000 |
147 | @@ -28,6 +28,8 @@ |
148 | extern "C" { |
149 | #endif |
150 | |
151 | +typedef int32_t spin_lock_t; |
152 | + |
153 | /* command line option */ |
154 | typedef enum |
155 | { |
156 | @@ -85,6 +87,7 @@ |
157 | volatile uint64_t pkt_disorder; /* disorder packages of UDP */ |
158 | uint64_t pkt_drop; /* packages dropped of UDP */ |
159 | uint64_t udp_timeout; /* how many times timeout of UDP happens */ |
160 | + spin_lock_t stats_lock; /* lock to update stats structure */ |
161 | } ms_stats_t; |
162 | |
163 | /* lock adapter */ |
164 | |
165 | === modified file 'clients/ms_stats.c' |
166 | --- clients/ms_stats.c 2009-12-03 20:16:27 +0000 |
167 | +++ clients/ms_stats.c 2009-12-11 17:27:14 +0000 |
168 | @@ -12,7 +12,9 @@ |
169 | #include "config.h" |
170 | |
171 | #include <inttypes.h> |
172 | +#include "ms_memslap.h" |
173 | #include "ms_stats.h" |
174 | +#include "ms_atomic.h" |
175 | |
176 | #define array_size(x) (sizeof(x) / sizeof((x)[0])) |
177 | |
178 | @@ -305,3 +307,22 @@ |
179 | stat->period_max_time= 0; |
180 | stat->pre_get_miss= stat->get_miss; |
181 | } /* ms_dump_format_stats */ |
182 | + |
183 | +void ms_update_stats(struct stats * stats, |
184 | + uint64_t * stat, |
185 | + int amount) |
186 | +{ |
187 | + spin_lock(&stats->stats_lock); |
188 | + *stat += (uint64_t)amount; |
189 | + spin_unlock(&stats->stats_lock); |
190 | +} |
191 | + |
192 | +void ms_update_conns(struct stats * stats, |
193 | + volatile uint32_t * num_conns, |
194 | + int amount) |
195 | +{ |
196 | + spin_lock(&stats->stats_lock); |
197 | + *(int32_t *)num_conns += (int32_t)amount; |
198 | + spin_unlock(&stats->stats_lock); |
199 | +} |
200 | + |
201 | |
202 | === modified file 'clients/ms_stats.h' |
203 | --- clients/ms_stats.h 2009-11-30 16:43:20 +0000 |
204 | +++ clients/ms_stats.h 2009-12-11 17:27:14 +0000 |
205 | @@ -62,6 +62,19 @@ |
206 | int obj_size); |
207 | |
208 | |
209 | +struct stats; |
210 | + |
211 | +/* update a stats counter */ |
212 | +void ms_update_stats(struct stats * stats, |
213 | + uint64_t * stat, |
214 | + int amount); |
215 | + |
216 | +/* update the number of connections */ |
217 | +void ms_update_conns(struct stats * stats, |
218 | + volatile uint32_t * num_conns, |
219 | + int amount); |
220 | + |
221 | + |
222 | #ifdef __cplusplus |
223 | } |
224 | #endif |
225 | |
226 | === modified file 'clients/ms_task.c' |
227 | --- clients/ms_task.c 2009-12-03 20:16:27 +0000 |
228 | +++ clients/ms_task.c 2009-12-11 17:27:14 +0000 |
229 | @@ -725,7 +725,7 @@ |
230 | /* update get miss counter */ |
231 | if (mlget_item->get_miss) |
232 | { |
233 | - atomic_add_64(&ms_stats.get_misses, 1); |
234 | + ms_update_stats(&ms_stats, &ms_stats.get_misses, 1); |
235 | } |
236 | |
237 | /* get nothing from server for this task item */ |
238 | @@ -741,7 +741,7 @@ |
239 | if (curr_time.tv_sec - item->client_time |
240 | < item->exp_time - EXPIRE_TIME_ERROR) |
241 | { |
242 | - atomic_add_64(&ms_stats.unexp_unget, 1); |
243 | + ms_update_stats(&ms_stats, &ms_stats.unexp_unget, 1); |
244 | |
245 | if (ms_setting.verbose) |
246 | { |
247 | @@ -779,7 +779,7 @@ |
248 | } |
249 | else |
250 | { |
251 | - atomic_add_64(&ms_stats.vef_miss, 1); |
252 | + ms_update_stats(&ms_stats, &ms_stats.vef_miss, 1); |
253 | |
254 | if (ms_setting.verbose) |
255 | { |
256 | @@ -829,7 +829,7 @@ |
257 | /* update get miss counter */ |
258 | if ((c->precmd.cmd == CMD_GET) && c->curr_task.get_miss) |
259 | { |
260 | - atomic_add_64(&ms_stats.get_misses, 1); |
261 | + ms_update_stats(&ms_stats, &ms_stats.get_misses, 1); |
262 | } |
263 | |
264 | /* get nothing from server for this task item */ |
265 | @@ -846,7 +846,7 @@ |
266 | if (curr_time.tv_sec - item->client_time |
267 | < item->exp_time - EXPIRE_TIME_ERROR) |
268 | { |
269 | - atomic_add_64(&ms_stats.unexp_unget, 1); |
270 | + ms_update_stats(&ms_stats, &ms_stats.unexp_unget, 1); |
271 | |
272 | if (ms_setting.verbose) |
273 | { |
274 | @@ -884,7 +884,7 @@ |
275 | } |
276 | else |
277 | { |
278 | - atomic_add_64(&ms_stats.vef_miss, 1); |
279 | + ms_update_stats(&ms_stats, &ms_stats.vef_miss, 1); |
280 | |
281 | if (ms_setting.verbose) |
282 | { |
283 | |
284 | === modified file 'clients/ms_thread.c' |
285 | --- clients/ms_thread.c 2009-12-06 09:02:23 +0000 |
286 | +++ clients/ms_thread.c 2009-12-11 17:27:14 +0000 |
287 | @@ -69,10 +69,10 @@ |
288 | /* calculate dropped packets count */ |
289 | if (c->recvpkt > 0) |
290 | { |
291 | - atomic_add_64(&ms_stats.pkt_drop, c->packets - c->recvpkt); |
292 | + ms_update_stats(&ms_stats, &ms_stats.pkt_drop, c->packets - c->recvpkt); |
293 | } |
294 | |
295 | - atomic_add_64(&ms_stats.udp_timeout, 1); |
296 | + ms_update_stats(&ms_stats, &ms_stats.udp_timeout, 1); |
297 | ms_reset_conn(c, true); |
298 | } |
299 | } |
300 | |
301 | === modified file 'configure.ac' |
302 | --- configure.ac 2009-12-05 13:11:26 +0000 |
303 | +++ configure.ac 2009-12-11 17:27:14 +0000 |
304 | @@ -14,6 +14,49 @@ |
305 | |
306 | PANDORA_CANONICAL_TARGET |
307 | |
308 | +#shared library versioning |
309 | +MEMCACHED_LIBRARY_VERSION=3:0:0 |
310 | +# | | | |
311 | +# +------+ | +---+ |
312 | +# | | | |
313 | +# current:revision:age |
314 | +# | | | |
315 | +# | | +- increment if interfaces have been added |
316 | +# | | set to zero if interfaces have been removed or changed |
317 | +# | +- increment if source code has changed |
318 | +# | set to zero if current is incremented |
319 | +# +- increment if interfaces have been added, removed or changed |
320 | +AC_SUBST(MEMCACHED_LIBRARY_VERSION) |
321 | +MEMCACHEDUTIL_LIBRARY_VERSION=0:0:0 |
322 | +AC_SUBST(MEMCACHEDUTIL_LIBRARY_VERSION) |
323 | +MEMCACHEDPROTOCOL_LIBRARY_VERSION=0:0:0 |
324 | +AC_SUBST(MEMCACHEDPROTOCOL_LIBRARY_VERSION) |
325 | +HASHKIT_LIBRARY_VERSION=0:0:0 |
326 | +AC_SUBST(HASHKIT_LIBRARY_VERSION) |
327 | + |
328 | + |
329 | +# libmemcached versioning when linked with GNU ld. |
330 | +if test "$lt_cv_prog_gnu_ld" = "yes" |
331 | +then |
332 | + LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_srcdir)/libmemcached/libmemcached.ver" |
333 | + LD_UTIL_VERSION_SCRIPT="-Wl,--version-script=\$(top_srcdir)/libmemcached/util/libmemcachedutil.ver" |
334 | + LD_PROTOCOL_VERSION_SCRIPT="-Wl,--version-script=\$(top_srcdir)/libmemcached/protocol/libmemcachedprotocol.ver" |
335 | +fi |
336 | +AC_SUBST(LD_VERSION_SCRIPT) |
337 | +AC_SUBST(LD_UTIL_VERSION_SCRIPT) |
338 | +AC_SUBST(LD_PROTOCOL_VERSION_SCRIPT) |
339 | + |
340 | + |
341 | +#-------------------------------------------------------------------- |
342 | +# Check for libpthread |
343 | +#-------------------------------------------------------------------- |
344 | + |
345 | +ACX_PTHREAD(,AC_MSG_ERROR(could not find libpthread)) |
346 | +LIBS="${PTHREAD_LIBS} ${LIBS}" |
347 | +CFLAGS="${PTHREAD_CFLAGS} ${CFLAGS}" |
348 | +CC="$PTHREAD_CC" |
349 | + |
350 | + |
351 | AC_SEARCH_LIBS(getopt_long, gnugetopt) |
352 | AC_SEARCH_LIBS(gethostbyname, nsl) |
353 | |
354 | @@ -35,6 +78,7 @@ |
355 | ENABLE_DEPRECATED |
356 | PANDORA_HAVE_LIBINNODB |
357 | PANDORA_PRINT_CALLSTACK |
358 | +PANDORA_BUNDLE_LIBHASHKIT |
359 | |
360 | AC_CONFIG_FILES([ |
361 | Makefile |
362 | @@ -48,6 +92,7 @@ |
363 | support/libmemcached.pc |
364 | support/libmemcached.spec |
365 | support/libmemcached-fc.spec |
366 | + libhashkit/Makefile |
367 | ]) |
368 | AC_OUTPUT |
369 | |
370 | |
371 | === added directory 'libhashkit' |
372 | === added file 'libhashkit/Makefile.am' |
373 | --- libhashkit/Makefile.am 1970-01-01 00:00:00 +0000 |
374 | +++ libhashkit/Makefile.am 2009-12-11 17:27:14 +0000 |
375 | @@ -0,0 +1,43 @@ |
376 | +# HashKit |
377 | +# Copyright (C) 2009 Brian Aker |
378 | +# All rights reserved. |
379 | +# |
380 | +# Use and distribution licensed under the BSD license. See |
381 | +# the COPYING file in the parent directory for full text. |
382 | + |
383 | +lib_LTLIBRARIES= libhashkit.la |
384 | + |
385 | +libhashkitincludedir= ${includedir}/libhashkit |
386 | + |
387 | +dist_libhashkitinclude_HEADERS= \ |
388 | + algorithm.h \ |
389 | + behavior.h \ |
390 | + hashkit.h \ |
391 | + types.h \ |
392 | + visibility.h |
393 | + |
394 | +noinst_HEADERS= \ |
395 | + common.h |
396 | + |
397 | +libhashkit_la_SOURCES= \ |
398 | + crc32.c \ |
399 | + behavior.c \ |
400 | + default.c \ |
401 | + fnv.c \ |
402 | + hashkit.c \ |
403 | + jenkins.c \ |
404 | + ketama.c \ |
405 | + md5.c \ |
406 | + murmur.c |
407 | + |
408 | +if INCLUDE_HSIEH_SRC |
409 | +libhashkit_la_SOURCES+= hsieh.c |
410 | +endif |
411 | + |
412 | +libhashkit_la_CFLAGS= \ |
413 | + ${AM_CFLAGS} \ |
414 | + -DBUILDING_HASHKIT |
415 | + |
416 | +libhashkit_la_LDFLAGS= \ |
417 | + -version-info \ |
418 | + $(HASHKIT_LIBRARY_VERSION) |
419 | |
420 | === added file 'libhashkit/algorithm.h' |
421 | --- libhashkit/algorithm.h 1970-01-01 00:00:00 +0000 |
422 | +++ libhashkit/algorithm.h 2009-12-11 17:27:14 +0000 |
423 | @@ -0,0 +1,49 @@ |
424 | +/* HashKit |
425 | + * Copyright (C) 2009 Brian Aker |
426 | + * All rights reserved. |
427 | + * |
428 | + * Use and distribution licensed under the BSD license. See |
429 | + * the COPYING file in the parent directory for full text. |
430 | + */ |
431 | + |
432 | +/** |
433 | + * @file |
434 | + * @brief HashKit Header |
435 | + */ |
436 | + |
437 | +#ifndef HASHKIT_ALGORITHM_H |
438 | +#define HASHKIT_ALGORITHM_H |
439 | + |
440 | +#ifdef __cplusplus |
441 | +extern "C" { |
442 | +#endif |
443 | + |
444 | +HASHKIT_API |
445 | +uint32_t hashkit_default(const char *key, size_t key_length); |
446 | +HASHKIT_API |
447 | +uint32_t hashkit_fnv1_64(const char *key, size_t key_length); |
448 | +HASHKIT_API |
449 | +uint32_t hashkit_fnv1a_64(const char *key, size_t key_length); |
450 | +HASHKIT_API |
451 | +uint32_t hashkit_fnv1_32(const char *key, size_t key_length); |
452 | +HASHKIT_API |
453 | +uint32_t hashkit_fnv1a_32(const char *key, size_t key_length); |
454 | +HASHKIT_API |
455 | +uint32_t hashkit_crc32(const char *key, size_t key_length); |
456 | +HASHKIT_API |
457 | +#ifdef HAVE_HSIEH_HASH |
458 | +HASHKIT_API |
459 | +uint32_t hashkit_hsieh(const char *key, size_t key_length); |
460 | +#endif |
461 | +HASHKIT_API |
462 | +uint32_t hashkit_murmur(const char *key, size_t key_length); |
463 | +HASHKIT_API |
464 | +uint32_t hashkit_jenkins(const char *key, size_t key_length); |
465 | +HASHKIT_API |
466 | +uint32_t hashkit_md5(const char *key, size_t key_length); |
467 | + |
468 | +#ifdef __cplusplus |
469 | +} |
470 | +#endif |
471 | + |
472 | +#endif /* HASHKIT_ALGORITHM_H */ |
473 | |
474 | === added file 'libhashkit/behavior.c' |
475 | --- libhashkit/behavior.c 1970-01-01 00:00:00 +0000 |
476 | +++ libhashkit/behavior.c 2009-12-11 17:27:14 +0000 |
477 | @@ -0,0 +1,89 @@ |
478 | +/* HashKit |
479 | + * Copyright (C) 2009 Brian Aker |
480 | + * All rights reserved. |
481 | + * |
482 | + * Use and distribution licensed under the BSD license. See |
483 | + * the COPYING file in the parent directory for full text. |
484 | + */ |
485 | + |
486 | +#include "common.h" |
487 | + |
488 | +void hashkit_set_distribution(hashkit_st *hashkit, hashkit_distribution_t distribution) |
489 | +{ |
490 | + hashkit->distribution= distribution; |
491 | +} |
492 | + |
493 | +hashkit_distribution_t hashkit_get_distribution(hashkit_st *hashkit) |
494 | +{ |
495 | + return hashkit->distribution; |
496 | +} |
497 | + |
498 | + |
499 | +void hashkit_set_hash_fn(hashkit_st *hashkit, hashkit_fn *function) |
500 | +{ |
501 | + hashkit->hash_fn= function; |
502 | +} |
503 | + |
504 | +hashkit_fn * hashkit_get_hash_fn(hashkit_st *hashkit) |
505 | +{ |
506 | + return hashkit->hash_fn; |
507 | +} |
508 | + |
509 | + |
510 | +void hashkit_set_active_fn(hashkit_st *hashkit, hashkit_active_fn *function) |
511 | +{ |
512 | + hashkit->active_fn= function; |
513 | +} |
514 | + |
515 | + |
516 | +hashkit_active_fn * hashkit_get_active_fn(hashkit_st *hashkit) |
517 | +{ |
518 | + return hashkit->active_fn; |
519 | +} |
520 | + |
521 | + |
522 | +void hashkit_set_continuum_hash_fn(hashkit_st *hashkit, hashkit_fn *function) |
523 | +{ |
524 | + hashkit->continuum_hash_fn= function; |
525 | +} |
526 | + |
527 | + |
528 | +hashkit_fn * hashkit_get_continuum_hash_fn(hashkit_st *hashkit) |
529 | +{ |
530 | + return hashkit->continuum_hash_fn; |
531 | +} |
532 | + |
533 | + |
534 | +void hashkit_set_continuum_key_fn(hashkit_st *hashkit, hashkit_key_fn *function) |
535 | +{ |
536 | + hashkit->continuum_key_fn= function; |
537 | +} |
538 | + |
539 | +hashkit_key_fn * hashkit_get_continuum_key_fn(hashkit_st *hashkit) |
540 | +{ |
541 | + return hashkit->continuum_key_fn; |
542 | +} |
543 | + |
544 | + |
545 | +void hashkit_set_sort_fn(hashkit_st *hashkit, hashkit_sort_fn *function) |
546 | +{ |
547 | + hashkit->sort_fn= function; |
548 | +} |
549 | + |
550 | + |
551 | +hashkit_sort_fn * hashkit_get_sort_fn(hashkit_st *hashkit) |
552 | +{ |
553 | + return hashkit->sort_fn; |
554 | +} |
555 | + |
556 | + |
557 | +void hashkit_set_weight_fn(hashkit_st *hashkit, hashkit_weight_fn *function) |
558 | +{ |
559 | + hashkit->weight_fn= function; |
560 | +} |
561 | + |
562 | + |
563 | +hashkit_weight_fn * hashkit_get_weight_fn(hashkit_st *hashkit) |
564 | +{ |
565 | + return hashkit->weight_fn; |
566 | +} |
567 | |
568 | === added file 'libhashkit/behavior.h' |
569 | --- libhashkit/behavior.h 1970-01-01 00:00:00 +0000 |
570 | +++ libhashkit/behavior.h 2009-12-11 17:27:14 +0000 |
571 | @@ -0,0 +1,68 @@ |
572 | +/* HashKit |
573 | + * Copyright (C) 2009 Brian Aker |
574 | + * All rights reserved. |
575 | + * |
576 | + * Use and distribution licensed under the BSD license. See |
577 | + * the COPYING file in the parent directory for full text. |
578 | + */ |
579 | + |
580 | +/** |
581 | + * @file |
582 | + * @brief HashKit Header |
583 | + */ |
584 | + |
585 | +#ifndef HASHKIT_BEHAVIOR_H |
586 | +#define HASHKIT_BEHAVIORH |
587 | + |
588 | +#ifdef __cplusplus |
589 | +extern "C" { |
590 | +#endif |
591 | + |
592 | + |
593 | +HASHKIT_API |
594 | +void hashkit_set_distribution(hashkit_st *hash, hashkit_distribution_t distribution); |
595 | + |
596 | +HASHKIT_API |
597 | +hashkit_distribution_t hashkit_get_distribution(hashkit_st *hash); |
598 | + |
599 | +HASHKIT_API |
600 | +void hashkit_set_hash_fn(hashkit_st *hash, hashkit_fn *function); |
601 | + |
602 | +HASHKIT_API |
603 | +hashkit_fn * hashkit_get_hash_fn(hashkit_st *hash); |
604 | + |
605 | +HASHKIT_API |
606 | +void hashkit_set_active_fn(hashkit_st *hash, hashkit_active_fn *function); |
607 | + |
608 | +HASHKIT_API |
609 | +hashkit_active_fn * hashkit_get_active_fn(hashkit_st *hash); |
610 | + |
611 | +HASHKIT_API |
612 | +void hashkit_set_continuum_hash_fn(hashkit_st *hash, hashkit_fn *function); |
613 | + |
614 | +HASHKIT_API |
615 | +hashkit_fn * hashkit_get_continuum_hash_fn(hashkit_st *hash); |
616 | + |
617 | +HASHKIT_API |
618 | +void hashkit_set_continuum_key_fn(hashkit_st *hash, hashkit_key_fn *function); |
619 | + |
620 | +HASHKIT_API |
621 | +hashkit_key_fn * hashkit_get_continuum_key_fn(hashkit_st *hash); |
622 | + |
623 | +HASHKIT_API |
624 | +void hashkit_set_sort_fn(hashkit_st *hash, hashkit_sort_fn *function); |
625 | + |
626 | +HASHKIT_API |
627 | +hashkit_sort_fn * hashkit_get_sort_fn(hashkit_st *hash); |
628 | + |
629 | +HASHKIT_API |
630 | +void hashkit_set_weight_fn(hashkit_st *hash, hashkit_weight_fn *function); |
631 | + |
632 | +HASHKIT_API |
633 | +hashkit_weight_fn * hashkit_get_weight_fn(hashkit_st *hash); |
634 | + |
635 | +#ifdef __cplusplus |
636 | +} |
637 | +#endif |
638 | + |
639 | +#endif /* HASHKIT_BEHAVIOR_H */ |
640 | |
641 | === added file 'libhashkit/common.h' |
642 | --- libhashkit/common.h 1970-01-01 00:00:00 +0000 |
643 | +++ libhashkit/common.h 2009-12-11 17:27:14 +0000 |
644 | @@ -0,0 +1,32 @@ |
645 | +/* HashKit |
646 | + * Copyright (C) 2009 Brian Aker |
647 | + * All rights reserved. |
648 | + * |
649 | + * Use and distribution licensed under the BSD license. See |
650 | + * the COPYING file in the parent directory for full text. |
651 | + */ |
652 | + |
653 | +/** |
654 | + * @file |
655 | + * @brief System Include Files |
656 | + */ |
657 | + |
658 | +#ifndef HASHKIT_COMMON_H |
659 | +#define HASHKIT_COMMON_H |
660 | + |
661 | +#include "config.h" |
662 | + |
663 | +#include <assert.h> |
664 | +#include <errno.h> |
665 | +#include <stdio.h> |
666 | +#include <stdlib.h> |
667 | + |
668 | +#include "hashkit.h" |
669 | + |
670 | +HASHKIT_LOCAL |
671 | +void md5_signature(const unsigned char *key, unsigned int length, unsigned char *result); |
672 | + |
673 | +HASHKIT_LOCAL |
674 | +int update_continuum(hashkit_st *hashkit); |
675 | + |
676 | +#endif /* HASHKIT_COMMON_H */ |
677 | |
678 | === renamed file 'libmemcached/crc.c' => 'libhashkit/crc32.c' |
679 | --- libmemcached/crc.c 2009-09-30 03:51:54 +0000 |
680 | +++ libhashkit/crc32.c 2009-12-11 17:27:14 +0000 |
681 | @@ -73,8 +73,7 @@ |
682 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, |
683 | }; |
684 | |
685 | - |
686 | -uint32_t hash_crc32(const char *key, size_t key_length) |
687 | +uint32_t hashkit_crc32(const char *key, size_t key_length) |
688 | { |
689 | uint64_t x; |
690 | uint32_t crc= UINT32_MAX; |
691 | @@ -82,5 +81,5 @@ |
692 | for (x= 0; x < key_length; x++) |
693 | crc= (crc >> 8) ^ crc32tab[(crc ^ (uint64_t)key[x]) & 0xff]; |
694 | |
695 | - return ~crc; |
696 | + return ((~crc) >> 16) & 0x7fff; |
697 | } |
698 | |
699 | === added file 'libhashkit/default.c' |
700 | --- libhashkit/default.c 1970-01-01 00:00:00 +0000 |
701 | +++ libhashkit/default.c 2009-12-11 17:27:14 +0000 |
702 | @@ -0,0 +1,28 @@ |
703 | +/* HashKit |
704 | + * Copyright (C) 2009 Brian Aker |
705 | + * All rights reserved. |
706 | + * |
707 | + * Use and distribution licensed under the BSD license. See |
708 | + * the COPYING file in the parent directory for full text. |
709 | + */ |
710 | + |
711 | +#include "common.h" |
712 | + |
713 | +uint32_t hashkit_default(const char *key, size_t key_length) |
714 | +{ |
715 | + const char *ptr= key; |
716 | + uint32_t value= 0; |
717 | + |
718 | + while (key_length--) |
719 | + { |
720 | + uint32_t val= (uint32_t) *ptr++; |
721 | + value += val; |
722 | + value += (value << 10); |
723 | + value ^= (value >> 6); |
724 | + } |
725 | + value += (value << 3); |
726 | + value ^= (value >> 11); |
727 | + value += (value << 15); |
728 | + |
729 | + return value; |
730 | +} |
731 | |
732 | === added file 'libhashkit/fnv.c' |
733 | --- libhashkit/fnv.c 1970-01-01 00:00:00 +0000 |
734 | +++ libhashkit/fnv.c 2009-12-11 17:27:14 +0000 |
735 | @@ -0,0 +1,75 @@ |
736 | +/* HashKit |
737 | + * Copyright (C) 2009 Brian Aker |
738 | + * All rights reserved. |
739 | + * |
740 | + * Use and distribution licensed under the BSD license. See |
741 | + * the COPYING file in the parent directory for full text. |
742 | + */ |
743 | + |
744 | +#include "common.h" |
745 | + |
746 | +/* FNV hash'es lifted from Dustin Sallings work */ |
747 | +static uint64_t FNV_64_INIT= UINT64_C(0xcbf29ce484222325); |
748 | +static uint64_t FNV_64_PRIME= UINT64_C(0x100000001b3); |
749 | +static uint32_t FNV_32_INIT= 2166136261UL; |
750 | +static uint32_t FNV_32_PRIME= 16777619; |
751 | + |
752 | +uint32_t hashkit_fnv1_64(const char *key, size_t key_length) |
753 | +{ |
754 | + /* Thanks to pierre@demartines.com for the pointer */ |
755 | + uint64_t hash= FNV_64_INIT; |
756 | + size_t x= 0; |
757 | + |
758 | + for (x= 0; x < key_length; x++) |
759 | + { |
760 | + hash *= FNV_64_PRIME; |
761 | + hash ^= (uint64_t)key[x]; |
762 | + } |
763 | + |
764 | + return (uint32_t)hash; |
765 | +} |
766 | + |
767 | +uint32_t hashkit_fnv1a_64(const char *key, size_t key_length) |
768 | +{ |
769 | + uint32_t hash= (uint32_t) FNV_64_INIT; |
770 | + size_t x= 0; |
771 | + |
772 | + for (x= 0; x < key_length; x++) |
773 | + { |
774 | + uint32_t val= (uint32_t)key[x]; |
775 | + hash ^= val; |
776 | + hash *= (uint32_t) FNV_64_PRIME; |
777 | + } |
778 | + |
779 | + return hash; |
780 | +} |
781 | + |
782 | +uint32_t hashkit_fnv1_32(const char *key, size_t key_length) |
783 | +{ |
784 | + uint32_t hash= FNV_32_INIT; |
785 | + size_t x= 0; |
786 | + |
787 | + for (x= 0; x < key_length; x++) |
788 | + { |
789 | + uint32_t val= (uint32_t)key[x]; |
790 | + hash *= FNV_32_PRIME; |
791 | + hash ^= val; |
792 | + } |
793 | + |
794 | + return hash; |
795 | +} |
796 | + |
797 | +uint32_t hashkit_fnv1a_32(const char *key, size_t key_length) |
798 | +{ |
799 | + uint32_t hash= FNV_32_INIT; |
800 | + size_t x= 0; |
801 | + |
802 | + for (x= 0; x < key_length; x++) |
803 | + { |
804 | + uint32_t val= (uint32_t)key[x]; |
805 | + hash ^= val; |
806 | + hash *= FNV_32_PRIME; |
807 | + } |
808 | + |
809 | + return hash; |
810 | +} |
811 | |
812 | === renamed file 'libmemcached/memcached_hash.c' => 'libhashkit/hashkit.c' |
813 | --- libmemcached/memcached_hash.c 2009-11-03 13:09:13 +0000 |
814 | +++ libhashkit/hashkit.c 2009-12-11 17:27:14 +0000 |
815 | @@ -1,234 +1,263 @@ |
816 | +/* HashKit |
817 | + * Copyright (C) 2009 Brian Aker |
818 | + * All rights reserved. |
819 | + * |
820 | + * Use and distribution licensed under the BSD license. See |
821 | + * the COPYING file in the parent directory for full text. |
822 | + */ |
823 | + |
824 | #include "common.h" |
825 | |
826 | - |
827 | -/* Defines */ |
828 | -static uint64_t FNV_64_INIT= UINT64_C(0xcbf29ce484222325); |
829 | -static uint64_t FNV_64_PRIME= UINT64_C(0x100000001b3); |
830 | - |
831 | -static uint32_t FNV_32_INIT= 2166136261UL; |
832 | -static uint32_t FNV_32_PRIME= 16777619; |
833 | - |
834 | -/* Prototypes */ |
835 | -static uint32_t internal_generate_hash(const char *key, size_t key_length); |
836 | -static uint32_t internal_generate_md5(const char *key, size_t key_length); |
837 | - |
838 | -uint32_t memcached_generate_hash_value(const char *key, size_t key_length, memcached_hash hash_algorithm) |
839 | -{ |
840 | - uint32_t hash= 1; /* Just here to remove compile warning */ |
841 | - uint32_t x= 0; |
842 | - |
843 | +inline static bool _is_allocated(const hashkit_st *hashk) |
844 | +{ |
845 | + return hashk->options.is_allocated == true; |
846 | +} |
847 | + |
848 | +inline static bool _is_initialized(const hashkit_st *hashk) |
849 | +{ |
850 | + return hashk->options.is_initialized == true; |
851 | +} |
852 | + |
853 | +/** |
854 | + @note We make no assumptions that "hashk" has been, or not been allocated from heap/stack. We just know we didn't do it. |
855 | +*/ |
856 | +hashkit_st *hashkit_create(hashkit_st *hashk) |
857 | +{ |
858 | + if (hashk == NULL) |
859 | + { |
860 | + hashk= (hashkit_st *)malloc(sizeof(hashkit_st)); |
861 | + if (hashk == NULL) |
862 | + { |
863 | + hashk->options.is_initialized= false; |
864 | + |
865 | + return NULL; |
866 | + } |
867 | + |
868 | + hashk->options.is_allocated= true; |
869 | + } |
870 | + else |
871 | + { |
872 | + hashk->options.is_allocated= false; |
873 | + } |
874 | + |
875 | + hashk->options.is_initialized= true; |
876 | + |
877 | + hashk->distribution= HASHKIT_DISTRIBUTION_MODULA; |
878 | + hashk->continuum_count= 0; |
879 | + hashk->continuum_points_count= 0; |
880 | + hashk->list_size= 0; |
881 | + hashk->context_size= 0; |
882 | + hashk->continuum= NULL; |
883 | + hashk->hash_fn= NULL; |
884 | + hashk->active_fn= NULL; |
885 | + hashk->continuum_hash_fn= NULL; |
886 | + hashk->continuum_key_fn= NULL; |
887 | + hashk->sort_fn= NULL; |
888 | + hashk->weight_fn= NULL; |
889 | + hashk->list= NULL; |
890 | + |
891 | + return hashk; |
892 | +} |
893 | + |
894 | + |
895 | +void hashkit_free(hashkit_st *hashk) |
896 | +{ |
897 | + assert(_is_initialized(hashk) == true); |
898 | + |
899 | + if (hashk->continuum != NULL) |
900 | + { |
901 | + free(hashk->continuum); |
902 | + } |
903 | + |
904 | + /** |
905 | + We don't know if hashk is pointing to something else, |
906 | + so we go on and set is_initialized. |
907 | + */ |
908 | + hashk->options.is_initialized= false; |
909 | + |
910 | + if (_is_allocated(hashk)) |
911 | + { |
912 | + free(hashk); |
913 | + } |
914 | +} |
915 | + |
916 | +bool hashkit_is_allocated(const hashkit_st *hashk) |
917 | +{ |
918 | + return _is_allocated(hashk); |
919 | +} |
920 | + |
921 | +bool hashkit_is_initialized(const hashkit_st *hashk) |
922 | +{ |
923 | + return _is_initialized(hashk); |
924 | +} |
925 | + |
926 | + |
927 | +/** |
928 | + @note We do assume source is valid. If source does not exist, we allocate. |
929 | +*/ |
930 | +hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) |
931 | +{ |
932 | + hashkit_st *new_clone; |
933 | + |
934 | + if (source == NULL) |
935 | + { |
936 | + return hashkit_create(destination); |
937 | + } |
938 | + else |
939 | + { |
940 | + assert(_is_initialized(source) == true); |
941 | + } |
942 | + |
943 | + /* new_clone will be a pointer to destination */ |
944 | + new_clone= hashkit_create(destination); |
945 | + assert((destination ? ((_is_allocated(new_clone) == false)) : (_is_allocated(new_clone) == true))); |
946 | + |
947 | + // Should only happen on allocation failure. |
948 | + if (new_clone == NULL) |
949 | + { |
950 | + return NULL; |
951 | + } |
952 | + |
953 | + // For the moment we will not clone this. |
954 | + new_clone->continuum= NULL; |
955 | + |
956 | + new_clone->distribution= source->distribution; |
957 | + new_clone->continuum_count= source->continuum_count; |
958 | + new_clone->continuum_points_count= source->continuum_points_count; |
959 | + new_clone->list_size= source->list_size; |
960 | + new_clone->context_size= source->context_size; |
961 | + |
962 | + |
963 | + new_clone->hash_fn= source->hash_fn; |
964 | + new_clone->active_fn= source->active_fn; |
965 | + new_clone->continuum_hash_fn= source->continuum_hash_fn; |
966 | + new_clone->continuum_key_fn= source->continuum_key_fn; |
967 | + new_clone->sort_fn= source->sort_fn; |
968 | + new_clone->weight_fn= source->weight_fn; |
969 | + new_clone->list= source->list; |
970 | + |
971 | + return new_clone; |
972 | +} |
973 | + |
974 | + |
975 | +void hashkit_set_list(hashkit_st *hashkit, void *list, size_t list_size, size_t context_size) |
976 | +{ |
977 | + hashkit->list= list; |
978 | + hashkit->list_size= list_size; |
979 | + hashkit->context_size= context_size; |
980 | +} |
981 | + |
982 | + |
983 | +uint32_t hashkit_value(hashkit_st *hashkit, const char *key, size_t key_length) |
984 | +{ |
985 | + if (hashkit->hash_fn == NULL) |
986 | + return hashkit_default(key, key_length); |
987 | + |
988 | + return hashkit->hash_fn(key, key_length); |
989 | +} |
990 | + |
991 | + |
992 | +uint32_t hashkit_index(hashkit_st *hashkit, uint32_t hash_value) |
993 | +{ |
994 | + if (hashkit->list_size == 1) |
995 | + return 0; |
996 | + |
997 | + switch (hashkit->distribution) |
998 | + { |
999 | + case HASHKIT_DISTRIBUTION_MODULA: |
1000 | + return hash_value % (uint32_t)hashkit->list_size; |
1001 | + |
1002 | + case HASHKIT_DISTRIBUTION_RANDOM: |
1003 | + return (uint32_t)random() % (uint32_t)hashkit->list_size; |
1004 | + |
1005 | + case HASHKIT_DISTRIBUTION_KETAMA: |
1006 | + { |
1007 | + hashkit_continuum_point_st *begin, *end, *left, *right, *middle; |
1008 | + begin= left= hashkit->continuum; |
1009 | + end= right= hashkit->continuum + hashkit->continuum_points_count; |
1010 | + |
1011 | + while (left < right) |
1012 | + { |
1013 | + middle= left + (right - left) / 2; |
1014 | + if (middle->value < hash_value) |
1015 | + left= middle + 1; |
1016 | + else |
1017 | + right= middle; |
1018 | + } |
1019 | + if (right == end) |
1020 | + right= begin; |
1021 | + return right->index; |
1022 | + } |
1023 | + |
1024 | + case HASHKIT_DISTRIBUTION_MAX: |
1025 | + default: |
1026 | + /* We have added a distribution without extending the logic */ |
1027 | + return hash_value % (uint32_t)hashkit->list_size; |
1028 | + } |
1029 | + |
1030 | + /* NOTREACHED */ |
1031 | +} |
1032 | + |
1033 | + |
1034 | +int hashkit_run_distribution(hashkit_st *hashkit) |
1035 | +{ |
1036 | + switch (hashkit->distribution) |
1037 | + { |
1038 | + case HASHKIT_DISTRIBUTION_MODULA: |
1039 | + if (hashkit->sort_fn != NULL && hashkit->list_size > 1) |
1040 | + hashkit->sort_fn(hashkit->list, hashkit->list_size); |
1041 | + break; |
1042 | + case HASHKIT_DISTRIBUTION_RANDOM: |
1043 | + break; |
1044 | + case HASHKIT_DISTRIBUTION_KETAMA: |
1045 | + return update_continuum(hashkit); |
1046 | + case HASHKIT_DISTRIBUTION_MAX: |
1047 | + default: |
1048 | + /* We have added a distribution without extending the logic */ |
1049 | + break; |
1050 | + } |
1051 | + |
1052 | + return 0; |
1053 | +} |
1054 | + |
1055 | + |
1056 | +uint32_t hashkit_generate_value(const char *key, size_t key_length, hashkit_hash_t hash_algorithm) |
1057 | +{ |
1058 | switch (hash_algorithm) |
1059 | { |
1060 | - case MEMCACHED_HASH_DEFAULT: |
1061 | - hash= internal_generate_hash(key, key_length); |
1062 | - break; |
1063 | - case MEMCACHED_HASH_MD5: |
1064 | - hash= internal_generate_md5(key, key_length); |
1065 | - break; |
1066 | - case MEMCACHED_HASH_CRC: |
1067 | - hash= ((hash_crc32(key, key_length) >> 16) & 0x7fff); |
1068 | - if (hash == 0) |
1069 | - hash= 1; |
1070 | - break; |
1071 | - /* FNV hash'es lifted from Dustin Sallings work */ |
1072 | - case MEMCACHED_HASH_FNV1_64: |
1073 | - { |
1074 | - /* Thanks to pierre@demartines.com for the pointer */ |
1075 | - uint64_t temp_hash; |
1076 | - |
1077 | - temp_hash= FNV_64_INIT; |
1078 | - for (x= 0; x < key_length; x++) |
1079 | - { |
1080 | - temp_hash *= FNV_64_PRIME; |
1081 | - temp_hash ^= (uint64_t)key[x]; |
1082 | - } |
1083 | - hash= (uint32_t)temp_hash; |
1084 | - } |
1085 | - break; |
1086 | - case MEMCACHED_HASH_FNV1A_64: |
1087 | - { |
1088 | - hash= (uint32_t) FNV_64_INIT; |
1089 | - for (x= 0; x < key_length; x++) |
1090 | - { |
1091 | - uint32_t val= (uint32_t)key[x]; |
1092 | - hash ^= val; |
1093 | - hash *= (uint32_t) FNV_64_PRIME; |
1094 | - } |
1095 | - } |
1096 | - break; |
1097 | - case MEMCACHED_HASH_FNV1_32: |
1098 | - { |
1099 | - hash= FNV_32_INIT; |
1100 | - for (x= 0; x < key_length; x++) |
1101 | - { |
1102 | - uint32_t val= (uint32_t)key[x]; |
1103 | - hash *= FNV_32_PRIME; |
1104 | - hash ^= val; |
1105 | - } |
1106 | - } |
1107 | - break; |
1108 | - case MEMCACHED_HASH_FNV1A_32: |
1109 | - { |
1110 | - hash= FNV_32_INIT; |
1111 | - for (x= 0; x < key_length; x++) |
1112 | - { |
1113 | - uint32_t val= (uint32_t)key[x]; |
1114 | - hash ^= val; |
1115 | - hash *= FNV_32_PRIME; |
1116 | - } |
1117 | - } |
1118 | - break; |
1119 | - case MEMCACHED_HASH_HSIEH: |
1120 | - { |
1121 | + case HASHKIT_HASH_DEFAULT: |
1122 | + return hashkit_default(key, key_length); |
1123 | + case HASHKIT_HASH_MD5: |
1124 | + return hashkit_md5(key, key_length); |
1125 | + case HASHKIT_HASH_CRC: |
1126 | + return hashkit_crc32(key, key_length); |
1127 | + case HASHKIT_HASH_FNV1_64: |
1128 | + return hashkit_fnv1_64(key, key_length); |
1129 | + case HASHKIT_HASH_FNV1A_64: |
1130 | + return hashkit_fnv1a_64(key, key_length); |
1131 | + case HASHKIT_HASH_FNV1_32: |
1132 | + return hashkit_fnv1_32(key, key_length); |
1133 | + case HASHKIT_HASH_FNV1A_32: |
1134 | + return hashkit_fnv1a_32(key, key_length); |
1135 | + case HASHKIT_HASH_HSIEH: |
1136 | #ifdef HAVE_HSIEH_HASH |
1137 | - hash= hsieh_hash(key, key_length); |
1138 | + return hashkit_hsieh(key, key_length); |
1139 | +#else |
1140 | + return 1; |
1141 | #endif |
1142 | - break; |
1143 | - } |
1144 | - case MEMCACHED_HASH_MURMUR: |
1145 | - { |
1146 | - hash= murmur_hash(key, key_length); |
1147 | - break; |
1148 | - } |
1149 | - case MEMCACHED_HASH_JENKINS: |
1150 | - { |
1151 | - hash=jenkins_hash(key, key_length, 13); |
1152 | - break; |
1153 | - } |
1154 | - default: |
1155 | - { |
1156 | - WATCHPOINT_ASSERT(hash_algorithm); |
1157 | - break; |
1158 | - } |
1159 | - } |
1160 | - return hash; |
1161 | -} |
1162 | - |
1163 | -uint32_t generate_hash(memcached_st *ptr, const char *key, size_t key_length) |
1164 | -{ |
1165 | - uint32_t hash= 1; /* Just here to remove compile warning */ |
1166 | - |
1167 | - |
1168 | - WATCHPOINT_ASSERT(ptr->number_of_hosts); |
1169 | - |
1170 | - if (ptr->number_of_hosts == 1) |
1171 | - return 0; |
1172 | - |
1173 | - hash= memcached_generate_hash_value(key, key_length, ptr->hash); |
1174 | - WATCHPOINT_ASSERT(hash); |
1175 | - return hash; |
1176 | -} |
1177 | - |
1178 | -static uint32_t dispatch_host(memcached_st *ptr, uint32_t hash) |
1179 | -{ |
1180 | - switch (ptr->distribution) |
1181 | - { |
1182 | - case MEMCACHED_DISTRIBUTION_CONSISTENT: |
1183 | - case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA: |
1184 | - case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY: |
1185 | - { |
1186 | - uint32_t num= ptr->continuum_points_counter; |
1187 | - WATCHPOINT_ASSERT(ptr->continuum); |
1188 | - |
1189 | - hash= hash; |
1190 | - memcached_continuum_item_st *begin, *end, *left, *right, *middle; |
1191 | - begin= left= ptr->continuum; |
1192 | - end= right= ptr->continuum + num; |
1193 | - |
1194 | - while (left < right) |
1195 | - { |
1196 | - middle= left + (right - left) / 2; |
1197 | - if (middle->value < hash) |
1198 | - left= middle + 1; |
1199 | - else |
1200 | - right= middle; |
1201 | - } |
1202 | - if (right == end) |
1203 | - right= begin; |
1204 | - return right->index; |
1205 | - } |
1206 | - case MEMCACHED_DISTRIBUTION_MODULA: |
1207 | - return hash % ptr->number_of_hosts; |
1208 | - case MEMCACHED_DISTRIBUTION_RANDOM: |
1209 | - return (uint32_t) random() % ptr->number_of_hosts; |
1210 | + case HASHKIT_HASH_MURMUR: |
1211 | + return hashkit_murmur(key, key_length); |
1212 | + case HASHKIT_HASH_JENKINS: |
1213 | + return hashkit_jenkins(key, key_length); |
1214 | + case HASHKIT_HASH_MAX: |
1215 | default: |
1216 | - WATCHPOINT_ASSERT(0); /* We have added a distribution without extending the logic */ |
1217 | - return hash % ptr->number_of_hosts; |
1218 | - } |
1219 | - |
1220 | - /* NOTREACHED */ |
1221 | -} |
1222 | - |
1223 | -/* |
1224 | - One day make this public, and have it return the actual memcached_server_st |
1225 | - to the calling application. |
1226 | -*/ |
1227 | -uint32_t memcached_generate_hash(memcached_st *ptr, const char *key, size_t key_length) |
1228 | -{ |
1229 | - uint32_t hash= 1; /* Just here to remove compile warning */ |
1230 | - |
1231 | - WATCHPOINT_ASSERT(ptr->number_of_hosts); |
1232 | - |
1233 | - if (ptr->number_of_hosts == 1) |
1234 | - return 0; |
1235 | - |
1236 | - if (ptr->flags & MEM_HASH_WITH_PREFIX_KEY) |
1237 | - { |
1238 | - size_t temp_length= ptr->prefix_key_length + key_length; |
1239 | - char temp[temp_length]; |
1240 | - |
1241 | - if (temp_length > MEMCACHED_MAX_KEY -1) |
1242 | - return 0; |
1243 | - |
1244 | - strncpy(temp, ptr->prefix_key, ptr->prefix_key_length); |
1245 | - strncpy(temp + ptr->prefix_key_length, key, key_length); |
1246 | - hash= generate_hash(ptr, temp, temp_length); |
1247 | - } |
1248 | - else |
1249 | - { |
1250 | - hash= generate_hash(ptr, key, key_length); |
1251 | - } |
1252 | - |
1253 | - WATCHPOINT_ASSERT(hash); |
1254 | - |
1255 | - if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS) && ptr->next_distribution_rebuild) { |
1256 | - struct timeval now; |
1257 | - |
1258 | - if (gettimeofday(&now, NULL) == 0 && |
1259 | - now.tv_sec > ptr->next_distribution_rebuild) |
1260 | - run_distribution(ptr); |
1261 | - } |
1262 | - |
1263 | - return dispatch_host(ptr, hash); |
1264 | -} |
1265 | - |
1266 | -static uint32_t internal_generate_hash(const char *key, size_t key_length) |
1267 | -{ |
1268 | - const char *ptr= key; |
1269 | - uint32_t value= 0; |
1270 | - |
1271 | - while (key_length--) |
1272 | - { |
1273 | - uint32_t val= (uint32_t) *ptr++; |
1274 | - value += val; |
1275 | - value += (value << 10); |
1276 | - value ^= (value >> 6); |
1277 | - } |
1278 | - value += (value << 3); |
1279 | - value ^= (value >> 11); |
1280 | - value += (value << 15); |
1281 | - |
1282 | - return value == 0 ? 1 : (uint32_t) value; |
1283 | -} |
1284 | - |
1285 | -static uint32_t internal_generate_md5(const char *key, size_t key_length) |
1286 | -{ |
1287 | - unsigned char results[16]; |
1288 | - |
1289 | - md5_signature((unsigned char*)key, (unsigned int)key_length, results); |
1290 | - |
1291 | - return ((uint32_t) (results[3] & 0xFF) << 24) |
1292 | - | ((uint32_t) (results[2] & 0xFF) << 16) |
1293 | - | ((uint32_t) (results[1] & 0xFF) << 8) |
1294 | - | (results[0] & 0xFF); |
1295 | +#ifdef HAVE_DEBUG |
1296 | + fprintf(stderr, "hashkit_hash_t was extended but hashkit_generate_value was not updated\n"); |
1297 | + fflush(stderr); |
1298 | + assert(0); |
1299 | +#endif |
1300 | + break; |
1301 | + } |
1302 | + |
1303 | + return 1; |
1304 | } |
1305 | |
1306 | === added file 'libhashkit/hashkit.h' |
1307 | --- libhashkit/hashkit.h 1970-01-01 00:00:00 +0000 |
1308 | +++ libhashkit/hashkit.h 2009-12-11 17:27:14 +0000 |
1309 | @@ -0,0 +1,117 @@ |
1310 | +/* HashKit |
1311 | + * Copyright (C) 2009 Brian Aker |
1312 | + * All rights reserved. |
1313 | + * |
1314 | + * Use and distribution licensed under the BSD license. See |
1315 | + * the COPYING file in the parent directory for full text. |
1316 | + */ |
1317 | + |
1318 | +/** |
1319 | + * @file |
1320 | + * @brief HashKit Header |
1321 | + */ |
1322 | + |
1323 | +#ifndef HASHKIT_H |
1324 | +#define HASHKIT_H |
1325 | + |
1326 | +#if !defined(__cplusplus) |
1327 | +# include <stdbool.h> |
1328 | +#endif |
1329 | +#include <inttypes.h> |
1330 | +#include <sys/types.h> |
1331 | +#include <libhashkit/visibility.h> |
1332 | +#include <libhashkit/types.h> |
1333 | +#include <libhashkit/algorithm.h> |
1334 | +#include <libhashkit/behavior.h> |
1335 | + |
1336 | +#ifdef __cplusplus |
1337 | +extern "C" { |
1338 | +#endif |
1339 | + |
1340 | +/** |
1341 | + * @addtogroup hashkit_constants Constants |
1342 | + * @ingroup hashkit |
1343 | + * @{ |
1344 | + */ |
1345 | + |
1346 | +/* Defines. */ |
1347 | +#define HASHKIT_MAX_KEY 251 |
1348 | +#define HASHKIT_POINTS_PER_NODE 100 |
1349 | +#define HASHKIT_POINTS_PER_NODE_WEIGHTED 160 |
1350 | +#define HASHKIT_CONTINUUM_ADDITION 10 |
1351 | +#define HASHKIT_CONTINUUM_KEY_SIZE 86 |
1352 | + |
1353 | +/** @} */ |
1354 | + |
1355 | +/** |
1356 | + * @ingroup hashkit |
1357 | + */ |
1358 | +struct hashkit_st |
1359 | +{ |
1360 | + hashkit_options_st options; |
1361 | + hashkit_distribution_t distribution; |
1362 | + uint32_t continuum_count; |
1363 | + uint32_t continuum_points_count; |
1364 | + size_t list_size; |
1365 | + size_t context_size; |
1366 | + hashkit_continuum_point_st *continuum; |
1367 | + hashkit_fn *hash_fn; |
1368 | + hashkit_active_fn *active_fn; |
1369 | + hashkit_fn *continuum_hash_fn; |
1370 | + hashkit_key_fn *continuum_key_fn; |
1371 | + hashkit_sort_fn *sort_fn; |
1372 | + hashkit_weight_fn *weight_fn; |
1373 | + void *list; |
1374 | +}; |
1375 | + |
1376 | +/** |
1377 | + * @ingroup hashkit |
1378 | + */ |
1379 | +struct hashkit_continuum_point_st |
1380 | +{ |
1381 | + uint32_t index; |
1382 | + uint32_t value; |
1383 | +}; |
1384 | + |
1385 | +/** |
1386 | + * @addtogroup hashkit Pandora Hash Declarations |
1387 | + * @{ |
1388 | + */ |
1389 | + |
1390 | +HASHKIT_API |
1391 | +hashkit_st *hashkit_create(hashkit_st *hash); |
1392 | + |
1393 | +HASHKIT_API |
1394 | +hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *ptr); |
1395 | + |
1396 | +HASHKIT_API |
1397 | +void hashkit_free(hashkit_st *hash); |
1398 | + |
1399 | +HASHKIT_API |
1400 | +bool hashkit_is_allocated(const hashkit_st *hash); |
1401 | + |
1402 | +HASHKIT_API |
1403 | +bool hashkit_is_initialized(const hashkit_st *hash); |
1404 | + |
1405 | +HASHKIT_API |
1406 | +void hashkit_set_list(hashkit_st *hash, void *list, size_t list_size, |
1407 | + size_t context_size); |
1408 | + |
1409 | +HASHKIT_API |
1410 | +uint32_t hashkit_value(hashkit_st *hash, const char *key, size_t key_length); |
1411 | +HASHKIT_API |
1412 | +uint32_t hashkit_index(hashkit_st *hash, uint32_t value); |
1413 | +HASHKIT_API |
1414 | +int hashkit_run_distribution(hashkit_st *hash); |
1415 | + |
1416 | + |
1417 | +HASHKIT_API |
1418 | +uint32_t hashkit_generate_value(const char *key, size_t key_length, hashkit_hash_t hash_algorithm); |
1419 | + |
1420 | +/** @} */ |
1421 | + |
1422 | +#ifdef __cplusplus |
1423 | +} |
1424 | +#endif |
1425 | + |
1426 | +#endif /* HASHKIT_H */ |
1427 | |
1428 | === renamed file 'libmemcached/hsieh_hash.c' => 'libhashkit/hsieh.c' |
1429 | --- libmemcached/hsieh_hash.c 2009-03-11 20:06:43 +0000 |
1430 | +++ libhashkit/hsieh.c 2009-12-11 17:27:14 +0000 |
1431 | @@ -5,7 +5,7 @@ |
1432 | * http://www.azillionmonkeys.com/qed/hash.html |
1433 | */ |
1434 | |
1435 | -#include "common.h" |
1436 | +#include "hash_common.h" |
1437 | |
1438 | #undef get16bits |
1439 | #if (defined(__GNUC__) && defined(__i386__)) |
1440 | @@ -17,7 +17,7 @@ |
1441 | +(uint32_t)(((const uint8_t *)(d))[0]) ) |
1442 | #endif |
1443 | |
1444 | -uint32_t hsieh_hash(const char *key, size_t key_length) |
1445 | +uint32_t hashkit_hsieh(const char *key, size_t key_length) |
1446 | { |
1447 | uint32_t hash = 0, tmp; |
1448 | int rem; |
1449 | |
1450 | === renamed file 'libmemcached/jenkins_hash.c' => 'libhashkit/jenkins.c' |
1451 | --- libmemcached/jenkins_hash.c 2009-12-02 03:09:57 +0000 |
1452 | +++ libhashkit/jenkins.c 2009-12-11 17:27:14 +0000 |
1453 | @@ -38,6 +38,8 @@ |
1454 | c ^= b; c -= rot(b,24); \ |
1455 | } |
1456 | |
1457 | +#define JENKINS_INITVAL 13 |
1458 | + |
1459 | /* |
1460 | jenkins_hash() -- hash a variable-length key into a 32-bit value |
1461 | k : the key (the unaligned variable-length array of bytes) |
1462 | @@ -54,13 +56,13 @@ |
1463 | In which case, the hash table should have hashsize(10) elements. |
1464 | */ |
1465 | |
1466 | -uint32_t jenkins_hash(const void *key, size_t length, uint32_t initval) |
1467 | +uint32_t hashkit_jenkins(const char *key, size_t length) |
1468 | { |
1469 | uint32_t a,b,c; /* internal state */ |
1470 | union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ |
1471 | |
1472 | /* Set up the internal state */ |
1473 | - a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; |
1474 | + a = b = c = 0xdeadbeef + ((uint32_t)length) + JENKINS_INITVAL; |
1475 | |
1476 | u.ptr = key; |
1477 | #ifndef WORDS_BIGENDIAN |
1478 | @@ -209,5 +211,3 @@ |
1479 | final(a,b,c); |
1480 | return c; |
1481 | } |
1482 | - |
1483 | - |
1484 | |
1485 | === renamed file 'libmemcached/memcached_hosts.c' => 'libhashkit/ketama.c' |
1486 | --- libmemcached/memcached_hosts.c 2009-11-03 13:09:13 +0000 |
1487 | +++ libhashkit/ketama.c 2009-12-11 17:27:14 +0000 |
1488 | @@ -1,82 +1,6 @@ |
1489 | #include "common.h" |
1490 | #include <math.h> |
1491 | |
1492 | -/* Protoypes (static) */ |
1493 | -static memcached_return server_add(memcached_st *ptr, const char *hostname, |
1494 | - unsigned int port, |
1495 | - uint32_t weight, |
1496 | - memcached_connection type); |
1497 | -memcached_return update_continuum(memcached_st *ptr); |
1498 | - |
1499 | -static int compare_servers(const void *p1, const void *p2) |
1500 | -{ |
1501 | - int return_value; |
1502 | - memcached_server_st *a= (memcached_server_st *)p1; |
1503 | - memcached_server_st *b= (memcached_server_st *)p2; |
1504 | - |
1505 | - return_value= strcmp(a->hostname, b->hostname); |
1506 | - |
1507 | - if (return_value == 0) |
1508 | - { |
1509 | - return_value= (int) (a->port - b->port); |
1510 | - } |
1511 | - |
1512 | - return return_value; |
1513 | -} |
1514 | - |
1515 | -static void sort_hosts(memcached_st *ptr) |
1516 | -{ |
1517 | - if (ptr->number_of_hosts) |
1518 | - { |
1519 | - qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers); |
1520 | - ptr->hosts[0].count= (uint16_t) ptr->number_of_hosts; |
1521 | - } |
1522 | -} |
1523 | - |
1524 | - |
1525 | -memcached_return run_distribution(memcached_st *ptr) |
1526 | -{ |
1527 | - switch (ptr->distribution) |
1528 | - { |
1529 | - case MEMCACHED_DISTRIBUTION_CONSISTENT: |
1530 | - case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA: |
1531 | - case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY: |
1532 | - return update_continuum(ptr); |
1533 | - case MEMCACHED_DISTRIBUTION_MODULA: |
1534 | - if (ptr->flags & MEM_USE_SORT_HOSTS) |
1535 | - sort_hosts(ptr); |
1536 | - break; |
1537 | - case MEMCACHED_DISTRIBUTION_RANDOM: |
1538 | - break; |
1539 | - default: |
1540 | - WATCHPOINT_ASSERT(0); /* We have added a distribution without extending the logic */ |
1541 | - } |
1542 | - |
1543 | - ptr->last_disconnected_server = NULL; |
1544 | - |
1545 | - return MEMCACHED_SUCCESS; |
1546 | -} |
1547 | - |
1548 | -void server_list_free(memcached_st *ptr, memcached_server_st *servers) |
1549 | -{ |
1550 | - unsigned int x; |
1551 | - |
1552 | - if (servers == NULL) |
1553 | - return; |
1554 | - |
1555 | - for (x= 0; x < servers->count; x++) |
1556 | - if (servers[x].address_info) |
1557 | - { |
1558 | - freeaddrinfo(servers[x].address_info); |
1559 | - servers[x].address_info= NULL; |
1560 | - } |
1561 | - |
1562 | - if (ptr) |
1563 | - ptr->call_free(ptr, servers); |
1564 | - else |
1565 | - free(servers); |
1566 | -} |
1567 | - |
1568 | static uint32_t ketama_server_hash(const char *key, unsigned int key_length, int alignment) |
1569 | { |
1570 | unsigned char results[16]; |
1571 | @@ -88,13 +12,11 @@ |
1572 | | (results[0 + alignment * 4] & 0xFF); |
1573 | } |
1574 | |
1575 | -static int continuum_item_cmp(const void *t1, const void *t2) |
1576 | +static int continuum_points_cmp(const void *t1, const void *t2) |
1577 | { |
1578 | - memcached_continuum_item_st *ct1= (memcached_continuum_item_st *)t1; |
1579 | - memcached_continuum_item_st *ct2= (memcached_continuum_item_st *)t2; |
1580 | + hashkit_continuum_point_st *ct1= (hashkit_continuum_point_st *)t1; |
1581 | + hashkit_continuum_point_st *ct2= (hashkit_continuum_point_st *)t2; |
1582 | |
1583 | - /* Why 153? Hmmm... */ |
1584 | - WATCHPOINT_ASSERT(ct1->value != 153); |
1585 | if (ct1->value == ct2->value) |
1586 | return 0; |
1587 | else if (ct1->value > ct2->value) |
1588 | @@ -103,412 +25,130 @@ |
1589 | return -1; |
1590 | } |
1591 | |
1592 | -memcached_return update_continuum(memcached_st *ptr) |
1593 | +int update_continuum(hashkit_st *hashkit) |
1594 | { |
1595 | - uint32_t host_index; |
1596 | + uint32_t count; |
1597 | uint32_t continuum_index= 0; |
1598 | uint32_t value; |
1599 | - memcached_server_st *list; |
1600 | - uint32_t pointer_index; |
1601 | - uint32_t pointer_counter= 0; |
1602 | - uint32_t pointer_per_server= MEMCACHED_POINTS_PER_SERVER; |
1603 | - uint32_t pointer_per_hash= 1; |
1604 | + uint32_t points_index; |
1605 | + uint32_t points_count= 0; |
1606 | + uint32_t points_per_server; |
1607 | + uint32_t points_per_hash; |
1608 | uint64_t total_weight= 0; |
1609 | - uint64_t is_ketama_weighted= 0; |
1610 | - uint64_t is_auto_ejecting= 0; |
1611 | - uint32_t points_per_server= 0; |
1612 | - uint32_t live_servers= 0; |
1613 | - struct timeval now; |
1614 | - |
1615 | - if (gettimeofday(&now, NULL) != 0) |
1616 | - { |
1617 | - ptr->cached_errno = errno; |
1618 | - return MEMCACHED_ERRNO; |
1619 | - } |
1620 | - |
1621 | - list = ptr->hosts; |
1622 | - |
1623 | - /* count live servers (those without a retry delay set) */ |
1624 | - is_auto_ejecting= memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS); |
1625 | - if (is_auto_ejecting) |
1626 | + uint32_t live_servers; |
1627 | + uint8_t *context; |
1628 | + |
1629 | + if (hashkit->active_fn != NULL || hashkit->weight_fn != NULL) |
1630 | { |
1631 | live_servers= 0; |
1632 | - ptr->next_distribution_rebuild= 0; |
1633 | - for (host_index= 0; host_index < ptr->number_of_hosts; ++host_index) |
1634 | + |
1635 | + for (count= 0, context= hashkit->list; count < hashkit->list_size; |
1636 | + count++, context+= hashkit->context_size) |
1637 | { |
1638 | - if (list[host_index].next_retry <= now.tv_sec) |
1639 | - live_servers++; |
1640 | - else |
1641 | + if (hashkit->active_fn != NULL) |
1642 | { |
1643 | - if (ptr->next_distribution_rebuild == 0 || list[host_index].next_retry < ptr->next_distribution_rebuild) |
1644 | - ptr->next_distribution_rebuild= list[host_index].next_retry; |
1645 | + if (hashkit->active_fn(context)) |
1646 | + live_servers++; |
1647 | + else |
1648 | + continue; |
1649 | } |
1650 | + |
1651 | + if (hashkit->weight_fn != NULL) |
1652 | + total_weight+= hashkit->weight_fn(context); |
1653 | } |
1654 | } |
1655 | - else |
1656 | - live_servers= ptr->number_of_hosts; |
1657 | |
1658 | - is_ketama_weighted= memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED); |
1659 | - points_per_server= (uint32_t) (is_ketama_weighted ? MEMCACHED_POINTS_PER_SERVER_KETAMA : MEMCACHED_POINTS_PER_SERVER); |
1660 | + if (hashkit->active_fn == NULL) |
1661 | + live_servers= (uint32_t)hashkit->list_size; |
1662 | |
1663 | if (live_servers == 0) |
1664 | - return MEMCACHED_SUCCESS; |
1665 | - |
1666 | - if (live_servers > ptr->continuum_count) |
1667 | - { |
1668 | - memcached_continuum_item_st *new_ptr; |
1669 | - |
1670 | - new_ptr= ptr->call_realloc(ptr, ptr->continuum, |
1671 | - sizeof(memcached_continuum_item_st) * (live_servers + MEMCACHED_CONTINUUM_ADDITION) * points_per_server); |
1672 | - |
1673 | - if (new_ptr == 0) |
1674 | - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; |
1675 | - |
1676 | - ptr->continuum= new_ptr; |
1677 | - ptr->continuum_count= live_servers + MEMCACHED_CONTINUUM_ADDITION; |
1678 | - } |
1679 | - |
1680 | - if (is_ketama_weighted) |
1681 | - { |
1682 | - for (host_index = 0; host_index < ptr->number_of_hosts; ++host_index) |
1683 | - { |
1684 | - if (list[host_index].weight == 0) |
1685 | - { |
1686 | - list[host_index].weight = 1; |
1687 | - } |
1688 | - if (!is_auto_ejecting || list[host_index].next_retry <= now.tv_sec) |
1689 | - total_weight += list[host_index].weight; |
1690 | - } |
1691 | - } |
1692 | - |
1693 | - for (host_index = 0; host_index < ptr->number_of_hosts; ++host_index) |
1694 | - { |
1695 | - if (is_auto_ejecting && list[host_index].next_retry > now.tv_sec) |
1696 | + return 0; |
1697 | + |
1698 | + if (hashkit->weight_fn == NULL) |
1699 | + { |
1700 | + points_per_server= HASHKIT_POINTS_PER_NODE; |
1701 | + points_per_hash= 1; |
1702 | + } |
1703 | + else |
1704 | + { |
1705 | + points_per_server= HASHKIT_POINTS_PER_NODE_WEIGHTED; |
1706 | + points_per_hash= 4; |
1707 | + } |
1708 | + |
1709 | + if (live_servers > hashkit->continuum_count) |
1710 | + { |
1711 | + hashkit_continuum_point_st *new_continuum; |
1712 | + |
1713 | + new_continuum= realloc(hashkit->continuum, |
1714 | + sizeof(hashkit_continuum_point_st) * |
1715 | + (live_servers + HASHKIT_CONTINUUM_ADDITION) * |
1716 | + points_per_server); |
1717 | + |
1718 | + if (new_continuum == NULL) |
1719 | + return ENOMEM; |
1720 | + |
1721 | + hashkit->continuum= new_continuum; |
1722 | + hashkit->continuum_count= live_servers + HASHKIT_CONTINUUM_ADDITION; |
1723 | + } |
1724 | + |
1725 | + for (count= 0, context= hashkit->list; count < hashkit->list_size; |
1726 | + count++, context+= hashkit->context_size) |
1727 | + { |
1728 | + if (hashkit->active_fn != NULL && hashkit->active_fn(context) == false) |
1729 | continue; |
1730 | |
1731 | - if (is_ketama_weighted) |
1732 | - { |
1733 | - float pct = (float)list[host_index].weight / (float)total_weight; |
1734 | - pointer_per_server= (uint32_t) ((floorf((float) (pct * MEMCACHED_POINTS_PER_SERVER_KETAMA / 4 * (float)live_servers + 0.0000000001))) * 4); |
1735 | - pointer_per_hash= 4; |
1736 | -#ifdef DEBUG |
1737 | - printf("ketama_weighted:%s|%d|%llu|%u\n", |
1738 | - list[host_index].hostname, |
1739 | - list[host_index].port, |
1740 | - (unsigned long long)list[host_index].weight, |
1741 | - pointer_per_server); |
1742 | -#endif |
1743 | - } |
1744 | - |
1745 | - |
1746 | - if (ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) |
1747 | - { |
1748 | - for (pointer_index= 0; |
1749 | - pointer_index < pointer_per_server / pointer_per_hash; |
1750 | - pointer_index++) |
1751 | - { |
1752 | - char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= ""; |
1753 | - size_t sort_host_length; |
1754 | - |
1755 | - // Spymemcached ketema key format is: hostname/ip:port-index |
1756 | - // If hostname is not available then: /ip:port-index |
1757 | - sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, |
1758 | - "/%s:%d-%d", |
1759 | - list[host_index].hostname, |
1760 | - list[host_index].port, |
1761 | - pointer_index); |
1762 | -#ifdef DEBUG |
1763 | - printf("update_continuum: key is %s\n", sort_host); |
1764 | -#endif |
1765 | - |
1766 | - WATCHPOINT_ASSERT(sort_host_length); |
1767 | - |
1768 | - if (is_ketama_weighted) |
1769 | - { |
1770 | - unsigned int i; |
1771 | - for (i = 0; i < pointer_per_hash; i++) |
1772 | - { |
1773 | - value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i); |
1774 | - ptr->continuum[continuum_index].index= host_index; |
1775 | - ptr->continuum[continuum_index++].value= value; |
1776 | - } |
1777 | - } |
1778 | - else |
1779 | - { |
1780 | - value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum); |
1781 | - ptr->continuum[continuum_index].index= host_index; |
1782 | - ptr->continuum[continuum_index++].value= value; |
1783 | - } |
1784 | - } |
1785 | - } |
1786 | - else |
1787 | - { |
1788 | - for (pointer_index= 1; |
1789 | - pointer_index <= pointer_per_server / pointer_per_hash; |
1790 | - pointer_index++) |
1791 | - { |
1792 | - char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= ""; |
1793 | - size_t sort_host_length; |
1794 | - |
1795 | - if (list[host_index].port == MEMCACHED_DEFAULT_PORT) |
1796 | - { |
1797 | - sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, |
1798 | - "%s-%d", |
1799 | - list[host_index].hostname, |
1800 | - pointer_index - 1); |
1801 | - } |
1802 | - else |
1803 | - { |
1804 | - sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH, |
1805 | - "%s:%d-%d", |
1806 | - list[host_index].hostname, |
1807 | - list[host_index].port, pointer_index - 1); |
1808 | - } |
1809 | - |
1810 | - WATCHPOINT_ASSERT(sort_host_length); |
1811 | - |
1812 | - if (is_ketama_weighted) |
1813 | - { |
1814 | - unsigned int i; |
1815 | - for (i = 0; i < pointer_per_hash; i++) |
1816 | - { |
1817 | - value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i); |
1818 | - ptr->continuum[continuum_index].index= host_index; |
1819 | - ptr->continuum[continuum_index++].value= value; |
1820 | - } |
1821 | - } |
1822 | - else |
1823 | - { |
1824 | - value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum); |
1825 | - ptr->continuum[continuum_index].index= host_index; |
1826 | - ptr->continuum[continuum_index++].value= value; |
1827 | - } |
1828 | - } |
1829 | - } |
1830 | - |
1831 | - pointer_counter+= pointer_per_server; |
1832 | - } |
1833 | - |
1834 | - WATCHPOINT_ASSERT(ptr); |
1835 | - WATCHPOINT_ASSERT(ptr->continuum); |
1836 | - WATCHPOINT_ASSERT(ptr->number_of_hosts * MEMCACHED_POINTS_PER_SERVER <= MEMCACHED_CONTINUUM_SIZE); |
1837 | - ptr->continuum_points_counter= pointer_counter; |
1838 | - qsort(ptr->continuum, ptr->continuum_points_counter, sizeof(memcached_continuum_item_st), continuum_item_cmp); |
1839 | - |
1840 | -#ifdef DEBUG |
1841 | - for (pointer_index= 0; ptr->number_of_hosts && pointer_index < ((live_servers * MEMCACHED_POINTS_PER_SERVER) - 1); pointer_index++) |
1842 | - { |
1843 | - WATCHPOINT_ASSERT(ptr->continuum[pointer_index].value <= ptr->continuum[pointer_index + 1].value); |
1844 | - } |
1845 | -#endif |
1846 | - |
1847 | - return MEMCACHED_SUCCESS; |
1848 | -} |
1849 | - |
1850 | - |
1851 | -memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list) |
1852 | -{ |
1853 | - unsigned int x; |
1854 | - uint16_t count; |
1855 | - memcached_server_st *new_host_list; |
1856 | - |
1857 | - if (!list) |
1858 | - return MEMCACHED_SUCCESS; |
1859 | - |
1860 | - count= list[0].count; |
1861 | - new_host_list= ptr->call_realloc(ptr, ptr->hosts, |
1862 | - sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); |
1863 | - |
1864 | - if (!new_host_list) |
1865 | - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; |
1866 | - |
1867 | - ptr->hosts= new_host_list; |
1868 | - |
1869 | - for (x= 0; x < count; x++) |
1870 | - { |
1871 | - if ((ptr->flags & MEM_USE_UDP && list[x].type != MEMCACHED_CONNECTION_UDP) |
1872 | - || ((list[x].type == MEMCACHED_CONNECTION_UDP) |
1873 | - && ! (ptr->flags & MEM_USE_UDP)) ) |
1874 | - return MEMCACHED_INVALID_HOST_PROTOCOL; |
1875 | - |
1876 | - WATCHPOINT_ASSERT(list[x].hostname[0] != 0); |
1877 | - memcached_server_create(ptr, &ptr->hosts[ptr->number_of_hosts]); |
1878 | - /* TODO check return type */ |
1879 | - (void)memcached_server_create_with(ptr, &ptr->hosts[ptr->number_of_hosts], list[x].hostname, |
1880 | - list[x].port, list[x].weight, list[x].type); |
1881 | - ptr->number_of_hosts++; |
1882 | - } |
1883 | - ptr->hosts[0].count= (uint16_t) ptr->number_of_hosts; |
1884 | - |
1885 | - return run_distribution(ptr); |
1886 | -} |
1887 | - |
1888 | -memcached_return memcached_server_add_unix_socket(memcached_st *ptr, |
1889 | - const char *filename) |
1890 | -{ |
1891 | - return memcached_server_add_unix_socket_with_weight(ptr, filename, 0); |
1892 | -} |
1893 | - |
1894 | -memcached_return memcached_server_add_unix_socket_with_weight(memcached_st *ptr, |
1895 | - const char *filename, |
1896 | - uint32_t weight) |
1897 | -{ |
1898 | - if (!filename) |
1899 | - return MEMCACHED_FAILURE; |
1900 | - |
1901 | - return server_add(ptr, filename, 0, weight, MEMCACHED_CONNECTION_UNIX_SOCKET); |
1902 | -} |
1903 | - |
1904 | -memcached_return memcached_server_add_udp(memcached_st *ptr, |
1905 | - const char *hostname, |
1906 | - unsigned int port) |
1907 | -{ |
1908 | - return memcached_server_add_udp_with_weight(ptr, hostname, port, 0); |
1909 | -} |
1910 | - |
1911 | -memcached_return memcached_server_add_udp_with_weight(memcached_st *ptr, |
1912 | - const char *hostname, |
1913 | - unsigned int port, |
1914 | - uint32_t weight) |
1915 | -{ |
1916 | - if (!port) |
1917 | - port= MEMCACHED_DEFAULT_PORT; |
1918 | - |
1919 | - if (!hostname) |
1920 | - hostname= "localhost"; |
1921 | - |
1922 | - return server_add(ptr, hostname, port, weight, MEMCACHED_CONNECTION_UDP); |
1923 | -} |
1924 | - |
1925 | -memcached_return memcached_server_add(memcached_st *ptr, |
1926 | - const char *hostname, |
1927 | - unsigned int port) |
1928 | -{ |
1929 | - return memcached_server_add_with_weight(ptr, hostname, port, 0); |
1930 | -} |
1931 | - |
1932 | -memcached_return memcached_server_add_with_weight(memcached_st *ptr, |
1933 | - const char *hostname, |
1934 | - unsigned int port, |
1935 | - uint32_t weight) |
1936 | -{ |
1937 | - if (!port) |
1938 | - port= MEMCACHED_DEFAULT_PORT; |
1939 | - |
1940 | - if (!hostname) |
1941 | - hostname= "localhost"; |
1942 | - |
1943 | - return server_add(ptr, hostname, port, weight, MEMCACHED_CONNECTION_TCP); |
1944 | -} |
1945 | - |
1946 | -static memcached_return server_add(memcached_st *ptr, const char *hostname, |
1947 | - unsigned int port, |
1948 | - uint32_t weight, |
1949 | - memcached_connection type) |
1950 | -{ |
1951 | - memcached_server_st *new_host_list; |
1952 | - |
1953 | - if ( (ptr->flags & MEM_USE_UDP && type != MEMCACHED_CONNECTION_UDP) |
1954 | - || ( (type == MEMCACHED_CONNECTION_UDP) && !(ptr->flags & MEM_USE_UDP) ) ) |
1955 | - return MEMCACHED_INVALID_HOST_PROTOCOL; |
1956 | - |
1957 | - new_host_list= ptr->call_realloc(ptr, ptr->hosts, |
1958 | - sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); |
1959 | - |
1960 | - if (new_host_list == NULL) |
1961 | - return MEMCACHED_MEMORY_ALLOCATION_FAILURE; |
1962 | - |
1963 | - ptr->hosts= new_host_list; |
1964 | - |
1965 | - /* TODO: Check return type */ |
1966 | - (void)memcached_server_create_with(ptr, &ptr->hosts[ptr->number_of_hosts], hostname, port, weight, type); |
1967 | - ptr->number_of_hosts++; |
1968 | - ptr->hosts[0].count= (uint16_t) ptr->number_of_hosts; |
1969 | - |
1970 | - return run_distribution(ptr); |
1971 | -} |
1972 | - |
1973 | -memcached_return memcached_server_remove(memcached_server_st *st_ptr) |
1974 | -{ |
1975 | - uint32_t x, host_index; |
1976 | - memcached_st *ptr= st_ptr->root; |
1977 | - memcached_server_st *list= ptr->hosts; |
1978 | - |
1979 | - for (x= 0, host_index= 0; x < ptr->number_of_hosts; x++) |
1980 | - { |
1981 | - if (strncmp(list[x].hostname, st_ptr->hostname, MEMCACHED_MAX_HOST_LENGTH) != 0 || list[x].port != st_ptr->port) |
1982 | - { |
1983 | - if (host_index != x) |
1984 | - memcpy(list+host_index, list+x, sizeof(memcached_server_st)); |
1985 | - host_index++; |
1986 | - } |
1987 | - } |
1988 | - ptr->number_of_hosts= host_index; |
1989 | - |
1990 | - if (st_ptr->address_info) |
1991 | - { |
1992 | - freeaddrinfo(st_ptr->address_info); |
1993 | - st_ptr->address_info= NULL; |
1994 | - } |
1995 | - run_distribution(ptr); |
1996 | - |
1997 | - return MEMCACHED_SUCCESS; |
1998 | -} |
1999 | - |
2000 | -memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, |
2001 | - const char *hostname, unsigned int port, |
2002 | - memcached_return *error) |
2003 | -{ |
2004 | - return memcached_server_list_append_with_weight(ptr, hostname, port, 0, error); |
2005 | -} |
2006 | - |
2007 | -memcached_server_st *memcached_server_list_append_with_weight(memcached_server_st *ptr, |
2008 | - const char *hostname, unsigned int port, |
2009 | - uint32_t weight, |
2010 | - memcached_return *error) |
2011 | -{ |
2012 | - unsigned int count; |
2013 | - memcached_server_st *new_host_list; |
2014 | - |
2015 | - if (hostname == NULL || error == NULL) |
2016 | - return NULL; |
2017 | - |
2018 | - if (!port) |
2019 | - port= MEMCACHED_DEFAULT_PORT; |
2020 | - |
2021 | - /* Increment count for hosts */ |
2022 | - count= 1; |
2023 | - if (ptr != NULL) |
2024 | - { |
2025 | - count+= ptr[0].count; |
2026 | - } |
2027 | - |
2028 | - new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count); |
2029 | - if (!new_host_list) |
2030 | - { |
2031 | - *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; |
2032 | - return NULL; |
2033 | - } |
2034 | - |
2035 | - /* TODO: Check return type */ |
2036 | - memcached_server_create_with(NULL, &new_host_list[count-1], hostname, port, weight, MEMCACHED_CONNECTION_TCP); |
2037 | - |
2038 | - /* Backwards compatibility hack */ |
2039 | - new_host_list[0].count= (uint16_t) count; |
2040 | - |
2041 | - *error= MEMCACHED_SUCCESS; |
2042 | - return new_host_list; |
2043 | -} |
2044 | - |
2045 | -unsigned int memcached_server_list_count(memcached_server_st *ptr) |
2046 | -{ |
2047 | - if (ptr == NULL) |
2048 | - return 0; |
2049 | - |
2050 | - return ptr[0].count; |
2051 | -} |
2052 | - |
2053 | -void memcached_server_list_free(memcached_server_st *ptr) |
2054 | -{ |
2055 | - server_list_free(NULL, ptr); |
2056 | + if (hashkit->weight_fn != NULL) |
2057 | + { |
2058 | + float pct = (float)hashkit->weight_fn(context) / (float)total_weight; |
2059 | + points_per_server= (uint32_t) ((floorf((float) (pct * HASHKIT_POINTS_PER_NODE_WEIGHTED / 4 * (float)live_servers + 0.0000000001))) * 4); |
2060 | + } |
2061 | + |
2062 | + for (points_index= 0; |
2063 | + points_index < points_per_server / points_per_hash; |
2064 | + points_index++) |
2065 | + { |
2066 | + char sort_host[HASHKIT_CONTINUUM_KEY_SIZE]= ""; |
2067 | + size_t sort_host_length; |
2068 | + |
2069 | + if (hashkit->continuum_key_fn == NULL) |
2070 | + { |
2071 | + sort_host_length= (size_t) snprintf(sort_host, HASHKIT_CONTINUUM_KEY_SIZE, "%d", |
2072 | + points_index); |
2073 | + } |
2074 | + else |
2075 | + { |
2076 | + sort_host_length= hashkit->continuum_key_fn(sort_host, HASHKIT_CONTINUUM_KEY_SIZE, |
2077 | + points_index, context); |
2078 | + } |
2079 | + |
2080 | + if (hashkit->weight_fn == NULL) |
2081 | + { |
2082 | + if (hashkit->continuum_hash_fn == NULL) |
2083 | + value= hashkit_default(sort_host, sort_host_length); |
2084 | + else |
2085 | + value= hashkit->continuum_hash_fn(sort_host, sort_host_length); |
2086 | + |
2087 | + hashkit->continuum[continuum_index].index= count; |
2088 | + hashkit->continuum[continuum_index++].value= value; |
2089 | + } |
2090 | + else |
2091 | + { |
2092 | + unsigned int i; |
2093 | + for (i = 0; i < points_per_hash; i++) |
2094 | + { |
2095 | + value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i); |
2096 | + hashkit->continuum[continuum_index].index= count; |
2097 | + hashkit->continuum[continuum_index++].value= value; |
2098 | + } |
2099 | + } |
2100 | + } |
2101 | + |
2102 | + points_count+= points_per_server; |
2103 | + } |
2104 | + |
2105 | + hashkit->continuum_points_count= points_count; |
2106 | + qsort(hashkit->continuum, hashkit->continuum_points_count, sizeof(hashkit_continuum_point_st), |
2107 | + continuum_points_cmp); |
2108 | + |
2109 | + return 0; |
2110 | } |
2111 | |
2112 | === renamed file 'libmemcached/md5.c' => 'libhashkit/md5.c' |
2113 | --- libmemcached/md5.c 2009-05-13 09:53:59 +0000 |
2114 | +++ libhashkit/md5.c 2009-12-11 17:27:14 +0000 |
2115 | @@ -29,7 +29,6 @@ |
2116 | documentation and/or software. |
2117 | */ |
2118 | |
2119 | - |
2120 | #include "common.h" |
2121 | |
2122 | #include <string.h> |
2123 | @@ -352,3 +351,15 @@ |
2124 | output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | |
2125 | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); |
2126 | } |
2127 | + |
2128 | +uint32_t hashkit_md5(const char *key, size_t key_length) |
2129 | +{ |
2130 | + unsigned char results[16]; |
2131 | + |
2132 | + md5_signature((unsigned char*)key, (unsigned int)key_length, results); |
2133 | + |
2134 | + return ((uint32_t) (results[3] & 0xFF) << 24) |
2135 | + | ((uint32_t) (results[2] & 0xFF) << 16) |
2136 | + | ((uint32_t) (results[1] & 0xFF) << 8) |
2137 | + | (results[0] & 0xFF); |
2138 | +} |
2139 | |
2140 | === renamed file 'libmemcached/murmur_hash.c' => 'libhashkit/murmur.c' |
2141 | --- libmemcached/murmur_hash.c 2009-08-11 18:56:12 +0000 |
2142 | +++ libhashkit/murmur.c 2009-12-11 17:27:14 +0000 |
2143 | @@ -17,7 +17,7 @@ |
2144 | |
2145 | #include "common.h" |
2146 | |
2147 | -uint32_t murmur_hash(const char *key, size_t length) |
2148 | +uint32_t hashkit_murmur(const char *key, size_t length) |
2149 | { |
2150 | /* |
2151 | 'm' and 'r' are mixing constants generated offline. They're not |
2152 | @@ -72,5 +72,5 @@ |
2153 | h *= m; |
2154 | h ^= h >> 15; |
2155 | |
2156 | - return (uint32_t) h; |
2157 | + return h; |
2158 | } |
2159 | |
2160 | === added file 'libhashkit/types.h' |
2161 | --- libhashkit/types.h 1970-01-01 00:00:00 +0000 |
2162 | +++ libhashkit/types.h 2009-12-11 17:27:14 +0000 |
2163 | @@ -0,0 +1,85 @@ |
2164 | + |
2165 | +/* HashKit |
2166 | + * Copyright (C) 2009 Brian Aker |
2167 | + * All rights reserved. |
2168 | + * |
2169 | + * Use and distribution licensed under the BSD license. See |
2170 | + * the COPYING file in the parent directory for full text. |
2171 | + */ |
2172 | + |
2173 | +/** |
2174 | + * @file |
2175 | + * @brief HashKit Header |
2176 | + */ |
2177 | + |
2178 | +#ifndef HASHKIT_TYPES_H |
2179 | +#define HASHKIT_TYPES_H |
2180 | + |
2181 | +#ifdef __cplusplus |
2182 | +extern "C" { |
2183 | +#endif |
2184 | + |
2185 | +/** |
2186 | + * @addtogroup hashkit_types Types |
2187 | + * @ingroup hashkit |
2188 | + * @{ |
2189 | + */ |
2190 | + |
2191 | +/** |
2192 | + @todo hashkit_options_t is for future use, currently we do not define any user options. |
2193 | + */ |
2194 | + |
2195 | +typedef enum |
2196 | +{ |
2197 | + HASHKIT_OPTION_MAX |
2198 | +} hashkit_options_t; |
2199 | + |
2200 | +typedef struct |
2201 | +{ |
2202 | + /* We use the following for internal book keeping. */ |
2203 | + bool is_initialized:1; |
2204 | + bool is_allocated:1; |
2205 | +} hashkit_options_st; |
2206 | + |
2207 | +typedef enum { |
2208 | + HASHKIT_HASH_DEFAULT= 0, |
2209 | + HASHKIT_HASH_MD5, |
2210 | + HASHKIT_HASH_CRC, |
2211 | + HASHKIT_HASH_FNV1_64, |
2212 | + HASHKIT_HASH_FNV1A_64, |
2213 | + HASHKIT_HASH_FNV1_32, |
2214 | + HASHKIT_HASH_FNV1A_32, |
2215 | + HASHKIT_HASH_HSIEH, |
2216 | + HASHKIT_HASH_MURMUR, |
2217 | + HASHKIT_HASH_JENKINS, |
2218 | + HASHKIT_HASH_MAX |
2219 | +} hashkit_hash_t; |
2220 | + |
2221 | +/** |
2222 | + * Hash distributions that are available to use. |
2223 | + */ |
2224 | +typedef enum |
2225 | +{ |
2226 | + HASHKIT_DISTRIBUTION_MODULA, |
2227 | + HASHKIT_DISTRIBUTION_RANDOM, |
2228 | + HASHKIT_DISTRIBUTION_KETAMA, |
2229 | + HASHKIT_DISTRIBUTION_MAX /* Always add new values before this. */ |
2230 | +} hashkit_distribution_t; |
2231 | + |
2232 | + |
2233 | +typedef struct hashkit_st hashkit_st; |
2234 | +typedef struct hashkit_continuum_point_st hashkit_continuum_point_st; |
2235 | +typedef bool (hashkit_active_fn)(void *context); |
2236 | +typedef uint32_t (hashkit_fn)(const char *key, size_t key_length); |
2237 | +typedef size_t (hashkit_key_fn)(char *key, size_t key_length, uint32_t point_index, void *context); |
2238 | +typedef void (hashkit_sort_fn)(void *context, size_t count); |
2239 | +typedef uint32_t (hashkit_weight_fn)(void *context); |
2240 | + |
2241 | +/** @} */ |
2242 | + |
2243 | + |
2244 | +#ifdef __cplusplus |
2245 | +} |
2246 | +#endif |
2247 | + |
2248 | +#endif /* HASHKIT_TYPES_H */ |
2249 | |
2250 | === added file 'libhashkit/visibility.h' |
2251 | --- libhashkit/visibility.h 1970-01-01 00:00:00 +0000 |
2252 | +++ libhashkit/visibility.h 2009-12-11 17:27:14 +0000 |
2253 | @@ -0,0 +1,51 @@ |
2254 | +/* |
2255 | + * Summary: interface for HashKit functions |
2256 | + * Description: visibitliy macros for HashKit library |
2257 | + * |
2258 | + * Use and distribution licensed under the BSD license. See |
2259 | + * the COPYING file in this directory for full text. |
2260 | + * |
2261 | + * Author: Monty Taylor |
2262 | + */ |
2263 | + |
2264 | +/** |
2265 | + * @file |
2266 | + * @brief Visibility control macros |
2267 | + */ |
2268 | + |
2269 | +#ifndef HASHKIT_VISIBILITY_H |
2270 | +#define HASHKIT_VISIBILITY_H |
2271 | + |
2272 | +/** |
2273 | + * |
2274 | + * HASHKIT_API is used for the public API symbols. It either DLL imports or |
2275 | + * DLL exports (or does nothing for static build). |
2276 | + * |
2277 | + * HASHKIT_LOCAL is used for non-api symbols. |
2278 | + */ |
2279 | + |
2280 | +#if defined(BUILDING_HASHKIT) |
2281 | +# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY |
2282 | +# define HASHKIT_API __attribute__ ((visibility("default"))) |
2283 | +# define HASHKIT_LOCAL __attribute__ ((visibility("hidden"))) |
2284 | +# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550) |
2285 | +# define HASHKIT_API __global |
2286 | +# define HASHKIT_LOCAL __hidden |
2287 | +# elif defined(_MSC_VER) |
2288 | +# define HASHKIT_API extern __declspec(dllexport) |
2289 | +# define HASHKIT_LOCAL |
2290 | +# else |
2291 | +# define HASHKIT_API |
2292 | +# define HASHKIT_LOCAL |
2293 | +# endif /* defined(HAVE_VISIBILITY) */ |
2294 | +#else /* defined(BUILDING_HASHKIT) */ |
2295 | +# if defined(_MSC_VER) |
2296 | +# define HASHKIT_API extern __declspec(dllimport) |
2297 | +# define HASHKIT_LOCAL |
2298 | +# else |
2299 | +# define HASHKIT_API |
2300 | +# define HASHKIT_LOCAL |
2301 | +# endif /* defined(_MSC_VER) */ |
2302 | +#endif /* defined(BUILDING_HASHKIT) */ |
2303 | + |
2304 | +#endif /* HASHKIT_VISIBILITY_H */ |
2305 | |
2306 | === modified file 'libmemcached/Makefile.am' |
2307 | --- libmemcached/Makefile.am 2009-12-02 04:43:41 +0000 |
2308 | +++ libmemcached/Makefile.am 2009-12-11 17:27:14 +0000 |
2309 | @@ -24,6 +24,7 @@ |
2310 | memcached_configure.h \ |
2311 | memcached_constants.h \ |
2312 | memcached_get.h \ |
2313 | + memcached_hash.h \ |
2314 | memcached_result.h \ |
2315 | memcached_server.h \ |
2316 | memcached_storage.h \ |
2317 | @@ -51,8 +52,7 @@ |
2318 | libmemcachedcallbacks_la_SOURCES = memcached_callback.c |
2319 | |
2320 | libmemcached_la_CFLAGS= ${AM_CFLAGS} ${NO_CONVERSION} |
2321 | -libmemcached_la_SOURCES = crc.c \ |
2322 | - memcached.c \ |
2323 | +libmemcached_la_SOURCES = memcached.c \ |
2324 | memcached_auto.c \ |
2325 | memcached_analyze.c \ |
2326 | memcached_behavior.c \ |
2327 | @@ -64,11 +64,9 @@ |
2328 | memcached_flush.c \ |
2329 | memcached_get.c \ |
2330 | memcached_hash.c \ |
2331 | - memcached_hosts.c \ |
2332 | memcached_io.c \ |
2333 | memcached_purge.c \ |
2334 | memcached_flush_buffers.c \ |
2335 | - md5.c \ |
2336 | memcached_key.c \ |
2337 | memcached_quit.c \ |
2338 | memcached_parse.c \ |
2339 | @@ -81,18 +79,11 @@ |
2340 | memcached_strerror.c \ |
2341 | memcached_verbosity.c \ |
2342 | memcached_version.c \ |
2343 | - murmur_hash.c \ |
2344 | - jenkins_hash.c \ |
2345 | memcached_allocators.c |
2346 | |
2347 | - |
2348 | -if INCLUDE_HSIEH_SRC |
2349 | -libmemcached_la_SOURCES += hsieh_hash.c |
2350 | -endif |
2351 | - |
2352 | libmemcached_la_DEPENDENCIES= libmemcachedcallbacks.la |
2353 | -libmemcached_la_LIBADD= $(LIBM) libmemcachedcallbacks.la |
2354 | -libmemcached_la_LDFLAGS= ${AM_LDFLAGS} -version-info 3:0:0 |
2355 | +libmemcached_la_LIBADD= $(LIBM) libmemcachedcallbacks.la $(LIBHASHKIT_LINK) |
2356 | +libmemcached_la_LDFLAGS = -version-info $(MEMCACHED_LIBRARY_VERSION) $(LD_VERSION_SCRIPT) $(LIBM) |
2357 | |
2358 | if BUILD_LIBMEMCACHEDUTIL |
2359 | pkginclude_HEADERS+= memcached_util.h memcached_pool.h |
2360 | |
2361 | === modified file 'libmemcached/common.h' |
2362 | --- libmemcached/common.h 2009-11-27 10:40:32 +0000 |
2363 | +++ libmemcached/common.h 2009-12-11 17:27:14 +0000 |
2364 | @@ -39,7 +39,6 @@ |
2365 | */ |
2366 | #define BUILDING_LIBMEMCACHED 1 |
2367 | |
2368 | - |
2369 | #include "libmemcached/memcached.h" |
2370 | #include "libmemcached/memcached_watchpoint.h" |
2371 | |
2372 | @@ -50,13 +49,6 @@ |
2373 | #include "libmemcached/memcached/protocol_binary.h" |
2374 | #include "libmemcached/byteorder.h" |
2375 | |
2376 | -/* string value */ |
2377 | -struct memcached_continuum_item_st { |
2378 | - uint32_t index; |
2379 | - uint32_t value; |
2380 | -}; |
2381 | - |
2382 | - |
2383 | #if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) |
2384 | |
2385 | #define likely(x) if((x)) |
2386 | @@ -97,21 +89,10 @@ |
2387 | MEM_RANDOMIZE_REPLICA_READ= (1 << 17) |
2388 | } memcached_flags; |
2389 | |
2390 | -/* Hashing algo */ |
2391 | - |
2392 | -LIBMEMCACHED_LOCAL |
2393 | -void md5_signature(const unsigned char *key, unsigned int length, unsigned char *result); |
2394 | -LIBMEMCACHED_LOCAL |
2395 | -uint32_t hash_crc32(const char *data, |
2396 | - size_t data_len); |
2397 | -#ifdef HAVE_HSIEH_HASH |
2398 | -LIBMEMCACHED_LOCAL |
2399 | -uint32_t hsieh_hash(const char *key, size_t key_length); |
2400 | -#endif |
2401 | -LIBMEMCACHED_LOCAL |
2402 | -uint32_t murmur_hash(const char *key, size_t key_length); |
2403 | -LIBMEMCACHED_LOCAL |
2404 | -uint32_t jenkins_hash(const void *key, size_t length, uint32_t initval); |
2405 | +LIBMEMCACHED_LOCAL |
2406 | +extern hashkit_fn *memcached_hash_fn_map[MEMCACHED_HASH_MAX]; |
2407 | +LIBMEMCACHED_LOCAL |
2408 | +extern hashkit_distribution_t memcached_distribution_map[MEMCACHED_DISTRIBUTION_MAX]; |
2409 | |
2410 | LIBMEMCACHED_LOCAL |
2411 | memcached_return memcached_connect(memcached_server_st *ptr); |
2412 | @@ -143,9 +124,6 @@ |
2413 | |
2414 | |
2415 | LIBMEMCACHED_LOCAL |
2416 | -uint32_t generate_hash(memcached_st *ptr, const char *key, size_t key_length); |
2417 | - |
2418 | -LIBMEMCACHED_LOCAL |
2419 | memcached_return memcached_purge(memcached_server_st *ptr); |
2420 | |
2421 | static inline memcached_return memcached_validate_key_length(size_t key_length, |
2422 | @@ -167,4 +145,13 @@ |
2423 | return MEMCACHED_SUCCESS; |
2424 | } |
2425 | |
2426 | +LIBMEMCACHED_LOCAL |
2427 | +bool memcached_server_active(void *context); |
2428 | +LIBMEMCACHED_LOCAL |
2429 | +uint32_t memcached_server_weight(void *context); |
2430 | +LIBMEMCACHED_LOCAL |
2431 | +void memcached_server_sort(void *context, size_t count); |
2432 | +LIBMEMCACHED_LOCAL |
2433 | +size_t memcached_server_key(char *key, size_t key_length, uint32_t point_index, void *context); |
2434 | + |
2435 | #endif /* LIBMEMCACHED_COMMON_H */ |
2436 | |
2437 | === modified file 'libmemcached/memcached.c' |
2438 | --- libmemcached/memcached.c 2009-06-14 18:52:39 +0000 |
2439 | +++ libmemcached/memcached.c 2009-12-11 17:27:14 +0000 |
2440 | @@ -3,6 +3,33 @@ |
2441 | */ |
2442 | #include "common.h" |
2443 | |
2444 | +hashkit_fn *memcached_hash_fn_map[MEMCACHED_HASH_MAX]= |
2445 | +{ |
2446 | + hashkit_default, |
2447 | + hashkit_md5, |
2448 | + hashkit_crc32, |
2449 | + hashkit_fnv1_64, |
2450 | + hashkit_fnv1a_64, |
2451 | + hashkit_fnv1_32, |
2452 | + hashkit_fnv1a_32, |
2453 | +#ifdef HAVE_HSIEH_HASH |
2454 | + hashkit_hsieh, |
2455 | +#else |
2456 | + NULL, |
2457 | +#endif |
2458 | + hashkit_murmur, |
2459 | + hashkit_jenkins |
2460 | +}; |
2461 | + |
2462 | +hashkit_distribution_t memcached_distribution_map[MEMCACHED_DISTRIBUTION_MAX]= |
2463 | +{ |
2464 | + HASHKIT_DISTRIBUTION_MODULA, |
2465 | + HASHKIT_DISTRIBUTION_KETAMA, |
2466 | + HASHKIT_DISTRIBUTION_KETAMA, |
2467 | + HASHKIT_DISTRIBUTION_RANDOM, |
2468 | + HASHKIT_DISTRIBUTION_KETAMA |
2469 | +}; |
2470 | + |
2471 | memcached_st *memcached_create(memcached_st *ptr) |
2472 | { |
2473 | memcached_result_st *result_ptr; |
2474 | @@ -29,6 +56,8 @@ |
2475 | ptr->connect_timeout= MEMCACHED_DEFAULT_TIMEOUT; |
2476 | ptr->retry_timeout= 0; |
2477 | ptr->distribution= MEMCACHED_DISTRIBUTION_MODULA; |
2478 | + hashkit_create(&ptr->hashkit); |
2479 | + hashkit_set_continuum_key_fn(&ptr->hashkit, memcached_server_key); |
2480 | |
2481 | /* TODO, Document why we picked these defaults */ |
2482 | ptr->io_msg_watermark= 500; |
2483 | @@ -47,8 +76,7 @@ |
2484 | if (ptr->on_cleanup) |
2485 | ptr->on_cleanup(ptr); |
2486 | |
2487 | - if (ptr->continuum) |
2488 | - ptr->call_free(ptr, ptr->continuum); |
2489 | + hashkit_free(&ptr->hashkit); |
2490 | |
2491 | if (ptr->is_allocated) |
2492 | ptr->call_free(ptr, ptr); |
2493 | @@ -67,7 +95,9 @@ |
2494 | memcached_st *new_clone; |
2495 | |
2496 | if (source == NULL) |
2497 | + { |
2498 | return memcached_create(clone); |
2499 | + } |
2500 | |
2501 | if (clone && clone->is_allocated) |
2502 | { |
2503 | @@ -86,8 +116,13 @@ |
2504 | new_clone->connect_timeout= source->connect_timeout; |
2505 | new_clone->retry_timeout= source->retry_timeout; |
2506 | new_clone->distribution= source->distribution; |
2507 | - new_clone->hash= source->hash; |
2508 | - new_clone->hash_continuum= source->hash_continuum; |
2509 | + hashkit_set_distribution(&new_clone->hashkit, |
2510 | + memcached_distribution_map[new_clone->distribution]); |
2511 | + new_clone->hash_type= source->hash_type; |
2512 | + hashkit_set_hash_fn(&new_clone->hashkit, memcached_hash_fn_map[new_clone->hash_type]); |
2513 | + new_clone->continuum_hash_type= source->continuum_hash_type; |
2514 | + hashkit_set_continuum_hash_fn(&new_clone->hashkit, |
2515 | + memcached_hash_fn_map[new_clone->continuum_hash_type]); |
2516 | new_clone->user_data= source->user_data; |
2517 | |
2518 | new_clone->snd_timeout= source->snd_timeout; |
2519 | @@ -148,3 +183,19 @@ |
2520 | ptr->user_data= data; |
2521 | return ret; |
2522 | } |
2523 | + |
2524 | +memcached_return run_distribution(memcached_st *ptr) |
2525 | +{ |
2526 | + if (gettimeofday(&ptr->now, NULL) == 0 && ptr->now.tv_sec > ptr->next_distribution_rebuild) |
2527 | + ptr->next_distribution_rebuild= 0; |
2528 | + |
2529 | + if (hashkit_run_distribution(&ptr->hashkit) != 0) |
2530 | + { |
2531 | + ptr->cached_errno= errno; |
2532 | + return MEMCACHED_ERRNO; |
2533 | + } |
2534 | + |
2535 | + ptr->last_disconnected_server = NULL; |
2536 | + |
2537 | + return MEMCACHED_SUCCESS; |
2538 | +} |
2539 | |
2540 | === modified file 'libmemcached/memcached.h' |
2541 | --- libmemcached/memcached.h 2009-12-02 22:04:02 +0000 |
2542 | +++ libmemcached/memcached.h 2009-12-11 17:27:14 +0000 |
2543 | @@ -18,11 +18,13 @@ |
2544 | #include <sys/types.h> |
2545 | #include <netinet/in.h> |
2546 | |
2547 | +#include <libhashkit/hashkit.h> |
2548 | #include <libmemcached/visibility.h> |
2549 | #include <libmemcached/memcached_configure.h> |
2550 | #include <libmemcached/memcached_constants.h> |
2551 | #include <libmemcached/memcached_types.h> |
2552 | #include <libmemcached/memcached_get.h> |
2553 | +#include <libmemcached/memcached_hash.h> |
2554 | #include <libmemcached/memcached_server.h> |
2555 | #include <libmemcached/memcached_string.h> |
2556 | #include <libmemcached/memcached_result.h> |
2557 | @@ -76,8 +78,6 @@ |
2558 | uint8_t purging; |
2559 | bool is_allocated; |
2560 | uint8_t distribution; |
2561 | - uint8_t hash; |
2562 | - uint32_t continuum_points_counter; |
2563 | memcached_server_st *hosts; |
2564 | memcached_server_st *last_disconnected_server; |
2565 | int32_t snd_timeout; |
2566 | @@ -93,15 +93,14 @@ |
2567 | int32_t poll_timeout; |
2568 | int32_t connect_timeout; |
2569 | int32_t retry_timeout; |
2570 | - uint32_t continuum_count; |
2571 | int send_size; |
2572 | int recv_size; |
2573 | void *user_data; |
2574 | time_t next_distribution_rebuild; |
2575 | size_t prefix_key_length; |
2576 | - memcached_hash hash_continuum; |
2577 | + memcached_hash hash_type; |
2578 | + memcached_hash continuum_hash_type; |
2579 | memcached_result_st result; |
2580 | - memcached_continuum_item_st *continuum; |
2581 | memcached_clone_func on_clone; |
2582 | memcached_cleanup_func on_cleanup; |
2583 | memcached_free_function call_free; |
2584 | @@ -110,9 +109,11 @@ |
2585 | memcached_calloc_function call_calloc; |
2586 | memcached_trigger_key get_key_failure; |
2587 | memcached_trigger_delete_key delete_trigger; |
2588 | + hashkit_st hashkit; |
2589 | char prefix_key[MEMCACHED_PREFIX_KEY_MAX_SIZE]; |
2590 | uint32_t number_of_replicas; |
2591 | memcached_callback_st *callbacks; |
2592 | + struct timeval now; |
2593 | }; |
2594 | |
2595 | LIBMEMCACHED_API |
2596 | @@ -214,12 +215,6 @@ |
2597 | LIBMEMCACHED_API |
2598 | uint64_t memcached_behavior_get(memcached_st *ptr, memcached_behavior flag); |
2599 | |
2600 | -/* The two public hash bits */ |
2601 | -LIBMEMCACHED_API |
2602 | -uint32_t memcached_generate_hash_value(const char *key, size_t key_length, memcached_hash hash_algorithm); |
2603 | -LIBMEMCACHED_API |
2604 | -uint32_t memcached_generate_hash(memcached_st *ptr, const char *key, size_t key_length); |
2605 | - |
2606 | LIBMEMCACHED_API |
2607 | memcached_return memcached_flush_buffers(memcached_st *mem); |
2608 | |
2609 | |
2610 | === modified file 'libmemcached/memcached_behavior.c' |
2611 | --- libmemcached/memcached_behavior.c 2009-11-27 19:46:16 +0000 |
2612 | +++ libmemcached/memcached_behavior.c 2009-12-11 17:27:14 +0000 |
2613 | @@ -75,6 +75,7 @@ |
2614 | case MEMCACHED_BEHAVIOR_DISTRIBUTION: |
2615 | { |
2616 | ptr->distribution= (memcached_server_distribution)(data); |
2617 | + hashkit_set_distribution(&ptr->hashkit, memcached_distribution_map[data]); |
2618 | if (ptr->distribution == MEMCACHED_DISTRIBUTION_RANDOM) |
2619 | { |
2620 | srandom((uint32_t) time(NULL)); |
2621 | @@ -86,21 +87,31 @@ |
2622 | { |
2623 | if (data) |
2624 | { |
2625 | - ptr->hash= MEMCACHED_HASH_MD5; |
2626 | + ptr->hash_type= MEMCACHED_HASH_MD5; |
2627 | + hashkit_set_hash_fn(&ptr->hashkit, hashkit_md5); |
2628 | ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA; |
2629 | + hashkit_set_distribution(&ptr->hashkit, HASHKIT_DISTRIBUTION_KETAMA); |
2630 | } |
2631 | else |
2632 | { |
2633 | - ptr->hash= 0; |
2634 | + ptr->hash_type= 0; |
2635 | + hashkit_set_hash_fn(&ptr->hashkit, NULL); |
2636 | ptr->distribution= 0; |
2637 | + hashkit_set_distribution(&ptr->hashkit, HASHKIT_DISTRIBUTION_MODULA); |
2638 | } |
2639 | run_distribution(ptr); |
2640 | break; |
2641 | } |
2642 | case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED: |
2643 | { |
2644 | - ptr->hash= MEMCACHED_HASH_MD5; |
2645 | + ptr->hash_type= MEMCACHED_HASH_MD5; |
2646 | + hashkit_set_hash_fn(&ptr->hashkit, hashkit_md5); |
2647 | ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA; |
2648 | + hashkit_set_distribution(&ptr->hashkit, HASHKIT_DISTRIBUTION_KETAMA); |
2649 | + if (data) |
2650 | + hashkit_set_weight_fn(&ptr->hashkit, memcached_server_weight); |
2651 | + else |
2652 | + hashkit_set_weight_fn(&ptr->hashkit, NULL); |
2653 | set_behavior_flag(ptr, MEM_KETAMA_WEIGHTED, data); |
2654 | run_distribution(ptr); |
2655 | break; |
2656 | @@ -109,12 +120,16 @@ |
2657 | switch (data) |
2658 | { |
2659 | case MEMCACHED_KETAMA_COMPAT_LIBMEMCACHED: |
2660 | - ptr->hash= MEMCACHED_HASH_MD5; |
2661 | + ptr->hash_type= MEMCACHED_HASH_MD5; |
2662 | + hashkit_set_hash_fn(&ptr->hashkit, hashkit_md5); |
2663 | ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA; |
2664 | + hashkit_set_distribution(&ptr->hashkit, HASHKIT_DISTRIBUTION_KETAMA); |
2665 | break; |
2666 | case MEMCACHED_KETAMA_COMPAT_SPY: |
2667 | - ptr->hash= MEMCACHED_HASH_MD5; |
2668 | + ptr->hash_type= MEMCACHED_HASH_MD5; |
2669 | + hashkit_set_hash_fn(&ptr->hashkit, hashkit_md5); |
2670 | ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY; |
2671 | + hashkit_set_distribution(&ptr->hashkit, HASHKIT_DISTRIBUTION_KETAMA); |
2672 | break; |
2673 | default: |
2674 | return MEMCACHED_FAILURE; |
2675 | @@ -122,14 +137,24 @@ |
2676 | run_distribution(ptr); |
2677 | break; |
2678 | case MEMCACHED_BEHAVIOR_HASH: |
2679 | + if ((memcached_hash)data >= MEMCACHED_HASH_MAX) |
2680 | + return MEMCACHED_FAILURE; |
2681 | #ifndef HAVE_HSIEH_HASH |
2682 | - if ((memcached_hash)(data) == MEMCACHED_HASH_HSIEH) |
2683 | + else if ((memcached_hash)data == MEMCACHED_HASH_HSIEH) |
2684 | return MEMCACHED_FAILURE; |
2685 | #endif |
2686 | - ptr->hash= (memcached_hash)(data); |
2687 | + ptr->hash_type= (memcached_hash)data; |
2688 | + hashkit_set_hash_fn(&ptr->hashkit, memcached_hash_fn_map[(memcached_hash)data]); |
2689 | break; |
2690 | case MEMCACHED_BEHAVIOR_KETAMA_HASH: |
2691 | - ptr->hash_continuum= (memcached_hash)(data); |
2692 | + if ((memcached_hash)data >= MEMCACHED_HASH_MAX) |
2693 | + return MEMCACHED_FAILURE; |
2694 | +#ifndef HAVE_HSIEH_HASH |
2695 | + else if ((memcached_hash)data == MEMCACHED_HASH_HSIEH) |
2696 | + return MEMCACHED_FAILURE; |
2697 | +#endif |
2698 | + ptr->continuum_hash_type= (memcached_hash)(data); |
2699 | + hashkit_set_continuum_hash_fn(&ptr->hashkit, memcached_hash_fn_map[(memcached_hash)data]); |
2700 | run_distribution(ptr); |
2701 | break; |
2702 | case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS: |
2703 | @@ -143,6 +168,10 @@ |
2704 | break; |
2705 | case MEMCACHED_BEHAVIOR_SORT_HOSTS: |
2706 | { |
2707 | + if (data) |
2708 | + hashkit_set_sort_fn(&ptr->hashkit, memcached_server_sort); |
2709 | + else |
2710 | + hashkit_set_sort_fn(&ptr->hashkit, NULL); |
2711 | set_behavior_flag(ptr, MEM_USE_SORT_HOSTS, data); |
2712 | run_distribution(ptr); |
2713 | |
2714 | @@ -174,6 +203,10 @@ |
2715 | set_behavior_flag(ptr, MEM_NOREPLY, data); |
2716 | break; |
2717 | case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS: |
2718 | + if (data) |
2719 | + hashkit_set_active_fn(&ptr->hashkit, memcached_server_active); |
2720 | + else |
2721 | + hashkit_set_active_fn(&ptr->hashkit, NULL); |
2722 | set_behavior_flag(ptr, MEM_AUTO_EJECT_HOSTS, data); |
2723 | break; |
2724 | case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ: |
2725 | @@ -247,9 +280,9 @@ |
2726 | } |
2727 | /* NOTREACHED */ |
2728 | case MEMCACHED_BEHAVIOR_HASH: |
2729 | - return ptr->hash; |
2730 | + return ptr->hash_type; |
2731 | case MEMCACHED_BEHAVIOR_KETAMA_HASH: |
2732 | - return ptr->hash_continuum; |
2733 | + return ptr->continuum_hash_type; |
2734 | case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT: |
2735 | return ptr->server_failure_limit; |
2736 | case MEMCACHED_BEHAVIOR_SORT_HOSTS: |
2737 | |
2738 | === modified file 'libmemcached/memcached_constants.h' |
2739 | --- libmemcached/memcached_constants.h 2009-11-27 10:40:32 +0000 |
2740 | +++ libmemcached/memcached_constants.h 2009-12-11 17:27:14 +0000 |
2741 | @@ -14,13 +14,8 @@ |
2742 | #define MEMCACHED_MAX_KEY 251 /* We add one to have it null terminated */ |
2743 | #define MEMCACHED_MAX_BUFFER 8196 |
2744 | #define MEMCACHED_MAX_HOST_LENGTH 64 |
2745 | -#define MEMCACHED_MAX_HOST_SORT_LENGTH 86 /* Used for Ketama */ |
2746 | -#define MEMCACHED_POINTS_PER_SERVER 100 |
2747 | -#define MEMCACHED_POINTS_PER_SERVER_KETAMA 160 |
2748 | -#define MEMCACHED_CONTINUUM_SIZE MEMCACHED_POINTS_PER_SERVER*100 /* This would then set max hosts to 100 */ |
2749 | #define MEMCACHED_STRIDE 4 |
2750 | #define MEMCACHED_DEFAULT_TIMEOUT 1000 |
2751 | -#define MEMCACHED_CONTINUUM_ADDITION 10 /* How many extra slots we should build for in the continuum */ |
2752 | #define MEMCACHED_PREFIX_KEY_MAX_SIZE 128 |
2753 | #define MEMCACHED_EXPIRATION_NOT_ADD 0xffffffffU |
2754 | |
2755 | @@ -72,7 +67,8 @@ |
2756 | MEMCACHED_DISTRIBUTION_CONSISTENT, |
2757 | MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA, |
2758 | MEMCACHED_DISTRIBUTION_RANDOM, |
2759 | - MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY |
2760 | + MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY, |
2761 | + MEMCACHED_DISTRIBUTION_MAX |
2762 | } memcached_server_distribution; |
2763 | |
2764 | typedef enum { |
2765 | @@ -137,7 +133,8 @@ |
2766 | MEMCACHED_HASH_FNV1A_32, |
2767 | MEMCACHED_HASH_HSIEH, |
2768 | MEMCACHED_HASH_MURMUR, |
2769 | - MEMCACHED_HASH_JENKINS |
2770 | + MEMCACHED_HASH_JENKINS, |
2771 | + MEMCACHED_HASH_MAX |
2772 | } memcached_hash; |
2773 | |
2774 | typedef enum { |
2775 | |
2776 | === added file 'libmemcached/memcached_hash.c' |
2777 | --- libmemcached/memcached_hash.c 1970-01-01 00:00:00 +0000 |
2778 | +++ libmemcached/memcached_hash.c 2009-12-11 17:27:14 +0000 |
2779 | @@ -0,0 +1,46 @@ |
2780 | +/* |
2781 | + Memcached library |
2782 | +*/ |
2783 | +#include "common.h" |
2784 | + |
2785 | +uint32_t memcached_generate_hash_value(const char *key, size_t key_length, memcached_hash hash_algorithm) |
2786 | +{ |
2787 | + return hashkit_generate_value(key, key_length, (hashkit_hash_t)hash_algorithm); |
2788 | + |
2789 | +} |
2790 | + |
2791 | +uint32_t memcached_generate_hash(memcached_st *ptr, const char *key, size_t key_length) |
2792 | +{ |
2793 | + uint32_t hash_value= 1; /* Just here to remove compile warning */ |
2794 | + |
2795 | + WATCHPOINT_ASSERT(ptr->number_of_hosts); |
2796 | + |
2797 | + if (ptr->number_of_hosts == 1) |
2798 | + return 0; |
2799 | + |
2800 | + if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS) && |
2801 | + ptr->next_distribution_rebuild) |
2802 | + { |
2803 | + if (gettimeofday(&ptr->now, NULL) == 0 && ptr->now.tv_sec > ptr->next_distribution_rebuild) |
2804 | + run_distribution(ptr); |
2805 | + } |
2806 | + |
2807 | + if (ptr->flags & MEM_HASH_WITH_PREFIX_KEY) |
2808 | + { |
2809 | + size_t temp_length= ptr->prefix_key_length + key_length; |
2810 | + char temp[temp_length]; |
2811 | + |
2812 | + if (temp_length > MEMCACHED_MAX_KEY -1) |
2813 | + return 0; |
2814 | + |
2815 | + strncpy(temp, ptr->prefix_key, ptr->prefix_key_length); |
2816 | + strncpy(temp + ptr->prefix_key_length, key, key_length); |
2817 | + hash_value= hashkit_value(&ptr->hashkit, temp, temp_length); |
2818 | + } |
2819 | + else |
2820 | + hash_value= hashkit_value(&ptr->hashkit, key, key_length); |
2821 | + |
2822 | + WATCHPOINT_ASSERT(hash_value); |
2823 | + |
2824 | + return hashkit_index(&ptr->hashkit, hash_value); |
2825 | +} |
2826 | |
2827 | === added file 'libmemcached/memcached_hash.h' |
2828 | --- libmemcached/memcached_hash.h 1970-01-01 00:00:00 +0000 |
2829 | +++ libmemcached/memcached_hash.h 2009-12-11 17:27:14 +0000 |
2830 | @@ -0,0 +1,9 @@ |
2831 | +/* |
2832 | + Memcached library |
2833 | +*/ |
2834 | + |
2835 | +/* The two public hash bits */ |
2836 | +LIBMEMCACHED_API |
2837 | +uint32_t memcached_generate_hash_value(const char *key, size_t key_length, memcached_hash hash_algorithm); |
2838 | +LIBMEMCACHED_API |
2839 | +uint32_t memcached_generate_hash(memcached_st *ptr, const char *key, size_t key_length); |
2840 | |
2841 | === modified file 'libmemcached/memcached_server.c' |
2842 | --- libmemcached/memcached_server.c 2009-10-10 11:57:03 +0000 |
2843 | +++ libmemcached/memcached_server.c 2009-12-11 17:27:14 +0000 |
2844 | @@ -3,6 +3,12 @@ |
2845 | */ |
2846 | #include "common.h" |
2847 | |
2848 | +/* Protoypes (static) */ |
2849 | +static memcached_return server_add(memcached_st *ptr, const char *hostname, |
2850 | + unsigned int port, |
2851 | + uint32_t weight, |
2852 | + memcached_connection type); |
2853 | + |
2854 | memcached_server_st *memcached_server_create(memcached_st *memc, memcached_server_st *ptr) |
2855 | { |
2856 | if (ptr == NULL) |
2857 | @@ -159,3 +165,295 @@ |
2858 | { |
2859 | return ptr->last_disconnected_server; |
2860 | } |
2861 | + |
2862 | +void server_list_free(memcached_st *ptr, memcached_server_st *servers) |
2863 | +{ |
2864 | + unsigned int x; |
2865 | + |
2866 | + if (servers == NULL) |
2867 | + return; |
2868 | + |
2869 | + for (x= 0; x < servers->count; x++) |
2870 | + if (servers[x].address_info) |
2871 | + { |
2872 | + freeaddrinfo(servers[x].address_info); |
2873 | + servers[x].address_info= NULL; |
2874 | + } |
2875 | + |
2876 | + if (ptr) |
2877 | + ptr->call_free(ptr, servers); |
2878 | + else |
2879 | + free(servers); |
2880 | +} |
2881 | + |
2882 | +memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list) |
2883 | +{ |
2884 | + unsigned int x; |
2885 | + uint16_t count; |
2886 | + memcached_server_st *new_host_list; |
2887 | + |
2888 | + if (!list) |
2889 | + return MEMCACHED_SUCCESS; |
2890 | + |
2891 | + count= list[0].count; |
2892 | + new_host_list= ptr->call_realloc(ptr, ptr->hosts, |
2893 | + sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); |
2894 | + |
2895 | + if (!new_host_list) |
2896 | + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; |
2897 | + |
2898 | + ptr->hosts= new_host_list; |
2899 | + hashkit_set_list(&ptr->hashkit, ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st)); |
2900 | + |
2901 | + for (x= 0; x < count; x++) |
2902 | + { |
2903 | + if ((ptr->flags & MEM_USE_UDP && list[x].type != MEMCACHED_CONNECTION_UDP) |
2904 | + || ((list[x].type == MEMCACHED_CONNECTION_UDP) |
2905 | + && ! (ptr->flags & MEM_USE_UDP)) ) |
2906 | + return MEMCACHED_INVALID_HOST_PROTOCOL; |
2907 | + |
2908 | + WATCHPOINT_ASSERT(list[x].hostname[0] != 0); |
2909 | + memcached_server_create(ptr, &ptr->hosts[ptr->number_of_hosts]); |
2910 | + /* TODO check return type */ |
2911 | + (void)memcached_server_create_with(ptr, &ptr->hosts[ptr->number_of_hosts], list[x].hostname, |
2912 | + list[x].port, list[x].weight, list[x].type); |
2913 | + ptr->number_of_hosts++; |
2914 | + hashkit_set_list(&ptr->hashkit, ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st)); |
2915 | + } |
2916 | + ptr->hosts[0].count= (uint16_t) ptr->number_of_hosts; |
2917 | + |
2918 | + return run_distribution(ptr); |
2919 | +} |
2920 | + |
2921 | +memcached_return memcached_server_add_unix_socket(memcached_st *ptr, |
2922 | + const char *filename) |
2923 | +{ |
2924 | + return memcached_server_add_unix_socket_with_weight(ptr, filename, 0); |
2925 | +} |
2926 | + |
2927 | +memcached_return memcached_server_add_unix_socket_with_weight(memcached_st *ptr, |
2928 | + const char *filename, |
2929 | + uint32_t weight) |
2930 | +{ |
2931 | + if (!filename) |
2932 | + return MEMCACHED_FAILURE; |
2933 | + |
2934 | + return server_add(ptr, filename, 0, weight, MEMCACHED_CONNECTION_UNIX_SOCKET); |
2935 | +} |
2936 | + |
2937 | +memcached_return memcached_server_add_udp(memcached_st *ptr, |
2938 | + const char *hostname, |
2939 | + unsigned int port) |
2940 | +{ |
2941 | + return memcached_server_add_udp_with_weight(ptr, hostname, port, 0); |
2942 | +} |
2943 | + |
2944 | +memcached_return memcached_server_add_udp_with_weight(memcached_st *ptr, |
2945 | + const char *hostname, |
2946 | + unsigned int port, |
2947 | + uint32_t weight) |
2948 | +{ |
2949 | + if (!port) |
2950 | + port= MEMCACHED_DEFAULT_PORT; |
2951 | + |
2952 | + if (!hostname) |
2953 | + hostname= "localhost"; |
2954 | + |
2955 | + return server_add(ptr, hostname, port, weight, MEMCACHED_CONNECTION_UDP); |
2956 | +} |
2957 | + |
2958 | +memcached_return memcached_server_add(memcached_st *ptr, |
2959 | + const char *hostname, |
2960 | + unsigned int port) |
2961 | +{ |
2962 | + return memcached_server_add_with_weight(ptr, hostname, port, 0); |
2963 | +} |
2964 | + |
2965 | +memcached_return memcached_server_add_with_weight(memcached_st *ptr, |
2966 | + const char *hostname, |
2967 | + unsigned int port, |
2968 | + uint32_t weight) |
2969 | +{ |
2970 | + if (!port) |
2971 | + port= MEMCACHED_DEFAULT_PORT; |
2972 | + |
2973 | + if (!hostname) |
2974 | + hostname= "localhost"; |
2975 | + |
2976 | + return server_add(ptr, hostname, port, weight, MEMCACHED_CONNECTION_TCP); |
2977 | +} |
2978 | + |
2979 | +static memcached_return server_add(memcached_st *ptr, const char *hostname, |
2980 | + unsigned int port, |
2981 | + uint32_t weight, |
2982 | + memcached_connection type) |
2983 | +{ |
2984 | + memcached_server_st *new_host_list; |
2985 | + |
2986 | + if ( (ptr->flags & MEM_USE_UDP && type != MEMCACHED_CONNECTION_UDP) |
2987 | + || ( (type == MEMCACHED_CONNECTION_UDP) && !(ptr->flags & MEM_USE_UDP) ) ) |
2988 | + return MEMCACHED_INVALID_HOST_PROTOCOL; |
2989 | + |
2990 | + new_host_list= ptr->call_realloc(ptr, ptr->hosts, |
2991 | + sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); |
2992 | + |
2993 | + if (new_host_list == NULL) |
2994 | + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; |
2995 | + |
2996 | + ptr->hosts= new_host_list; |
2997 | + |
2998 | + /* TODO: Check return type */ |
2999 | + (void)memcached_server_create_with(ptr, &ptr->hosts[ptr->number_of_hosts], hostname, port, weight, type); |
3000 | + ptr->number_of_hosts++; |
3001 | + ptr->hosts[0].count= (uint16_t) ptr->number_of_hosts; |
3002 | + |
3003 | + hashkit_set_list(&ptr->hashkit, ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st)); |
3004 | + |
3005 | + return run_distribution(ptr); |
3006 | +} |
3007 | + |
3008 | +memcached_return memcached_server_remove(memcached_server_st *st_ptr) |
3009 | +{ |
3010 | + uint32_t x, host_index; |
3011 | + memcached_st *ptr= st_ptr->root; |
3012 | + memcached_server_st *list= ptr->hosts; |
3013 | + |
3014 | + for (x= 0, host_index= 0; x < ptr->number_of_hosts; x++) |
3015 | + { |
3016 | + if (strncmp(list[x].hostname, st_ptr->hostname, MEMCACHED_MAX_HOST_LENGTH) != 0 || list[x].port != st_ptr->port) |
3017 | + { |
3018 | + if (host_index != x) |
3019 | + memcpy(list+host_index, list+x, sizeof(memcached_server_st)); |
3020 | + host_index++; |
3021 | + } |
3022 | + } |
3023 | + ptr->number_of_hosts= host_index; |
3024 | + |
3025 | + if (st_ptr->address_info) |
3026 | + { |
3027 | + freeaddrinfo(st_ptr->address_info); |
3028 | + st_ptr->address_info= NULL; |
3029 | + } |
3030 | + run_distribution(ptr); |
3031 | + |
3032 | + return MEMCACHED_SUCCESS; |
3033 | +} |
3034 | + |
3035 | +memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, |
3036 | + const char *hostname, unsigned int port, |
3037 | + memcached_return *error) |
3038 | +{ |
3039 | + return memcached_server_list_append_with_weight(ptr, hostname, port, 0, error); |
3040 | +} |
3041 | + |
3042 | +memcached_server_st *memcached_server_list_append_with_weight(memcached_server_st *ptr, |
3043 | + const char *hostname, unsigned int port, |
3044 | + uint32_t weight, |
3045 | + memcached_return *error) |
3046 | +{ |
3047 | + unsigned int count; |
3048 | + memcached_server_st *new_host_list; |
3049 | + |
3050 | + if (hostname == NULL || error == NULL) |
3051 | + return NULL; |
3052 | + |
3053 | + if (!port) |
3054 | + port= MEMCACHED_DEFAULT_PORT; |
3055 | + |
3056 | + /* Increment count for hosts */ |
3057 | + count= 1; |
3058 | + if (ptr != NULL) |
3059 | + { |
3060 | + count+= ptr[0].count; |
3061 | + } |
3062 | + |
3063 | + new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count); |
3064 | + if (!new_host_list) |
3065 | + { |
3066 | + *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; |
3067 | + return NULL; |
3068 | + } |
3069 | + |
3070 | + /* TODO: Check return type */ |
3071 | + memcached_server_create_with(NULL, &new_host_list[count-1], hostname, port, weight, MEMCACHED_CONNECTION_TCP); |
3072 | + |
3073 | + /* Backwards compatibility hack */ |
3074 | + new_host_list[0].count= (uint16_t) count; |
3075 | + |
3076 | + *error= MEMCACHED_SUCCESS; |
3077 | + return new_host_list; |
3078 | +} |
3079 | + |
3080 | +unsigned int memcached_server_list_count(memcached_server_st *ptr) |
3081 | +{ |
3082 | + if (ptr == NULL) |
3083 | + return 0; |
3084 | + |
3085 | + return ptr[0].count; |
3086 | +} |
3087 | + |
3088 | +void memcached_server_list_free(memcached_server_st *ptr) |
3089 | +{ |
3090 | + server_list_free(NULL, ptr); |
3091 | +} |
3092 | + |
3093 | +bool memcached_server_active(void *context) |
3094 | +{ |
3095 | + memcached_server_st *ptr= (memcached_server_st *)context; |
3096 | + |
3097 | + if (ptr->next_retry <= ptr->root->now.tv_sec) |
3098 | + return true; |
3099 | + else if (ptr->root->next_distribution_rebuild == 0 || |
3100 | + ptr->next_retry < ptr->root->next_distribution_rebuild) |
3101 | + { |
3102 | + ptr->root->next_distribution_rebuild= ptr->next_retry; |
3103 | + } |
3104 | + |
3105 | + return false; |
3106 | +} |
3107 | + |
3108 | +uint32_t memcached_server_weight(void *context) |
3109 | +{ |
3110 | + memcached_server_st *ptr= (memcached_server_st *)context; |
3111 | + |
3112 | + if (ptr->weight == 0) |
3113 | + ptr->weight= 1; |
3114 | + |
3115 | + return ptr->weight; |
3116 | +} |
3117 | + |
3118 | +static int compare_servers(const void *p1, const void *p2) |
3119 | +{ |
3120 | + int return_value; |
3121 | + memcached_server_st *a= (memcached_server_st *)p1; |
3122 | + memcached_server_st *b= (memcached_server_st *)p2; |
3123 | + |
3124 | + return_value= strcmp(a->hostname, b->hostname); |
3125 | + |
3126 | + if (return_value == 0) |
3127 | + { |
3128 | + return_value= (int) (a->port - b->port); |
3129 | + } |
3130 | + |
3131 | + return return_value; |
3132 | +} |
3133 | + |
3134 | +void memcached_server_sort(void *context, size_t count) |
3135 | +{ |
3136 | + memcached_server_st *ptr= (memcached_server_st *)context; |
3137 | + |
3138 | + qsort(context, count, sizeof(memcached_server_st), compare_servers); |
3139 | + ptr[0].count= (uint16_t) count; |
3140 | +} |
3141 | + |
3142 | +size_t memcached_server_key(char *key, size_t key_length, uint32_t point_index, void *context) |
3143 | +{ |
3144 | + memcached_server_st *ptr= (memcached_server_st *)context; |
3145 | + |
3146 | + if (ptr->root->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) |
3147 | + return (size_t)snprintf(key, key_length, "/%s:%d-%d", ptr->hostname, ptr->port, point_index); |
3148 | + else if (ptr->port == MEMCACHED_DEFAULT_PORT) |
3149 | + return (size_t)snprintf(key, key_length, "%s-%d", ptr->hostname, point_index); |
3150 | + |
3151 | + return (size_t)snprintf(key, key_length, "%s:%d-%d", ptr->hostname, ptr->port, point_index); |
3152 | +} |
3153 | |
3154 | === modified file 'libmemcached/memcached_types.h' |
3155 | --- libmemcached/memcached_types.h 2009-10-13 10:05:51 +0000 |
3156 | +++ libmemcached/memcached_types.h 2009-12-11 17:27:14 +0000 |
3157 | @@ -19,7 +19,6 @@ |
3158 | typedef struct memcached_result_st memcached_result_st; |
3159 | typedef struct memcached_string_st memcached_string_st; |
3160 | typedef struct memcached_server_st memcached_server_st; |
3161 | -typedef struct memcached_continuum_item_st memcached_continuum_item_st; |
3162 | typedef memcached_return (*memcached_clone_func)(memcached_st *parent, memcached_st *clone); |
3163 | typedef memcached_return (*memcached_cleanup_func)(memcached_st *ptr); |
3164 | typedef void (*memcached_free_function)(memcached_st *ptr, void *mem); |
3165 | @@ -28,13 +27,13 @@ |
3166 | typedef void *(*memcached_calloc_function)(memcached_st *ptr, size_t nelem, const size_t elsize); |
3167 | typedef memcached_return (*memcached_execute_function)(memcached_st *ptr, memcached_result_st *result, void *context); |
3168 | typedef memcached_return (*memcached_server_function)(memcached_st *ptr, memcached_server_st *server, void *context); |
3169 | -typedef memcached_return (*memcached_trigger_key)(memcached_st *ptr, |
3170 | - const char *key, size_t key_length, |
3171 | +typedef memcached_return (*memcached_trigger_key)(memcached_st *ptr, |
3172 | + const char *key, size_t key_length, |
3173 | memcached_result_st *result); |
3174 | -typedef memcached_return (*memcached_trigger_delete_key)(memcached_st *ptr, |
3175 | +typedef memcached_return (*memcached_trigger_delete_key)(memcached_st *ptr, |
3176 | const char *key, size_t key_length); |
3177 | |
3178 | -typedef memcached_return (*memcached_dump_func)(memcached_st *ptr, |
3179 | +typedef memcached_return (*memcached_dump_func)(memcached_st *ptr, |
3180 | const char *key, size_t key_length, void *context); |
3181 | |
3182 | typedef struct { |
3183 | |
3184 | === added file 'm4/pandora_have_libhashkit.m4' |
3185 | --- m4/pandora_have_libhashkit.m4 1970-01-01 00:00:00 +0000 |
3186 | +++ m4/pandora_have_libhashkit.m4 2009-12-11 17:27:14 +0000 |
3187 | @@ -0,0 +1,51 @@ |
3188 | +dnl Copyright (C) 2009 Sun Microsystems |
3189 | +dnl This file is free software; Sun Microsystems |
3190 | +dnl gives unlimited permission to copy and/or distribute it, |
3191 | +dnl with or without modifications, as long as this notice is preserved. |
3192 | + |
3193 | +AC_DEFUN([_PANDORA_SEARCH_LIBHASHKIT],[ |
3194 | + AC_REQUIRE([AC_LIB_PREFIX]) |
3195 | + |
3196 | + dnl -------------------------------------------------------------------- |
3197 | + dnl Check for libhashkit |
3198 | + dnl -------------------------------------------------------------------- |
3199 | + |
3200 | + AC_ARG_ENABLE([libhashkit], |
3201 | + [AS_HELP_STRING([--disable-libhashkit], |
3202 | + [Build with libhashkit support @<:@default=on@:>@])], |
3203 | + [ac_enable_libhashkit="$enableval"], |
3204 | + [ac_enable_libhashkit="yes"]) |
3205 | + |
3206 | + AS_IF([test "x$ac_enable_libhashkit" = "xyes"],[ |
3207 | + AC_LIB_HAVE_LINKFLAGS(hashkit,,[ |
3208 | + #include <libhashkit/hashkit.h> |
3209 | + ],[ |
3210 | + hashkit_st hashkit; |
3211 | + hashkit_create(&hashkit); |
3212 | + ]) |
3213 | + ],[ |
3214 | + ac_cv_libhashkit="no" |
3215 | + ]) |
3216 | + |
3217 | + AM_CONDITIONAL(HAVE_LIBHASHKIT, [test "x${ac_cv_libhashkit}" = "xyes"]) |
3218 | +]) |
3219 | + |
3220 | +AC_DEFUN([PANDORA_HAVE_LIBHASHKIT],[ |
3221 | + AC_REQUIRE([_PANDORA_SEARCH_LIBHASHKIT]) |
3222 | +]) |
3223 | + |
3224 | +AC_DEFUN([PANDORA_REQUIRE_LIBHASHKIT],[ |
3225 | + AC_REQUIRE([PANDORA_HAVE_LIBHASHKIT]) |
3226 | + AS_IF([test "x${ac_cv_libhashkit}" = "xno"], |
3227 | + AC_MSG_ERROR([libhashkit is required for ${PACKAGE}])) |
3228 | +]) |
3229 | + |
3230 | +AC_DEFUN([PANDORA_BUNDLE_LIBHASHKIT],[ |
3231 | + AC_REQUIRE([PANDORA_HAVE_LIBHASHKIT]) |
3232 | + AS_IF([test "x${ac_cv_libhashkit}" = "xno"], |
3233 | + PANDORA_BUNDLED_SUBDIRS="${PANDORA_BUNDLED_SUBDIRS} libhashkit" |
3234 | + LIBHASHKIT_LINK="\$(top_builddir)/libhashkit/libhashkit.la", |
3235 | + LIBHASHKIT_LINK="${LTLIBHASHKIT}") |
3236 | + AC_SUBST(PANDORA_BUNDLED_SUBDIRS) |
3237 | + AC_SUBST(LIBHASHKIT_LINK) |
3238 | +]) |
3239 | |
3240 | === modified file 'tests/Makefile.am' |
3241 | --- tests/Makefile.am 2009-11-10 03:57:08 +0000 |
3242 | +++ tests/Makefile.am 2009-12-11 17:27:14 +0000 |
3243 | @@ -18,8 +18,11 @@ |
3244 | |
3245 | LIBS = |
3246 | |
3247 | +clean-local: |
3248 | + -rm -r ketama_keys.txt |
3249 | + |
3250 | noinst_HEADERS = test.h server.h ketama_test_cases.h ketama_test_cases_spy.h |
3251 | -noinst_PROGRAMS = testapp testplus udptest atomsmasher startservers |
3252 | +noinst_PROGRAMS = testapp testplus udptest atomsmasher startservers testhashkit |
3253 | noinst_LTLIBRARIES= libserver.la libtest.la |
3254 | |
3255 | libserver_la_SOURCES= server.c |
3256 | @@ -27,7 +30,11 @@ |
3257 | |
3258 | testapp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING) |
3259 | testapp_SOURCES = function.c |
3260 | -testapp_LDADD = $(top_builddir)/clients/libgenexec.la libtest.la libserver.la $(LDADDS) |
3261 | +testapp_LDADD = $(top_builddir)/clients/libgenexec.la libtest.la libserver.la $(LDADDS) $(LIBHASHKIT_LINK) |
3262 | + |
3263 | +testhashkit_CFLAGS=$(AM_CFLAGS) |
3264 | +testhashkit_SOURCES= hashkit_functions.c |
3265 | +testhashkit_LDADD = libtest.la $(LDADDS) $(LIBHASHKIT_LINK) |
3266 | |
3267 | testplus_SOURCES = plus.cpp |
3268 | testplus_LDADD = libtest.la libserver.la $(LDADDS) |
3269 | @@ -41,10 +48,6 @@ |
3270 | startservers_SOURCES = start.c |
3271 | startservers_LDADD = libserver.la $(LDADDS) |
3272 | |
3273 | -record: |
3274 | - ./testapp > output.res |
3275 | - ./testplus > output_plus.res |
3276 | - |
3277 | client-record: |
3278 | sh t/memcat.test > r/memcat.res |
3279 | sh t/memcp.test > r/memcp.res |
3280 | @@ -52,17 +55,15 @@ |
3281 | sh t/memslap.test > r/memslap.res |
3282 | sh t/memstat.test > r/memstat.res |
3283 | |
3284 | -record-extended: |
3285 | - ./testapp extended > output2.res |
3286 | - |
3287 | -test: testapp testplus library_test memcapable |
3288 | +test: testapp testhashkit testplus libmemcached_test libmhashkit_test memcapable |
3289 | echo "Tests completed" |
3290 | |
3291 | -library_test: |
3292 | - ./testapp > output.cmp |
3293 | - diff output.res output.cmp |
3294 | -# ./testplus > output_plus.cmp |
3295 | -# diff output_plus.res output_plus.cmp |
3296 | +libmhashkit_test: |
3297 | + ./testhashkit |
3298 | + |
3299 | +libmemcached_test: |
3300 | + ./testapp |
3301 | +# ./testplus |
3302 | |
3303 | memcapable: |
3304 | @MEMC_BINARY@ -d -P /tmp/Xumemc.pid -p 12555 |
3305 | @@ -86,6 +87,12 @@ |
3306 | cat /tmp/Xumemc.pid | xargs kill |
3307 | rm /tmp/Xumemc.pid |
3308 | |
3309 | +gdb-hash: |
3310 | + $(LIBTOOL) --mode=execute gdb testhashkit |
3311 | + |
3312 | +valgrind-hash: |
3313 | + $(LIBTOOL) --mode=execute valgrind testhashkit |
3314 | + |
3315 | valgrind: |
3316 | libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes testapp |
3317 | |
3318 | |
3319 | === modified file 'tests/atomsmasher.c' |
3320 | --- tests/atomsmasher.c 2009-11-25 08:21:57 +0000 |
3321 | +++ tests/atomsmasher.c 2009-12-11 17:27:14 +0000 |
3322 | @@ -199,10 +199,10 @@ |
3323 | } |
3324 | |
3325 | test_st smash_tests[] ={ |
3326 | - {"generate_pairs", 1, generate_pairs }, |
3327 | - {"drizzle", 1, drizzle }, |
3328 | - {"cleanup", 1, cleanup_pairs }, |
3329 | - {"many_adds", 1, many_adds }, |
3330 | + {"generate_pairs", 1, (test_execution_fn *)generate_pairs }, |
3331 | + {"drizzle", 1, (test_execution_fn *)drizzle }, |
3332 | + {"cleanup", 1, (test_execution_fn *)cleanup_pairs }, |
3333 | + {"many_adds", 1, (test_execution_fn *)many_adds }, |
3334 | {0, 0, 0} |
3335 | }; |
3336 | |
3337 | |
3338 | === modified file 'tests/function.c' |
3339 | --- tests/function.c 2009-12-02 23:07:20 +0000 |
3340 | +++ tests/function.c 2009-12-11 17:27:14 +0000 |
3341 | @@ -1,3 +1,11 @@ |
3342 | +/* libMemcached Functions Test |
3343 | + * Copyright (C) 2006-2009 Brian Aker |
3344 | + * All rights reserved. |
3345 | + * |
3346 | + * Use and distribution licensed under the BSD license. See |
3347 | + * the COPYING file in the parent directory for full text. |
3348 | + */ |
3349 | + |
3350 | /* |
3351 | Sample test application. |
3352 | */ |
3353 | @@ -33,6 +41,8 @@ |
3354 | #include "libmemcached/memcached_util.h" |
3355 | #endif |
3356 | |
3357 | +#include "hash_results.h" |
3358 | + |
3359 | #define GLOBAL_COUNT 10000 |
3360 | #define GLOBAL2_COUNT 100 |
3361 | #define SERVERS_TO_CREATE 5 |
3362 | @@ -223,8 +233,8 @@ |
3363 | test_truth(memc_clone->distribution == memc->distribution); |
3364 | test_truth(memc_clone->flags == memc->flags); |
3365 | test_truth(memc_clone->get_key_failure == memc->get_key_failure); |
3366 | - test_truth(memc_clone->hash == memc->hash); |
3367 | - test_truth(memc_clone->hash_continuum == memc->hash_continuum); |
3368 | + test_truth(memc_clone->hash_type == memc->hash_type); |
3369 | + test_truth(memc_clone->continuum_hash_type == memc->continuum_hash_type); |
3370 | test_truth(memc_clone->io_bytes_watermark == memc->io_bytes_watermark); |
3371 | test_truth(memc_clone->io_msg_watermark == memc->io_msg_watermark); |
3372 | test_truth(memc_clone->io_key_prefetch == memc->io_key_prefetch); |
3373 | @@ -1625,18 +1635,18 @@ |
3374 | |
3375 | static test_return_t get_stats_keys(memcached_st *memc) |
3376 | { |
3377 | - char **list; |
3378 | + char **stat_list; |
3379 | char **ptr; |
3380 | memcached_stat_st memc_stat; |
3381 | memcached_return rc; |
3382 | |
3383 | - list= memcached_stat_get_keys(memc, &memc_stat, &rc); |
3384 | + stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc); |
3385 | test_truth(rc == MEMCACHED_SUCCESS); |
3386 | - for (ptr= list; *ptr; ptr++) |
3387 | + for (ptr= stat_list; *ptr; ptr++) |
3388 | test_truth(*ptr); |
3389 | fflush(stdout); |
3390 | |
3391 | - free(list); |
3392 | + free(stat_list); |
3393 | |
3394 | return TEST_SUCCESS; |
3395 | } |
3396 | @@ -1655,7 +1665,7 @@ |
3397 | static test_return_t get_stats(memcached_st *memc) |
3398 | { |
3399 | unsigned int x; |
3400 | - char **list; |
3401 | + char **stat_list; |
3402 | char **ptr; |
3403 | memcached_return rc; |
3404 | memcached_stat_st *memc_stat; |
3405 | @@ -1668,11 +1678,11 @@ |
3406 | |
3407 | for (x= 0; x < memcached_server_count(memc); x++) |
3408 | { |
3409 | - list= memcached_stat_get_keys(memc, memc_stat+x, &rc); |
3410 | + stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc); |
3411 | test_truth(rc == MEMCACHED_SUCCESS); |
3412 | - for (ptr= list; *ptr; ptr++); |
3413 | + for (ptr= stat_list; *ptr; ptr++); |
3414 | |
3415 | - free(list); |
3416 | + free(stat_list); |
3417 | } |
3418 | |
3419 | memcached_stat_free(NULL, memc_stat); |
3420 | @@ -2699,7 +2709,7 @@ |
3421 | /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets |
3422 | * us test the boundary wraparound. |
3423 | */ |
3424 | - test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index); |
3425 | + test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->hashkit.continuum[0].index); |
3426 | |
3427 | /* verify the standard ketama set. */ |
3428 | for (x= 0; x < 99; x++) |
3429 | @@ -3368,7 +3378,7 @@ |
3430 | |
3431 | static memcached_return pre_hash_fnv1_64(memcached_st *memc) |
3432 | { |
3433 | - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64); |
3434 | + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)HASHKIT_HASH_MURMUR); |
3435 | |
3436 | return MEMCACHED_SUCCESS; |
3437 | } |
3438 | @@ -3759,19 +3769,19 @@ |
3439 | switch (count) |
3440 | { |
3441 | case 0: |
3442 | - ret=memcached_add(memc, key, len, key, len, 0, 0); |
3443 | + ret= memcached_add(memc, key, len, key, len, 0, 0); |
3444 | break; |
3445 | case 1: |
3446 | - ret=memcached_replace(memc, key, len, key, len, 0, 0); |
3447 | + ret= memcached_replace(memc, key, len, key, len, 0, 0); |
3448 | break; |
3449 | case 2: |
3450 | - ret=memcached_set(memc, key, len, key, len, 0, 0); |
3451 | + ret= memcached_set(memc, key, len, key, len, 0, 0); |
3452 | break; |
3453 | case 3: |
3454 | - ret=memcached_append(memc, key, len, key, len, 0, 0); |
3455 | + ret= memcached_append(memc, key, len, key, len, 0, 0); |
3456 | break; |
3457 | case 4: |
3458 | - ret=memcached_prepend(memc, key, len, key, len, 0, 0); |
3459 | + ret= memcached_prepend(memc, key, len, key, len, 0, 0); |
3460 | break; |
3461 | default: |
3462 | test_truth(count); |
3463 | @@ -3923,7 +3933,7 @@ |
3464 | } |
3465 | |
3466 | #ifdef HAVE_LIBMEMCACHEDUTIL |
3467 | -static void* connection_release(void *arg) |
3468 | +static void* connection_release(void *arg) |
3469 | { |
3470 | struct { |
3471 | memcached_pool_st* pool; |
3472 | @@ -4170,7 +4180,7 @@ |
3473 | rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0); |
3474 | test_truth(rc == MEMCACHED_SUCCESS); |
3475 | } |
3476 | - |
3477 | + |
3478 | memcached_quit(memc); |
3479 | |
3480 | for (int x=0; x< 7; ++x) { |
3481 | @@ -4567,25 +4577,55 @@ |
3482 | { |
3483 | test_st current_op; |
3484 | test_st mixed_io_ops [] ={ |
3485 | - {"udp_set_test", 0, udp_set_test}, |
3486 | - {"udp_set_too_big_test", 0, udp_set_too_big_test}, |
3487 | - {"udp_delete_test", 0, udp_delete_test}, |
3488 | - {"udp_verbosity_test", 0, udp_verbosity_test}, |
3489 | - {"udp_quit_test", 0, udp_quit_test}, |
3490 | - {"udp_flush_test", 0, udp_flush_test}, |
3491 | - {"udp_incr_test", 0, udp_incr_test}, |
3492 | - {"udp_decr_test", 0, udp_decr_test}, |
3493 | - {"udp_version_test", 0, udp_version_test} |
3494 | + {"udp_set_test", 0, |
3495 | + (test_execution_fn *)udp_set_test}, |
3496 | + {"udp_set_too_big_test", 0, |
3497 | + (test_execution_fn *)udp_set_too_big_test}, |
3498 | + {"udp_delete_test", 0, |
3499 | + (test_execution_fn *)udp_delete_test}, |
3500 | + {"udp_verbosity_test", 0, |
3501 | + (test_execution_fn *)udp_verbosity_test}, |
3502 | + {"udp_quit_test", 0, |
3503 | + (test_execution_fn *)udp_quit_test}, |
3504 | + {"udp_flush_test", 0, |
3505 | + (test_execution_fn *)udp_flush_test}, |
3506 | + {"udp_incr_test", 0, |
3507 | + (test_execution_fn *)udp_incr_test}, |
3508 | + {"udp_decr_test", 0, |
3509 | + (test_execution_fn *)udp_decr_test}, |
3510 | + {"udp_version_test", 0, |
3511 | + (test_execution_fn *)udp_version_test} |
3512 | }; |
3513 | unsigned int x= 0; |
3514 | for (x= 0; x < 500; x++) |
3515 | { |
3516 | current_op= mixed_io_ops[random() % 9]; |
3517 | - test_truth(current_op.function(memc) == TEST_SUCCESS); |
3518 | + test_truth(current_op.test_fn(memc) == TEST_SUCCESS); |
3519 | } |
3520 | return TEST_SUCCESS; |
3521 | } |
3522 | |
3523 | +static test_return_t hash_sanity_test (memcached_st *memc) |
3524 | +{ |
3525 | + (void)memc; |
3526 | + |
3527 | + assert(HASHKIT_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT); |
3528 | + assert(HASHKIT_HASH_MD5 == MEMCACHED_HASH_MD5); |
3529 | + assert(HASHKIT_HASH_CRC == MEMCACHED_HASH_CRC); |
3530 | + assert(HASHKIT_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64); |
3531 | + assert(HASHKIT_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64); |
3532 | + assert(HASHKIT_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32); |
3533 | + assert(HASHKIT_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32); |
3534 | +#ifdef HAVE_HSIEH_HASH |
3535 | + assert(HASHKIT_HASH_HSIEH == MEMCACHED_HASH_HSIEH); |
3536 | +#endif |
3537 | + assert(HASHKIT_HASH_MURMUR == MEMCACHED_HASH_MURMUR); |
3538 | + assert(HASHKIT_HASH_JENKINS == MEMCACHED_HASH_JENKINS); |
3539 | + assert(HASHKIT_HASH_MAX == MEMCACHED_HASH_MAX); |
3540 | + |
3541 | + return TEST_SUCCESS; |
3542 | +} |
3543 | + |
3544 | static test_return_t hsieh_avaibility_test (memcached_st *memc) |
3545 | { |
3546 | memcached_return expected_rc= MEMCACHED_FAILURE; |
3547 | @@ -4598,55 +4638,17 @@ |
3548 | return TEST_SUCCESS; |
3549 | } |
3550 | |
3551 | -static const char *list[]= |
3552 | -{ |
3553 | - "apple", |
3554 | - "beat", |
3555 | - "carrot", |
3556 | - "daikon", |
3557 | - "eggplant", |
3558 | - "flower", |
3559 | - "green", |
3560 | - "hide", |
3561 | - "ick", |
3562 | - "jack", |
3563 | - "kick", |
3564 | - "lime", |
3565 | - "mushrooms", |
3566 | - "nectarine", |
3567 | - "orange", |
3568 | - "peach", |
3569 | - "quant", |
3570 | - "ripen", |
3571 | - "strawberry", |
3572 | - "tang", |
3573 | - "up", |
3574 | - "volumne", |
3575 | - "when", |
3576 | - "yellow", |
3577 | - "zip", |
3578 | - NULL |
3579 | -}; |
3580 | - |
3581 | static test_return_t md5_run (memcached_st *memc __attribute__((unused))) |
3582 | { |
3583 | uint32_t x; |
3584 | const char **ptr; |
3585 | - uint32_t values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U, |
3586 | - 245758794U, 2550894432U, 121710495U, 3053817768U, |
3587 | - 1250994555U, 1862072655U, 2631955953U, 2951528551U, |
3588 | - 1451250070U, 2820856945U, 2060845566U, 3646985608U, |
3589 | - 2138080750U, 217675895U, 2230934345U, 1234361223U, |
3590 | - 3968582726U, 2455685270U, 1293568479U, 199067604U, |
3591 | - 2042482093U }; |
3592 | - |
3593 | - |
3594 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3595 | + |
3596 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3597 | { |
3598 | uint32_t hash_val; |
3599 | |
3600 | hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5); |
3601 | - test_truth(values[x] == hash_val); |
3602 | + test_truth(md5_values[x] == hash_val); |
3603 | } |
3604 | |
3605 | return TEST_SUCCESS; |
3606 | @@ -4656,17 +4658,13 @@ |
3607 | { |
3608 | uint32_t x; |
3609 | const char **ptr; |
3610 | - uint32_t values[]= { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U, |
3611 | - 9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U, |
3612 | - 7621U, 30628U, 15218U, 25967U, 2695U, 9380U, |
3613 | - 17300U, 28156U, 9192U, 20484U, 16925U }; |
3614 | |
3615 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3616 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3617 | { |
3618 | uint32_t hash_val; |
3619 | |
3620 | hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC); |
3621 | - assert(values[x] == hash_val); |
3622 | + assert(crc_values[x] == hash_val); |
3623 | } |
3624 | |
3625 | return TEST_SUCCESS; |
3626 | @@ -4676,20 +4674,13 @@ |
3627 | { |
3628 | uint32_t x; |
3629 | const char **ptr; |
3630 | - uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U, |
3631 | - 1722477987U, 2991193800U, 4147007314U, 3633179701U, |
3632 | - 1805162104U, 3503289120U, 3395702895U, 3325073042U, |
3633 | - 2345265314U, 3340346032U, 2722964135U, 1173398992U, |
3634 | - 2815549194U, 2562818319U, 224996066U, 2680194749U, |
3635 | - 3035305390U, 246890365U, 2395624193U, 4145193337U, |
3636 | - 1801941682U }; |
3637 | |
3638 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3639 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3640 | { |
3641 | uint32_t hash_val; |
3642 | |
3643 | hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64); |
3644 | - assert(values[x] == hash_val); |
3645 | + assert(fnv1_64_values[x] == hash_val); |
3646 | } |
3647 | |
3648 | return TEST_SUCCESS; |
3649 | @@ -4699,20 +4690,13 @@ |
3650 | { |
3651 | uint32_t x; |
3652 | const char **ptr; |
3653 | - uint32_t values[]= { 1488911807U, 2500855813U, 1510099634U, 1390325195U, |
3654 | - 3647689787U, 3241528582U, 1669328060U, 2604311949U, |
3655 | - 734810122U, 1516407546U, 560948863U, 1767346780U, |
3656 | - 561034892U, 4156330026U, 3716417003U, 3475297030U, |
3657 | - 1518272172U, 227211583U, 3938128828U, 126112909U, |
3658 | - 3043416448U, 3131561933U, 1328739897U, 2455664041U, |
3659 | - 2272238452U }; |
3660 | |
3661 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3662 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3663 | { |
3664 | uint32_t hash_val; |
3665 | |
3666 | hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64); |
3667 | - assert(values[x] == hash_val); |
3668 | + assert(fnv1a_64_values[x] == hash_val); |
3669 | } |
3670 | |
3671 | return TEST_SUCCESS; |
3672 | @@ -4722,21 +4706,14 @@ |
3673 | { |
3674 | uint32_t x; |
3675 | const char **ptr; |
3676 | - uint32_t values[]= { 67176023U, 1190179409U, 2043204404U, 3221866419U, |
3677 | - 2567703427U, 3787535528U, 4147287986U, 3500475733U, |
3678 | - 344481048U, 3865235296U, 2181839183U, 119581266U, |
3679 | - 510234242U, 4248244304U, 1362796839U, 103389328U, |
3680 | - 1449620010U, 182962511U, 3554262370U, 3206747549U, |
3681 | - 1551306158U, 4127558461U, 1889140833U, 2774173721U, |
3682 | - 1180552018U }; |
3683 | - |
3684 | - |
3685 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3686 | + |
3687 | + |
3688 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3689 | { |
3690 | uint32_t hash_val; |
3691 | |
3692 | hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32); |
3693 | - assert(values[x] == hash_val); |
3694 | + assert(fnv1_32_values[x] == hash_val); |
3695 | } |
3696 | |
3697 | return TEST_SUCCESS; |
3698 | @@ -4746,20 +4723,13 @@ |
3699 | { |
3700 | uint32_t x; |
3701 | const char **ptr; |
3702 | - uint32_t values[]= { 280767167U, 2421315013U, 3072375666U, 855001899U, |
3703 | - 459261019U, 3521085446U, 18738364U, 1625305005U, |
3704 | - 2162232970U, 777243802U, 3323728671U, 132336572U, |
3705 | - 3654473228U, 260679466U, 1169454059U, 2698319462U, |
3706 | - 1062177260U, 235516991U, 2218399068U, 405302637U, |
3707 | - 1128467232U, 3579622413U, 2138539289U, 96429129U, |
3708 | - 2877453236U }; |
3709 | |
3710 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3711 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3712 | { |
3713 | uint32_t hash_val; |
3714 | |
3715 | hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32); |
3716 | - assert(values[x] == hash_val); |
3717 | + assert(fnv1a_32_values[x] == hash_val); |
3718 | } |
3719 | |
3720 | return TEST_SUCCESS; |
3721 | @@ -4769,22 +4739,13 @@ |
3722 | { |
3723 | uint32_t x; |
3724 | const char **ptr; |
3725 | -#ifdef HAVE_HSIEH_HASH |
3726 | - uint32_t values[]= { 3738850110, 3636226060, 3821074029, 3489929160, 3485772682, 80540287, |
3727 | - 1805464076, 1895033657, 409795758, 979934958, 3634096985, 1284445480, |
3728 | - 2265380744, 707972988, 353823508, 1549198350, 1327930172, 9304163, |
3729 | - 4220749037, 2493964934, 2777873870, 2057831732, 1510213931, 2027828987, |
3730 | - 3395453351 }; |
3731 | -#else |
3732 | - uint32_t values[]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; |
3733 | -#endif |
3734 | |
3735 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3736 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3737 | { |
3738 | uint32_t hash_val; |
3739 | |
3740 | hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH); |
3741 | - assert(values[x] == hash_val); |
3742 | + assert(hsieh_values[x] == hash_val); |
3743 | } |
3744 | |
3745 | return TEST_SUCCESS; |
3746 | @@ -4794,20 +4755,13 @@ |
3747 | { |
3748 | uint32_t x; |
3749 | const char **ptr; |
3750 | - uint32_t values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U, |
3751 | - 1722477987U, 2991193800U, 4147007314U, 3633179701U, |
3752 | - 1805162104U, 3503289120U, 3395702895U, 3325073042U, |
3753 | - 2345265314U, 3340346032U, 2722964135U, 1173398992U, |
3754 | - 2815549194U, 2562818319U, 224996066U, 2680194749U, |
3755 | - 3035305390U, 246890365U, 2395624193U, 4145193337U, |
3756 | - 1801941682U }; |
3757 | |
3758 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3759 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3760 | { |
3761 | uint32_t hash_val; |
3762 | |
3763 | - hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64); |
3764 | - assert(values[x] == hash_val); |
3765 | + hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR); |
3766 | + assert(murmur_values[x] == hash_val); |
3767 | } |
3768 | |
3769 | return TEST_SUCCESS; |
3770 | @@ -4817,21 +4771,14 @@ |
3771 | { |
3772 | uint32_t x; |
3773 | const char **ptr; |
3774 | - uint32_t values[]= { 1442444624U, 4253821186U, 1885058256U, 2120131735U, |
3775 | - 3261968576U, 3515188778U, 4232909173U, 4288625128U, |
3776 | - 1812047395U, 3689182164U, 2502979932U, 1214050606U, |
3777 | - 2415988847U, 1494268927U, 1025545760U, 3920481083U, |
3778 | - 4153263658U, 3824871822U, 3072759809U, 798622255U, |
3779 | - 3065432577U, 1453328165U, 2691550971U, 3408888387U, |
3780 | - 2629893356U }; |
3781 | - |
3782 | - |
3783 | - for (ptr= list, x= 0; *ptr; ptr++, x++) |
3784 | + |
3785 | + |
3786 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
3787 | { |
3788 | uint32_t hash_val; |
3789 | |
3790 | hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS); |
3791 | - assert(values[x] == hash_val); |
3792 | + assert(jenkins_values[x] == hash_val); |
3793 | } |
3794 | |
3795 | return TEST_SUCCESS; |
3796 | @@ -4881,7 +4828,7 @@ |
3797 | /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets |
3798 | * us test the boundary wraparound. |
3799 | */ |
3800 | - assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index); |
3801 | + assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->hashkit.continuum[0].index); |
3802 | |
3803 | /* verify the standard ketama set. */ |
3804 | for (x= 0; x < 99; x++) |
3805 | @@ -4940,7 +4887,7 @@ |
3806 | /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets |
3807 | * us test the boundary wraparound. |
3808 | */ |
3809 | - assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index); |
3810 | + assert(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->hashkit.continuum[0].index); |
3811 | |
3812 | /* verify the standard ketama set. */ |
3813 | for (x= 0; x < 99; x++) |
3814 | @@ -5393,140 +5340,157 @@ |
3815 | } |
3816 | |
3817 | test_st udp_setup_server_tests[] ={ |
3818 | - {"set_udp_behavior_test", 0, set_udp_behavior_test}, |
3819 | - {"add_tcp_server_udp_client_test", 0, add_tcp_server_udp_client_test}, |
3820 | - {"add_udp_server_tcp_client_test", 0, add_udp_server_tcp_client_test}, |
3821 | + {"set_udp_behavior_test", 0, |
3822 | + (test_execution_fn *)set_udp_behavior_test}, |
3823 | + {"add_tcp_server_udp_client_test", 0, |
3824 | + (test_execution_fn *)add_tcp_server_udp_client_test}, |
3825 | + {"add_udp_server_tcp_client_test", 0, |
3826 | + (test_execution_fn *)add_udp_server_tcp_client_test}, |
3827 | {0, 0, 0} |
3828 | }; |
3829 | |
3830 | test_st upd_io_tests[] ={ |
3831 | - {"udp_set_test", 0, udp_set_test}, |
3832 | - {"udp_buffered_set_test", 0, udp_buffered_set_test}, |
3833 | - {"udp_set_too_big_test", 0, udp_set_too_big_test}, |
3834 | - {"udp_delete_test", 0, udp_delete_test}, |
3835 | - {"udp_buffered_delete_test", 0, udp_buffered_delete_test}, |
3836 | - {"udp_verbosity_test", 0, udp_verbosity_test}, |
3837 | - {"udp_quit_test", 0, udp_quit_test}, |
3838 | - {"udp_flush_test", 0, udp_flush_test}, |
3839 | - {"udp_incr_test", 0, udp_incr_test}, |
3840 | - {"udp_decr_test", 0, udp_decr_test}, |
3841 | - {"udp_stat_test", 0, udp_stat_test}, |
3842 | - {"udp_version_test", 0, udp_version_test}, |
3843 | - {"udp_get_test", 0, udp_get_test}, |
3844 | - {"udp_mixed_io_test", 0, udp_mixed_io_test}, |
3845 | + {"udp_set_test", 0, |
3846 | + (test_execution_fn *)udp_set_test}, |
3847 | + {"udp_buffered_set_test", 0, |
3848 | + (test_execution_fn *)udp_buffered_set_test}, |
3849 | + {"udp_set_too_big_test", 0, |
3850 | + (test_execution_fn *)udp_set_too_big_test}, |
3851 | + {"udp_delete_test", 0, |
3852 | + (test_execution_fn *)udp_delete_test}, |
3853 | + {"udp_buffered_delete_test", 0, |
3854 | + (test_execution_fn *)udp_buffered_delete_test}, |
3855 | + {"udp_verbosity_test", 0, |
3856 | + (test_execution_fn *)udp_verbosity_test}, |
3857 | + {"udp_quit_test", 0, |
3858 | + (test_execution_fn *)udp_quit_test}, |
3859 | + {"udp_flush_test", 0, |
3860 | + (test_execution_fn *)udp_flush_test}, |
3861 | + {"udp_incr_test", 0, |
3862 | + (test_execution_fn *)udp_incr_test}, |
3863 | + {"udp_decr_test", 0, |
3864 | + (test_execution_fn *)udp_decr_test}, |
3865 | + {"udp_stat_test", 0, |
3866 | + (test_execution_fn *)udp_stat_test}, |
3867 | + {"udp_version_test", 0, |
3868 | + (test_execution_fn *)udp_version_test}, |
3869 | + {"udp_get_test", 0, |
3870 | + (test_execution_fn *)udp_get_test}, |
3871 | + {"udp_mixed_io_test", 0, |
3872 | + (test_execution_fn *)udp_mixed_io_test}, |
3873 | {0, 0, 0} |
3874 | }; |
3875 | |
3876 | /* Clean the server before beginning testing */ |
3877 | test_st tests[] ={ |
3878 | - {"flush", 0, flush_test }, |
3879 | - {"init", 0, init_test }, |
3880 | - {"allocation", 0, allocation_test }, |
3881 | - {"server_list_null_test", 0, server_list_null_test}, |
3882 | - {"server_unsort", 0, server_unsort_test}, |
3883 | - {"server_sort", 0, server_sort_test}, |
3884 | - {"server_sort2", 0, server_sort2_test}, |
3885 | - {"clone_test", 0, clone_test }, |
3886 | - {"connection_test", 0, connection_test}, |
3887 | - {"callback_test", 0, callback_test}, |
3888 | - {"behavior_test", 0, behavior_test}, |
3889 | - {"userdata_test", 0, userdata_test}, |
3890 | - {"error", 0, error_test }, |
3891 | - {"set", 0, set_test }, |
3892 | - {"set2", 0, set_test2 }, |
3893 | - {"set3", 0, set_test3 }, |
3894 | - {"dump", 1, dump_test}, |
3895 | - {"add", 1, add_test }, |
3896 | - {"replace", 1, replace_test }, |
3897 | - {"delete", 1, delete_test }, |
3898 | - {"get", 1, get_test }, |
3899 | - {"get2", 0, get_test2 }, |
3900 | - {"get3", 0, get_test3 }, |
3901 | - {"get4", 0, get_test4 }, |
3902 | - {"partial mget", 0, get_test5 }, |
3903 | - {"stats_servername", 0, stats_servername_test }, |
3904 | - {"increment", 0, increment_test }, |
3905 | - {"increment_with_initial", 1, increment_with_initial_test }, |
3906 | - {"decrement", 0, decrement_test }, |
3907 | - {"decrement_with_initial", 1, decrement_with_initial_test }, |
3908 | - {"increment_by_key", 0, increment_by_key_test }, |
3909 | - {"increment_with_initial_by_key", 1, increment_with_initial_by_key_test }, |
3910 | - {"decrement_by_key", 0, decrement_by_key_test }, |
3911 | - {"decrement_with_initial_by_key", 1, decrement_with_initial_by_key_test }, |
3912 | - {"quit", 0, quit_test }, |
3913 | - {"mget", 1, mget_test }, |
3914 | - {"mget_result", 1, mget_result_test }, |
3915 | - {"mget_result_alloc", 1, mget_result_alloc_test }, |
3916 | - {"mget_result_function", 1, mget_result_function }, |
3917 | - {"mget_execute", 1, mget_execute }, |
3918 | - {"mget_end", 0, mget_end }, |
3919 | - {"get_stats", 0, get_stats }, |
3920 | - {"add_host_test", 0, add_host_test }, |
3921 | - {"add_host_test_1", 0, add_host_test1 }, |
3922 | - {"get_stats_keys", 0, get_stats_keys }, |
3923 | - {"behavior_test", 0, get_stats_keys }, |
3924 | - {"callback_test", 0, get_stats_keys }, |
3925 | - {"version_string_test", 0, version_string_test}, |
3926 | - {"bad_key", 1, bad_key_test }, |
3927 | - {"memcached_server_cursor", 1, memcached_server_cursor_test }, |
3928 | - {"read_through", 1, read_through }, |
3929 | - {"delete_through", 1, delete_through }, |
3930 | - {"noreply", 1, noreply_test}, |
3931 | - {"analyzer", 1, analyzer_test}, |
3932 | + {"flush", 0, (test_execution_fn *)flush_test }, |
3933 | + {"init", 0, (test_execution_fn *)init_test }, |
3934 | + {"allocation", 0, (test_execution_fn *)allocation_test }, |
3935 | + {"server_list_null_test", 0, (test_execution_fn *)server_list_null_test}, |
3936 | + {"server_unsort", 0, (test_execution_fn *)server_unsort_test}, |
3937 | + {"server_sort", 0, (test_execution_fn *)server_sort_test}, |
3938 | + {"server_sort2", 0, (test_execution_fn *)server_sort2_test}, |
3939 | + {"clone_test", 0, (test_execution_fn *)clone_test }, |
3940 | + {"connection_test", 0, (test_execution_fn *)connection_test}, |
3941 | + {"callback_test", 0, (test_execution_fn *)callback_test}, |
3942 | + {"behavior_test", 0, (test_execution_fn *)behavior_test}, |
3943 | + {"userdata_test", 0, (test_execution_fn *)userdata_test}, |
3944 | + {"error", 0, (test_execution_fn *)error_test }, |
3945 | + {"set", 0, (test_execution_fn *)set_test }, |
3946 | + {"set2", 0, (test_execution_fn *)set_test2 }, |
3947 | + {"set3", 0, (test_execution_fn *)set_test3 }, |
3948 | + {"dump", 1, (test_execution_fn *)dump_test}, |
3949 | + {"add", 1, (test_execution_fn *)add_test }, |
3950 | + {"replace", 1, (test_execution_fn *)replace_test }, |
3951 | + {"delete", 1, (test_execution_fn *)delete_test }, |
3952 | + {"get", 1, (test_execution_fn *)get_test }, |
3953 | + {"get2", 0, (test_execution_fn *)get_test2 }, |
3954 | + {"get3", 0, (test_execution_fn *)get_test3 }, |
3955 | + {"get4", 0, (test_execution_fn *)get_test4 }, |
3956 | + {"partial mget", 0, (test_execution_fn *)get_test5 }, |
3957 | + {"stats_servername", 0, (test_execution_fn *)stats_servername_test }, |
3958 | + {"increment", 0, (test_execution_fn *)increment_test }, |
3959 | + {"increment_with_initial", 1, (test_execution_fn *)increment_with_initial_test }, |
3960 | + {"decrement", 0, (test_execution_fn *)decrement_test }, |
3961 | + {"decrement_with_initial", 1, (test_execution_fn *)decrement_with_initial_test }, |
3962 | + {"increment_by_key", 0, (test_execution_fn *)increment_by_key_test }, |
3963 | + {"increment_with_initial_by_key", 1, (test_execution_fn *)increment_with_initial_by_key_test }, |
3964 | + {"decrement_by_key", 0, (test_execution_fn *)decrement_by_key_test }, |
3965 | + {"decrement_with_initial_by_key", 1, (test_execution_fn *)decrement_with_initial_by_key_test }, |
3966 | + {"quit", 0, (test_execution_fn *)quit_test }, |
3967 | + {"mget", 1, (test_execution_fn *)mget_test }, |
3968 | + {"mget_result", 1, (test_execution_fn *)mget_result_test }, |
3969 | + {"mget_result_alloc", 1, (test_execution_fn *)mget_result_alloc_test }, |
3970 | + {"mget_result_function", 1, (test_execution_fn *)mget_result_function }, |
3971 | + {"mget_execute", 1, (test_execution_fn *)mget_execute }, |
3972 | + {"mget_end", 0, (test_execution_fn *)mget_end }, |
3973 | + {"get_stats", 0, (test_execution_fn *)get_stats }, |
3974 | + {"add_host_test", 0, (test_execution_fn *)add_host_test }, |
3975 | + {"add_host_test_1", 0, (test_execution_fn *)add_host_test1 }, |
3976 | + {"get_stats_keys", 0, (test_execution_fn *)get_stats_keys }, |
3977 | + {"behavior_test", 0, (test_execution_fn *)get_stats_keys }, |
3978 | + {"callback_test", 0, (test_execution_fn *)get_stats_keys }, |
3979 | + {"version_string_test", 0, (test_execution_fn *)version_string_test}, |
3980 | + {"bad_key", 1, (test_execution_fn *)bad_key_test }, |
3981 | + {"memcached_server_cursor", 1, (test_execution_fn *)memcached_server_cursor_test }, |
3982 | + {"read_through", 1, (test_execution_fn *)read_through }, |
3983 | + {"delete_through", 1, (test_execution_fn *)delete_through }, |
3984 | + {"noreply", 1, (test_execution_fn *)noreply_test}, |
3985 | + {"analyzer", 1, (test_execution_fn *)analyzer_test}, |
3986 | #ifdef HAVE_LIBMEMCACHEDUTIL |
3987 | - {"connectionpool", 1, connection_pool_test }, |
3988 | + {"connectionpool", 1, (test_execution_fn *)connection_pool_test }, |
3989 | #endif |
3990 | - {"test_get_last_disconnect", 1, test_get_last_disconnect}, |
3991 | + {"test_get_last_disconnect", 1, (test_execution_fn *)test_get_last_disconnect}, |
3992 | {0, 0, 0} |
3993 | }; |
3994 | |
3995 | test_st async_tests[] ={ |
3996 | - {"add", 1, add_wrapper }, |
3997 | + {"add", 1, (test_execution_fn *)add_wrapper }, |
3998 | {0, 0, 0} |
3999 | }; |
4000 | |
4001 | test_st string_tests[] ={ |
4002 | - {"string static with null", 0, string_static_null }, |
4003 | - {"string alloc with null", 0, string_alloc_null }, |
4004 | - {"string alloc with 1K", 0, string_alloc_with_size }, |
4005 | - {"string alloc with malloc failure", 0, string_alloc_with_size_toobig }, |
4006 | - {"string append", 0, string_alloc_append }, |
4007 | - {"string append failure (too big)", 0, string_alloc_append_toobig }, |
4008 | - {0, 0, 0} |
4009 | + {"string static with null", 0, (test_execution_fn *)string_static_null }, |
4010 | + {"string alloc with null", 0, (test_execution_fn *)string_alloc_null }, |
4011 | + {"string alloc with 1K", 0, (test_execution_fn *)string_alloc_with_size }, |
4012 | + {"string alloc with malloc failure", 0, (test_execution_fn *)string_alloc_with_size_toobig }, |
4013 | + {"string append", 0, (test_execution_fn *)string_alloc_append }, |
4014 | + {"string append failure (too big)", 0, (test_execution_fn *)string_alloc_append_toobig }, |
4015 | + {0, 0, (test_execution_fn *)0} |
4016 | }; |
4017 | |
4018 | test_st result_tests[] ={ |
4019 | - {"result static", 0, result_static}, |
4020 | - {"result alloc", 0, result_alloc}, |
4021 | - {0, 0, 0} |
4022 | + {"result static", 0, (test_execution_fn *)result_static}, |
4023 | + {"result alloc", 0, (test_execution_fn *)result_alloc}, |
4024 | + {0, 0, (test_execution_fn *)0} |
4025 | }; |
4026 | |
4027 | test_st version_1_2_3[] ={ |
4028 | - {"append", 0, append_test }, |
4029 | - {"prepend", 0, prepend_test }, |
4030 | - {"cas", 0, cas_test }, |
4031 | - {"cas2", 0, cas2_test }, |
4032 | - {"append_binary", 0, append_binary_test }, |
4033 | - {0, 0, 0} |
4034 | + {"append", 0, (test_execution_fn *)append_test }, |
4035 | + {"prepend", 0, (test_execution_fn *)prepend_test }, |
4036 | + {"cas", 0, (test_execution_fn *)cas_test }, |
4037 | + {"cas2", 0, (test_execution_fn *)cas2_test }, |
4038 | + {"append_binary", 0, (test_execution_fn *)append_binary_test }, |
4039 | + {0, 0, (test_execution_fn *)0} |
4040 | }; |
4041 | |
4042 | test_st user_tests[] ={ |
4043 | - {"user_supplied_bug1", 0, user_supplied_bug1 }, |
4044 | - {"user_supplied_bug2", 0, user_supplied_bug2 }, |
4045 | - {"user_supplied_bug3", 0, user_supplied_bug3 }, |
4046 | - {"user_supplied_bug4", 0, user_supplied_bug4 }, |
4047 | - {"user_supplied_bug5", 1, user_supplied_bug5 }, |
4048 | - {"user_supplied_bug6", 1, user_supplied_bug6 }, |
4049 | - {"user_supplied_bug7", 1, user_supplied_bug7 }, |
4050 | - {"user_supplied_bug8", 1, user_supplied_bug8 }, |
4051 | - {"user_supplied_bug9", 1, user_supplied_bug9 }, |
4052 | - {"user_supplied_bug10", 1, user_supplied_bug10 }, |
4053 | - {"user_supplied_bug11", 1, user_supplied_bug11 }, |
4054 | - {"user_supplied_bug12", 1, user_supplied_bug12 }, |
4055 | - {"user_supplied_bug13", 1, user_supplied_bug13 }, |
4056 | - {"user_supplied_bug14", 1, user_supplied_bug14 }, |
4057 | - {"user_supplied_bug15", 1, user_supplied_bug15 }, |
4058 | - {"user_supplied_bug16", 1, user_supplied_bug16 }, |
4059 | + {"user_supplied_bug1", 0, (test_execution_fn *)user_supplied_bug1 }, |
4060 | + {"user_supplied_bug2", 0, (test_execution_fn *)user_supplied_bug2 }, |
4061 | + {"user_supplied_bug3", 0, (test_execution_fn *)user_supplied_bug3 }, |
4062 | + {"user_supplied_bug4", 0, (test_execution_fn *)user_supplied_bug4 }, |
4063 | + {"user_supplied_bug5", 1, (test_execution_fn *)user_supplied_bug5 }, |
4064 | + {"user_supplied_bug6", 1, (test_execution_fn *)user_supplied_bug6 }, |
4065 | + {"user_supplied_bug7", 1, (test_execution_fn *)user_supplied_bug7 }, |
4066 | + {"user_supplied_bug8", 1, (test_execution_fn *)user_supplied_bug8 }, |
4067 | + {"user_supplied_bug9", 1, (test_execution_fn *)user_supplied_bug9 }, |
4068 | + {"user_supplied_bug10", 1, (test_execution_fn *)user_supplied_bug10 }, |
4069 | + {"user_supplied_bug11", 1, (test_execution_fn *)user_supplied_bug11 }, |
4070 | + {"user_supplied_bug12", 1, (test_execution_fn *)user_supplied_bug12 }, |
4071 | + {"user_supplied_bug13", 1, (test_execution_fn *)user_supplied_bug13 }, |
4072 | + {"user_supplied_bug14", 1, (test_execution_fn *)user_supplied_bug14 }, |
4073 | + {"user_supplied_bug15", 1, (test_execution_fn *)user_supplied_bug15 }, |
4074 | + {"user_supplied_bug16", 1, (test_execution_fn *)user_supplied_bug16 }, |
4075 | #ifndef __sun |
4076 | /* |
4077 | ** It seems to be something weird with the character sets.. |
4078 | @@ -5535,23 +5499,23 @@ |
4079 | ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success, |
4080 | ** so just disable the code for now...). |
4081 | */ |
4082 | - {"user_supplied_bug17", 1, user_supplied_bug17 }, |
4083 | + {"user_supplied_bug17", 1, (test_execution_fn *)user_supplied_bug17 }, |
4084 | #endif |
4085 | - {"user_supplied_bug18", 1, user_supplied_bug18 }, |
4086 | - {"user_supplied_bug19", 1, user_supplied_bug19 }, |
4087 | - {"user_supplied_bug20", 1, user_supplied_bug20 }, |
4088 | - {"user_supplied_bug21", 1, user_supplied_bug21 }, |
4089 | - {"wrong_failure_counter_test", 1, wrong_failure_counter_test}, |
4090 | - {0, 0, 0} |
4091 | + {"user_supplied_bug18", 1, (test_execution_fn *)user_supplied_bug18 }, |
4092 | + {"user_supplied_bug19", 1, (test_execution_fn *)user_supplied_bug19 }, |
4093 | + {"user_supplied_bug20", 1, (test_execution_fn *)user_supplied_bug20 }, |
4094 | + {"user_supplied_bug21", 1, (test_execution_fn *)user_supplied_bug21 }, |
4095 | + {"wrong_failure_counter_test", 1, (test_execution_fn *)wrong_failure_counter_test}, |
4096 | + {0, 0, (test_execution_fn *)0} |
4097 | }; |
4098 | |
4099 | test_st replication_tests[]= { |
4100 | - {"set", 1, replication_set_test }, |
4101 | - {"get", 0, replication_get_test }, |
4102 | - {"mget", 0, replication_mget_test }, |
4103 | - {"delete", 0, replication_delete_test }, |
4104 | - {"rand_mget", 0, replication_randomize_mget_test }, |
4105 | - {0, 0, 0} |
4106 | + {"set", 1, (test_execution_fn *)replication_set_test }, |
4107 | + {"get", 0, (test_execution_fn *)replication_get_test }, |
4108 | + {"mget", 0, (test_execution_fn *)replication_mget_test }, |
4109 | + {"delete", 0, (test_execution_fn *)replication_delete_test }, |
4110 | + {"rand_mget", 0, (test_execution_fn *)replication_randomize_mget_test }, |
4111 | + {0, 0, (test_execution_fn *)0} |
4112 | }; |
4113 | |
4114 | /* |
4115 | @@ -5561,82 +5525,88 @@ |
4116 | * http://bugs.launchpad.net/libmemcached |
4117 | */ |
4118 | test_st regression_tests[]= { |
4119 | - {"lp:434484", 1, regression_bug_434484 }, |
4120 | - {"lp:434843", 1, regression_bug_434843 }, |
4121 | - {"lp:434843 buffered", 1, regression_bug_434843_buffered }, |
4122 | - {"lp:421108", 1, regression_bug_421108 }, |
4123 | - {"lp:442914", 1, regression_bug_442914 }, |
4124 | - {"lp:447342", 1, regression_bug_447342 }, |
4125 | - {"lp:463297", 1, regression_bug_463297 }, |
4126 | - {0, 0, 0} |
4127 | + {"lp:434484", 1, (test_execution_fn *)regression_bug_434484 }, |
4128 | + {"lp:434843", 1, (test_execution_fn *)regression_bug_434843 }, |
4129 | + {"lp:434843 buffered", 1, (test_execution_fn *)regression_bug_434843_buffered }, |
4130 | + {"lp:421108", 1, (test_execution_fn *)regression_bug_421108 }, |
4131 | + {"lp:442914", 1, (test_execution_fn *)regression_bug_442914 }, |
4132 | + {"lp:447342", 1, (test_execution_fn *)regression_bug_447342 }, |
4133 | + {"lp:463297", 1, (test_execution_fn *)regression_bug_463297 }, |
4134 | + {0, 0, (test_execution_fn *)0} |
4135 | }; |
4136 | |
4137 | test_st ketama_compatibility[]= { |
4138 | - {"libmemcached", 1, ketama_compatibility_libmemcached }, |
4139 | - {"spymemcached", 1, ketama_compatibility_spymemcached }, |
4140 | - {0, 0, 0} |
4141 | + {"libmemcached", 1, (test_execution_fn *)ketama_compatibility_libmemcached }, |
4142 | + {"spymemcached", 1, (test_execution_fn *)ketama_compatibility_spymemcached }, |
4143 | + {0, 0, (test_execution_fn *)0} |
4144 | }; |
4145 | |
4146 | test_st generate_tests[] ={ |
4147 | - {"generate_pairs", 1, generate_pairs }, |
4148 | - {"generate_data", 1, generate_data }, |
4149 | - {"get_read", 0, get_read }, |
4150 | - {"delete_generate", 0, delete_generate }, |
4151 | - {"generate_buffer_data", 1, generate_buffer_data }, |
4152 | - {"delete_buffer", 0, delete_buffer_generate}, |
4153 | - {"generate_data", 1, generate_data }, |
4154 | - {"mget_read", 0, mget_read }, |
4155 | - {"mget_read_result", 0, mget_read_result }, |
4156 | - {"mget_read_function", 0, mget_read_function }, |
4157 | - {"cleanup", 1, cleanup_pairs }, |
4158 | - {"generate_large_pairs", 1, generate_large_pairs }, |
4159 | - {"generate_data", 1, generate_data }, |
4160 | - {"generate_buffer_data", 1, generate_buffer_data }, |
4161 | - {"cleanup", 1, cleanup_pairs }, |
4162 | - {0, 0, 0} |
4163 | + {"generate_pairs", 1, (test_execution_fn *)generate_pairs }, |
4164 | + {"generate_data", 1, (test_execution_fn *)generate_data }, |
4165 | + {"get_read", 0, (test_execution_fn *)get_read }, |
4166 | + {"delete_generate", 0, (test_execution_fn *)delete_generate }, |
4167 | + {"generate_buffer_data", 1, (test_execution_fn *)generate_buffer_data }, |
4168 | + {"delete_buffer", 0, (test_execution_fn *)delete_buffer_generate}, |
4169 | + {"generate_data", 1, (test_execution_fn *)generate_data }, |
4170 | + {"mget_read", 0, (test_execution_fn *)mget_read }, |
4171 | + {"mget_read_result", 0, (test_execution_fn *)mget_read_result }, |
4172 | + {"mget_read_function", 0, (test_execution_fn *)mget_read_function }, |
4173 | + {"cleanup", 1, (test_execution_fn *)cleanup_pairs }, |
4174 | + {"generate_large_pairs", 1, (test_execution_fn *)generate_large_pairs }, |
4175 | + {"generate_data", 1, (test_execution_fn *)generate_data }, |
4176 | + {"generate_buffer_data", 1, (test_execution_fn *)generate_buffer_data }, |
4177 | + {"cleanup", 1, (test_execution_fn *)cleanup_pairs }, |
4178 | + {0, 0, (test_execution_fn *)0} |
4179 | }; |
4180 | |
4181 | test_st consistent_tests[] ={ |
4182 | - {"generate_pairs", 1, generate_pairs }, |
4183 | - {"generate_data", 1, generate_data }, |
4184 | - {"get_read", 0, get_read_count }, |
4185 | - {"cleanup", 1, cleanup_pairs }, |
4186 | - {0, 0, 0} |
4187 | + {"generate_pairs", 1, (test_execution_fn *)generate_pairs }, |
4188 | + {"generate_data", 1, (test_execution_fn *)generate_data }, |
4189 | + {"get_read", 0, (test_execution_fn *)get_read_count }, |
4190 | + {"cleanup", 1, (test_execution_fn *)cleanup_pairs }, |
4191 | + {0, 0, (test_execution_fn *)0} |
4192 | }; |
4193 | |
4194 | test_st consistent_weighted_tests[] ={ |
4195 | - {"generate_pairs", 1, generate_pairs }, |
4196 | - {"generate_data", 1, generate_data_with_stats }, |
4197 | - {"get_read", 0, get_read_count }, |
4198 | - {"cleanup", 1, cleanup_pairs }, |
4199 | - {0, 0, 0} |
4200 | + {"generate_pairs", 1, (test_execution_fn *)generate_pairs }, |
4201 | + {"generate_data", 1, (test_execution_fn *)generate_data_with_stats }, |
4202 | + {"get_read", 0, (test_execution_fn *)get_read_count }, |
4203 | + {"cleanup", 1, (test_execution_fn *)cleanup_pairs }, |
4204 | + {0, 0, (test_execution_fn *)0} |
4205 | }; |
4206 | |
4207 | test_st hsieh_availability[] ={ |
4208 | - {"hsieh_avaibility_test",0,hsieh_avaibility_test}, |
4209 | - {0, 0, 0} |
4210 | + {"hsieh_avaibility_test", 0, (test_execution_fn *)hsieh_avaibility_test}, |
4211 | + {0, 0, (test_execution_fn *)0} |
4212 | +}; |
4213 | + |
4214 | +test_st hash_sanity[] ={ |
4215 | + {"hash sanity", 0, (test_execution_fn *)hash_sanity_test}, |
4216 | + {0, 0, (test_execution_fn *)0} |
4217 | }; |
4218 | |
4219 | test_st ketama_auto_eject_hosts[] ={ |
4220 | - {"auto_eject_hosts", 1, auto_eject_hosts }, |
4221 | - {"output_ketama_weighted_keys", 1, output_ketama_weighted_keys }, |
4222 | - {0, 0, 0} |
4223 | + {"auto_eject_hosts", 1, (test_execution_fn *)auto_eject_hosts }, |
4224 | + {"output_ketama_weighted_keys", 1, (test_execution_fn *)output_ketama_weighted_keys }, |
4225 | + {0, 0, (test_execution_fn *)0} |
4226 | }; |
4227 | |
4228 | test_st hash_tests[] ={ |
4229 | - {"md5", 0, md5_run }, |
4230 | - {"crc", 0, crc_run }, |
4231 | - {"fnv1_64", 0, fnv1_64_run }, |
4232 | - {"fnv1a_64", 0, fnv1a_64_run }, |
4233 | - {"fnv1_32", 0, fnv1_32_run }, |
4234 | - {"fnv1a_32", 0, fnv1a_32_run }, |
4235 | - {"hsieh", 0, hsieh_run }, |
4236 | - {"murmur", 0, murmur_run }, |
4237 | - {"jenkis", 0, jenkins_run }, |
4238 | - {0, 0, 0} |
4239 | + {"md5", 0, (test_execution_fn *)md5_run }, |
4240 | + {"crc", 0, (test_execution_fn *)crc_run }, |
4241 | + {"fnv1_64", 0, (test_execution_fn *)fnv1_64_run }, |
4242 | + {"fnv1a_64", 0, (test_execution_fn *)fnv1a_64_run }, |
4243 | + {"fnv1_32", 0, (test_execution_fn *)fnv1_32_run }, |
4244 | + {"fnv1a_32", 0, (test_execution_fn *)fnv1a_32_run }, |
4245 | + {"hsieh", 0, (test_execution_fn *)hsieh_run }, |
4246 | + {"murmur", 0, (test_execution_fn *)murmur_run }, |
4247 | + {"jenkis", 0, (test_execution_fn *)jenkins_run }, |
4248 | + {0, 0, (test_execution_fn *)0} |
4249 | }; |
4250 | |
4251 | collection_st collection[] ={ |
4252 | + {"hash_sanity", 0, 0, hash_sanity}, |
4253 | {"hsieh_availability",0,0,hsieh_availability}, |
4254 | {"udp_setup", init_udp, 0, udp_setup_server_tests}, |
4255 | {"udp_io", init_udp, 0, upd_io_tests}, |
4256 | @@ -5725,4 +5695,5 @@ |
4257 | world->collections= collection; |
4258 | world->create= world_create; |
4259 | world->destroy= world_destroy; |
4260 | + world->is_libmemcached= true; |
4261 | } |
4262 | |
4263 | === added file 'tests/hash_results.h' |
4264 | --- tests/hash_results.h 1970-01-01 00:00:00 +0000 |
4265 | +++ tests/hash_results.h 2009-12-11 17:27:14 +0000 |
4266 | @@ -0,0 +1,115 @@ |
4267 | +/* |
4268 | + * Copyright (C) 2006-2009 Brian Aker |
4269 | + * All rights reserved. |
4270 | + * |
4271 | + * Use and distribution licensed under the BSD license. See |
4272 | + * the COPYING file in the parent directory for full text. |
4273 | + */ |
4274 | + |
4275 | +/** |
4276 | + @brief We list strings and results for testing different hashing algo in |
4277 | + this file. |
4278 | +*/ |
4279 | + |
4280 | + |
4281 | +static const char *list_to_hash[]= |
4282 | +{ |
4283 | + "apple", |
4284 | + "beat", |
4285 | + "carrot", |
4286 | + "daikon", |
4287 | + "eggplant", |
4288 | + "flower", |
4289 | + "green", |
4290 | + "hide", |
4291 | + "ick", |
4292 | + "jack", |
4293 | + "kick", |
4294 | + "lime", |
4295 | + "mushrooms", |
4296 | + "nectarine", |
4297 | + "orange", |
4298 | + "peach", |
4299 | + "quant", |
4300 | + "ripen", |
4301 | + "strawberry", |
4302 | + "tang", |
4303 | + "up", |
4304 | + "volumne", |
4305 | + "when", |
4306 | + "yellow", |
4307 | + "zip", |
4308 | + NULL |
4309 | +}; |
4310 | + |
4311 | +static uint32_t md5_values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U, |
4312 | + 245758794U, 2550894432U, 121710495U, 3053817768U, |
4313 | + 1250994555U, 1862072655U, 2631955953U, 2951528551U, |
4314 | + 1451250070U, 2820856945U, 2060845566U, 3646985608U, |
4315 | + 2138080750U, 217675895U, 2230934345U, 1234361223U, |
4316 | + 3968582726U, 2455685270U, 1293568479U, 199067604U, |
4317 | + 2042482093U }; |
4318 | + |
4319 | +static uint32_t crc_values[]= { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U, |
4320 | + 9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U, |
4321 | + 7621U, 30628U, 15218U, 25967U, 2695U, 9380U, |
4322 | + 17300U, 28156U, 9192U, 20484U, 16925U }; |
4323 | + |
4324 | +static uint32_t fnv1_64_values[]= { 473199127U, 4148981457U, 3971873300U, 3257986707U, |
4325 | + 1722477987U, 2991193800U, 4147007314U, 3633179701U, |
4326 | + 1805162104U, 3503289120U, 3395702895U, 3325073042U, |
4327 | + 2345265314U, 3340346032U, 2722964135U, 1173398992U, |
4328 | + 2815549194U, 2562818319U, 224996066U, 2680194749U, |
4329 | + 3035305390U, 246890365U, 2395624193U, 4145193337U, |
4330 | + 1801941682U }; |
4331 | + |
4332 | +static uint32_t fnv1a_64_values[]= { 1488911807U, 2500855813U, 1510099634U, 1390325195U, |
4333 | + 3647689787U, 3241528582U, 1669328060U, 2604311949U, |
4334 | + 734810122U, 1516407546U, 560948863U, 1767346780U, |
4335 | + 561034892U, 4156330026U, 3716417003U, 3475297030U, |
4336 | + 1518272172U, 227211583U, 3938128828U, 126112909U, |
4337 | + 3043416448U, 3131561933U, 1328739897U, 2455664041U, |
4338 | + 2272238452U }; |
4339 | + |
4340 | +static uint32_t fnv1_32_values[]= { 67176023U, 1190179409U, 2043204404U, 3221866419U, |
4341 | + 2567703427U, 3787535528U, 4147287986U, 3500475733U, |
4342 | + 344481048U, 3865235296U, 2181839183U, 119581266U, |
4343 | + 510234242U, 4248244304U, 1362796839U, 103389328U, |
4344 | + 1449620010U, 182962511U, 3554262370U, 3206747549U, |
4345 | + 1551306158U, 4127558461U, 1889140833U, 2774173721U, |
4346 | + 1180552018U }; |
4347 | + |
4348 | +static uint32_t fnv1a_32_values[]= { 280767167U, 2421315013U, 3072375666U, 855001899U, |
4349 | + 459261019U, 3521085446U, 18738364U, 1625305005U, |
4350 | + 2162232970U, 777243802U, 3323728671U, 132336572U, |
4351 | + 3654473228U, 260679466U, 1169454059U, 2698319462U, |
4352 | + 1062177260U, 235516991U, 2218399068U, 405302637U, |
4353 | + 1128467232U, 3579622413U, 2138539289U, 96429129U, |
4354 | + 2877453236U }; |
4355 | + |
4356 | +#ifdef HAVE_HSIEH_HASH |
4357 | +static uint32_t hsieh_values[]= { 3738850110U, 3636226060U, 3821074029U, 3489929160U, 3485772682U, 80540287U, |
4358 | + 1805464076U, 1895033657U, 409795758U, 979934958U, 3634096985U, 1284445480U, |
4359 | + 2265380744U, 707972988U, 353823508U, 1549198350U, 1327930172U, 9304163U, |
4360 | + 4220749037U, 2493964934U, 2777873870U, 2057831732U, 1510213931U, 2027828987U, |
4361 | + 3395453351U }; |
4362 | +#else |
4363 | +static uint32_t hsieh_values[]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; |
4364 | +#endif |
4365 | + |
4366 | +static uint32_t murmur_values[]= { 4142305122U, 734504955U, 3802834688U, 4076891445U, |
4367 | + 387802650U, 560515427U, 3274673488U, 3150339524U, |
4368 | + 1527441970U, 2728642900U, 3613992239U, 2938419259U, |
4369 | + 2321988328U, 1145154116U, 4038540960U, 2224541613U, |
4370 | + 264013145U, 3995512858U, 2400956718U, 2346666219U, |
4371 | + 926327338U, 442757446U, 1770805201U, 560483147U, |
4372 | + 3902279934U }; |
4373 | + |
4374 | +static uint32_t jenkins_values[]= { 1442444624U, 4253821186U, 1885058256U, 2120131735U, |
4375 | + 3261968576U, 3515188778U, 4232909173U, 4288625128U, |
4376 | + 1812047395U, 3689182164U, 2502979932U, 1214050606U, |
4377 | + 2415988847U, 1494268927U, 1025545760U, 3920481083U, |
4378 | + 4153263658U, 3824871822U, 3072759809U, 798622255U, |
4379 | + 3065432577U, 1453328165U, 2691550971U, 3408888387U, |
4380 | + 2629893356U }; |
4381 | + |
4382 | |
4383 | === added file 'tests/hashkit_functions.c' |
4384 | --- tests/hashkit_functions.c 1970-01-01 00:00:00 +0000 |
4385 | +++ tests/hashkit_functions.c 2009-12-11 17:27:14 +0000 |
4386 | @@ -0,0 +1,363 @@ |
4387 | +/* libHashKit Functions Test |
4388 | + * Copyright (C) 2006-2009 Brian Aker |
4389 | + * All rights reserved. |
4390 | + * |
4391 | + * Use and distribution licensed under the BSD license. See |
4392 | + * the COPYING file in the parent directory for full text. |
4393 | + */ |
4394 | + |
4395 | +#include <assert.h> |
4396 | +#include <stdio.h> |
4397 | +#include <stdlib.h> |
4398 | +#include <string.h> |
4399 | + |
4400 | +#include <libhashkit/hashkit.h> |
4401 | + |
4402 | +#include "test.h" |
4403 | + |
4404 | +#include "hash_results.h" |
4405 | + |
4406 | +static hashkit_st global_hashk; |
4407 | + |
4408 | +/** |
4409 | + @brief hash_test_st is a structure we use in testing. It is currently empty. |
4410 | +*/ |
4411 | +typedef struct hash_test_st hash_test_st; |
4412 | + |
4413 | +struct hash_test_st |
4414 | +{ |
4415 | + bool _unused; |
4416 | +}; |
4417 | + |
4418 | +static test_return_t init_test(void *not_used __attribute__((unused))) |
4419 | +{ |
4420 | + hashkit_st hashk; |
4421 | + hashkit_st *hashk_ptr; |
4422 | + |
4423 | + hashk_ptr= hashkit_create(&hashk); |
4424 | + test_truth(hashk_ptr); |
4425 | + test_truth(hashk_ptr == &hashk); |
4426 | + test_truth(hashkit_is_initialized(&hashk) == true); |
4427 | + test_truth(hashkit_is_allocated(hashk_ptr) == false); |
4428 | + |
4429 | + hashkit_free(hashk_ptr); |
4430 | + |
4431 | + test_truth(hashkit_is_initialized(&hashk) == false); |
4432 | + |
4433 | + return TEST_SUCCESS; |
4434 | +} |
4435 | + |
4436 | +static test_return_t allocation_test(void *not_used __attribute__((unused))) |
4437 | +{ |
4438 | + hashkit_st *hashk_ptr; |
4439 | + |
4440 | + hashk_ptr= hashkit_create(NULL); |
4441 | + test_truth(hashk_ptr); |
4442 | + test_truth(hashkit_is_allocated(hashk_ptr) == true); |
4443 | + test_truth(hashkit_is_initialized(hashk_ptr) == true); |
4444 | + hashkit_free(hashk_ptr); |
4445 | + |
4446 | + return TEST_SUCCESS; |
4447 | +} |
4448 | + |
4449 | +static test_return_t clone_test(hashkit_st *hashk) |
4450 | +{ |
4451 | + // First we make sure that the testing system is giving us what we expect. |
4452 | + assert(&global_hashk == hashk); |
4453 | + |
4454 | + // Second we test if hashk is even valid |
4455 | + test_truth(hashkit_is_initialized(hashk) == true); |
4456 | + |
4457 | + /* All null? */ |
4458 | + { |
4459 | + hashkit_st *hashk_ptr; |
4460 | + hashk_ptr= hashkit_clone(NULL, NULL); |
4461 | + test_truth(hashk_ptr); |
4462 | + test_truth(hashkit_is_allocated(hashk_ptr) == true); |
4463 | + test_truth(hashkit_is_initialized(hashk_ptr) == true); |
4464 | + hashkit_free(hashk_ptr); |
4465 | + } |
4466 | + |
4467 | + /* Can we init from null? */ |
4468 | + { |
4469 | + hashkit_st *hashk_ptr; |
4470 | + |
4471 | + hashk_ptr= hashkit_clone(NULL, hashk); |
4472 | + |
4473 | + test_truth(hashk_ptr); |
4474 | + test_truth(hashkit_is_allocated(hashk_ptr) == true); |
4475 | + test_truth(hashkit_is_initialized(hashk_ptr) == true); |
4476 | + |
4477 | + test_truth(hashk_ptr->distribution == hashk->distribution); |
4478 | + test_truth(hashk_ptr->continuum_count == hashk->continuum_count); |
4479 | + test_truth(hashk_ptr->continuum_points_count == hashk->continuum_points_count); |
4480 | + test_truth(hashk_ptr->list_size == hashk->list_size); |
4481 | + test_truth(hashk_ptr->context_size == hashk->context_size); |
4482 | + test_truth(hashk_ptr->continuum == NULL); |
4483 | + test_truth(hashk_ptr->hash_fn == hashk->hash_fn); |
4484 | + test_truth(hashk_ptr->active_fn == hashk->active_fn); |
4485 | + test_truth(hashk_ptr->continuum_hash_fn == hashk->continuum_hash_fn); |
4486 | + test_truth(hashk_ptr->continuum_key_fn == hashk->continuum_key_fn); |
4487 | + test_truth(hashk_ptr->sort_fn == hashk->sort_fn); |
4488 | + test_truth(hashk_ptr->weight_fn == hashk->weight_fn); |
4489 | + test_truth(hashk_ptr->list == hashk->list); |
4490 | + |
4491 | + hashkit_free(hashk_ptr); |
4492 | + } |
4493 | + |
4494 | + /* Can we init from struct? */ |
4495 | + { |
4496 | + hashkit_st declared_clone; |
4497 | + hashkit_st *hash_clone; |
4498 | + |
4499 | + hash_clone= hashkit_clone(&declared_clone, NULL); |
4500 | + test_truth(hash_clone); |
4501 | + |
4502 | + hashkit_free(hash_clone); |
4503 | + } |
4504 | + |
4505 | + /* Can we init from struct? */ |
4506 | + { |
4507 | + hashkit_st declared_clone; |
4508 | + hashkit_st *hash_clone; |
4509 | + memset(&declared_clone, 0 , sizeof(hashkit_st)); |
4510 | + hash_clone= hashkit_clone(&declared_clone, hashk); |
4511 | + test_truth(hash_clone); |
4512 | + hashkit_free(hash_clone); |
4513 | + } |
4514 | + |
4515 | + return TEST_SUCCESS; |
4516 | +} |
4517 | + |
4518 | + |
4519 | +static test_return_t md5_run (hashkit_st *hashk __attribute__((unused))) |
4520 | +{ |
4521 | + uint32_t x; |
4522 | + const char **ptr; |
4523 | + |
4524 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4525 | + { |
4526 | + uint32_t hash_val; |
4527 | + |
4528 | + hash_val= hashkit_md5(*ptr, strlen(*ptr)); |
4529 | + test_truth(md5_values[x] == hash_val); |
4530 | + } |
4531 | + |
4532 | + return TEST_SUCCESS; |
4533 | +} |
4534 | + |
4535 | +static test_return_t crc_run (hashkit_st *hashk __attribute__((unused))) |
4536 | +{ |
4537 | + uint32_t x; |
4538 | + const char **ptr; |
4539 | + |
4540 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4541 | + { |
4542 | + uint32_t hash_val; |
4543 | + |
4544 | + hash_val= hashkit_crc32(*ptr, strlen(*ptr)); |
4545 | + assert(crc_values[x] == hash_val); |
4546 | + } |
4547 | + |
4548 | + return TEST_SUCCESS; |
4549 | +} |
4550 | + |
4551 | +static test_return_t fnv1_64_run (hashkit_st *hashk __attribute__((unused))) |
4552 | +{ |
4553 | + uint32_t x; |
4554 | + const char **ptr; |
4555 | + |
4556 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4557 | + { |
4558 | + uint32_t hash_val; |
4559 | + |
4560 | + hash_val= hashkit_fnv1_64(*ptr, strlen(*ptr)); |
4561 | + assert(fnv1_64_values[x] == hash_val); |
4562 | + } |
4563 | + |
4564 | + return TEST_SUCCESS; |
4565 | +} |
4566 | + |
4567 | +static test_return_t fnv1a_64_run (hashkit_st *hashk __attribute__((unused))) |
4568 | +{ |
4569 | + uint32_t x; |
4570 | + const char **ptr; |
4571 | + |
4572 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4573 | + { |
4574 | + uint32_t hash_val; |
4575 | + |
4576 | + hash_val= hashkit_fnv1a_64(*ptr, strlen(*ptr)); |
4577 | + assert(fnv1a_64_values[x] == hash_val); |
4578 | + } |
4579 | + |
4580 | + return TEST_SUCCESS; |
4581 | +} |
4582 | + |
4583 | +static test_return_t fnv1_32_run (hashkit_st *hashk __attribute__((unused))) |
4584 | +{ |
4585 | + uint32_t x; |
4586 | + const char **ptr; |
4587 | + |
4588 | + |
4589 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4590 | + { |
4591 | + uint32_t hash_val; |
4592 | + |
4593 | + hash_val= hashkit_fnv1_32(*ptr, strlen(*ptr)); |
4594 | + assert(fnv1_32_values[x] == hash_val); |
4595 | + } |
4596 | + |
4597 | + return TEST_SUCCESS; |
4598 | +} |
4599 | + |
4600 | +static test_return_t fnv1a_32_run (hashkit_st *hashk __attribute__((unused))) |
4601 | +{ |
4602 | + uint32_t x; |
4603 | + const char **ptr; |
4604 | + |
4605 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4606 | + { |
4607 | + uint32_t hash_val; |
4608 | + |
4609 | + hash_val= hashkit_fnv1a_32(*ptr, strlen(*ptr)); |
4610 | + assert(fnv1a_32_values[x] == hash_val); |
4611 | + } |
4612 | + |
4613 | + return TEST_SUCCESS; |
4614 | +} |
4615 | + |
4616 | +static test_return_t hsieh_run (hashkit_st *hashk __attribute__((unused))) |
4617 | +{ |
4618 | + uint32_t x; |
4619 | + const char **ptr; |
4620 | + |
4621 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4622 | + { |
4623 | + uint32_t hash_val; |
4624 | + |
4625 | +#ifdef HAVE_HSIEH_HASH |
4626 | + hash_val= hashkit_hsieh(*ptr, strlen(*ptr)); |
4627 | +#else |
4628 | + hash_val= 1; |
4629 | +#endif |
4630 | + assert(hsieh_values[x] == hash_val); |
4631 | + } |
4632 | + |
4633 | + return TEST_SUCCESS; |
4634 | +} |
4635 | + |
4636 | +static test_return_t murmur_run (hashkit_st *hashk __attribute__((unused))) |
4637 | +{ |
4638 | + uint32_t x; |
4639 | + const char **ptr; |
4640 | + |
4641 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4642 | + { |
4643 | + uint32_t hash_val; |
4644 | + |
4645 | + hash_val= hashkit_murmur(*ptr, strlen(*ptr)); |
4646 | + assert(murmur_values[x] == hash_val); |
4647 | + } |
4648 | + |
4649 | + return TEST_SUCCESS; |
4650 | +} |
4651 | + |
4652 | +static test_return_t jenkins_run (hashkit_st *hashk __attribute__((unused))) |
4653 | +{ |
4654 | + uint32_t x; |
4655 | + const char **ptr; |
4656 | + |
4657 | + |
4658 | + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) |
4659 | + { |
4660 | + uint32_t hash_val; |
4661 | + |
4662 | + hash_val= hashkit_jenkins(*ptr, strlen(*ptr)); |
4663 | + assert(jenkins_values[x] == hash_val); |
4664 | + } |
4665 | + |
4666 | + return TEST_SUCCESS; |
4667 | +} |
4668 | + |
4669 | + |
4670 | + |
4671 | + |
4672 | +/** |
4673 | + @brief now we list out the tests. |
4674 | +*/ |
4675 | + |
4676 | +test_st allocation[]= { |
4677 | + {"init", 0, (test_execution_fn *)init_test}, |
4678 | + {"create and free", 0, (test_execution_fn *)allocation_test}, |
4679 | + {"clone", 0, (test_execution_fn *)clone_test}, |
4680 | + {0, 0, 0} |
4681 | +}; |
4682 | + |
4683 | +test_st hash_tests[] ={ |
4684 | + {"md5", 0, (test_execution_fn *)md5_run }, |
4685 | + {"crc", 0, (test_execution_fn *)crc_run }, |
4686 | + {"fnv1_64", 0, (test_execution_fn *)fnv1_64_run }, |
4687 | + {"fnv1a_64", 0, (test_execution_fn *)fnv1a_64_run }, |
4688 | + {"fnv1_32", 0, (test_execution_fn *)fnv1_32_run }, |
4689 | + {"fnv1a_32", 0, (test_execution_fn *)fnv1a_32_run }, |
4690 | + {"hsieh", 0, (test_execution_fn *)hsieh_run }, |
4691 | + {"murmur", 0, (test_execution_fn *)murmur_run }, |
4692 | + {"jenkis", 0, (test_execution_fn *)jenkins_run }, |
4693 | + {0, 0, (test_execution_fn *)0} |
4694 | +}; |
4695 | + |
4696 | +/* |
4697 | + * The following test suite is used to verify that we don't introduce |
4698 | + * regression bugs. If you want more information about the bug / test, |
4699 | + * you should look in the bug report at |
4700 | + * http://bugs.launchpad.net/libmemcached |
4701 | + */ |
4702 | +test_st regression[]= { |
4703 | + {0, 0, 0} |
4704 | +}; |
4705 | + |
4706 | +collection_st collection[] ={ |
4707 | + {"allocation", 0, 0, allocation}, |
4708 | + {"regression", 0, 0, regression}, |
4709 | + {"hashing", 0, 0, hash_tests}, |
4710 | + {0, 0, 0, 0} |
4711 | +}; |
4712 | + |
4713 | +/* Prototypes for functions we will pass to test framework */ |
4714 | +void *world_create(void); |
4715 | +void world_destroy(void *p); |
4716 | + |
4717 | +void *world_create(void) |
4718 | +{ |
4719 | + hashkit_st *hashk_ptr; |
4720 | + |
4721 | + hashk_ptr= hashkit_create(&global_hashk); |
4722 | + |
4723 | + assert(hashk_ptr == &global_hashk); |
4724 | + |
4725 | + // First we test if hashk is even valid |
4726 | + assert(hashkit_is_initialized(hashk_ptr) == true); |
4727 | + assert(hashkit_is_allocated(hashk_ptr) == false); |
4728 | + assert(hashk_ptr->continuum == NULL); |
4729 | + |
4730 | + return hashk_ptr; |
4731 | +} |
4732 | + |
4733 | + |
4734 | +void world_destroy(void *p) |
4735 | +{ |
4736 | + hashkit_st *hashk= (hashkit_st *)p; |
4737 | + |
4738 | + // Did we get back what we expected? |
4739 | + assert(hashkit_is_initialized(hashk) == true); |
4740 | + assert(hashkit_is_allocated(hashk) == false); |
4741 | + hashkit_free(&global_hashk); |
4742 | +} |
4743 | + |
4744 | +void get_world(world_st *world) |
4745 | +{ |
4746 | + world->collections= collection; |
4747 | + world->create= world_create; |
4748 | + world->destroy= world_destroy; |
4749 | +} |
4750 | |
4751 | === modified file 'tests/output_plus.res' |
4752 | --- tests/output_plus.res 2009-07-15 22:13:28 +0000 |
4753 | +++ tests/output_plus.res 2009-12-11 17:27:14 +0000 |
4754 | @@ -1,5 +0,0 @@ |
4755 | -servers localhost:11221, |
4756 | - localhost : 11221 |
4757 | - |
4758 | - |
4759 | -retvalue 1 |
4760 | |
4761 | === modified file 'tests/plus.cpp' |
4762 | --- tests/plus.cpp 2009-11-19 22:46:49 +0000 |
4763 | +++ tests/plus.cpp 2009-12-11 17:27:14 +0000 |
4764 | @@ -30,7 +30,7 @@ |
4765 | test_return_t basic_behavior(memcached_st *memc); |
4766 | test_return_t mget_test(memcached_st *memc); |
4767 | memcached_return callback_counter(memcached_st *, |
4768 | - memcached_result_st *, |
4769 | + memcached_result_st *, |
4770 | void *context); |
4771 | void *world_create(void); |
4772 | void world_destroy(void *p); |
4773 | @@ -65,7 +65,7 @@ |
4774 | |
4775 | assert((memcmp(&test_value[0], &value[0], test_value.size()) == 0)); |
4776 | |
4777 | - /* |
4778 | + /* |
4779 | * Simple test of the exceptions here...this should throw an exception |
4780 | * saying that the key is empty. |
4781 | */ |
4782 | @@ -109,7 +109,7 @@ |
4783 | |
4784 | int_inc_value= uint64_t(atol(inc_value.c_str())); |
4785 | int_ret_value= uint64_t(atol(ret_string.c_str())); |
4786 | - assert(int_ret_value == int_inc_value); |
4787 | + assert(int_ret_value == int_inc_value); |
4788 | |
4789 | rc= mcach.increment(key, 1, &int_ret_value); |
4790 | assert(rc == true); |
4791 | @@ -153,7 +153,7 @@ |
4792 | |
4793 | /* Count the results */ |
4794 | memcached_return callback_counter(memcached_st *, |
4795 | - memcached_result_st *, |
4796 | + memcached_result_st *, |
4797 | void *context) |
4798 | { |
4799 | unsigned int *counter= static_cast<unsigned int *>(context); |
4800 | @@ -199,7 +199,7 @@ |
4801 | |
4802 | callbacks[0]= &callback_counter; |
4803 | counter= 0; |
4804 | - rc= mc.fetchExecute(callbacks, static_cast<void *>(&counter), 1); |
4805 | + rc= mc.fetchExecute(callbacks, static_cast<void *>(&counter), 1); |
4806 | |
4807 | assert(counter == 3); |
4808 | |
4809 | @@ -274,12 +274,18 @@ |
4810 | } |
4811 | |
4812 | test_st tests[] ={ |
4813 | - { "basic", 0, basic_test }, |
4814 | - { "basic_master_key", 0, basic_master_key_test }, |
4815 | - { "increment_test", 0, increment_test }, |
4816 | - { "mget", 1, mget_test }, |
4817 | - { "mget_result_function", 1, mget_result_function }, |
4818 | - { "basic_behavior", 0, basic_behavior }, |
4819 | + { "basic", 0, |
4820 | + reinterpret_cast<test_execution_fn *>(basic_test) }, |
4821 | + { "basic_master_key", 0, |
4822 | + reinterpret_cast<test_execution_fn *>(basic_master_key_test) }, |
4823 | + { "increment_test", 0, |
4824 | + reinterpret_cast<test_execution_fn *>(increment_test) }, |
4825 | + { "mget", 1, |
4826 | + reinterpret_cast<test_execution_fn *>(mget_test) }, |
4827 | + { "mget_result_function", 1, |
4828 | + reinterpret_cast<test_execution_fn *>(mget_result_function) }, |
4829 | + { "basic_behavior", 0, |
4830 | + reinterpret_cast<test_execution_fn *>(basic_behavior) }, |
4831 | {0, 0, 0} |
4832 | }; |
4833 | |
4834 | |
4835 | === modified file 'tests/test.c' |
4836 | --- tests/test.c 2009-12-05 12:53:58 +0000 |
4837 | +++ tests/test.c 2009-12-11 17:27:14 +0000 |
4838 | @@ -1,3 +1,11 @@ |
4839 | +/* uTest |
4840 | + * Copyright (C) 2006-2009 Brian Aker |
4841 | + * All rights reserved. |
4842 | + * |
4843 | + * Use and distribution licensed under the BSD license. See |
4844 | + * the COPYING file in the parent directory for full text. |
4845 | + */ |
4846 | + |
4847 | /* |
4848 | Sample test application. |
4849 | */ |
4850 | @@ -57,7 +65,7 @@ |
4851 | char *collection_to_run= NULL; |
4852 | char *wildcard= NULL; |
4853 | server_startup_st *startup_ptr; |
4854 | - memcached_server_st *servers; |
4855 | + memcached_server_st *servers= NULL; |
4856 | world_st world; |
4857 | collection_st *collection; |
4858 | collection_st *next; |
4859 | @@ -72,8 +80,11 @@ |
4860 | else |
4861 | world_ptr= NULL; |
4862 | |
4863 | - startup_ptr= (server_startup_st *)world_ptr; |
4864 | - servers= (memcached_server_st *)startup_ptr->servers; |
4865 | + if (world.is_libmemcached) |
4866 | + { |
4867 | + startup_ptr= (server_startup_st *)world_ptr; |
4868 | + servers= (memcached_server_st *)startup_ptr->servers; |
4869 | + } |
4870 | |
4871 | if (argc > 1) |
4872 | collection_to_run= argv[1]; |
4873 | @@ -94,7 +105,7 @@ |
4874 | for (x= 0; run->name; run++) |
4875 | { |
4876 | unsigned int loop; |
4877 | - memcached_st *memc; |
4878 | + memcached_st *memc= NULL; |
4879 | memcached_return rc; |
4880 | struct timeval start_time, end_time; |
4881 | long int load_time; |
4882 | @@ -104,22 +115,31 @@ |
4883 | |
4884 | fprintf(stderr, "Testing %s", run->name); |
4885 | |
4886 | - memc= memcached_create(NULL); |
4887 | - test_truth(memc); |
4888 | + if (world.is_libmemcached) |
4889 | + { |
4890 | + memc= memcached_create(NULL); |
4891 | + test_truth(memc); |
4892 | |
4893 | - rc= memcached_server_push(memc, servers); |
4894 | - test_truth(rc == MEMCACHED_SUCCESS); |
4895 | + rc= memcached_server_push(memc, servers); |
4896 | + test_truth(rc == MEMCACHED_SUCCESS); |
4897 | + } |
4898 | |
4899 | if (run->requires_flush) |
4900 | { |
4901 | - memcached_flush(memc, 0); |
4902 | - memcached_quit(memc); |
4903 | + if (world.is_libmemcached) |
4904 | + { |
4905 | + memcached_flush(memc, 0); |
4906 | + memcached_quit(memc); |
4907 | + } |
4908 | } |
4909 | |
4910 | - for (loop= 0; loop < memcached_server_list_count(servers); loop++) |
4911 | + if (world.is_libmemcached) |
4912 | { |
4913 | - test_truth(memc->hosts[loop].fd == -1); |
4914 | - test_truth(memc->hosts[loop].cursor_active == 0); |
4915 | + for (loop= 0; loop < memcached_server_list_count(servers); loop++) |
4916 | + { |
4917 | + test_truth(memc->hosts[loop].fd == -1); |
4918 | + test_truth(memc->hosts[loop].cursor_active == 0); |
4919 | + } |
4920 | } |
4921 | |
4922 | if (next->pre) |
4923 | @@ -134,7 +154,7 @@ |
4924 | } |
4925 | |
4926 | gettimeofday(&start_time, NULL); |
4927 | - failed= run->function(memc); |
4928 | + failed= run->test_fn(world.is_libmemcached ? memc : world_ptr); |
4929 | gettimeofday(&end_time, NULL); |
4930 | load_time= timedif(end_time, start_time); |
4931 | |
4932 | @@ -144,9 +164,11 @@ |
4933 | if (next->post) |
4934 | (void)next->post(memc); |
4935 | |
4936 | - test_truth(memc); |
4937 | + if (world.is_libmemcached) |
4938 | + assert(memc); |
4939 | error: |
4940 | - memcached_free(memc); |
4941 | + if (world.is_libmemcached) |
4942 | + memcached_free(memc); |
4943 | } |
4944 | } |
4945 | |
4946 | |
4947 | === modified file 'tests/test.h' |
4948 | --- tests/test.h 2009-12-03 15:22:16 +0000 |
4949 | +++ tests/test.h 2009-12-11 17:27:14 +0000 |
4950 | @@ -1,6 +1,15 @@ |
4951 | +/* uTest |
4952 | + * Copyright (C) 2006-2009 Brian Aker |
4953 | + * All rights reserved. |
4954 | + * |
4955 | + * Use and distribution licensed under the BSD license. See |
4956 | + * the COPYING file in the parent directory for full text. |
4957 | + */ |
4958 | + |
4959 | /* |
4960 | Structures for generic tests. |
4961 | */ |
4962 | + |
4963 | #ifdef __cplusplus |
4964 | extern "C" { |
4965 | #endif |
4966 | @@ -20,10 +29,12 @@ |
4967 | TEST_MAXIMUM_RETURN /* Always add new error code before */ |
4968 | } test_return_t; |
4969 | |
4970 | +typedef test_return_t (test_execution_fn)(void *context); |
4971 | + |
4972 | struct test_st { |
4973 | const char *name; |
4974 | unsigned int requires_flush; |
4975 | - test_return_t (*function)(memcached_st *memc); |
4976 | + test_execution_fn *test_fn; |
4977 | }; |
4978 | |
4979 | struct collection_st { |
4980 | @@ -37,6 +48,7 @@ |
4981 | collection_st *collections; |
4982 | void *(*create)(void); |
4983 | void (*destroy)(void *collection_object); |
4984 | + bool is_libmemcached; // This will eventually go away |
4985 | }; |
4986 | |
4987 | /* How we make all of this work :) */ |
4988 | |
4989 | === modified file 'tests/udp.c' |
4990 | --- tests/udp.c 2009-11-25 08:21:57 +0000 |
4991 | +++ tests/udp.c 2009-12-11 17:27:14 +0000 |
4992 | @@ -34,7 +34,7 @@ |
4993 | } |
4994 | |
4995 | test_st tests[] ={ |
4996 | - {"set", 1, set_test }, |
4997 | + {"set", 1, (test_execution_fn *)set_test }, |
4998 | {0, 0, 0} |
4999 | }; |
5000 |
Here's the code to hopefully fix the ubuntu 32-bit build issue.