Merge lp:~mordred/libmemcached/one-makefile into lp:~tangent-org/libmemcached/trunk

Proposed by Monty Taylor
Status: Merged
Merged at revision: not available
Proposed branch: lp:~mordred/libmemcached/one-makefile
Merge into: lp:~tangent-org/libmemcached/trunk
Diff against target: 4056 lines (+2944/-380)
53 files modified
ChangeLog (+1/-0)
Makefile.am (+25/-17)
clients/include.am (+91/-76)
configure.ac (+4/-5)
example/include.am (+17/-13)
libhashkit/Makefile.am (+45/-0)
libhashkit/algorithm.h (+49/-0)
libhashkit/behavior.c (+147/-0)
libhashkit/behavior.h (+68/-0)
libhashkit/common.h (+33/-0)
libhashkit/crc32.c (+85/-0)
libhashkit/default.c (+28/-0)
libhashkit/fnv.c (+75/-0)
libhashkit/hashkit.c (+252/-0)
libhashkit/hashkit.h (+112/-0)
libhashkit/hsieh.c (+68/-0)
libhashkit/jenkins.c (+213/-0)
libhashkit/ketama.c (+161/-0)
libhashkit/md5.c (+365/-0)
libhashkit/murmur.c (+76/-0)
libhashkit/strerror.c (+26/-0)
libhashkit/strerror.h (+22/-0)
libhashkit/types.h (+92/-0)
libhashkit/visibility.h (+51/-0)
libmemcached/dump.c (+2/-3)
libmemcached/dump.h (+27/-0)
libmemcached/hosts.c (+3/-2)
libmemcached/include.am (+121/-120)
libmemcached/libmemcached.ver (+0/-1)
libmemcached/memcached.c (+0/-1)
libmemcached/memcached.h (+3/-6)
libmemcached/protocol/libmemcachedprotocol.ver (+0/-1)
libmemcached/result.c (+14/-7)
libmemcached/string.c (+3/-3)
libmemcached/util/libmemcachedutil.ver (+0/-1)
libmemcached/watchpoint.h (+11/-11)
m4/pandora_canonical.m4 (+2/-15)
m4/pandora_check_cxx_standard.m4 (+9/-2)
m4/pandora_cinttypes.m4 (+4/-1)
m4/pandora_cstdint.m4 (+3/-0)
m4/pandora_cxx_demangle.m4 (+3/-0)
m4/pandora_drizzle_build.m4 (+26/-5)
m4/pandora_have_libreadline.m4 (+1/-1)
m4/pandora_libtool.m4 (+10/-0)
m4/pandora_shared_ptr.m4 (+3/-0)
m4/pandora_stl_hash.m4 (+3/-0)
m4/pandora_warnings.m4 (+12/-5)
support/include.am (+9/-2)
support/libmemcached.spec.in (+1/-0)
tests/function.c (+63/-3)
tests/hashkit_functions.c (+363/-0)
tests/include.am (+125/-77)
tests/test.c (+17/-2)
To merge this branch: bzr merge lp:~mordred/libmemcached/one-makefile
Reviewer Review Type Date Requested Status
Libmemcached-developers Pending
Review via email: mp+16312@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Monty Taylor (mordred) wrote :

Made makefiles single root makefile. Updated to latest pandora-build. Put test artifacts in tests dir rather than in /tmp for better build host joy.

Still to be done - unique process id's so that a single machine can run more than one copy of the test suite.

646. By Monty Taylor

Merged from build.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2009-12-17 07:20:58 +0000
3+++ ChangeLog 2009-12-18 01:27:26 +0000
4@@ -1,3 +1,4 @@
5+ * Modified use_sort so that the option can be applied to any distribution type.
6 * We removed the MEMCACHED_BEHAVIOR_KETAMA_COMPAT_MODE added in 0.35. Instead use
7 memcached_behavior_set_distribution().
8
9
10=== modified file 'Makefile.am'
11--- Makefile.am 2009-12-17 00:11:59 +0000
12+++ Makefile.am 2009-12-18 01:27:26 +0000
13@@ -1,26 +1,36 @@
14 ACLOCAL_AMFLAGS = -I m4
15
16-SUBDIRS = docs libmemcached support clients tests example
17-EXTRA_dist = README.FIRST
18+# includes append to these:
19+SUFFIXES =
20+PHONY =
21+TESTS =
22+CLEANFILES =
23+bin_PROGRAMS =
24+noinst_HEADERS =
25+lib_LTLIBRARIES =
26+noinst_LTLIBRARIES =
27+noinst_PROGRAMS =
28+pkginclude_HEADERS =
29+nobase_pkginclude_HEADERS =
30+EXTRA_HEADERS =
31+BUILT_SOURCES=
32+EXTRA_DIST = README.FIRST
33+
34+SUBDIRS = docs libhashkit
35+
36+include libmemcached/include.am
37+include clients/include.am
38+include tests/include.am
39+include example/include.am
40+include support/include.am
41
42 check-local: test-no-outputdiff
43
44-test: all
45- @(cd tests; ${MAKE} test)
46-
47-test-extended: all
48- @(cd tests; ${MAKE} test-extended)
49-
50-valgrind: all
51- @(cd tests; ${MAKE} valgrind)
52-
53-test-no-outputdiff:
54- @(cd tests; ${MAKE} test-no-outputdiff)
55
56 fedora:
57 rm -f ~/rpmbuild/RPMS/x86_64/libmemcached-$(VERSION)*.rpm
58 rm -f ~/rpmbuild/SRPMS/libmemcached-$(VERSION)*.rpm
59- cp libmemcached-$(VERSION).tar.gz /home/brian/rpmbuild/SOURCES/
60+ cp libmemcached-$(VERSION).tar.gz ~/rpmbuild/SOURCES/
61 rpmbuild -ba support/libmemcached.spec
62 cp ~/rpmbuild/RPMS/x86_64/libmemcached-$(VERSION)*.rpm .
63 cp ~/rpmbuild/SRPMS/libmemcached-$(VERSION)*.rpm .
64@@ -28,7 +38,7 @@
65 generic:
66 rm -f ~/rpmbuild/RPMS/x86_64/libmemcached-$(VERSION)*.rpm
67 rm -f ~/rpmbuild/SRPMS/libmemcached-$(VERSION)*.rpm
68- cp libmemcached-$(VERSION).tar.gz /home/brian/rpmbuild/SOURCES/
69+ cp libmemcached-$(VERSION).tar.gz ~/rpmbuild/SOURCES/
70 rpmbuild -ba support/libmemcached.spec
71 cp ~/rpmbuild/RPMS/x86_64/libmemcached-$(VERSION)*.rpm .
72 cp ~/rpmbuild/SRPMS/libmemcached-$(VERSION)*.rpm .
73@@ -41,5 +51,3 @@
74 find ./ | $(GREP) \~$$ | xargs rm -f
75 bzr unknowns
76
77-hudson-valgrind: all
78- @(cd tests; ${MAKE} hudson-valgrind)
79
80=== renamed file 'clients/Makefile.am' => 'clients/include.am'
81--- clients/Makefile.am 2009-12-16 17:26:45 +0000
82+++ clients/include.am 2009-12-18 01:27:26 +0000
83@@ -1,85 +1,100 @@
84-LDADDS = libutilities.la $(top_builddir)/libmemcached/libmemcached.la
85-
86-bin_PROGRAMS = memcat memdump memcp memstat memrm memflush memerror memcapable
87+# vim:ft=automake
88+# included from Top Level Makefile.am
89+# All paths should be given relative to the root
90+
91+CLIENTS_LDADDS = \
92+ clients/libutilities.la \
93+ libmemcached/libmemcached.la
94+
95+bin_PROGRAMS+= \
96+ clients/memcapable \
97+ clients/memcat \
98+ clients/memcp \
99+ clients/memdump \
100+ clients/memerror \
101+ clients/memflush \
102+ clients/memrm \
103+ clients/memstat
104
105 if HAVE_LIBEVENT
106- bin_PROGRAMS += memslap
107+ bin_PROGRAMS+= clients/memslap
108 endif
109
110-noinst_HEADERS = \
111- client_options.h \
112- execute.h \
113- generator.h \
114- ms_atomic.h \
115- ms_conn.h \
116- ms_memslap.h \
117- ms_setting.h \
118- ms_sigsegv.h \
119- ms_stats.h \
120- ms_task.h \
121- ms_thread.h \
122- utilities.h
123-
124-noinst_LTLIBRARIES= libutilities.la libgenexec.la
125-
126-libutilities_la_SOURCES= utilities.c
127-libgenexec_la_SOURCES= generator.c execute.c
128-
129-memcat_SOURCES = memcat.c
130-memcat_LDADD = $(LDADDS)
131-
132-memcp_SOURCES = memcp.c
133-memcp_LDADD = $(LDADDS)
134-
135-memdump_SOURCES = memdump.c
136-memdump_LDADD = $(LDADDS)
137-
138-memstat_SOURCES = memstat.c
139-memstat_LDADD = $(LDADDS)
140-
141-memrm_SOURCES = memrm.c
142-memrm_LDADD = $(LDADDS)
143-
144-memflush_SOURCES = memflush.c
145-memflush_LDADD = $(LDADDS)
146-
147-memerror_SOURCES = memerror.c
148-memerror_LDADD = $(LDADDS)
149-
150-memslap_SOURCES = \
151- memslap.c \
152- ms_conn.c \
153- ms_setting.c \
154- ms_sigsegv.c \
155- ms_stats.c \
156- ms_task.c \
157- ms_thread.c
158-memslap_LDADD = $(LTLIBEVENT) libgenexec.la $(LDADDS)
159-
160-memcapable_SOURCES = memcapable.c
161+noinst_HEADERS+= \
162+ clients/client_options.h \
163+ clients/execute.h \
164+ clients/generator.h \
165+ clients/ms_atomic.h \
166+ clients/ms_conn.h \
167+ clients/ms_memslap.h \
168+ clients/ms_setting.h \
169+ clients/ms_sigsegv.h \
170+ clients/ms_stats.h \
171+ clients/ms_task.h \
172+ clients/ms_thread.h \
173+ clients/utilities.h
174+
175+noinst_LTLIBRARIES+= clients/libutilities.la
176+clients_libutilities_la_SOURCES= clients/utilities.c
177+
178+noinst_LTLIBRARIES+= clients/libgenexec.la
179+clients_libgenexec_la_SOURCES= clients/generator.c clients/execute.c
180+
181+clients_memcat_SOURCES= clients/memcat.c
182+clients_memcat_LDADD= $(CLIENTS_LDADDS)
183+
184+clients_memcp_SOURCES= clients/memcp.c
185+clients_memcp_LDADD= $(CLIENTS_LDADDS)
186+
187+clients_memdump_SOURCES= clients/memdump.c
188+clients_memdump_LDADD= $(CLIENTS_LDADDS)
189+
190+clients_memstat_SOURCES= clients/memstat.c
191+clients_memstat_LDADD= $(CLIENTS_LDADDS)
192+
193+clients_memrm_SOURCES= clients/memrm.c
194+clients_memrm_LDADD= $(CLIENTS_LDADDS)
195+
196+clients_memflush_SOURCES= clients/memflush.c
197+clients_memflush_LDADD= $(CLIENTS_LDADDS)
198+
199+clients_memerror_SOURCES= clients/memerror.c
200+clients_memerror_LDADD= $(CLIENTS_LDADDS)
201+
202+clients_memslap_SOURCES= \
203+ clients/memslap.c \
204+ clients/ms_conn.c \
205+ clients/ms_setting.c \
206+ clients/ms_sigsegv.c \
207+ clients/ms_stats.c \
208+ clients/ms_task.c \
209+ clients/ms_thread.c
210+clients_memslap_LDADD= $(LTLIBEVENT) clients/libgenexec.la $(CLIENTS_LDADDS)
211+
212+clients_memcapable_SOURCES= clients/memcapable.c
213 if BUILD_BYTEORDER
214-memcapable_LDADD=$(top_builddir)/libmemcached/libbyteorder.la
215+clients_memcapable_LDADD= libmemcached/libbyteorder.la
216 endif
217
218 test-start-server:
219- memflush --servers=localhost
220- memcp --servers=localhost /etc/services
221- memcat --servers=localhost /etc/services
222- memrm --servers=localhost /etc/services
223- memstat --servers=localhost
224- memslap --servers=localhost
225- memslap --servers=localhost --concurrency=10
226- memslap --servers=localhost --concurrency=10 --initial-load=1000
227- memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10
228- memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=get
229- memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=set
230- memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=set --non-blocking
231+ clients/memflush --servers=localhost
232+ clients/memcp --servers=localhost /etc/services
233+ clients/memcat --servers=localhost /etc/services
234+ clients/memrm --servers=localhost /etc/services
235+ clients/memstat --servers=localhost
236+ clients/memslap --servers=localhost
237+ clients/memslap --servers=localhost --concurrency=10
238+ clients/memslap --servers=localhost --concurrency=10 --initial-load=1000
239+ clients/memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10
240+ clients/memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=get
241+ clients/memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=set
242+ clients/memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=set --non-blocking
243
244-valgrind:
245- libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes memslap --servers=localhost
246- libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes memslap --servers=localhost --concurrency=10
247- libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes memslap --servers=localhost --concurrency=10 --initial-load=1000
248- libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10
249- libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=get
250- libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=set
251- libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=set --non-blocking
252+client-valgrind:
253+ libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes clients/memslap --servers=localhost
254+ libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes clients/memslap --servers=localhost --concurrency=10
255+ libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes clients/memslap --servers=localhost --concurrency=10 --initial-load=1000
256+ libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes clients/memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10
257+ libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes clients/memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=get
258+ libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes clients/memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=set
259+ libtool --mode=execute valgrind --leak-check=yes --show-reachable=yes clients/memslap --servers=localhost --concurrency=10 --initial-load=1000 --execute-number=10 --test=set --non-blocking
260
261=== modified file 'configure.ac'
262--- configure.ac 2009-12-16 20:17:21 +0000
263+++ configure.ac 2009-12-18 01:27:26 +0000
264@@ -14,6 +14,9 @@
265
266 PANDORA_CANONICAL_TARGET
267
268+HASHKIT_LIBRARY_VERSION=0:0:0
269+AC_SUBST(HASHKIT_LIBRARY_VERSION)
270+
271 AC_SEARCH_LIBS(getopt_long, gnugetopt)
272 AC_SEARCH_LIBS(gethostbyname, nsl)
273
274@@ -46,13 +49,9 @@
275
276 AC_CONFIG_FILES([
277 Makefile
278- clients/Makefile
279- tests/Makefile
280 docs/Makefile
281- example/Makefile
282- libmemcached/Makefile
283 libmemcached/memcached_configure.h
284- support/Makefile
285+ libhashkit/Makefile
286 support/libmemcached.pc
287 support/libmemcached.spec
288 support/libmemcached-fc.spec
289
290=== renamed file 'example/Makefile.am' => 'example/include.am'
291--- example/Makefile.am 2009-10-05 22:32:26 +0000
292+++ example/include.am 2009-12-18 01:27:26 +0000
293@@ -1,20 +1,24 @@
294-noinst_PROGRAMS = memcached_light
295-
296-memcached_light_SOURCES= memcached_light.c \
297- memcached_light.h \
298- storage.h \
299- interface_v0.c \
300- interface_v1.c
301-memcached_light_LDADD= $(top_builddir)/libmemcached/libmemcachedprotocol.la $(LIBINNODB)
302-memcached_light_DEPENDENCIES= $(top_builddir)/libmemcached/libmemcachedprotocol.la
303+# vim:ft=automake
304+# included from Top Level Makefile.am
305+# All paths should be given relative to the root
306+
307+noinst_PROGRAMS += example/memcached_light
308+
309+example_memcached_light_SOURCES= \
310+ example/interface_v0.c \
311+ example/interface_v1.c \
312+ example/memcached_light.c \
313+ example/memcached_light.h \
314+ example/storage.h
315+
316+example_memcached_light_LDADD= libmemcached/libmemcachedprotocol.la $(LIBINNODB)
317
318 if BUILD_BYTEORDER
319-memcached_light_LDADD+= $(top_builddir)/libmemcached/libbyteorder.la
320-memcached_light_DEPENDENCIES+= $(top_builddir)/libmemcached/libbyteorder.la
321+example_memcached_light_LDADD+= libmemcached/libbyteorder.la
322 endif
323
324 if HAVE_LIBINNODB
325-memcached_light_SOURCES+= storage_innodb.c
326+example_memcached_light_SOURCES+= example/storage_innodb.c
327 else
328-memcached_light_SOURCES+= storage.c
329+example_memcached_light_SOURCES+= example/storage.c
330 endif
331
332=== added directory 'libhashkit'
333=== added file 'libhashkit/Makefile.am'
334--- libhashkit/Makefile.am 1970-01-01 00:00:00 +0000
335+++ libhashkit/Makefile.am 2009-12-18 01:27:26 +0000
336@@ -0,0 +1,45 @@
337+# HashKit
338+# Copyright (C) 2009 Brian Aker
339+# All rights reserved.
340+#
341+# Use and distribution licensed under the BSD license. See
342+# the COPYING file in the parent directory for full text.
343+
344+lib_LTLIBRARIES= libhashkit.la
345+
346+libhashkitincludedir= ${includedir}/libhashkit
347+
348+dist_libhashkitinclude_HEADERS= \
349+ algorithm.h \
350+ behavior.h \
351+ hashkit.h \
352+ strerror.h \
353+ types.h \
354+ visibility.h
355+
356+noinst_HEADERS= \
357+ common.h
358+
359+libhashkit_la_SOURCES= \
360+ crc32.c \
361+ behavior.c \
362+ default.c \
363+ fnv.c \
364+ hashkit.c \
365+ jenkins.c \
366+ ketama.c \
367+ md5.c \
368+ murmur.c \
369+ strerror.c
370+
371+if INCLUDE_HSIEH_SRC
372+libhashkit_la_SOURCES+= hsieh.c
373+endif
374+
375+libhashkit_la_CFLAGS= \
376+ ${AM_CFLAGS} \
377+ -DBUILDING_HASHKIT
378+
379+libhashkit_la_LDFLAGS= \
380+ $(LIBM) \
381+ -version-info $(HASHKIT_LIBRARY_VERSION)
382
383=== added file 'libhashkit/algorithm.h'
384--- libhashkit/algorithm.h 1970-01-01 00:00:00 +0000
385+++ libhashkit/algorithm.h 2009-12-18 01:27:26 +0000
386@@ -0,0 +1,49 @@
387+/* HashKit
388+ * Copyright (C) 2009 Brian Aker
389+ * All rights reserved.
390+ *
391+ * Use and distribution licensed under the BSD license. See
392+ * the COPYING file in the parent directory for full text.
393+ */
394+
395+/**
396+ * @file
397+ * @brief HashKit Header
398+ */
399+
400+#ifndef HASHKIT_ALGORITHM_H
401+#define HASHKIT_ALGORITHM_H
402+
403+#ifdef __cplusplus
404+extern "C" {
405+#endif
406+
407+HASHKIT_API
408+uint32_t hashkit_default(const char *key, size_t key_length);
409+HASHKIT_API
410+uint32_t hashkit_fnv1_64(const char *key, size_t key_length);
411+HASHKIT_API
412+uint32_t hashkit_fnv1a_64(const char *key, size_t key_length);
413+HASHKIT_API
414+uint32_t hashkit_fnv1_32(const char *key, size_t key_length);
415+HASHKIT_API
416+uint32_t hashkit_fnv1a_32(const char *key, size_t key_length);
417+HASHKIT_API
418+uint32_t hashkit_crc32(const char *key, size_t key_length);
419+HASHKIT_API
420+#ifdef HAVE_HSIEH_HASH
421+HASHKIT_API
422+uint32_t hashkit_hsieh(const char *key, size_t key_length);
423+#endif
424+HASHKIT_API
425+uint32_t hashkit_murmur(const char *key, size_t key_length);
426+HASHKIT_API
427+uint32_t hashkit_jenkins(const char *key, size_t key_length);
428+HASHKIT_API
429+uint32_t hashkit_md5(const char *key, size_t key_length);
430+
431+#ifdef __cplusplus
432+}
433+#endif
434+
435+#endif /* HASHKIT_ALGORITHM_H */
436
437=== added file 'libhashkit/behavior.c'
438--- libhashkit/behavior.c 1970-01-01 00:00:00 +0000
439+++ libhashkit/behavior.c 2009-12-18 01:27:26 +0000
440@@ -0,0 +1,147 @@
441+/* HashKit
442+ * Copyright (C) 2009 Brian Aker
443+ * All rights reserved.
444+ *
445+ * Use and distribution licensed under the BSD license. See
446+ * the COPYING file in the parent directory for full text.
447+ */
448+
449+#include "common.h"
450+
451+static hashkit_fn *fetch_hash_fn(hashkit_hash_algorithm_t hash_algorithm)
452+{
453+ switch (hash_algorithm)
454+ {
455+ case HASHKIT_HASH_DEFAULT:
456+ return hashkit_default;
457+ case HASHKIT_HASH_MD5:
458+ return hashkit_md5;
459+ case HASHKIT_HASH_CRC:
460+ return hashkit_crc32;
461+ case HASHKIT_HASH_FNV1_64:
462+ return hashkit_fnv1_64;
463+ case HASHKIT_HASH_FNV1A_64:
464+ return hashkit_fnv1a_64;
465+ case HASHKIT_HASH_FNV1_32:
466+ return hashkit_fnv1_32;
467+ case HASHKIT_HASH_FNV1A_32:
468+ return hashkit_fnv1a_32;
469+ case HASHKIT_HASH_HSIEH:
470+#ifdef HAVE_HSIEH_HASH
471+ return hashkit_hsieh;
472+#else
473+ return NULL;
474+#endif
475+ case HASHKIT_HASH_MURMUR:
476+ return hashkit_murmur;
477+ case HASHKIT_HASH_JENKINS:
478+ return hashkit_jenkins;
479+ case HASHKIT_HASH_MAX:
480+ default:
481+#ifdef HAVE_DEBUG
482+ fprintf(stderr, "hashkit_hash_t was extended but hashkit_generate_value was not updated\n");
483+ fflush(stderr);
484+ assert(0);
485+#endif
486+ break;
487+ }
488+
489+ return NULL;
490+}
491+
492+hashkit_return_t hashkit_behavior_set_distribution(hashkit_st *hashkit, hashkit_distribution_t distribution)
493+{
494+ hashkit->distribution= distribution;
495+
496+ return HASHKIT_SUCCESS;
497+}
498+
499+
500+hashkit_distribution_t hashkit_behavior_get_distribution(hashkit_st *hashkit)
501+{
502+ return hashkit->distribution;
503+}
504+
505+
506+/**
507+ @note For the moment we will not allow the user to set the distribution hash type.
508+*/
509+hashkit_return_t hashkit_behavior_set_key_hash_algorithm(hashkit_st *hashkit, hashkit_hash_algorithm_t hash_algorithm)
510+{
511+ hashkit_fn *hash_fn= fetch_hash_fn(hash_algorithm);
512+
513+ if (hash_fn == NULL)
514+ return HASHKIT_FAILURE;
515+
516+ hashkit->hash_fn= hash_fn;
517+ hashkit->for_key= hash_algorithm;
518+ hashkit->for_distribution= hash_algorithm;
519+
520+ return HASHKIT_SUCCESS;
521+}
522+
523+
524+hashkit_hash_algorithm_t hashkit_behavior_get_key_hash_algorithm(hashkit_st *hashkit)
525+{
526+ return hashkit->for_key;
527+}
528+
529+
530+void hashkit_behavior_set_active_fn(hashkit_st *hashkit, hashkit_active_fn *function)
531+{
532+ hashkit->active_fn= function;
533+}
534+
535+
536+hashkit_active_fn * hashkit_behavior_get_active_fn(hashkit_st *hashkit)
537+{
538+ return hashkit->active_fn;
539+}
540+
541+
542+void hashkit_behavior_set_continuum_hash_fn(hashkit_st *hashkit, hashkit_fn *function)
543+{
544+ hashkit->continuum_hash_fn= function;
545+}
546+
547+
548+hashkit_fn * hashkit_behavior_get_continuum_hash_fn(hashkit_st *hashkit)
549+{
550+ return hashkit->continuum_hash_fn;
551+}
552+
553+
554+void hashkit_behavior_set_continuum_key_fn(hashkit_st *hashkit, hashkit_key_fn *function)
555+{
556+ hashkit->continuum_key_fn= function;
557+}
558+
559+
560+hashkit_key_fn * hashkit_behavior_get_continuum_key_fn(hashkit_st *hashkit)
561+{
562+ return hashkit->continuum_key_fn;
563+}
564+
565+
566+void hashkit_behavior_set_sort_fn(hashkit_st *hashkit, hashkit_sort_fn *function)
567+{
568+ hashkit->sort_fn= function;
569+}
570+
571+
572+hashkit_sort_fn * hashkit_behavior_get_sort_fn(hashkit_st *hashkit)
573+{
574+ return hashkit->sort_fn;
575+}
576+
577+
578+void hashkit_behavior_set_weight_fn(hashkit_st *hashkit, hashkit_weight_fn *function)
579+{
580+ hashkit->weight_fn= function;
581+}
582+
583+
584+hashkit_weight_fn * hashkit_behavior_get_weight_fn(hashkit_st *hashkit)
585+{
586+ return hashkit->weight_fn;
587+}
588
589=== added file 'libhashkit/behavior.h'
590--- libhashkit/behavior.h 1970-01-01 00:00:00 +0000
591+++ libhashkit/behavior.h 2009-12-18 01:27:26 +0000
592@@ -0,0 +1,68 @@
593+/* HashKit
594+ * Copyright (C) 2009 Brian Aker
595+ * All rights reserved.
596+ *
597+ * Use and distribution licensed under the BSD license. See
598+ * the COPYING file in the parent directory for full text.
599+ */
600+
601+/**
602+ * @file
603+ * @brief HashKit Header
604+ */
605+
606+#ifndef HASHKIT_BEHAVIOR_H
607+#define HASHKIT_BEHAVIORH
608+
609+#ifdef __cplusplus
610+extern "C" {
611+#endif
612+
613+
614+HASHKIT_API
615+hashkit_return_t hashkit_behavior_set_distribution(hashkit_st *hashkit, hashkit_distribution_t distribution);
616+
617+HASHKIT_API
618+hashkit_distribution_t hashkit_behavior_get_distribution(hashkit_st *hashkit);
619+
620+HASHKIT_API
621+hashkit_return_t hashkit_behavior_set_key_hash_algorithm(hashkit_st *hashkit, hashkit_hash_algorithm_t hash_algorithm);
622+
623+HASHKIT_API
624+hashkit_hash_algorithm_t hashkit_behavior_get_key_hash_algorithm(hashkit_st *hashkit);
625+
626+HASHKIT_API
627+void hashkit_behavior_set_active_fn(hashkit_st *hash, hashkit_active_fn *function);
628+
629+HASHKIT_API
630+hashkit_active_fn * hashkit_behavior_get_active_fn(hashkit_st *hash);
631+
632+HASHKIT_API
633+void hashkit_behavior_set_continuum_hash_fn(hashkit_st *hash, hashkit_fn *function);
634+
635+HASHKIT_API
636+hashkit_fn * hashkit_behavior_get_continuum_hash_fn(hashkit_st *hash);
637+
638+HASHKIT_API
639+void hashkit_behavior_set_continuum_key_fn(hashkit_st *hash, hashkit_key_fn *function);
640+
641+HASHKIT_API
642+hashkit_key_fn * hashkit_behavior_get_continuum_key_fn(hashkit_st *hash);
643+
644+HASHKIT_API
645+void hashkit_behavior_set_sort_fn(hashkit_st *hash, hashkit_sort_fn *function);
646+
647+HASHKIT_API
648+hashkit_sort_fn * hashkit_behavior_get_sort_fn(hashkit_st *hash);
649+
650+HASHKIT_API
651+void hashkit_behavior_set_weight_fn(hashkit_st *hash, hashkit_weight_fn *function);
652+
653+HASHKIT_API
654+hashkit_weight_fn * hashkit_behavior_get_weight_fn(hashkit_st *hash);
655+
656+#ifdef __cplusplus
657+}
658+#endif
659+
660+#endif /* HASHKIT_BEHAVIOR_H */
661
662=== added file 'libhashkit/common.h'
663--- libhashkit/common.h 1970-01-01 00:00:00 +0000
664+++ libhashkit/common.h 2009-12-18 01:27:26 +0000
665@@ -0,0 +1,33 @@
666+/* HashKit
667+ * Copyright (C) 2009 Brian Aker
668+ * All rights reserved.
669+ *
670+ * Use and distribution licensed under the BSD license. See
671+ * the COPYING file in the parent directory for full text.
672+ */
673+
674+/**
675+ * @file
676+ * @brief System Include Files
677+ */
678+
679+#ifndef HASHKIT_COMMON_H
680+#define HASHKIT_COMMON_H
681+
682+#include "config.h"
683+
684+#include <assert.h>
685+#include <errno.h>
686+#include <stdio.h>
687+#include <stdlib.h>
688+#include <math.h>
689+
690+#include "hashkit.h"
691+
692+HASHKIT_LOCAL
693+void md5_signature(const unsigned char *key, unsigned int length, unsigned char *result);
694+
695+HASHKIT_LOCAL
696+int update_continuum(hashkit_st *hashkit);
697+
698+#endif /* HASHKIT_COMMON_H */
699
700=== added file 'libhashkit/crc32.c'
701--- libhashkit/crc32.c 1970-01-01 00:00:00 +0000
702+++ libhashkit/crc32.c 2009-12-18 01:27:26 +0000
703@@ -0,0 +1,85 @@
704+/* The crc32 functions and data was originally written by Spencer
705+ * Garrett <srg@quick.com> and was gleaned from the PostgreSQL source
706+ * tree via the files contrib/ltree/crc32.[ch] and from FreeBSD at
707+ * src/usr.bin/cksum/crc32.c.
708+ */
709+
710+#include "common.h"
711+
712+static const uint32_t crc32tab[256] = {
713+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
714+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
715+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
716+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
717+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
718+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
719+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
720+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
721+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
722+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
723+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
724+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
725+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
726+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
727+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
728+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
729+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
730+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
731+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
732+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
733+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
734+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
735+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
736+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
737+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
738+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
739+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
740+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
741+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
742+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
743+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
744+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
745+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
746+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
747+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
748+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
749+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
750+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
751+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
752+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
753+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
754+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
755+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
756+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
757+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
758+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
759+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
760+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
761+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
762+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
763+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
764+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
765+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
766+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
767+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
768+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
769+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
770+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
771+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
772+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
773+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
774+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
775+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
776+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
777+};
778+
779+uint32_t hashkit_crc32(const char *key, size_t key_length)
780+{
781+ uint64_t x;
782+ uint32_t crc= UINT32_MAX;
783+
784+ for (x= 0; x < key_length; x++)
785+ crc= (crc >> 8) ^ crc32tab[(crc ^ (uint64_t)key[x]) & 0xff];
786+
787+ return ((~crc) >> 16) & 0x7fff;
788+}
789
790=== added file 'libhashkit/default.c'
791--- libhashkit/default.c 1970-01-01 00:00:00 +0000
792+++ libhashkit/default.c 2009-12-18 01:27:26 +0000
793@@ -0,0 +1,28 @@
794+/* HashKit
795+ * Copyright (C) 2009 Brian Aker
796+ * All rights reserved.
797+ *
798+ * Use and distribution licensed under the BSD license. See
799+ * the COPYING file in the parent directory for full text.
800+ */
801+
802+#include "common.h"
803+
804+uint32_t hashkit_default(const char *key, size_t key_length)
805+{
806+ const char *ptr= key;
807+ uint32_t value= 0;
808+
809+ while (key_length--)
810+ {
811+ uint32_t val= (uint32_t) *ptr++;
812+ value += val;
813+ value += (value << 10);
814+ value ^= (value >> 6);
815+ }
816+ value += (value << 3);
817+ value ^= (value >> 11);
818+ value += (value << 15);
819+
820+ return value;
821+}
822
823=== added file 'libhashkit/fnv.c'
824--- libhashkit/fnv.c 1970-01-01 00:00:00 +0000
825+++ libhashkit/fnv.c 2009-12-18 01:27:26 +0000
826@@ -0,0 +1,75 @@
827+/* HashKit
828+ * Copyright (C) 2009 Brian Aker
829+ * All rights reserved.
830+ *
831+ * Use and distribution licensed under the BSD license. See
832+ * the COPYING file in the parent directory for full text.
833+ */
834+
835+#include "common.h"
836+
837+/* FNV hash'es lifted from Dustin Sallings work */
838+static uint64_t FNV_64_INIT= UINT64_C(0xcbf29ce484222325);
839+static uint64_t FNV_64_PRIME= UINT64_C(0x100000001b3);
840+static uint32_t FNV_32_INIT= 2166136261UL;
841+static uint32_t FNV_32_PRIME= 16777619;
842+
843+uint32_t hashkit_fnv1_64(const char *key, size_t key_length)
844+{
845+ /* Thanks to pierre@demartines.com for the pointer */
846+ uint64_t hash= FNV_64_INIT;
847+ size_t x= 0;
848+
849+ for (x= 0; x < key_length; x++)
850+ {
851+ hash *= FNV_64_PRIME;
852+ hash ^= (uint64_t)key[x];
853+ }
854+
855+ return (uint32_t)hash;
856+}
857+
858+uint32_t hashkit_fnv1a_64(const char *key, size_t key_length)
859+{
860+ uint32_t hash= (uint32_t) FNV_64_INIT;
861+ size_t x= 0;
862+
863+ for (x= 0; x < key_length; x++)
864+ {
865+ uint32_t val= (uint32_t)key[x];
866+ hash ^= val;
867+ hash *= (uint32_t) FNV_64_PRIME;
868+ }
869+
870+ return hash;
871+}
872+
873+uint32_t hashkit_fnv1_32(const char *key, size_t key_length)
874+{
875+ uint32_t hash= FNV_32_INIT;
876+ size_t x= 0;
877+
878+ for (x= 0; x < key_length; x++)
879+ {
880+ uint32_t val= (uint32_t)key[x];
881+ hash *= FNV_32_PRIME;
882+ hash ^= val;
883+ }
884+
885+ return hash;
886+}
887+
888+uint32_t hashkit_fnv1a_32(const char *key, size_t key_length)
889+{
890+ uint32_t hash= FNV_32_INIT;
891+ size_t x= 0;
892+
893+ for (x= 0; x < key_length; x++)
894+ {
895+ uint32_t val= (uint32_t)key[x];
896+ hash ^= val;
897+ hash *= FNV_32_PRIME;
898+ }
899+
900+ return hash;
901+}
902
903=== added file 'libhashkit/hashkit.c'
904--- libhashkit/hashkit.c 1970-01-01 00:00:00 +0000
905+++ libhashkit/hashkit.c 2009-12-18 01:27:26 +0000
906@@ -0,0 +1,252 @@
907+/* HashKit
908+ * Copyright (C) 2006-2009 Brian Aker
909+ * All rights reserved.
910+ *
911+ * Use and distribution licensed under the BSD license. See
912+ * the COPYING file in the parent directory for full text.
913+ */
914+
915+#include "common.h"
916+
917+inline static bool _is_allocated(const hashkit_st *hashk)
918+{
919+ return hashk->options.is_allocated == true;
920+}
921+
922+inline static bool _is_initialized(const hashkit_st *hashk)
923+{
924+ return hashk->options.is_initialized == true;
925+}
926+
927+/**
928+ @note We make no assumptions that "hashk" has been, or not been allocated from heap/stack. We just know we didn't do it.
929+*/
930+hashkit_st *hashkit_create(hashkit_st *hashk)
931+{
932+ if (hashk == NULL)
933+ {
934+ hashk= (hashkit_st *)malloc(sizeof(hashkit_st));
935+ if (hashk == NULL)
936+ {
937+ return NULL;
938+ }
939+
940+ hashk->options.is_allocated= true;
941+ }
942+ else
943+ {
944+ hashk->options.is_allocated= false;
945+ }
946+
947+ hashk->options.is_initialized= true;
948+
949+ hashk->distribution= HASHKIT_DISTRIBUTION_MODULA;
950+ hashk->continuum_count= 0;
951+ hashk->continuum_points_count= 0;
952+ hashk->list_size= 0;
953+ hashk->context_size= 0;
954+ hashk->continuum= NULL;
955+ hashk->hash_fn= NULL;
956+ hashk->active_fn= NULL;
957+ hashk->continuum_hash_fn= NULL;
958+ hashk->continuum_key_fn= NULL;
959+ hashk->sort_fn= NULL;
960+ hashk->weight_fn= NULL;
961+ hashk->list= NULL;
962+
963+ return hashk;
964+}
965+
966+
967+void hashkit_free(hashkit_st *hashk)
968+{
969+ assert(_is_initialized(hashk) == true);
970+
971+ if (hashk->continuum != NULL)
972+ {
973+ free(hashk->continuum);
974+ }
975+
976+ /**
977+ We don't know if hashk is pointing to something else,
978+ so we go on and set is_initialized.
979+ */
980+ hashk->options.is_initialized= false;
981+
982+ if (_is_allocated(hashk))
983+ {
984+ free(hashk);
985+ }
986+}
987+
988+/**
989+ @note We do assume source is valid. If source does not exist, we allocate.
990+*/
991+hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source)
992+{
993+ hashkit_st *new_clone;
994+
995+ if (source == NULL)
996+ {
997+ return hashkit_create(destination);
998+ }
999+ else
1000+ {
1001+ assert(_is_initialized(source) == true);
1002+ }
1003+
1004+ /* new_clone will be a pointer to destination */
1005+ new_clone= hashkit_create(destination);
1006+ assert((destination ? ((_is_allocated(new_clone) == false)) : (_is_allocated(new_clone) == true)));
1007+
1008+ // Should only happen on allocation failure.
1009+ if (new_clone == NULL)
1010+ {
1011+ return NULL;
1012+ }
1013+
1014+ // For the moment we will not clone this.
1015+ new_clone->continuum= NULL;
1016+
1017+ new_clone->distribution= source->distribution;
1018+ new_clone->continuum_count= source->continuum_count;
1019+ new_clone->continuum_points_count= source->continuum_points_count;
1020+ new_clone->list_size= source->list_size;
1021+ new_clone->context_size= source->context_size;
1022+
1023+
1024+ new_clone->hash_fn= source->hash_fn;
1025+ new_clone->active_fn= source->active_fn;
1026+ new_clone->continuum_hash_fn= source->continuum_hash_fn;
1027+ new_clone->continuum_key_fn= source->continuum_key_fn;
1028+ new_clone->sort_fn= source->sort_fn;
1029+ new_clone->weight_fn= source->weight_fn;
1030+ new_clone->list= source->list;
1031+
1032+ return new_clone;
1033+}
1034+
1035+
1036+#if 0
1037+void hashkit_set_list(hashkit_st *hashkit, void *list, size_t list_size, size_t context_size)
1038+{
1039+ hashkit->list= list;
1040+ hashkit->list_size= list_size;
1041+ hashkit->context_size= context_size;
1042+}
1043+
1044+
1045+uint32_t hashkit_value(hashkit_st *hashkit, const char *key, size_t key_length)
1046+{
1047+ if (hashkit->hash_fn == NULL)
1048+ return hashkit_default(key, key_length);
1049+
1050+ return hashkit->hash_fn(key, key_length);
1051+}
1052+
1053+
1054+uint32_t hashkit_index(hashkit_st *hashkit, uint32_t hash_value)
1055+{
1056+ if (hashkit->list_size == 1)
1057+ return 0;
1058+
1059+ switch (hashkit->distribution)
1060+ {
1061+ case HASHKIT_DISTRIBUTION_MODULA:
1062+ return hash_value % (uint32_t)hashkit->list_size;
1063+
1064+ case HASHKIT_DISTRIBUTION_RANDOM:
1065+ return (uint32_t)random() % (uint32_t)hashkit->list_size;
1066+
1067+ case HASHKIT_DISTRIBUTION_KETAMA:
1068+ {
1069+ hashkit_continuum_point_st *begin, *end, *left, *right, *middle;
1070+ begin= left= hashkit->continuum;
1071+ end= right= hashkit->continuum + hashkit->continuum_points_count;
1072+
1073+ while (left < right)
1074+ {
1075+ middle= left + (right - left) / 2;
1076+ if (middle->value < hash_value)
1077+ left= middle + 1;
1078+ else
1079+ right= middle;
1080+ }
1081+ if (right == end)
1082+ right= begin;
1083+ return right->index;
1084+ }
1085+
1086+ case HASHKIT_DISTRIBUTION_MAX:
1087+ default:
1088+ /* We have added a distribution without extending the logic */
1089+ return hash_value % (uint32_t)hashkit->list_size;
1090+ }
1091+
1092+ /* NOTREACHED */
1093+}
1094+
1095+
1096+int hashkit_run_distribution(hashkit_st *hashkit)
1097+{
1098+ switch (hashkit->distribution)
1099+ {
1100+ case HASHKIT_DISTRIBUTION_MODULA:
1101+ if (hashkit->sort_fn != NULL && hashkit->list_size > 1)
1102+ hashkit->sort_fn(hashkit->list, hashkit->list_size);
1103+ break;
1104+ case HASHKIT_DISTRIBUTION_RANDOM:
1105+ break;
1106+ case HASHKIT_DISTRIBUTION_KETAMA:
1107+ return update_continuum(hashkit);
1108+ case HASHKIT_DISTRIBUTION_MAX:
1109+ default:
1110+ /* We have added a distribution without extending the logic */
1111+ break;
1112+ }
1113+
1114+ return 0;
1115+}
1116+#endif
1117+
1118+
1119+uint32_t hashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm)
1120+{
1121+ switch (hash_algorithm)
1122+ {
1123+ case HASHKIT_HASH_DEFAULT:
1124+ return hashkit_default(key, key_length);
1125+ case HASHKIT_HASH_MD5:
1126+ return hashkit_md5(key, key_length);
1127+ case HASHKIT_HASH_CRC:
1128+ return hashkit_crc32(key, key_length);
1129+ case HASHKIT_HASH_FNV1_64:
1130+ return hashkit_fnv1_64(key, key_length);
1131+ case HASHKIT_HASH_FNV1A_64:
1132+ return hashkit_fnv1a_64(key, key_length);
1133+ case HASHKIT_HASH_FNV1_32:
1134+ return hashkit_fnv1_32(key, key_length);
1135+ case HASHKIT_HASH_FNV1A_32:
1136+ return hashkit_fnv1a_32(key, key_length);
1137+ case HASHKIT_HASH_HSIEH:
1138+#ifdef HAVE_HSIEH_HASH
1139+ return hashkit_hsieh(key, key_length);
1140+#else
1141+ return 1;
1142+#endif
1143+ case HASHKIT_HASH_MURMUR:
1144+ return hashkit_murmur(key, key_length);
1145+ case HASHKIT_HASH_JENKINS:
1146+ return hashkit_jenkins(key, key_length);
1147+ case HASHKIT_HASH_MAX:
1148+ default:
1149+#ifdef HAVE_DEBUG
1150+ fprintf(stderr, "hashkit_hash_t was extended but hashkit_generate_value was not updated\n");
1151+ fflush(stderr);
1152+ assert(0);
1153+#endif
1154+ break;
1155+ }
1156+
1157+ return 1;
1158+}
1159
1160=== added file 'libhashkit/hashkit.h'
1161--- libhashkit/hashkit.h 1970-01-01 00:00:00 +0000
1162+++ libhashkit/hashkit.h 2009-12-18 01:27:26 +0000
1163@@ -0,0 +1,112 @@
1164+/* HashKit
1165+ * Copyright (C) 2009 Brian Aker
1166+ * All rights reserved.
1167+ *
1168+ * Use and distribution licensed under the BSD license. See
1169+ * the COPYING file in the parent directory for full text.
1170+ */
1171+
1172+/**
1173+ * @file
1174+ * @brief HashKit Header
1175+ */
1176+
1177+#ifndef HASHKIT_H
1178+#define HASHKIT_H
1179+
1180+#if !defined(__cplusplus)
1181+# include <stdbool.h>
1182+#endif
1183+#include <inttypes.h>
1184+#include <sys/types.h>
1185+#include <libhashkit/visibility.h>
1186+#include <libhashkit/types.h>
1187+#include <libhashkit/algorithm.h>
1188+#include <libhashkit/behavior.h>
1189+#include <libhashkit/strerror.h>
1190+
1191+#ifdef __cplusplus
1192+extern "C" {
1193+#endif
1194+
1195+/**
1196+ * @addtogroup hashkit_constants Constants
1197+ * @ingroup hashkit
1198+ * @{
1199+ */
1200+
1201+/* Defines. */
1202+#define HASHKIT_MAX_KEY 251
1203+#define HASHKIT_POINTS_PER_NODE 100
1204+#define HASHKIT_POINTS_PER_NODE_WEIGHTED 160
1205+#define HASHKIT_CONTINUUM_ADDITION 10
1206+#define HASHKIT_CONTINUUM_KEY_SIZE 86
1207+
1208+/** @} */
1209+
1210+/**
1211+ * @ingroup hashkit
1212+ */
1213+struct hashkit_st
1214+{
1215+ hashkit_options_st options;
1216+ hashkit_distribution_t distribution;
1217+ uint32_t continuum_count;
1218+ uint32_t continuum_points_count;
1219+ size_t list_size;
1220+ size_t context_size;
1221+
1222+ /**
1223+ @note There are two places we use hashing, one is for when we have a key
1224+ and we want to find out what server it should be placed on. The second is
1225+ for when we are placing a value into the continuum.
1226+ */
1227+ hashkit_hash_algorithm_t for_key;
1228+ hashkit_hash_algorithm_t for_distribution;
1229+
1230+ hashkit_continuum_point_st *continuum;
1231+ hashkit_fn *hash_fn;
1232+ hashkit_active_fn *active_fn;
1233+ hashkit_fn *continuum_hash_fn;
1234+ hashkit_key_fn *continuum_key_fn;
1235+ hashkit_sort_fn *sort_fn;
1236+ hashkit_weight_fn *weight_fn;
1237+ void *list;
1238+};
1239+
1240+/**
1241+ * @ingroup hashkit
1242+ */
1243+struct hashkit_continuum_point_st
1244+{
1245+ uint32_t index;
1246+ uint32_t value;
1247+};
1248+
1249+/**
1250+ * @addtogroup hashkit Pandora Hash Declarations
1251+ * @{
1252+ */
1253+
1254+HASHKIT_API
1255+hashkit_st *hashkit_create(hashkit_st *hash);
1256+
1257+HASHKIT_API
1258+hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *ptr);
1259+
1260+HASHKIT_API
1261+void hashkit_free(hashkit_st *hash);
1262+
1263+HASHKIT_API
1264+uint32_t hashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm);
1265+
1266+#define hashkit_is_allocated(__object) ((__object)->options.is_allocated)
1267+#define hashkit_is_initialized(__object) ((__object)->options.is_initialized)
1268+
1269+/** @} */
1270+
1271+#ifdef __cplusplus
1272+}
1273+#endif
1274+
1275+#endif /* HASHKIT_H */
1276
1277=== added file 'libhashkit/hsieh.c'
1278--- libhashkit/hsieh.c 1970-01-01 00:00:00 +0000
1279+++ libhashkit/hsieh.c 2009-12-18 01:27:26 +0000
1280@@ -0,0 +1,68 @@
1281+/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh
1282+ * derivative license.
1283+ * See: http://www.azillionmonkeys.com/qed/weblicense.html for license
1284+ * details.
1285+ * http://www.azillionmonkeys.com/qed/hash.html
1286+*/
1287+
1288+#include "hash_common.h"
1289+
1290+#undef get16bits
1291+#if (defined(__GNUC__) && defined(__i386__))
1292+#define get16bits(d) (*((const uint16_t *) (d)))
1293+#endif
1294+
1295+#if !defined (get16bits)
1296+#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
1297+ +(uint32_t)(((const uint8_t *)(d))[0]) )
1298+#endif
1299+
1300+uint32_t hashkit_hsieh(const char *key, size_t key_length)
1301+{
1302+ uint32_t hash = 0, tmp;
1303+ int rem;
1304+
1305+ if (key_length <= 0 || key == NULL)
1306+ return 0;
1307+
1308+ rem = key_length & 3;
1309+ key_length >>= 2;
1310+
1311+ /* Main loop */
1312+ for (;key_length > 0; key_length--)
1313+ {
1314+ hash += get16bits (key);
1315+ tmp = (get16bits (key+2) << 11) ^ hash;
1316+ hash = (hash << 16) ^ tmp;
1317+ key += 2*sizeof (uint16_t);
1318+ hash += hash >> 11;
1319+ }
1320+
1321+ /* Handle end cases */
1322+ switch (rem)
1323+ {
1324+ case 3: hash += get16bits (key);
1325+ hash ^= hash << 16;
1326+ hash ^= key[sizeof (uint16_t)] << 18;
1327+ hash += hash >> 11;
1328+ break;
1329+ case 2: hash += get16bits (key);
1330+ hash ^= hash << 11;
1331+ hash += hash >> 17;
1332+ break;
1333+ case 1: hash += *key;
1334+ hash ^= hash << 10;
1335+ hash += hash >> 1;
1336+ }
1337+
1338+ /* Force "avalanching" of final 127 bits */
1339+ hash ^= hash << 3;
1340+ hash += hash >> 5;
1341+ hash ^= hash << 4;
1342+ hash += hash >> 17;
1343+ hash ^= hash << 25;
1344+ hash += hash >> 6;
1345+
1346+ return hash;
1347+}
1348+
1349
1350=== added file 'libhashkit/jenkins.c'
1351--- libhashkit/jenkins.c 1970-01-01 00:00:00 +0000
1352+++ libhashkit/jenkins.c 2009-12-18 01:27:26 +0000
1353@@ -0,0 +1,213 @@
1354+/*
1355+*
1356+* By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
1357+* code any way you wish, private, educational, or commercial. It's free.
1358+* Use for hash table lookup, or anything where one collision in 2^^32 is
1359+* acceptable. Do NOT use for cryptographic purposes.
1360+* http://burtleburtle.net/bob/hash/index.html
1361+*
1362+* Modified by Brian Pontz for libmemcached
1363+* TODO:
1364+* Add big endian support
1365+*/
1366+
1367+#include "common.h"
1368+
1369+#define hashsize(n) ((uint32_t)1<<(n))
1370+#define hashmask(n) (hashsize(n)-1)
1371+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
1372+
1373+#define mix(a,b,c) \
1374+{ \
1375+ a -= c; a ^= rot(c, 4); c += b; \
1376+ b -= a; b ^= rot(a, 6); a += c; \
1377+ c -= b; c ^= rot(b, 8); b += a; \
1378+ a -= c; a ^= rot(c,16); c += b; \
1379+ b -= a; b ^= rot(a,19); a += c; \
1380+ c -= b; c ^= rot(b, 4); b += a; \
1381+}
1382+
1383+#define final(a,b,c) \
1384+{ \
1385+ c ^= b; c -= rot(b,14); \
1386+ a ^= c; a -= rot(c,11); \
1387+ b ^= a; b -= rot(a,25); \
1388+ c ^= b; c -= rot(b,16); \
1389+ a ^= c; a -= rot(c,4); \
1390+ b ^= a; b -= rot(a,14); \
1391+ c ^= b; c -= rot(b,24); \
1392+}
1393+
1394+#define JENKINS_INITVAL 13
1395+
1396+/*
1397+jenkins_hash() -- hash a variable-length key into a 32-bit value
1398+ k : the key (the unaligned variable-length array of bytes)
1399+ length : the length of the key, counting by bytes
1400+ initval : can be any 4-byte value
1401+Returns a 32-bit value. Every bit of the key affects every bit of
1402+the return value. Two keys differing by one or two bits will have
1403+totally different hash values.
1404+
1405+The best hash table sizes are powers of 2. There is no need to do
1406+mod a prime (mod is sooo slow!). If you need less than 32 bits,
1407+use a bitmask. For example, if you need only 10 bits, do
1408+ h = (h & hashmask(10));
1409+In which case, the hash table should have hashsize(10) elements.
1410+*/
1411+
1412+uint32_t hashkit_jenkins(const char *key, size_t length)
1413+{
1414+ uint32_t a,b,c; /* internal state */
1415+ union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
1416+
1417+ /* Set up the internal state */
1418+ a = b = c = 0xdeadbeef + ((uint32_t)length) + JENKINS_INITVAL;
1419+
1420+ u.ptr = key;
1421+#ifndef WORDS_BIGENDIAN
1422+ if ((u.i & 0x3) == 0)
1423+ {
1424+ const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
1425+
1426+ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
1427+ while (length > 12)
1428+ {
1429+ a += k[0];
1430+ b += k[1];
1431+ c += k[2];
1432+ mix(a,b,c);
1433+ length -= 12;
1434+ k += 3;
1435+ }
1436+
1437+ /*----------------------------- handle the last (probably partial) block */
1438+ /*
1439+ * "k[2]&0xffffff" actually reads beyond the end of the string, but
1440+ * then masks off the part it's not allowed to read. Because the
1441+ * string is aligned, the masked-off tail is in the same word as the
1442+ * rest of the string. Every machine with memory protection I've seen
1443+ * does it on word boundaries, so is OK with this. But VALGRIND will
1444+ * still catch it and complain. The masking trick does make the hash
1445+ * noticably faster for short strings (like English words).
1446+ */
1447+ switch(length)
1448+ {
1449+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
1450+ case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
1451+ case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
1452+ case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
1453+ case 8 : b+=k[1]; a+=k[0]; break;
1454+ case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
1455+ case 6 : b+=k[1]&0xffff; a+=k[0]; break;
1456+ case 5 : b+=k[1]&0xff; a+=k[0]; break;
1457+ case 4 : a+=k[0]; break;
1458+ case 3 : a+=k[0]&0xffffff; break;
1459+ case 2 : a+=k[0]&0xffff; break;
1460+ case 1 : a+=k[0]&0xff; break;
1461+ case 0 : return c; /* zero length strings require no mixing */
1462+ default: return c;
1463+ }
1464+
1465+ }
1466+ else if ((u.i & 0x1) == 0)
1467+ {
1468+ const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
1469+ const uint8_t *k8;
1470+
1471+ /*--------------- all but last block: aligned reads and different mixing */
1472+ while (length > 12)
1473+ {
1474+ a += k[0] + (((uint32_t)k[1])<<16);
1475+ b += k[2] + (((uint32_t)k[3])<<16);
1476+ c += k[4] + (((uint32_t)k[5])<<16);
1477+ mix(a,b,c);
1478+ length -= 12;
1479+ k += 6;
1480+ }
1481+
1482+ /*----------------------------- handle the last (probably partial) block */
1483+ k8 = (const uint8_t *)k;
1484+ switch(length)
1485+ {
1486+ case 12: c+=k[4]+(((uint32_t)k[5])<<16);
1487+ b+=k[2]+(((uint32_t)k[3])<<16);
1488+ a+=k[0]+(((uint32_t)k[1])<<16);
1489+ break;
1490+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
1491+ case 10: c+=k[4];
1492+ b+=k[2]+(((uint32_t)k[3])<<16);
1493+ a+=k[0]+(((uint32_t)k[1])<<16);
1494+ break;
1495+ case 9 : c+=k8[8]; /* fall through */
1496+ case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
1497+ a+=k[0]+(((uint32_t)k[1])<<16);
1498+ break;
1499+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
1500+ case 6 : b+=k[2];
1501+ a+=k[0]+(((uint32_t)k[1])<<16);
1502+ break;
1503+ case 5 : b+=k8[4]; /* fall through */
1504+ case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
1505+ break;
1506+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
1507+ case 2 : a+=k[0];
1508+ break;
1509+ case 1 : a+=k8[0];
1510+ break;
1511+ case 0 : return c; /* zero length requires no mixing */
1512+ default: return c;
1513+ }
1514+
1515+ }
1516+ else
1517+ { /* need to read the key one byte at a time */
1518+#endif /* little endian */
1519+ const uint8_t *k = (const uint8_t *)key;
1520+
1521+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
1522+ while (length > 12)
1523+ {
1524+ a += k[0];
1525+ a += ((uint32_t)k[1])<<8;
1526+ a += ((uint32_t)k[2])<<16;
1527+ a += ((uint32_t)k[3])<<24;
1528+ b += k[4];
1529+ b += ((uint32_t)k[5])<<8;
1530+ b += ((uint32_t)k[6])<<16;
1531+ b += ((uint32_t)k[7])<<24;
1532+ c += k[8];
1533+ c += ((uint32_t)k[9])<<8;
1534+ c += ((uint32_t)k[10])<<16;
1535+ c += ((uint32_t)k[11])<<24;
1536+ mix(a,b,c);
1537+ length -= 12;
1538+ k += 12;
1539+ }
1540+
1541+ /*-------------------------------- last block: affect all 32 bits of (c) */
1542+ switch(length) /* all the case statements fall through */
1543+ {
1544+ case 12: c+=((uint32_t)k[11])<<24;
1545+ case 11: c+=((uint32_t)k[10])<<16;
1546+ case 10: c+=((uint32_t)k[9])<<8;
1547+ case 9 : c+=k[8];
1548+ case 8 : b+=((uint32_t)k[7])<<24;
1549+ case 7 : b+=((uint32_t)k[6])<<16;
1550+ case 6 : b+=((uint32_t)k[5])<<8;
1551+ case 5 : b+=k[4];
1552+ case 4 : a+=((uint32_t)k[3])<<24;
1553+ case 3 : a+=((uint32_t)k[2])<<16;
1554+ case 2 : a+=((uint32_t)k[1])<<8;
1555+ case 1 : a+=k[0];
1556+ break;
1557+ case 0 : return c;
1558+ default : return c;
1559+ }
1560+#ifndef WORDS_BIGENDIAN
1561+ }
1562+#endif
1563+
1564+ final(a,b,c);
1565+ return c;
1566+}
1567
1568=== added file 'libhashkit/ketama.c'
1569--- libhashkit/ketama.c 1970-01-01 00:00:00 +0000
1570+++ libhashkit/ketama.c 2009-12-18 01:27:26 +0000
1571@@ -0,0 +1,161 @@
1572+/* HashKit
1573+ * Copyright (C) 2006-2009 Brian Aker
1574+ * All rights reserved.
1575+ *
1576+ * Use and distribution licensed under the BSD license. See
1577+ * the COPYING file in the parent directory for full text.
1578+ */
1579+
1580+#include "common.h"
1581+
1582+static uint32_t ketama_server_hash(const char *key, unsigned int key_length, int alignment)
1583+{
1584+ unsigned char results[16];
1585+
1586+ md5_signature((unsigned char*)key, key_length, results);
1587+ return ((uint32_t) (results[3 + alignment * 4] & 0xFF) << 24)
1588+ | ((uint32_t) (results[2 + alignment * 4] & 0xFF) << 16)
1589+ | ((uint32_t) (results[1 + alignment * 4] & 0xFF) << 8)
1590+ | (results[0 + alignment * 4] & 0xFF);
1591+}
1592+
1593+static int continuum_points_cmp(const void *t1, const void *t2)
1594+{
1595+ hashkit_continuum_point_st *ct1= (hashkit_continuum_point_st *)t1;
1596+ hashkit_continuum_point_st *ct2= (hashkit_continuum_point_st *)t2;
1597+
1598+ if (ct1->value == ct2->value)
1599+ return 0;
1600+ else if (ct1->value > ct2->value)
1601+ return 1;
1602+ else
1603+ return -1;
1604+}
1605+
1606+int update_continuum(hashkit_st *hashkit)
1607+{
1608+ uint32_t count;
1609+ uint32_t continuum_index= 0;
1610+ uint32_t value;
1611+ uint32_t points_index;
1612+ uint32_t points_count= 0;
1613+ uint32_t points_per_server;
1614+ uint32_t points_per_hash;
1615+ uint64_t total_weight= 0;
1616+ uint32_t live_servers;
1617+ uint8_t *context;
1618+
1619+ if (hashkit->active_fn != NULL || hashkit->weight_fn != NULL)
1620+ {
1621+ live_servers= 0;
1622+
1623+ for (count= 0, context= hashkit->list; count < hashkit->list_size;
1624+ count++, context+= hashkit->context_size)
1625+ {
1626+ if (hashkit->active_fn != NULL)
1627+ {
1628+ if (hashkit->active_fn(context))
1629+ live_servers++;
1630+ else
1631+ continue;
1632+ }
1633+
1634+ if (hashkit->weight_fn != NULL)
1635+ total_weight+= hashkit->weight_fn(context);
1636+ }
1637+ }
1638+
1639+ if (hashkit->active_fn == NULL)
1640+ live_servers= (uint32_t)hashkit->list_size;
1641+
1642+ if (live_servers == 0)
1643+ return 0;
1644+
1645+ if (hashkit->weight_fn == NULL)
1646+ {
1647+ points_per_server= HASHKIT_POINTS_PER_NODE;
1648+ points_per_hash= 1;
1649+ }
1650+ else
1651+ {
1652+ points_per_server= HASHKIT_POINTS_PER_NODE_WEIGHTED;
1653+ points_per_hash= 4;
1654+ }
1655+
1656+ if (live_servers > hashkit->continuum_count)
1657+ {
1658+ hashkit_continuum_point_st *new_continuum;
1659+
1660+ new_continuum= realloc(hashkit->continuum,
1661+ sizeof(hashkit_continuum_point_st) *
1662+ (live_servers + HASHKIT_CONTINUUM_ADDITION) *
1663+ points_per_server);
1664+
1665+ if (new_continuum == NULL)
1666+ return ENOMEM;
1667+
1668+ hashkit->continuum= new_continuum;
1669+ hashkit->continuum_count= live_servers + HASHKIT_CONTINUUM_ADDITION;
1670+ }
1671+
1672+ for (count= 0, context= hashkit->list; count < hashkit->list_size;
1673+ count++, context+= hashkit->context_size)
1674+ {
1675+ if (hashkit->active_fn != NULL && hashkit->active_fn(context) == false)
1676+ continue;
1677+
1678+ if (hashkit->weight_fn != NULL)
1679+ {
1680+ float pct = (float)hashkit->weight_fn(context) / (float)total_weight;
1681+ points_per_server= (uint32_t) ((floorf((float) (pct * HASHKIT_POINTS_PER_NODE_WEIGHTED / 4 * (float)live_servers + 0.0000000001))) * 4);
1682+ }
1683+
1684+ for (points_index= 0;
1685+ points_index < points_per_server / points_per_hash;
1686+ points_index++)
1687+ {
1688+ char sort_host[HASHKIT_CONTINUUM_KEY_SIZE]= "";
1689+ size_t sort_host_length;
1690+
1691+ if (hashkit->continuum_key_fn == NULL)
1692+ {
1693+ sort_host_length= (size_t) snprintf(sort_host, HASHKIT_CONTINUUM_KEY_SIZE, "%d",
1694+ points_index);
1695+ }
1696+ else
1697+ {
1698+ sort_host_length= hashkit->continuum_key_fn(sort_host, HASHKIT_CONTINUUM_KEY_SIZE,
1699+ points_index, context);
1700+ }
1701+
1702+ if (hashkit->weight_fn == NULL)
1703+ {
1704+ if (hashkit->continuum_hash_fn == NULL)
1705+ value= hashkit_default(sort_host, sort_host_length);
1706+ else
1707+ value= hashkit->continuum_hash_fn(sort_host, sort_host_length);
1708+
1709+ hashkit->continuum[continuum_index].index= count;
1710+ hashkit->continuum[continuum_index++].value= value;
1711+ }
1712+ else
1713+ {
1714+ unsigned int i;
1715+ for (i = 0; i < points_per_hash; i++)
1716+ {
1717+ value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i);
1718+ hashkit->continuum[continuum_index].index= count;
1719+ hashkit->continuum[continuum_index++].value= value;
1720+ }
1721+ }
1722+ }
1723+
1724+ points_count+= points_per_server;
1725+ }
1726+
1727+ hashkit->continuum_points_count= points_count;
1728+ qsort(hashkit->continuum, hashkit->continuum_points_count, sizeof(hashkit_continuum_point_st),
1729+ continuum_points_cmp);
1730+
1731+ return 0;
1732+}
1733
1734=== added file 'libhashkit/md5.c'
1735--- libhashkit/md5.c 1970-01-01 00:00:00 +0000
1736+++ libhashkit/md5.c 2009-12-18 01:27:26 +0000
1737@@ -0,0 +1,365 @@
1738+/*
1739+ This Library has been modified from its original form by
1740+ Brian Aker (brian@tangent.org)
1741+
1742+ See below for original Copyright.
1743+*/
1744+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
1745+ */
1746+
1747+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
1748+rights reserved.
1749+
1750+License to copy and use this software is granted provided that it
1751+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
1752+Algorithm" in all material mentioning or referencing this software
1753+or this function.
1754+
1755+License is also granted to make and use derivative works provided
1756+that such works are identified as "derived from the RSA Data
1757+Security, Inc. MD5 Message-Digest Algorithm" in all material
1758+mentioning or referencing the derived work.
1759+
1760+RSA Data Security, Inc. makes no representations concerning either
1761+the merchantability of this software or the suitability of this
1762+software for any particular purpose. It is provided "as is"
1763+without express or implied warranty of any kind.
1764+
1765+These notices must be retained in any copies of any part of this
1766+documentation and/or software.
1767+*/
1768+
1769+#include "common.h"
1770+
1771+#include <string.h>
1772+#include <sys/types.h>
1773+
1774+/* POINTER defines a generic pointer type */
1775+typedef unsigned char *POINTER;
1776+
1777+
1778+/* UINT4 defines a four byte word */
1779+typedef unsigned int UINT4;
1780+
1781+
1782+/* MD5 context. */
1783+typedef struct {
1784+ UINT4 state[4]; /* state (ABCD) */
1785+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
1786+ unsigned char buffer[64]; /* input buffer */
1787+} MD5_CTX;
1788+
1789+static void MD5Init (MD5_CTX *context); /* context */
1790+static void MD5Update ( MD5_CTX *context, /* context */
1791+ const unsigned char *input, /* input block */
1792+ unsigned int inputLen); /* length of input block */
1793+static void MD5Final ( unsigned char digest[16], /* message digest */
1794+ MD5_CTX *context); /* context */
1795+
1796+/* Constants for MD5Transform routine. */
1797+
1798+#define S11 7
1799+#define S12 12
1800+#define S13 17
1801+#define S14 22
1802+#define S21 5
1803+#define S22 9
1804+#define S23 14
1805+#define S24 20
1806+#define S31 4
1807+#define S32 11
1808+#define S33 16
1809+#define S34 23
1810+#define S41 6
1811+#define S42 10
1812+#define S43 15
1813+#define S44 21
1814+
1815+
1816+static void MD5Transform (UINT4 state[4],
1817+ unsigned char block[64]);
1818+static void Encode (unsigned char *output,
1819+ UINT4 *input,
1820+ unsigned int len);
1821+static void Decode(UINT4 *output, unsigned char *input, unsigned int len);
1822+
1823+static unsigned char PADDING[64] = {
1824+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1825+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1826+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1827+};
1828+
1829+/* F, G, H and I are basic MD5 functions.
1830+ */
1831+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
1832+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
1833+#define H(x, y, z) ((x) ^ (y) ^ (z))
1834+#define I(x, y, z) ((y) ^ ((x) | (~z)))
1835+
1836+/* ROTATE_LEFT rotates x left n bits.
1837+ */
1838+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
1839+
1840+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
1841+Rotation is separate from addition to prevent recomputation.
1842+ */
1843+#define FF(a, b, c, d, x, s, ac) { \
1844+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
1845+ (a) = ROTATE_LEFT ((a), (s)); \
1846+ (a) += (b); \
1847+ }
1848+#define GG(a, b, c, d, x, s, ac) { \
1849+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
1850+ (a) = ROTATE_LEFT ((a), (s)); \
1851+ (a) += (b); \
1852+ }
1853+#define HH(a, b, c, d, x, s, ac) { \
1854+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
1855+ (a) = ROTATE_LEFT ((a), (s)); \
1856+ (a) += (b); \
1857+ }
1858+#define II(a, b, c, d, x, s, ac) { \
1859+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
1860+ (a) = ROTATE_LEFT ((a), (s)); \
1861+ (a) += (b); \
1862+ }
1863+
1864+
1865+/*
1866+ Just a simple method for getting the signature
1867+ result must be == 16
1868+*/
1869+void md5_signature(const unsigned char *key, unsigned int length, unsigned char *result)
1870+{
1871+ MD5_CTX my_md5;
1872+
1873+ MD5Init(&my_md5);
1874+ (void)MD5Update(&my_md5, key, length);
1875+ MD5Final(result, &my_md5);
1876+}
1877+
1878+/* MD5 initialization. Begins an MD5 operation, writing a new context.
1879+ */
1880+static void MD5Init (MD5_CTX *context) /* context */
1881+{
1882+ context->count[0] = context->count[1] = 0;
1883+ /* Load magic initialization constants.
1884+*/
1885+ context->state[0] = 0x67452301;
1886+ context->state[1] = 0xefcdab89;
1887+ context->state[2] = 0x98badcfe;
1888+ context->state[3] = 0x10325476;
1889+}
1890+
1891+/* MD5 block update operation. Continues an MD5 message-digest
1892+ operation, processing another message block, and updating the
1893+ context.
1894+ */
1895+
1896+static void MD5Update (
1897+ MD5_CTX *context, /* context */
1898+ const unsigned char *input, /* input block */
1899+ unsigned int inputLen) /* length of input block */
1900+{
1901+ unsigned int i, idx, partLen;
1902+
1903+ /* Compute number of bytes mod 64 */
1904+ idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
1905+
1906+
1907+ /* Update number of bits */
1908+ if ((context->count[0] += ((UINT4)inputLen << 3))
1909+ < ((UINT4)inputLen << 3))
1910+ context->count[1]++;
1911+ context->count[1] += ((UINT4)inputLen >> 29);
1912+
1913+ partLen = 64 - idx;
1914+
1915+ /* Transform as many times as possible.
1916+*/
1917+ if (inputLen >= partLen) {
1918+ memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
1919+ MD5Transform(context->state, context->buffer);
1920+
1921+ for (i = partLen; i + 63 < inputLen; i += 64)
1922+ MD5Transform (context->state, (unsigned char *)&input[i]);
1923+
1924+ idx = 0;
1925+ }
1926+ else
1927+ i = 0;
1928+
1929+ /* Buffer remaining input */
1930+ memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
1931+ inputLen-i);
1932+}
1933+
1934+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
1935+ the message digest and zeroizing the context.
1936+ */
1937+
1938+static void MD5Final (
1939+ unsigned char digest[16], /* message digest */
1940+ MD5_CTX *context) /* context */
1941+{
1942+ unsigned char bits[8];
1943+ unsigned int idx, padLen;
1944+
1945+ /* Save number of bits */
1946+ Encode (bits, context->count, 8);
1947+
1948+ /* Pad out to 56 mod 64.
1949+*/
1950+ idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
1951+ padLen = (idx < 56) ? (56 - idx) : (120 - idx);
1952+ MD5Update (context, PADDING, padLen);
1953+
1954+ /* Append length (before padding) */
1955+ MD5Update (context, bits, 8);
1956+
1957+ /* Store state in digest */
1958+ Encode (digest, context->state, 16);
1959+
1960+ /* Zeroize sensitive information.
1961+*/
1962+ memset((POINTER)context, 0, sizeof (*context));
1963+}
1964+
1965+/* MD5 basic transformation. Transforms state based on block.
1966+ */
1967+static void MD5Transform (
1968+ UINT4 state[4],
1969+ unsigned char block[64])
1970+{
1971+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
1972+
1973+ Decode (x, block, 64);
1974+
1975+ /* Round 1 */
1976+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
1977+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
1978+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
1979+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
1980+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
1981+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
1982+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
1983+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
1984+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
1985+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
1986+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
1987+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
1988+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
1989+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
1990+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
1991+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
1992+
1993+ /* Round 2 */
1994+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
1995+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
1996+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
1997+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
1998+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
1999+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
2000+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
2001+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
2002+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
2003+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
2004+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
2005+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
2006+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
2007+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
2008+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
2009+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
2010+
2011+ /* Round 3 */
2012+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
2013+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
2014+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
2015+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
2016+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
2017+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
2018+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
2019+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
2020+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
2021+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
2022+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
2023+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
2024+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
2025+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
2026+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
2027+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
2028+
2029+ /* Round 4 */
2030+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
2031+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
2032+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
2033+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
2034+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
2035+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
2036+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
2037+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
2038+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
2039+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
2040+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
2041+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
2042+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
2043+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
2044+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
2045+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
2046+
2047+
2048+ state[0] += a;
2049+ state[1] += b;
2050+ state[2] += c;
2051+ state[3] += d;
2052+
2053+ /* Zeroize sensitive information.
2054+*/
2055+ memset((POINTER)x, 0, sizeof (x));
2056+}
2057+
2058+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
2059+ a multiple of 4.
2060+ */
2061+static void Encode (
2062+unsigned char *output,
2063+UINT4 *input,
2064+unsigned int len)
2065+{
2066+ unsigned int i, j;
2067+
2068+ for (i = 0, j = 0; j < len; i++, j += 4) {
2069+ output[j] = (unsigned char)(input[i] & 0xff);
2070+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
2071+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
2072+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
2073+ }
2074+}
2075+
2076+
2077+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
2078+ a multiple of 4.
2079+ */
2080+static void Decode (
2081+UINT4 *output,
2082+unsigned char *input,
2083+unsigned int len)
2084+{
2085+ unsigned int i, j;
2086+
2087+ for (i = 0, j = 0; j < len; i++, j += 4)
2088+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
2089+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
2090+}
2091+
2092+uint32_t hashkit_md5(const char *key, size_t key_length)
2093+{
2094+ unsigned char results[16];
2095+
2096+ md5_signature((unsigned char*)key, (unsigned int)key_length, results);
2097+
2098+ return ((uint32_t) (results[3] & 0xFF) << 24)
2099+ | ((uint32_t) (results[2] & 0xFF) << 16)
2100+ | ((uint32_t) (results[1] & 0xFF) << 8)
2101+ | (results[0] & 0xFF);
2102+}
2103
2104=== added file 'libhashkit/murmur.c'
2105--- libhashkit/murmur.c 1970-01-01 00:00:00 +0000
2106+++ libhashkit/murmur.c 2009-12-18 01:27:26 +0000
2107@@ -0,0 +1,76 @@
2108+/*
2109+ "Murmur" hash provided by Austin, tanjent@gmail.com
2110+ http://murmurhash.googlepages.com/
2111+
2112+ Note - This code makes a few assumptions about how your machine behaves -
2113+
2114+ 1. We can read a 4-byte value from any address without crashing
2115+ 2. sizeof(int) == 4
2116+
2117+ And it has a few limitations -
2118+ 1. It will not work incrementally.
2119+ 2. It will not produce the same results on little-endian and big-endian
2120+ machines.
2121+
2122+ Updated to murmur2 hash - BP
2123+*/
2124+
2125+#include "common.h"
2126+
2127+uint32_t hashkit_murmur(const char *key, size_t length)
2128+{
2129+ /*
2130+ 'm' and 'r' are mixing constants generated offline. They're not
2131+ really 'magic', they just happen to work well.
2132+ */
2133+
2134+ const unsigned int m= 0x5bd1e995;
2135+ const uint32_t seed= (0xdeadbeef * (uint32_t)length);
2136+ const int r= 24;
2137+
2138+
2139+ // Initialize the hash to a 'random' value
2140+
2141+ uint32_t h= seed ^ (uint32_t)length;
2142+
2143+ // Mix 4 bytes at a time into the hash
2144+
2145+ const unsigned char * data= (const unsigned char *)key;
2146+
2147+ while(length >= 4)
2148+ {
2149+ unsigned int k = *(unsigned int *)data;
2150+
2151+ k *= m;
2152+ k ^= k >> r;
2153+ k *= m;
2154+
2155+ h *= m;
2156+ h ^= k;
2157+
2158+ data += 4;
2159+ length -= 4;
2160+ }
2161+
2162+ // Handle the last few bytes of the input array
2163+
2164+ switch(length)
2165+ {
2166+ case 3: h ^= ((uint32_t)data[2]) << 16;
2167+ case 2: h ^= ((uint32_t)data[1]) << 8;
2168+ case 1: h ^= data[0];
2169+ h *= m;
2170+ default: break;
2171+ };
2172+
2173+ /*
2174+ Do a few final mixes of the hash to ensure the last few bytes are
2175+ well-incorporated.
2176+ */
2177+
2178+ h ^= h >> 13;
2179+ h *= m;
2180+ h ^= h >> 15;
2181+
2182+ return h;
2183+}
2184
2185=== added file 'libhashkit/strerror.c'
2186--- libhashkit/strerror.c 1970-01-01 00:00:00 +0000
2187+++ libhashkit/strerror.c 2009-12-18 01:27:26 +0000
2188@@ -0,0 +1,26 @@
2189+/* HashKit
2190+ * Copyright (C) 2009 Brian Aker
2191+ * All rights reserved.
2192+ *
2193+ * Use and distribution licensed under the BSD license. See
2194+ * the COPYING file in the parent directory for full text.
2195+ */
2196+
2197+#include "common.h"
2198+
2199+const char *hashkit_strerror(hashkit_st *ptr __attribute__((unused)), hashkit_return_t rc)
2200+{
2201+ switch (rc)
2202+ {
2203+ case HASHKIT_SUCCESS:
2204+ return "SUCCESS";
2205+ case HASHKIT_FAILURE:
2206+ return "FAILURE";
2207+ case HASHKIT_MEMORY_ALLOCATION_FAILURE:
2208+ return "MEMORY ALLOCATION FAILURE";
2209+ case HASHKIT_MAXIMUM_RETURN:
2210+ return "Gibberish returned!";
2211+ default:
2212+ return "Gibberish returned!";
2213+ }
2214+}
2215
2216=== added file 'libhashkit/strerror.h'
2217--- libhashkit/strerror.h 1970-01-01 00:00:00 +0000
2218+++ libhashkit/strerror.h 2009-12-18 01:27:26 +0000
2219@@ -0,0 +1,22 @@
2220+/* HashKit
2221+ * Copyright (C) 2009 Brian Aker
2222+ * All rights reserved.
2223+ *
2224+ * Use and distribution licensed under the BSD license. See
2225+ * the COPYING file in the parent directory for full text.
2226+ */
2227+
2228+#ifndef HASHKIT_STRERROR_H
2229+#define HASHKIT_STRERROR_H
2230+
2231+#ifdef __cplusplus
2232+extern "C" {
2233+#endif
2234+
2235+const char *hashkit_strerror(hashkit_st *ptr __attribute__((unused)), hashkit_return_t rc);
2236+
2237+#ifdef __cplusplus
2238+}
2239+#endif
2240+
2241+#endif /* HASHKIT_STRERROR_H */
2242
2243=== added file 'libhashkit/types.h'
2244--- libhashkit/types.h 1970-01-01 00:00:00 +0000
2245+++ libhashkit/types.h 2009-12-18 01:27:26 +0000
2246@@ -0,0 +1,92 @@
2247+
2248+/* HashKit
2249+ * Copyright (C) 2009 Brian Aker
2250+ * All rights reserved.
2251+ *
2252+ * Use and distribution licensed under the BSD license. See
2253+ * the COPYING file in the parent directory for full text.
2254+ */
2255+
2256+/**
2257+ * @file
2258+ * @brief HashKit Header
2259+ */
2260+
2261+#ifndef HASHKIT_TYPES_H
2262+#define HASHKIT_TYPES_H
2263+
2264+#ifdef __cplusplus
2265+extern "C" {
2266+#endif
2267+
2268+/**
2269+ * @addtogroup hashkit_types Types
2270+ * @ingroup hashkit
2271+ * @{
2272+ */
2273+
2274+typedef enum {
2275+ HASHKIT_SUCCESS,
2276+ HASHKIT_FAILURE,
2277+ HASHKIT_MEMORY_ALLOCATION_FAILURE,
2278+ HASHKIT_MAXIMUM_RETURN /* Always add new error code before */
2279+} hashkit_return_t;
2280+
2281+/**
2282+ @todo hashkit_options_t is for future use, currently we do not define any user options.
2283+ */
2284+
2285+typedef enum
2286+{
2287+ HASHKIT_OPTION_MAX
2288+} hashkit_options_t;
2289+
2290+typedef struct
2291+{
2292+ /* We use the following for internal book keeping. */
2293+ bool is_initialized:1;
2294+ bool is_allocated:1;
2295+} hashkit_options_st;
2296+
2297+typedef enum {
2298+ HASHKIT_HASH_DEFAULT= 0,
2299+ HASHKIT_HASH_MD5,
2300+ HASHKIT_HASH_CRC,
2301+ HASHKIT_HASH_FNV1_64,
2302+ HASHKIT_HASH_FNV1A_64,
2303+ HASHKIT_HASH_FNV1_32,
2304+ HASHKIT_HASH_FNV1A_32,
2305+ HASHKIT_HASH_HSIEH,
2306+ HASHKIT_HASH_MURMUR,
2307+ HASHKIT_HASH_JENKINS,
2308+ HASHKIT_HASH_MAX
2309+} hashkit_hash_algorithm_t;
2310+
2311+/**
2312+ * Hash distributions that are available to use.
2313+ */
2314+typedef enum
2315+{
2316+ HASHKIT_DISTRIBUTION_MODULA,
2317+ HASHKIT_DISTRIBUTION_RANDOM,
2318+ HASHKIT_DISTRIBUTION_KETAMA,
2319+ HASHKIT_DISTRIBUTION_MAX /* Always add new values before this. */
2320+} hashkit_distribution_t;
2321+
2322+
2323+typedef struct hashkit_st hashkit_st;
2324+typedef struct hashkit_continuum_point_st hashkit_continuum_point_st;
2325+typedef bool (hashkit_active_fn)(void *context);
2326+typedef uint32_t (hashkit_fn)(const char *key, size_t key_length);
2327+typedef size_t (hashkit_key_fn)(char *key, size_t key_length, uint32_t point_index, void *context);
2328+typedef void (hashkit_sort_fn)(void *context, size_t count);
2329+typedef uint32_t (hashkit_weight_fn)(void *context);
2330+
2331+/** @} */
2332+
2333+
2334+#ifdef __cplusplus
2335+}
2336+#endif
2337+
2338+#endif /* HASHKIT_TYPES_H */
2339
2340=== added file 'libhashkit/visibility.h'
2341--- libhashkit/visibility.h 1970-01-01 00:00:00 +0000
2342+++ libhashkit/visibility.h 2009-12-18 01:27:26 +0000
2343@@ -0,0 +1,51 @@
2344+/*
2345+ * Summary: interface for HashKit functions
2346+ * Description: visibitliy macros for HashKit library
2347+ *
2348+ * Use and distribution licensed under the BSD license. See
2349+ * the COPYING file in this directory for full text.
2350+ *
2351+ * Author: Monty Taylor
2352+ */
2353+
2354+/**
2355+ * @file
2356+ * @brief Visibility control macros
2357+ */
2358+
2359+#ifndef HASHKIT_VISIBILITY_H
2360+#define HASHKIT_VISIBILITY_H
2361+
2362+/**
2363+ *
2364+ * HASHKIT_API is used for the public API symbols. It either DLL imports or
2365+ * DLL exports (or does nothing for static build).
2366+ *
2367+ * HASHKIT_LOCAL is used for non-api symbols.
2368+ */
2369+
2370+#if defined(BUILDING_HASHKIT)
2371+# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
2372+# define HASHKIT_API __attribute__ ((visibility("default")))
2373+# define HASHKIT_LOCAL __attribute__ ((visibility("hidden")))
2374+# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
2375+# define HASHKIT_API __global
2376+# define HASHKIT_LOCAL __hidden
2377+# elif defined(_MSC_VER)
2378+# define HASHKIT_API extern __declspec(dllexport)
2379+# define HASHKIT_LOCAL
2380+# else
2381+# define HASHKIT_API
2382+# define HASHKIT_LOCAL
2383+# endif /* defined(HAVE_VISIBILITY) */
2384+#else /* defined(BUILDING_HASHKIT) */
2385+# if defined(_MSC_VER)
2386+# define HASHKIT_API extern __declspec(dllimport)
2387+# define HASHKIT_LOCAL
2388+# else
2389+# define HASHKIT_API
2390+# define HASHKIT_LOCAL
2391+# endif /* defined(_MSC_VER) */
2392+#endif /* defined(BUILDING_HASHKIT) */
2393+
2394+#endif /* HASHKIT_VISIBILITY_H */
2395
2396=== modified file 'libmemcached/dump.c'
2397--- libmemcached/dump.c 2009-12-16 23:01:10 +0000
2398+++ libmemcached/dump.c 2009-12-18 01:27:26 +0000
2399@@ -9,7 +9,7 @@
2400 #include "common.h"
2401 static memcached_return_t ascii_dump(memcached_st *ptr, memcached_dump_fn *callback, void *context, uint32_t number_of_callbacks)
2402 {
2403- memcached_return_t rc= 0;
2404+ memcached_return_t rc= MEMCACHED_SUCCESS;
2405 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
2406 size_t send_length;
2407 uint32_t server_key;
2408@@ -23,7 +23,7 @@
2409 /* 256 I BELIEVE is the upper limit of slabs */
2410 for (x= 0; x < 256; x++)
2411 {
2412- send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
2413+ send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
2414 "stats cachedump %u 0 0\r\n", x);
2415
2416 rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1);
2417@@ -88,4 +88,3 @@
2418
2419 return ascii_dump(ptr, callback, context, number_of_callbacks);
2420 }
2421-
2422
2423=== added file 'libmemcached/dump.h'
2424--- libmemcached/dump.h 1970-01-01 00:00:00 +0000
2425+++ libmemcached/dump.h 2009-12-18 01:27:26 +0000
2426@@ -0,0 +1,27 @@
2427+/* LibMemcached
2428+ * Copyright (C) 2006-2009 Brian Aker
2429+ * All rights reserved.
2430+ *
2431+ * Use and distribution licensed under the BSD license. See
2432+ * the COPYING file in the parent directory for full text.
2433+ *
2434+ * Summary: Simple method for dumping data from Memcached.
2435+ *
2436+ */
2437+
2438+#ifndef __MEMCACHED_DUMP_H__
2439+#define __MEMCACHED_DUMP_H__
2440+
2441+#ifdef __cplusplus
2442+extern "C" {
2443+#endif
2444+
2445+LIBMEMCACHED_API
2446+memcached_return_t memcached_dump(memcached_st *ptr, memcached_dump_fn *function, void *context, uint32_t number_of_callbacks);
2447+
2448+
2449+#ifdef __cplusplus
2450+}
2451+#endif
2452+
2453+#endif /* __MEMCACHED_DUMP_H__ */
2454
2455=== modified file 'libmemcached/hosts.c'
2456--- libmemcached/hosts.c 2009-12-17 08:03:27 +0000
2457+++ libmemcached/hosts.c 2009-12-18 01:27:26 +0000
2458@@ -36,6 +36,9 @@
2459
2460 memcached_return_t run_distribution(memcached_st *ptr)
2461 {
2462+ if (ptr->flags.use_sort_hosts)
2463+ sort_hosts(ptr);
2464+
2465 switch (ptr->distribution)
2466 {
2467 case MEMCACHED_DISTRIBUTION_CONSISTENT:
2468@@ -43,8 +46,6 @@
2469 case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY:
2470 return update_continuum(ptr);
2471 case MEMCACHED_DISTRIBUTION_MODULA:
2472- if (ptr->flags.use_sort_hosts)
2473- sort_hosts(ptr);
2474 break;
2475 case MEMCACHED_DISTRIBUTION_RANDOM:
2476 srandom((uint32_t) time(NULL));
2477
2478=== renamed file 'libmemcached/Makefile.am' => 'libmemcached/include.am'
2479--- libmemcached/Makefile.am 2009-12-16 23:01:10 +0000
2480+++ libmemcached/include.am 2009-12-18 01:27:26 +0000
2481@@ -1,140 +1,141 @@
2482-EXTRA_DIST = \
2483- libmemcached.ver \
2484- libmemcached_probes.d \
2485- memcached/README.txt \
2486- memcached_configure.h.in \
2487- protocol/libmemcachedprotocol.ver \
2488- util/libmemcachedutil.ver
2489-
2490-
2491-EXTRA_HEADERS =
2492-BUILT_SOURCES=
2493-
2494-noinst_HEADERS = libmemcached_probes.h \
2495- io.h \
2496- internal.h \
2497- common.h \
2498- memcached/protocol_binary.h \
2499- protocol/common.h \
2500- protocol/ascii_handler.h \
2501- protocol/binary_handler.h
2502-
2503-pkginclude_HEADERS= \
2504- behavior.h \
2505- callback.h \
2506- constants.h \
2507- exception.hpp \
2508- get.h \
2509- memcached.h \
2510- memcached.hpp \
2511- memcached_configure.h \
2512- protocol_handler.h \
2513- result.h \
2514- server.h \
2515- storage.h \
2516- string.h \
2517- types.h \
2518- visibility.h \
2519- watchpoint.h
2520-
2521-nobase_pkginclude_HEADERS = \
2522- protocol/cache.h \
2523- protocol/callback.h
2524-
2525-
2526-libmemcachedprotocol_la_SOURCES = \
2527- protocol/ascii_handler.c \
2528- protocol/binary_handler.c \
2529- protocol/cache.c \
2530- protocol/pedantic.c \
2531- protocol/protocol_handler.c
2532-
2533-libmemcachedprotocol_la_LDFLAGS= ${AM_LDFLAGS} -version-info 0:0:0
2534-
2535-lib_LTLIBRARIES = libmemcached.la libmemcachedprotocol.la
2536-noinst_LTLIBRARIES = libmemcachedcallbacks.la
2537-libmemcachedcallbacks_la_CFLAGS = ${AM_CFLAGS} ${NO_STRICT_ALIASING}
2538-libmemcachedcallbacks_la_SOURCES = callback.c
2539-
2540-libmemcached_la_CFLAGS= ${AM_CFLAGS} ${NO_CONVERSION}
2541-libmemcached_la_SOURCES = \
2542- allocators.c \
2543- analyze.c \
2544- auto.c \
2545- behavior.c \
2546- connect.c \
2547- crc.c \
2548- delete.c \
2549- do.c \
2550- dump.c \
2551- fetch.c \
2552- flush.c \
2553- flush_buffers.c \
2554- get.c \
2555- hash.c \
2556- hosts.c \
2557- io.c \
2558- jenkins_hash.c \
2559- key.c \
2560- md5.c \
2561- memcached.c \
2562- murmur_hash.c \
2563- parse.c \
2564- purge.c \
2565- quit.c \
2566- response.c \
2567- result.c \
2568- server.c \
2569- stats.c \
2570- storage.c \
2571- strerror.c \
2572- string.c \
2573- verbosity.c \
2574- version.c
2575+# vim:ft=automake
2576+# included from Top Level Makefile.am
2577+# All paths should be given relative to the root
2578+
2579+EXTRA_DIST+= \
2580+ libmemcached/libmemcached_probes.d \
2581+ libmemcached/memcached/README.txt \
2582+ libmemcached/memcached_configure.h.in
2583+
2584+
2585+noinst_HEADERS+= \
2586+ libmemcached/byteorder.h \
2587+ libmemcached/libmemcached_probes.h \
2588+ libmemcached/io.h \
2589+ libmemcached/internal.h \
2590+ libmemcached/common.h \
2591+ libmemcached/memcached/protocol_binary.h \
2592+ libmemcached/protocol/common.h \
2593+ libmemcached/protocol/ascii_handler.h \
2594+ libmemcached/protocol/binary_handler.h
2595+
2596+nobase_pkginclude_HEADERS+= \
2597+ libmemcached/behavior.h \
2598+ libmemcached/callback.h \
2599+ libmemcached/constants.h \
2600+ libmemcached/dump.h \
2601+ libmemcached/exception.hpp \
2602+ libmemcached/get.h \
2603+ libmemcached/memcached.h \
2604+ libmemcached/memcached.hpp \
2605+ libmemcached/memcached_configure.h \
2606+ libmemcached/protocol/cache.h \
2607+ libmemcached/protocol/callback.h \
2608+ libmemcached/protocol_handler.h \
2609+ libmemcached/result.h \
2610+ libmemcached/server.h \
2611+ libmemcached/storage.h \
2612+ libmemcached/string.h \
2613+ libmemcached/types.h \
2614+ libmemcached/visibility.h \
2615+ libmemcached/watchpoint.h
2616+
2617+
2618+
2619+lib_LTLIBRARIES+= libmemcached/libmemcachedprotocol.la
2620+libmemcached_libmemcachedprotocol_la_SOURCES = \
2621+ libmemcached/protocol/ascii_handler.c \
2622+ libmemcached/protocol/binary_handler.c \
2623+ libmemcached/protocol/cache.c \
2624+ libmemcached/protocol/pedantic.c \
2625+ libmemcached/protocol/protocol_handler.c
2626+
2627+libmemcached_libmemcachedprotocol_la_LDFLAGS= ${AM_LDFLAGS} -version-info 0:0:0
2628+
2629+noinst_LTLIBRARIES+= libmemcached/libmemcachedcallbacks.la
2630+libmemcached_libmemcachedcallbacks_la_CFLAGS = ${AM_CFLAGS} ${NO_STRICT_ALIASING}
2631+libmemcached_libmemcachedcallbacks_la_SOURCES = libmemcached/callback.c
2632+
2633+lib_LTLIBRARIES+= libmemcached/libmemcached.la
2634+libmemcached_libmemcached_la_CFLAGS= ${AM_CFLAGS} ${NO_CONVERSION}
2635+libmemcached_libmemcached_la_SOURCES = \
2636+ libmemcached/allocators.c \
2637+ libmemcached/analyze.c \
2638+ libmemcached/auto.c \
2639+ libmemcached/behavior.c \
2640+ libmemcached/connect.c \
2641+ libmemcached/crc.c \
2642+ libmemcached/delete.c \
2643+ libmemcached/do.c \
2644+ libmemcached/dump.c \
2645+ libmemcached/fetch.c \
2646+ libmemcached/flush.c \
2647+ libmemcached/flush_buffers.c \
2648+ libmemcached/get.c \
2649+ libmemcached/hash.c \
2650+ libmemcached/hosts.c \
2651+ libmemcached/io.c \
2652+ libmemcached/jenkins_hash.c \
2653+ libmemcached/key.c \
2654+ libmemcached/md5.c \
2655+ libmemcached/memcached.c \
2656+ libmemcached/murmur_hash.c \
2657+ libmemcached/parse.c \
2658+ libmemcached/purge.c \
2659+ libmemcached/quit.c \
2660+ libmemcached/response.c \
2661+ libmemcached/result.c \
2662+ libmemcached/server.c \
2663+ libmemcached/stats.c \
2664+ libmemcached/storage.c \
2665+ libmemcached/strerror.c \
2666+ libmemcached/string.c \
2667+ libmemcached/verbosity.c \
2668+ libmemcached/version.c
2669
2670
2671 if INCLUDE_HSIEH_SRC
2672-libmemcached_la_SOURCES += hsieh_hash.c
2673+libmemcached_libmemcached_la_SOURCES += libmemcached/hsieh_hash.c
2674 endif
2675
2676-libmemcached_la_DEPENDENCIES= libmemcachedcallbacks.la
2677-libmemcached_la_LIBADD= $(LIBM) libmemcachedcallbacks.la
2678-libmemcached_la_LDFLAGS= ${AM_LDFLAGS} -version-info 3:0:0
2679+libmemcached_libmemcached_la_DEPENDENCIES= libmemcached/libmemcachedcallbacks.la
2680+libmemcached_libmemcached_la_LIBADD= $(LIBM) libmemcached/libmemcachedcallbacks.la
2681+libmemcached_libmemcached_la_LDFLAGS= ${AM_LDFLAGS} -version-info 3:0:0
2682
2683 if BUILD_LIBMEMCACHEDUTIL
2684-pkginclude_HEADERS+= memcached_util.h pool.h
2685-lib_LTLIBRARIES+= libmemcachedutil.la
2686+pkginclude_HEADERS+= libmemcached/memcached_util.h libmemcached/pool.h
2687+lib_LTLIBRARIES+= libmemcached/libmemcachedutil.la
2688 endif
2689
2690-libmemcachedutil_la_SOURCES= util/pool.c
2691-libmemcachedutil_la_LIBADD= libmemcached.la
2692-libmemcachedutil_la_LDFLAGS= ${AM_LDFLAGS} -version-info 0:0:0
2693-libmemcachedutil_la_DEPENDENCIES=libmemcached.la
2694+libmemcached_libmemcachedutil_la_SOURCES= libmemcached/util/pool.c
2695+libmemcached_libmemcachedutil_la_LIBADD= libmemcached/libmemcached.la
2696+libmemcached_libmemcachedutil_la_LDFLAGS= ${AM_LDFLAGS} -version-info 0:0:0
2697+libmemcached_libmemcachedutil_la_DEPENDENCIES= libmemcached/libmemcached.la
2698
2699 if BUILD_BYTEORDER
2700-noinst_LTLIBRARIES += libbyteorder.la
2701-libbyteorder_la_SOURCES= byteorder.c byteorder.h
2702-libmemcached_la_LIBADD += libbyteorder.la
2703-libmemcached_la_DEPENDENCIES+= libbyteorder.la
2704-libmemcachedprotocol_la_LIBADD=libbyteorder.la
2705-libmemcachedprotocol_la_DEPENDENCIES=libbyteorder.la
2706+noinst_LTLIBRARIES += libmemcached/libbyteorder.la
2707+libmemcached_libbyteorder_la_SOURCES= libmemcached/byteorder.c
2708+libmemcached_libmemcached_la_LIBADD += libmemcached/libbyteorder.la
2709+libmemcached_libmemcached_la_DEPENDENCIES+= libmemcached/libbyteorder.la
2710+libmemcached_libmemcachedprotocol_la_LIBADD=libmemcached/libbyteorder.la
2711+libmemcached_libmemcachedprotocol_la_DEPENDENCIES=libmemcached/libbyteorder.la
2712 endif
2713
2714 if HAVE_DTRACE
2715-BUILT_SOURCES+= dtrace_probes.h
2716-libmemcached_la_SOURCES += libmemcached_probes.d
2717+BUILT_SOURCES+= libmemcached/dtrace_probes.h
2718+libmemcached_libmemcached_la_SOURCES += libmemcached/libmemcached_probes.d
2719 endif
2720
2721 if DTRACE_NEEDS_OBJECTS
2722-libmemcached_la_DEPENDENCIES += libmemcached_probes.o
2723+libmemcached_libmemcached_la_DEPENDENCIES += libmemcached/libmemcached_probes.o
2724 endif
2725
2726-SUFFIXES= .d
2727-
2728-dtrace_probes.h: libmemcached_probes.d
2729- $(DTRACE) $(DTRACEFLAGS) -h -o dtrace_probes.h -s libmemcached_probes.d
2730-
2731-libmemcached_probes.o: libmemcached_probes.d $(libmemcached_la_OBJECTS)
2732- $(DTRACE) $(DTRACEFLAGS) -o .libs/libmemcached_probes.o -G -s libmemcached_probes.d `grep '^pic_object' *.lo | cut -f 2 -d\'`
2733- $(DTRACE) $(DTRACEFLAGS) -o libmemcached_probes.o -G -s libmemcached_probes.d `grep non_pic_object *.lo | cut -f 2 -d\' `
2734+SUFFIXES+= .d
2735+
2736+libmemcached/dtrace_probes.h: libmemcached/libmemcached_probes.d
2737+ $(DTRACE) $(DTRACEFLAGS) -h -o libmemcached/dtrace_probes.h -s libmemcached/libmemcached_probes.d
2738+
2739+libmemcached/libmemcached_probes.o: libmemcached/libmemcached_probes.d $(libmemcached_libmemcached_la_OBJECTS)
2740+ $(DTRACE) $(DTRACEFLAGS) -o libmemcached/.libs/libmemcached_probes.o -G -s libmemcached/libmemcached_probes.d `grep '^pic_object' *.lo | cut -f 2 -d\'`
2741+ $(DTRACE) $(DTRACEFLAGS) -o libmemcached/libmemcached_probes.o -G -s libmemcached/libmemcached_probes.d `grep non_pic_object *.lo | cut -f 2 -d\' `
2742
2743
2744=== removed file 'libmemcached/libmemcached.ver'
2745--- libmemcached/libmemcached.ver 2009-10-04 18:22:43 +0000
2746+++ libmemcached/libmemcached.ver 1970-01-01 00:00:00 +0000
2747@@ -1,1 +0,0 @@
2748-libmemcached_3 { global: *; };
2749
2750=== modified file 'libmemcached/memcached.c'
2751--- libmemcached/memcached.c 2009-12-17 07:20:58 +0000
2752+++ libmemcached/memcached.c 2009-12-18 01:27:26 +0000
2753@@ -39,7 +39,6 @@
2754 ptr->io_bytes_watermark= 65 * 1024;
2755
2756 WATCHPOINT_ASSERT_INITIALIZED(&ptr->result);
2757- WATCHPOINT_ASSERT_INITIALIZED(&ptr->hashkit);
2758
2759 return ptr;
2760 }
2761
2762=== modified file 'libmemcached/memcached.h'
2763--- libmemcached/memcached.h 2009-12-17 08:34:22 +0000
2764+++ libmemcached/memcached.h 2009-12-18 01:27:26 +0000
2765@@ -31,6 +31,7 @@
2766 // Everything above this line must be in the order specified.
2767 #include <libmemcached/behavior.h>
2768 #include <libmemcached/callback.h>
2769+#include <libmemcached/dump.h>
2770 #include <libmemcached/get.h>
2771 #include <libmemcached/result.h>
2772 #include <libmemcached/server.h>
2773@@ -126,6 +127,7 @@
2774 void *user_data;
2775 time_t next_distribution_rebuild;
2776 size_t prefix_key_length;
2777+ uint32_t number_of_replicas;
2778 memcached_hash_t distribution_hash;
2779 memcached_result_st result;
2780 memcached_continuum_item_st *continuum;
2781@@ -137,9 +139,8 @@
2782 memcached_calloc_fn call_calloc;
2783 memcached_trigger_key_fn get_key_failure;
2784 memcached_trigger_delete_key_fn delete_trigger;
2785+ memcached_callback_st *callbacks;
2786 char prefix_key[MEMCACHED_PREFIX_KEY_MAX_SIZE];
2787- uint32_t number_of_replicas;
2788- memcached_callback_st *callbacks;
2789 };
2790
2791 LIBMEMCACHED_API
2792@@ -322,10 +323,6 @@
2793 unsigned int number_of_callbacks);
2794
2795 LIBMEMCACHED_API
2796-memcached_return_t memcached_dump(memcached_st *ptr, memcached_dump_fn *function, void *context, uint32_t number_of_callbacks);
2797-
2798-
2799-LIBMEMCACHED_API
2800 memcached_return_t memcached_set_memory_allocators(memcached_st *ptr,
2801 memcached_malloc_fn mem_malloc,
2802 memcached_free_fn mem_free,
2803
2804=== removed file 'libmemcached/protocol/libmemcachedprotocol.ver'
2805--- libmemcached/protocol/libmemcachedprotocol.ver 2009-09-17 13:29:16 +0000
2806+++ libmemcached/protocol/libmemcachedprotocol.ver 1970-01-01 00:00:00 +0000
2807@@ -1,1 +0,0 @@
2808-libmemcachedprotocol_0 { global: *; };
2809
2810=== modified file 'libmemcached/result.c'
2811--- libmemcached/result.c 2009-12-16 23:01:10 +0000
2812+++ libmemcached/result.c 2009-12-18 01:27:26 +0000
2813@@ -1,5 +1,5 @@
2814 /* LibMemcached
2815- * Copyright (C) 2006-2009 Brian Aker
2816+ * Copyright (C) 2006-2009 Brian Aker
2817 * All rights reserved.
2818 *
2819 * Use and distribution licensed under the BSD license. See
2820@@ -9,15 +9,15 @@
2821 *
2822 */
2823
2824-/*
2825+/*
2826 memcached_result_st are used to internally represent the return values from
2827- memcached. We use a structure so that long term as identifiers are added
2828- to memcached we will be able to absorb new attributes without having
2829+ memcached. We use a structure so that long term as identifiers are added
2830+ to memcached we will be able to absorb new attributes without having
2831 to addjust the entire API.
2832 */
2833 #include "common.h"
2834
2835-memcached_result_st *memcached_result_create(memcached_st *memc,
2836+memcached_result_st *memcached_result_create(memcached_st *memc,
2837 memcached_result_st *ptr)
2838 {
2839 WATCHPOINT_ASSERT(memc && memc->options.is_initialized);
2840@@ -29,7 +29,7 @@
2841 }
2842 else
2843 {
2844- ptr= memc->call_malloc(memc, sizeof(memcached_result_st));
2845+ ptr= memc->call_calloc(memc, 1, sizeof(memcached_result_st));
2846
2847 if (ptr == NULL)
2848 return NULL;
2849@@ -72,7 +72,14 @@
2850
2851 if (memcached_is_allocated(ptr))
2852 {
2853- free(ptr);
2854+ if (ptr->root != NULL)
2855+ {
2856+ ptr->root->call_free(ptr->root, ptr);
2857+ }
2858+ else
2859+ {
2860+ free(ptr);
2861+ }
2862 }
2863 else
2864 {
2865
2866=== modified file 'libmemcached/string.c'
2867--- libmemcached/string.c 2009-12-16 23:01:10 +0000
2868+++ libmemcached/string.c 2009-12-18 01:27:26 +0000
2869@@ -50,7 +50,7 @@
2870 /* Saving malloc calls :) */
2871 if (string)
2872 {
2873- WATCHPOINT_ASSERT(memc->options.is_safe && string->options.is_initialized == false);
2874+ WATCHPOINT_ASSERT(string->options.is_initialized == false);
2875
2876 memset(string, 0, sizeof(memcached_string_st));
2877 }
2878@@ -82,7 +82,7 @@
2879 return string;
2880 }
2881
2882-memcached_return_t memcached_string_append_character(memcached_string_st *string,
2883+memcached_return_t memcached_string_append_character(memcached_string_st *string,
2884 char character)
2885 {
2886 memcached_return_t rc;
2887@@ -139,7 +139,7 @@
2888 memcached_return_t memcached_string_reset(memcached_string_st *string)
2889 {
2890 string->end= string->string;
2891-
2892+
2893 return MEMCACHED_SUCCESS;
2894 }
2895
2896
2897=== removed file 'libmemcached/util/libmemcachedutil.ver'
2898--- libmemcached/util/libmemcachedutil.ver 2009-05-20 18:34:05 +0000
2899+++ libmemcached/util/libmemcachedutil.ver 1970-01-01 00:00:00 +0000
2900@@ -1,1 +0,0 @@
2901-libmemcachedutil_0 { global: *; };
2902
2903=== modified file 'libmemcached/watchpoint.h'
2904--- libmemcached/watchpoint.h 2009-12-16 23:01:10 +0000
2905+++ libmemcached/watchpoint.h 2009-12-18 01:27:26 +0000
2906@@ -1,5 +1,5 @@
2907 /* LibMemcached
2908- * Copyright (C) 2006-2009 Brian Aker
2909+ * Copyright (C) 2006-2009 Brian Aker
2910 * All rights reserved.
2911 *
2912 * Use and distribution licensed under the BSD license. See
2913@@ -17,16 +17,16 @@
2914
2915 #include <assert.h>
2916
2917-#define WATCHPOINT fprintf(stderr, "\nWATCHPOINT %s:%d (%s)\n", __FILE__, __LINE__,__func__);fflush(stdout);
2918-#define WATCHPOINT_ERROR(A) fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout);
2919-#define WATCHPOINT_IFERROR(A) if(A != MEMCACHED_SUCCESS)fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout);
2920-#define WATCHPOINT_STRING(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__,A);fflush(stdout);
2921-#define WATCHPOINT_STRING_LENGTH(A,B) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %.*s\n", __FILE__, __LINE__,__func__,(int)B,A);fflush(stdout);
2922-#define WATCHPOINT_NUMBER(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %zu\n", __FILE__, __LINE__,__func__,(size_t)(A));fflush(stdout);
2923-#define WATCHPOINT_ERRNO(A) fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__, strerror(A));fflush(stdout);
2924-#define WATCHPOINT_ASSERT_PRINT(A,B,C) if(!(A)){fprintf(stderr, "\nWATCHPOINT ASSERT %s:%d (%s) ", __FILE__, __LINE__,__func__);fprintf(stderr, (B),(C));fprintf(stderr,"\n");fflush(stdout);}assert((A));
2925-#define WATCHPOINT_ASSERT(A) assert((A));
2926-#define WATCHPOINT_ASSERT_INITIALIZED(A) (memcached_is_initialized((A));
2927+#define WATCHPOINT do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s)\n", __FILE__, __LINE__,__func__);fflush(stdout); } while (0)
2928+#define WATCHPOINT_ERROR(A) do {fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout); } while (0)
2929+#define WATCHPOINT_IFERROR(A) do { if(A != MEMCACHED_SUCCESS)fprintf(stderr, "\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout); } while (0)
2930+#define WATCHPOINT_STRING(A) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__,A);fflush(stdout); } while (0)
2931+#define WATCHPOINT_STRING_LENGTH(A,B) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %.*s\n", __FILE__, __LINE__,__func__,(int)B,A);fflush(stdout); } while (0)
2932+#define WATCHPOINT_NUMBER(A) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %zu\n", __FILE__, __LINE__,__func__,(size_t)(A));fflush(stdout); } while (0)
2933+#define WATCHPOINT_ERRNO(A) do { fprintf(stderr, "\nWATCHPOINT %s:%d (%s) %s\n", __FILE__, __LINE__,__func__, strerror(A));fflush(stdout); } while (0)
2934+#define WATCHPOINT_ASSERT_PRINT(A,B,C) do { if(!(A)){fprintf(stderr, "\nWATCHPOINT ASSERT %s:%d (%s) ", __FILE__, __LINE__,__func__);fprintf(stderr, (B),(C));fprintf(stderr,"\n");fflush(stdout);}assert((A)); } while (0)
2935+#define WATCHPOINT_ASSERT(A) assert((A))
2936+#define WATCHPOINT_ASSERT_INITIALIZED(A) assert(memcached_is_initialized((A)))
2937
2938 #else
2939
2940
2941=== modified file 'm4/pandora_canonical.m4'
2942--- m4/pandora_canonical.m4 2009-12-02 23:07:36 +0000
2943+++ m4/pandora_canonical.m4 2009-12-18 01:27:26 +0000
2944@@ -4,7 +4,7 @@
2945 dnl with or without modifications, as long as this notice is preserved.
2946
2947 dnl Which version of the canonical setup we're using
2948-AC_DEFUN([PANDORA_CANONICAL_VERSION],[0.80])
2949+AC_DEFUN([PANDORA_CANONICAL_VERSION],[0.86])
2950
2951 AC_DEFUN([PANDORA_FORCE_DEPEND_TRACKING],[
2952 dnl Force dependency tracking on for Sun Studio builds
2953@@ -97,13 +97,6 @@
2954
2955 PANDORA_LIBTOOL
2956
2957- AS_IF([test "$lt_cv_prog_gnu_ld" = "yes"],[
2958- ${LD} --help | grep default-symver >/dev/null 2>&1
2959- AS_IF([test $? -eq 0],[
2960- AM_LDFLAGS="${AM_LDFLAGS} -Wl,--default-symver"
2961- ])
2962- ])
2963-
2964 dnl autoconf doesn't automatically provide a fail-if-no-C++ macro
2965 dnl so we check c++98 features and fail if we don't have them, mainly
2966 dnl for that reason
2967@@ -176,12 +169,7 @@
2968 dnl alloca - but we need to know it anyway for check_stack_overrun.
2969 PANDORA_STACK_DIRECTION
2970
2971- save_LIBS="${LIBS}"
2972- LIBS=""
2973- AC_CHECK_LIB(m, floor, [], AC_CHECK_LIB(m, __infinity))
2974- LIBM="${LIBS}"
2975- LIBS="${save_LIBS}"
2976- AC_SUBST([LIBM])
2977+ AC_CHECK_LIBM
2978
2979 AC_CHECK_FUNC(setsockopt, [], [AC_CHECK_LIB(socket, setsockopt)])
2980 AC_CHECK_FUNC(bind, [], [AC_CHECK_LIB(bind, bind)])
2981@@ -244,6 +232,5 @@
2982 AC_SUBST([AM_CFLAGS])
2983 AC_SUBST([AM_CXXFLAGS])
2984 AC_SUBST([AM_CPPFLAGS])
2985- AC_SUBST([AM_LDFLAGS])
2986
2987 ])
2988
2989=== modified file 'm4/pandora_check_cxx_standard.m4'
2990--- m4/pandora_check_cxx_standard.m4 2009-07-08 07:37:38 +0000
2991+++ m4/pandora_check_cxx_standard.m4 2009-12-18 01:27:26 +0000
2992@@ -8,9 +8,16 @@
2993 AS_IF([test "$GCC" = "yes"],
2994 [AS_IF([test "$ac_cv_cxx_compile_cxx0x_native" = "yes"],[],
2995 [AS_IF([test "$ac_cv_cxx_compile_cxx0x_gxx" = "yes"],
2996- [CXXFLAGS="-std=gnu++0x ${CXXFLAGS}"],
2997- [CXXFLAGS="-std=gnu++98"])
2998+ [CXX_STANDARD="-std=gnu++0x"],
2999+ [CXX_STANDARD="-std=gnu++98"])
3000 ])
3001 ])
3002+ AM_CXXFLAGS="${CXX_STANDARD} ${AM_CXXFLAGS}"
3003+
3004+ save_CXXFLAGS="${CXXFLAGS}"
3005+ CXXFLAGS="${CXXFLAGS} ${CXX_STANDARD}"
3006 AC_CXX_HEADER_STDCXX_98
3007+ CXXFLAGS="${save_CXXFLAGS}"
3008+
3009+ AC_SUBST([CXX_STANDARD])
3010 ])
3011
3012=== modified file 'm4/pandora_cinttypes.m4'
3013--- m4/pandora_cinttypes.m4 2009-12-02 02:57:53 +0000
3014+++ m4/pandora_cinttypes.m4 2009-12-18 01:27:26 +0000
3015@@ -8,6 +8,8 @@
3016 [AC_REQUIRE([PANDORA_CXX_CSTDINT])
3017 AC_MSG_CHECKING(the location of cinttypes)
3018 AC_LANG_PUSH(C++)
3019+ save_CXXFLAGS="${CXXFLAGS}"
3020+ CXXFLAGS="${CXX_STANDARD} ${CXXFLAGS}"
3021 ac_cv_cxx_cinttypes=""
3022 for location in tr1/cinttypes boost/cinttypes cinttypes; do
3023 if test -z "$ac_cv_cxx_cinttypes"; then
3024@@ -18,14 +20,15 @@
3025 fi
3026 done
3027 AC_LANG_POP()
3028+ CXXFLAGS="${save_CXXFLAGS}"
3029 if test -n "$ac_cv_cxx_cinttypes"; then
3030 AC_MSG_RESULT([$ac_cv_cxx_cinttypes])
3031 else
3032- AC_DEFINE([__STDC_LIMIT_MACROS],[1],[Use STDC Limit Macros in C++])
3033 ac_cv_cxx_cinttypes="<inttypes.h>"
3034 AC_MSG_RESULT()
3035 AC_MSG_WARN([Could not find a cinttypes header.])
3036 fi
3037+ AC_DEFINE([__STDC_LIMIT_MACROS],[1],[Use STDC Limit Macros in C++])
3038 AC_DEFINE_UNQUOTED(CINTTYPES_H,$ac_cv_cxx_cinttypes,
3039 [the location of <cinttypes>])
3040 ])
3041
3042=== modified file 'm4/pandora_cstdint.m4'
3043--- m4/pandora_cstdint.m4 2009-12-02 02:57:53 +0000
3044+++ m4/pandora_cstdint.m4 2009-12-18 01:27:26 +0000
3045@@ -7,6 +7,8 @@
3046 AC_DEFUN([PANDORA_CXX_CSTDINT],
3047 [AC_MSG_CHECKING(the location of cstdint)
3048 AC_LANG_PUSH(C++)
3049+ save_CXXFLAGS="${CXXFLAGS}"
3050+ CXXFLAGS="${CXX_STANDARD} ${CXXFLAGS}"
3051 ac_cv_cxx_cstdint=""
3052 for location in tr1/cstdint boost/cstdint cstdint; do
3053 if test -z "$ac_cv_cxx_cstdint"; then
3054@@ -16,6 +18,7 @@
3055 fi
3056 done
3057 AC_LANG_POP()
3058+ CXXFLAGS="${save_CXXFLAGS}"
3059 if test -n "$ac_cv_cxx_cstdint"; then
3060 AC_MSG_RESULT([$ac_cv_cxx_cstdint])
3061 else
3062
3063=== modified file 'm4/pandora_cxx_demangle.m4'
3064--- m4/pandora_cxx_demangle.m4 2009-12-02 04:43:41 +0000
3065+++ m4/pandora_cxx_demangle.m4 2009-12-18 01:27:26 +0000
3066@@ -9,12 +9,15 @@
3067
3068 AC_DEFUN([PANDORA_CXX_DEMANGLE],[
3069 AC_LANG_PUSH([C++])
3070+ save_CXXFLAGS="${CXXFLAGS}"
3071+ CXXFLAGS="${CXX_STANDARD} ${CXXFLAGS}"
3072 AC_CHECK_HEADERS(cxxabi.h)
3073 AC_CACHE_CHECK([checking for abi::__cxa_demangle], pandora_cv_cxa_demangle,
3074 [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <cxxabi.h>]], [[
3075 char *foo= 0; int bar= 0;
3076 foo= abi::__cxa_demangle(foo, foo, 0, &bar);
3077 ]])],[pandora_cv_cxa_demangle=yes],[pandora_cv_cxa_demangle=no])])
3078+ CXXFLAGS="${save_CXXFLAGS}"
3079 AC_LANG_POP()
3080
3081 AS_IF([test "x$pandora_cv_cxa_demangle" = xyes],[
3082
3083=== modified file 'm4/pandora_drizzle_build.m4'
3084--- m4/pandora_drizzle_build.m4 2009-12-02 04:43:41 +0000
3085+++ m4/pandora_drizzle_build.m4 2009-12-18 01:27:26 +0000
3086@@ -10,10 +10,7 @@
3087 AC_DEFUN([PANDORA_DRIZZLE_BUILD],[
3088
3089 dnl We need to turn on our CXXFLAGS to make sure it shows up correctly
3090- save_CXXFLAGS="${CXXFLAGS}"
3091- CXXFLAGS="${CXXFLAGS} ${AM_CXXFLAGS}"
3092 PANDORA_CXX_STL_HASH
3093- CXXFLAGS="${save_CXXFLAGS}"
3094
3095 PANDORA_CXX_CSTDINT
3096 PANDORA_CXX_CINTTYPES
3097@@ -39,7 +36,7 @@
3098 AC_HEADER_SYS_WAIT
3099 AC_HEADER_STDBOOL
3100
3101- AC_CHECK_HEADERS(sys/fpu.h fpu_control.h ieeefp.h)
3102+ AC_CHECK_HEADERS(sys/types.h sys/fpu.h fpu_control.h ieeefp.h)
3103 AC_CHECK_HEADERS(select.h sys/select.h)
3104 AC_CHECK_HEADERS(utime.h sys/utime.h )
3105 AC_CHECK_HEADERS(synch.h sys/mman.h sys/socket.h)
3106@@ -70,8 +67,32 @@
3107 # include <curses.h>
3108 #endif
3109 ]])
3110- AC_CHECK_TYPES([ulong])
3111+ AC_CHECK_TYPES([uint, ulong])
3112
3113 PANDORA_CXX_DEMANGLE
3114
3115+ AH_TOP([
3116+#ifndef __CONFIG_H__
3117+#define __CONFIG_H__
3118+
3119+#if defined(i386) && !defined(__i386__)
3120+#define __i386__
3121+#endif
3122+
3123+ ])
3124+ AH_BOTTOM([
3125+#if defined(__cplusplus)
3126+# include CSTDINT_H
3127+# include CINTTYPES_H
3128+#else
3129+# include <stdint.h>
3130+# include <inttypes.h>
3131+#endif
3132+
3133+#if !defined(HAVE_ULONG) && !defined(__USE_MISC)
3134+typedef unsigned long int ulong;
3135+#endif
3136+
3137+#endif /* __CONFIG_H__ */
3138+ ])
3139 ])
3140
3141=== modified file 'm4/pandora_have_libreadline.m4'
3142--- m4/pandora_have_libreadline.m4 2009-12-02 02:57:53 +0000
3143+++ m4/pandora_have_libreadline.m4 2009-12-18 01:27:26 +0000
3144@@ -105,9 +105,9 @@
3145 [Does system provide rl_compentry_func_t])
3146 ])
3147
3148- AC_LANG_PUSH(C++)
3149 save_CXXFLAGS="${CXXFLAGS}"
3150 CXXFLAGS="${AM_CXXFLAGS} ${CXXFLAGS}"
3151+ AC_LANG_PUSH(C++)
3152 AC_CACHE_CHECK([rl_compentry_func_t works], [pandora_cv_rl_compentry_works],[
3153 AC_COMPILE_IFELSE([
3154 AC_LANG_PROGRAM([[
3155
3156=== modified file 'm4/pandora_libtool.m4'
3157--- m4/pandora_libtool.m4 2009-07-08 07:37:38 +0000
3158+++ m4/pandora_libtool.m4 2009-12-18 01:27:26 +0000
3159@@ -4,7 +4,17 @@
3160 dnl with or without modifications, as long as this notice is preserved.
3161
3162 AC_DEFUN([PANDORA_LIBTOOL],[
3163+ AC_REQUIRE([AC_DISABLE_STATIC])
3164 AC_REQUIRE([AC_PROG_LIBTOOL])
3165+ m4_ifndef([LT_PREREQ],[
3166+ pandora_have_old_libtool=yes
3167+ ],[
3168+ pandora_have_old_libtool=no
3169+ ])
3170+ AS_IF([test "$SUNCC" = "yes" -a "${pandora_have_old_libtool}" = "yes"],[
3171+ AC_MSG_ERROR([Building ${PACKAGE} with Sun Studio requires at least libtool 2.2])
3172+ ])
3173+
3174 dnl By requiring AC_PROG_LIBTOOL, we should force the macro system to read
3175 dnl libtool.m4, where in 2.2 AC_PROG_LIBTOOL is an alias for LT_INIT
3176 dnl Then, if we're on 2.2, we should have LT_LANG, so we'll call it.
3177
3178=== modified file 'm4/pandora_shared_ptr.m4'
3179--- m4/pandora_shared_ptr.m4 2009-07-08 07:37:38 +0000
3180+++ m4/pandora_shared_ptr.m4 2009-12-18 01:27:26 +0000
3181@@ -20,6 +20,8 @@
3182 AC_DEFUN([PANDORA_SHARED_PTR],[
3183 AC_REQUIRE([PANDORA_CHECK_CXX_STANDARD])
3184 AC_LANG_PUSH(C++)
3185+ save_CXXFLAGS="${CXXFLAGS}"
3186+ CXXFLAGS="${CXX_STANDARD} ${CXXFLAGS}"
3187 AC_CHECK_HEADERS(memory tr1/memory boost/shared_ptr.hpp)
3188 AC_CACHE_CHECK([the location of shared_ptr header file],
3189 [ac_cv_shared_ptr_h],[
3190@@ -52,5 +54,6 @@
3191 AC_DEFINE_UNQUOTED([SHARED_PTR_NAMESPACE],
3192 ${ac_cv_shared_ptr_namespace},
3193 [The namespace in which SHARED_PTR can be found])
3194+ CXXFLAGS="${save_CXXFLAGS}"
3195 AC_LANG_POP()
3196 ])
3197
3198=== modified file 'm4/pandora_stl_hash.m4'
3199--- m4/pandora_stl_hash.m4 2009-12-02 23:07:36 +0000
3200+++ m4/pandora_stl_hash.m4 2009-12-18 01:27:26 +0000
3201@@ -12,6 +12,8 @@
3202
3203 AC_DEFUN([PANDORA_CXX_STL_HASH],
3204 [AC_MSG_CHECKING(the location of hash_map)
3205+ save_CXXFLAGS="${CXXFLAGS}"
3206+ CXXFLAGS="${AM_CXXFLAGS} ${CXXFLAGS}"
3207 AC_LANG_PUSH(C++)
3208 ac_cv_cxx_hash_map=""
3209 for location in "" "ext/" "tr1/" ; do
3210@@ -103,5 +105,6 @@
3211 AS_IF([test $ac_cv_redefine_hash_string = yes],[
3212 AC_DEFINE(REDEFINE_HASH_STRING, 1, [if hash<string> needs to be defined])
3213 ])
3214+ CXXFLAGS="${save_CXXFLAGS}"
3215 AC_LANG_POP()
3216 ])
3217
3218=== modified file 'm4/pandora_warnings.m4'
3219--- m4/pandora_warnings.m4 2009-12-02 02:57:53 +0000
3220+++ m4/pandora_warnings.m4 2009-12-18 01:27:26 +0000
3221@@ -50,6 +50,7 @@
3222
3223 AS_IF([test "$ac_profiling" = "yes"],[
3224 CC_PROFILING="-pg"
3225+ GCOV_LIBS="-pg -lgcov"
3226 save_LIBS="${LIBS}"
3227 LIBS=""
3228 AC_CHECK_LIB(c_p, read)
3229@@ -61,7 +62,12 @@
3230 ])
3231
3232 AS_IF([test "$ac_coverage" = "yes"],
3233- [CC_COVERAGE="-fprofile-arcs -ftest-coverage"])
3234+ [
3235+ CC_COVERAGE="--coverage"
3236+ GCOV_LIBS="-lgcov"
3237+ ])
3238+
3239+
3240
3241 AS_IF([test "$ac_cv_warnings_as_errors" = "yes"],
3242 [W_FAIL="-Werror"])
3243@@ -129,9 +135,9 @@
3244
3245 AS_IF([test "$INTELCC" = "yes"],[
3246 m4_if(PW_LESS_WARNINGS,[no],[
3247- BASE_WARNINGS="-w1 -Wall -Werror -Wcheck -Wformat -Wp64 -Woverloaded-virtual -Wcast-qual"
3248+ BASE_WARNINGS="-w1 -Werror -Wcheck -Wformat -Wp64 -Woverloaded-virtual -Wcast-qual"
3249 ],[
3250- BASE_WARNINGS="-w1 -Wall -Wcheck -Wformat -Wp64 -Woverloaded-virtual -Wcast-qual -diag-disable 981"
3251+ BASE_WARNINGS="-w1 -Wcheck -Wformat -Wp64 -Woverloaded-virtual -Wcast-qual -diag-disable 981"
3252 ])
3253 CC_WARNINGS="${BASE_WARNINGS}"
3254 CXX_WARNINGS="${BASE_WARNINGS}"
3255@@ -217,8 +223,8 @@
3256 AC_INCLUDES_DEFAULT])],
3257 [ac_cv_safe_to_use_Wredundant_decls_=yes],
3258 [ac_cv_safe_to_use_Wredundant_decls_=no])
3259- CXXFLAGS="${save_CXXFLAGS}"
3260- AC_LANG_POP()])
3261+ CXXFLAGS="${save_CXXFLAGS}"
3262+ AC_LANG_POP()])
3263 AS_IF([test "$ac_cv_safe_to_use_Wredundant_decls_" = "yes"],
3264 [CXX_WARNINGS="${CXX_WARNINGS} -Wredundant-decls"],
3265 [CXX_WARNINGS="${CXX_WARNINGS} -Wno-redundant-decls"])
3266@@ -339,5 +345,6 @@
3267 AC_SUBST(PROTOSKIP_WARNINGS)
3268 AC_SUBST(INNOBASE_SKIP_WARNINGS)
3269 AC_SUBST(NO_WERROR)
3270+ AC_SUBST([GCOV_LIBS])
3271
3272 ])
3273
3274=== renamed file 'support/Makefile.am' => 'support/include.am'
3275--- support/Makefile.am 2009-05-01 20:51:45 +0000
3276+++ support/include.am 2009-12-18 01:27:26 +0000
3277@@ -1,4 +1,11 @@
3278-EXTRA_DIST = libmemcached.spec set_benchmark.sh libmemcached-fc.spec.in
3279+# vim:ft=automake
3280+# included from Top Level Makefile.am
3281+# All paths should be given relative to the root
3282+
3283+EXTRA_DIST += \
3284+ support/libmemcached.spec \
3285+ support/libmemcached-fc.spec.in \
3286+ support/set_benchmark.sh
3287
3288 pkgconfigdir = $(libdir)/pkgconfig
3289-pkgconfig_DATA = libmemcached.pc
3290+pkgconfig_DATA = support/libmemcached.pc
3291
3292=== modified file 'support/libmemcached.spec.in'
3293--- support/libmemcached.spec.in 2009-12-16 20:03:28 +0000
3294+++ support/libmemcached.spec.in 2009-12-18 01:27:26 +0000
3295@@ -88,6 +88,7 @@
3296 %{_libdir}/libmemcachedutil.so.*
3297 %{_libdir}/libmemcachedprotocol.so.*
3298 %{_mandir}/man1/mem*
3299+%exclude libhashkit/*
3300
3301
3302 %files devel
3303
3304=== modified file 'tests/function.c'
3305--- tests/function.c 2009-12-17 08:34:22 +0000
3306+++ tests/function.c 2009-12-18 01:27:26 +0000
3307@@ -3554,26 +3554,65 @@
3308
3309 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3310 {
3311+#ifdef HARD_MALLOC_TESTS
3312+ void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3313+ free(real_ptr);
3314+#else
3315 free(mem);
3316+#endif
3317 }
3318
3319 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3320 {
3321+#ifdef HARD_MALLOC_TESTS
3322+ void *ret= malloc(size + 8);
3323+ if (ret != NULL)
3324+ {
3325+ ret= (void*)((caddr_t)ret + 8);
3326+ }
3327+#else
3328 void *ret= malloc(size);
3329+#endif
3330+
3331 if (ret != NULL)
3332+ {
3333 memset(ret, 0xff, size);
3334+ }
3335
3336 return ret;
3337 }
3338
3339 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3340 {
3341+#ifdef HARD_MALLOC_TESTS
3342+ void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3343+ void *nmem= realloc(real_ptr, size + 8);
3344+
3345+ void *ret= NULL;
3346+ if (nmem != NULL)
3347+ {
3348+ ret= (void*)((caddr_t)nmem + 8);
3349+ }
3350+
3351+ return ret;
3352+#else
3353 return realloc(mem, size);
3354+#endif
3355 }
3356
3357 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3358 {
3359+#ifdef HARD_MALLOC_TESTS
3360+ void *mem= my_malloc(ptr, nelem * size);
3361+ if (mem)
3362+ {
3363+ memset(mem, 0, nelem * size);
3364+ }
3365+
3366+ return mem;
3367+#else
3368 return calloc(nelem, size);
3369+#endif
3370 }
3371
3372 static test_return_t set_prefix(memcached_st *memc)
3373@@ -3718,7 +3757,27 @@
3374 return TEST_SUCCESS;
3375 }
3376
3377-static test_return_t enable_consistent(memcached_st *memc)
3378+static test_return_t enable_consistent_crc(memcached_st *memc)
3379+{
3380+ test_return_t rc;
3381+ memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3382+ memcached_hash_t hash;
3383+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3384+ if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3385+ return rc;
3386+
3387+ value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3388+ test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3389+
3390+ hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3391+
3392+ if (hash != MEMCACHED_HASH_CRC)
3393+ return TEST_SKIPPED;
3394+
3395+ return TEST_SUCCESS;
3396+}
3397+
3398+static test_return_t enable_consistent_hsieh(memcached_st *memc)
3399 {
3400 test_return_t rc;
3401 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3402@@ -5703,7 +5762,8 @@
3403 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
3404 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
3405 {"gets", (test_callback_fn)enable_cas, 0, tests},
3406- {"consistent", (test_callback_fn)enable_consistent, 0, tests},
3407+ {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
3408+ {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
3409 #ifdef MEMCACHED_ENABLE_DEPRECATED
3410 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
3411 #endif
3412@@ -5718,7 +5778,7 @@
3413 {"generate", 0, 0, generate_tests},
3414 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
3415 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
3416- {"generate_hsieh_consistent", (test_callback_fn)enable_consistent, 0, generate_tests},
3417+ {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
3418 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
3419 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
3420 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
3421
3422=== added file 'tests/hashkit_functions.c'
3423--- tests/hashkit_functions.c 1970-01-01 00:00:00 +0000
3424+++ tests/hashkit_functions.c 2009-12-18 01:27:26 +0000
3425@@ -0,0 +1,363 @@
3426+/* libHashKit Functions Test
3427+ * Copyright (C) 2006-2009 Brian Aker
3428+ * All rights reserved.
3429+ *
3430+ * Use and distribution licensed under the BSD license. See
3431+ * the COPYING file in the parent directory for full text.
3432+ */
3433+
3434+#include <assert.h>
3435+#include <stdio.h>
3436+#include <stdlib.h>
3437+#include <string.h>
3438+
3439+#include <libhashkit/hashkit.h>
3440+
3441+#include "test.h"
3442+
3443+#include "hash_results.h"
3444+
3445+static hashkit_st global_hashk;
3446+
3447+/**
3448+ @brief hash_test_st is a structure we use in testing. It is currently empty.
3449+*/
3450+typedef struct hash_test_st hash_test_st;
3451+
3452+struct hash_test_st
3453+{
3454+ bool _unused;
3455+};
3456+
3457+static test_return_t init_test(void *not_used __attribute__((unused)))
3458+{
3459+ hashkit_st hashk;
3460+ hashkit_st *hashk_ptr;
3461+
3462+ hashk_ptr= hashkit_create(&hashk);
3463+ test_truth(hashk_ptr);
3464+ test_truth(hashk_ptr == &hashk);
3465+ test_truth(hashkit_is_initialized(&hashk) == true);
3466+ test_truth(hashkit_is_allocated(hashk_ptr) == false);
3467+
3468+ hashkit_free(hashk_ptr);
3469+
3470+ test_truth(hashkit_is_initialized(&hashk) == false);
3471+
3472+ return TEST_SUCCESS;
3473+}
3474+
3475+static test_return_t allocation_test(void *not_used __attribute__((unused)))
3476+{
3477+ hashkit_st *hashk_ptr;
3478+
3479+ hashk_ptr= hashkit_create(NULL);
3480+ test_truth(hashk_ptr);
3481+ test_truth(hashkit_is_allocated(hashk_ptr) == true);
3482+ test_truth(hashkit_is_initialized(hashk_ptr) == true);
3483+ hashkit_free(hashk_ptr);
3484+
3485+ return TEST_SUCCESS;
3486+}
3487+
3488+static test_return_t clone_test(hashkit_st *hashk)
3489+{
3490+ // First we make sure that the testing system is giving us what we expect.
3491+ assert(&global_hashk == hashk);
3492+
3493+ // Second we test if hashk is even valid
3494+ test_truth(hashkit_is_initialized(hashk) == true);
3495+
3496+ /* All null? */
3497+ {
3498+ hashkit_st *hashk_ptr;
3499+ hashk_ptr= hashkit_clone(NULL, NULL);
3500+ test_truth(hashk_ptr);
3501+ test_truth(hashkit_is_allocated(hashk_ptr) == true);
3502+ test_truth(hashkit_is_initialized(hashk_ptr) == true);
3503+ hashkit_free(hashk_ptr);
3504+ }
3505+
3506+ /* Can we init from null? */
3507+ {
3508+ hashkit_st *hashk_ptr;
3509+
3510+ hashk_ptr= hashkit_clone(NULL, hashk);
3511+
3512+ test_truth(hashk_ptr);
3513+ test_truth(hashkit_is_allocated(hashk_ptr) == true);
3514+ test_truth(hashkit_is_initialized(hashk_ptr) == true);
3515+
3516+ test_truth(hashk_ptr->distribution == hashk->distribution);
3517+ test_truth(hashk_ptr->continuum_count == hashk->continuum_count);
3518+ test_truth(hashk_ptr->continuum_points_count == hashk->continuum_points_count);
3519+ test_truth(hashk_ptr->list_size == hashk->list_size);
3520+ test_truth(hashk_ptr->context_size == hashk->context_size);
3521+ test_truth(hashk_ptr->continuum == NULL);
3522+ test_truth(hashk_ptr->hash_fn == hashk->hash_fn);
3523+ test_truth(hashk_ptr->active_fn == hashk->active_fn);
3524+ test_truth(hashk_ptr->continuum_hash_fn == hashk->continuum_hash_fn);
3525+ test_truth(hashk_ptr->continuum_key_fn == hashk->continuum_key_fn);
3526+ test_truth(hashk_ptr->sort_fn == hashk->sort_fn);
3527+ test_truth(hashk_ptr->weight_fn == hashk->weight_fn);
3528+ test_truth(hashk_ptr->list == hashk->list);
3529+
3530+ hashkit_free(hashk_ptr);
3531+ }
3532+
3533+ /* Can we init from struct? */
3534+ {
3535+ hashkit_st declared_clone;
3536+ hashkit_st *hash_clone;
3537+
3538+ hash_clone= hashkit_clone(&declared_clone, NULL);
3539+ test_truth(hash_clone);
3540+
3541+ hashkit_free(hash_clone);
3542+ }
3543+
3544+ /* Can we init from struct? */
3545+ {
3546+ hashkit_st declared_clone;
3547+ hashkit_st *hash_clone;
3548+ memset(&declared_clone, 0 , sizeof(hashkit_st));
3549+ hash_clone= hashkit_clone(&declared_clone, hashk);
3550+ test_truth(hash_clone);
3551+ hashkit_free(hash_clone);
3552+ }
3553+
3554+ return TEST_SUCCESS;
3555+}
3556+
3557+
3558+static test_return_t md5_run (hashkit_st *hashk __attribute__((unused)))
3559+{
3560+ uint32_t x;
3561+ const char **ptr;
3562+
3563+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3564+ {
3565+ uint32_t hash_val;
3566+
3567+ hash_val= hashkit_md5(*ptr, strlen(*ptr));
3568+ test_truth(md5_values[x] == hash_val);
3569+ }
3570+
3571+ return TEST_SUCCESS;
3572+}
3573+
3574+static test_return_t crc_run (hashkit_st *hashk __attribute__((unused)))
3575+{
3576+ uint32_t x;
3577+ const char **ptr;
3578+
3579+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3580+ {
3581+ uint32_t hash_val;
3582+
3583+ hash_val= hashkit_crc32(*ptr, strlen(*ptr));
3584+ assert(crc_values[x] == hash_val);
3585+ }
3586+
3587+ return TEST_SUCCESS;
3588+}
3589+
3590+static test_return_t fnv1_64_run (hashkit_st *hashk __attribute__((unused)))
3591+{
3592+ uint32_t x;
3593+ const char **ptr;
3594+
3595+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3596+ {
3597+ uint32_t hash_val;
3598+
3599+ hash_val= hashkit_fnv1_64(*ptr, strlen(*ptr));
3600+ assert(fnv1_64_values[x] == hash_val);
3601+ }
3602+
3603+ return TEST_SUCCESS;
3604+}
3605+
3606+static test_return_t fnv1a_64_run (hashkit_st *hashk __attribute__((unused)))
3607+{
3608+ uint32_t x;
3609+ const char **ptr;
3610+
3611+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3612+ {
3613+ uint32_t hash_val;
3614+
3615+ hash_val= hashkit_fnv1a_64(*ptr, strlen(*ptr));
3616+ assert(fnv1a_64_values[x] == hash_val);
3617+ }
3618+
3619+ return TEST_SUCCESS;
3620+}
3621+
3622+static test_return_t fnv1_32_run (hashkit_st *hashk __attribute__((unused)))
3623+{
3624+ uint32_t x;
3625+ const char **ptr;
3626+
3627+
3628+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3629+ {
3630+ uint32_t hash_val;
3631+
3632+ hash_val= hashkit_fnv1_32(*ptr, strlen(*ptr));
3633+ assert(fnv1_32_values[x] == hash_val);
3634+ }
3635+
3636+ return TEST_SUCCESS;
3637+}
3638+
3639+static test_return_t fnv1a_32_run (hashkit_st *hashk __attribute__((unused)))
3640+{
3641+ uint32_t x;
3642+ const char **ptr;
3643+
3644+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3645+ {
3646+ uint32_t hash_val;
3647+
3648+ hash_val= hashkit_fnv1a_32(*ptr, strlen(*ptr));
3649+ assert(fnv1a_32_values[x] == hash_val);
3650+ }
3651+
3652+ return TEST_SUCCESS;
3653+}
3654+
3655+static test_return_t hsieh_run (hashkit_st *hashk __attribute__((unused)))
3656+{
3657+ uint32_t x;
3658+ const char **ptr;
3659+
3660+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3661+ {
3662+ uint32_t hash_val;
3663+
3664+#ifdef HAVE_HSIEH_HASH
3665+ hash_val= hashkit_hsieh(*ptr, strlen(*ptr));
3666+#else
3667+ hash_val= 1;
3668+#endif
3669+ assert(hsieh_values[x] == hash_val);
3670+ }
3671+
3672+ return TEST_SUCCESS;
3673+}
3674+
3675+static test_return_t murmur_run (hashkit_st *hashk __attribute__((unused)))
3676+{
3677+ uint32_t x;
3678+ const char **ptr;
3679+
3680+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3681+ {
3682+ uint32_t hash_val;
3683+
3684+ hash_val= hashkit_murmur(*ptr, strlen(*ptr));
3685+ assert(murmur_values[x] == hash_val);
3686+ }
3687+
3688+ return TEST_SUCCESS;
3689+}
3690+
3691+static test_return_t jenkins_run (hashkit_st *hashk __attribute__((unused)))
3692+{
3693+ uint32_t x;
3694+ const char **ptr;
3695+
3696+
3697+ for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3698+ {
3699+ uint32_t hash_val;
3700+
3701+ hash_val= hashkit_jenkins(*ptr, strlen(*ptr));
3702+ assert(jenkins_values[x] == hash_val);
3703+ }
3704+
3705+ return TEST_SUCCESS;
3706+}
3707+
3708+
3709+
3710+
3711+/**
3712+ @brief now we list out the tests.
3713+*/
3714+
3715+test_st allocation[]= {
3716+ {"init", 0, (test_callback_fn)init_test},
3717+ {"create and free", 0, (test_callback_fn)allocation_test},
3718+ {"clone", 0, (test_callback_fn)clone_test},
3719+ {0, 0, 0}
3720+};
3721+
3722+test_st hash_tests[] ={
3723+ {"md5", 0, (test_callback_fn)md5_run },
3724+ {"crc", 0, (test_callback_fn)crc_run },
3725+ {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
3726+ {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
3727+ {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
3728+ {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
3729+ {"hsieh", 0, (test_callback_fn)hsieh_run },
3730+ {"murmur", 0, (test_callback_fn)murmur_run },
3731+ {"jenkis", 0, (test_callback_fn)jenkins_run },
3732+ {0, 0, (test_callback_fn)0}
3733+};
3734+
3735+/*
3736+ * The following test suite is used to verify that we don't introduce
3737+ * regression bugs. If you want more information about the bug / test,
3738+ * you should look in the bug report at
3739+ * http://bugs.launchpad.net/libmemcached
3740+ */
3741+test_st regression[]= {
3742+ {0, 0, 0}
3743+};
3744+
3745+collection_st collection[] ={
3746+ {"allocation", 0, 0, allocation},
3747+ {"regression", 0, 0, regression},
3748+ {"hashing", 0, 0, hash_tests},
3749+ {0, 0, 0, 0}
3750+};
3751+
3752+/* Prototypes for functions we will pass to test framework */
3753+void *world_create(void);
3754+test_return_t world_destroy(hashkit_st *hashk);
3755+
3756+void *world_create(void)
3757+{
3758+ hashkit_st *hashk_ptr;
3759+
3760+ hashk_ptr= hashkit_create(&global_hashk);
3761+
3762+ assert(hashk_ptr == &global_hashk);
3763+
3764+ // First we test if hashk is even valid
3765+ assert(hashkit_is_initialized(hashk_ptr) == true);
3766+ assert(hashkit_is_allocated(hashk_ptr) == false);
3767+ assert(hashk_ptr->continuum == NULL);
3768+
3769+ return hashk_ptr;
3770+}
3771+
3772+
3773+test_return_t world_destroy(hashkit_st *hashk)
3774+{
3775+ // Did we get back what we expected?
3776+ assert(hashkit_is_initialized(hashk) == true);
3777+ assert(hashkit_is_allocated(hashk) == false);
3778+ hashkit_free(&global_hashk);
3779+
3780+ return TEST_SUCCESS;
3781+}
3782+
3783+void get_world(world_st *world)
3784+{
3785+ world->collections= collection;
3786+ world->create= (test_callback_create_fn)world_create;
3787+ world->destroy= (test_callback_fn)world_destroy;
3788+}
3789
3790=== renamed file 'tests/Makefile.am' => 'tests/include.am'
3791--- tests/Makefile.am 2009-12-16 23:24:08 +0000
3792+++ tests/include.am 2009-12-18 01:27:26 +0000
3793@@ -1,103 +1,151 @@
3794-LDADDS = $(top_builddir)/libmemcached/libmemcached.la
3795+# vim:ft=automake
3796+# included from Top Level Makefile.am
3797+# All paths should be given relative to the root
3798+
3799+TESTS_LDADDS = libmemcached/libmemcached.la
3800
3801 if BUILD_LIBMEMCACHEDUTIL
3802-LDADDS+= $(top_builddir)/libmemcached/libmemcachedutil.la
3803+TESTS_LDADDS+= libmemcached/libmemcachedutil.la
3804 endif
3805
3806-EXTRA_DIST = \
3807- r/memcat.res\
3808- r/memcp.res\
3809- r/memrm.res\
3810- r/memslap.res\
3811- r/memstat.res\
3812- t/memcat.test\
3813- t/memcp.test\
3814- t/memrm.test\
3815- t/memslap.test\
3816- t/memstat.test
3817-
3818-LIBS =
3819-
3820-noinst_HEADERS = test.h server.h ketama_test_cases.h ketama_test_cases_spy.h hash_results.h libmemcached_world.h
3821-noinst_PROGRAMS = testapp testplus udptest atomsmasher startservers
3822-noinst_LTLIBRARIES= libserver.la libtest.la
3823-
3824-libserver_la_SOURCES= server.c
3825-libtest_la_SOURCES= test.c
3826-
3827-testapp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
3828-testapp_SOURCES = function.c
3829-testapp_LDADD = $(top_builddir)/clients/libgenexec.la libtest.la libserver.la $(LDADDS)
3830-
3831-testplus_SOURCES = plus.cpp
3832-testplus_LDADD = libtest.la libserver.la $(LDADDS)
3833-
3834-udptest_SOURCES = udp.c
3835-udptest_LDADD = libtest.la libserver.la $(LDADDS)
3836-
3837-atomsmasher_SOURCES = atomsmasher.c
3838-atomsmasher_LDADD = $(top_builddir)/clients/libgenexec.la libtest.la libserver.la $(LDADDS)
3839-
3840-startservers_SOURCES = start.c
3841-startservers_LDADD = libserver.la $(LDADDS)
3842+EXTRA_DIST+= \
3843+ tests/r/memcat.res \
3844+ tests/r/memcp.res \
3845+ tests/r/memrm.res \
3846+ tests/r/memslap.res \
3847+ tests/r/memstat.res \
3848+ tests/t/memcat.test \
3849+ tests/t/memcp.test \
3850+ tests/t/memrm.test \
3851+ tests/t/memslap.test \
3852+ tests/t/memstat.test
3853+
3854+noinst_HEADERS+= \
3855+ tests/hash_results.h \
3856+ tests/ketama_test_cases.h \
3857+ tests/ketama_test_cases_spy.h \
3858+ tests/libmemcached_world.h \
3859+ tests/server.h \
3860+ tests/test.h
3861+
3862+noinst_PROGRAMS+= \
3863+ tests/atomsmasher \
3864+ tests/startservers \
3865+ tests/testapp \
3866+ tests/testhashkit \
3867+ tests/testplus \
3868+ tests/udptest
3869+
3870+noinst_LTLIBRARIES+= tests/libserver.la
3871+tests_libserver_la_SOURCES= tests/server.c
3872+
3873+noinst_LTLIBRARIES+= tests/libtest.la
3874+tests_libtest_la_SOURCES= tests/test.c
3875+
3876+tests_testapp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
3877+tests_testapp_SOURCES= tests/function.c
3878+tests_testapp_LDADD= \
3879+ clients/libgenexec.la \
3880+ tests/libserver.la \
3881+ tests/libtest.la \
3882+ $(TESTS_LDADDS)
3883+
3884+tests_testplus_SOURCES= tests/plus.cpp
3885+tests_testplus_LDADD= tests/libtest.la tests/libserver.la $(TESTS_LDADDS)
3886+
3887+tests_udptest_SOURCES= tests/udp.c
3888+tests_udptest_LDADD= tests/libtest.la tests/libserver.la $(TESTS_LDADDS)
3889+
3890+tests_atomsmasher_SOURCES= tests/atomsmasher.c
3891+tests_atomsmasher_LDADD= \
3892+ clients/libgenexec.la \
3893+ tests/libserver.la \
3894+ tests/libtest.la \
3895+ $(TESTS_LDADDS)
3896+
3897+tests_startservers_SOURCES= tests/start.c
3898+tests_startservers_LDADD= tests/libserver.la $(TESTS_LDADDS)
3899+
3900+tests_testhashkit_SOURCES = tests/hashkit_functions.c
3901+tests_testhashkit_LDADD = tests/libtest.la libhashkit/libhashkit.la
3902+tests_testhashkit_DEPENDENCIES = libhashkit
3903
3904 client-record:
3905- sh t/memcat.test > r/memcat.res
3906- sh t/memcp.test > r/memcp.res
3907- sh t/memrm.test > r/memrm.res
3908- sh t/memslap.test > r/memslap.res
3909- sh t/memstat.test > r/memstat.res
3910+ sh tests/t/memcat.test > tests/r/memcat.res
3911+ sh tests/t/memcp.test > tests/r/memcp.res
3912+ sh tests/t/memrm.test > tests/r/memrm.res
3913+ sh tests/t/memslap.test > tests/r/memslap.res
3914+ sh tests/t/memstat.test > tests/r/memstat.res
3915
3916-test: testapp testplus library_test memcapable
3917+test: tests/testapp tests/testplus library_test memcapable libmhashkit_test
3918 echo "Tests completed"
3919
3920 library_test:
3921- ./testapp
3922-# ./testplus
3923-
3924-memcapable:
3925- @MEMC_BINARY@ -d -P /tmp/Xumemc.pid -p 12555
3926- @$(top_builddir)/clients/memcapable -p 12555 || echo "Your memcached server does not support all commands"
3927- @cat /tmp/Xumemc.pid | xargs kill || echo "Failed to kill memcached server"
3928- @rm /tmp/Xumemc.pid
3929-
3930+ tests/testapp
3931+# tests/testplus
3932+
3933+libmhashkit_test: libhashkit
3934+ tests/testhashkit
3935+
3936+memcapable: clients/memcapable
3937+ @MEMC_BINARY@ -d -P `pwd`/tests/Xumemc.pid -p 12555
3938+ @clients/memcapable -p 12555 || echo "Your memcached server does not support all commands"
3939+ @cat tests/Xumemc.pid | xargs kill || echo "Failed to kill memcached server"
3940+ @rm tests/Xumemc.pid
3941+
3942+PHONY += clients
3943 clients:
3944- @MEMC_BINARY@ -d -P /tmp/Xumemc.pid -p 12555
3945+ @MEMC_BINARY@ -d -P `pwd`/tests/Xumemc.pid -p 12555
3946 export MEMCACHED_SERVERS="localhost:12555"
3947- sh t/memcat.test > r/memcat.cmp
3948- diff r/memcat.res r/memcat.cmp
3949- sh t/memcp.test > r/memcp.cmp
3950- diff r/memcp.res r/memcp.cmp
3951- sh t/memrm.test > r/memrm.cmp
3952- diff r/memrm.res r/memrm.cmp
3953- sh t/memslap.test > r/memslap.cmp
3954- diff r/memslap.res r/memslap.cmp
3955- sh t/memstat.test > r/memstat.cmp
3956- diff r/memstat.res r/memstat.cmp
3957- cat /tmp/Xumemc.pid | xargs kill
3958- rm /tmp/Xumemc.pid
3959-
3960+ sh tests/t/memcat.test > tests/r/memcat.cmp
3961+ diff tests/r/memcat.res tests/r/memcat.cmp
3962+ sh tests/t/memcp.test > tests/r/memcp.cmp
3963+ diff tests/r/memcp.res tests/r/memcp.cmp
3964+ sh tests/t/memrm.test > tests/r/memrm.cmp
3965+ diff tests/r/memrm.res tests/r/memrm.cmp
3966+ sh tests/t/memslap.test > tests/r/memslap.cmp
3967+ diff tests/r/memslap.res tests/r/memslap.cmp
3968+ sh tests/t/memstat.test > tests/r/memstat.cmp
3969+ diff tests/r/memstat.res tests/r/memstat.cmp
3970+ cat tests/Xumemc.pid | xargs kill
3971+ rm tests/Xumemc.pid
3972+
3973+gdb-mem:
3974+ $(LIBTOOL) --mode=execute gdb tests/testapp
3975+
3976+gdb-hash:
3977+ $(LIBTOOL) --mode=execute gdb tests/testhashkit
3978+
3979+
3980+PHONY += valgrind
3981 valgrind:
3982- $(LIBTOOL) --mode=execute valgrind --leak-check=yes --show-reachable=yes testapp
3983+ $(LIBTOOL) --mode=execute valgrind --leak-check=yes --show-reachable=yes tests/testapp
3984
3985+PHONY += cachegrind
3986+CLEANFILES += tests/cachegrind.out
3987 cachegrind:
3988- rm -f cachegrind.out.*
3989- $(LIBTOOL) --mode=execute valgrind --tool=cachegrind --branch-sim=yes testapp
3990- cg_annotate cachegrind.out.* --auto=yes > /tmp/cachegrind.out
3991+ rm -f tests/cachegrind.out.*
3992+ $(LIBTOOL) --mode=execute valgrind --tool=cachegrind --cachegrind-out-file=tests/cachegrind.out.%p --branch-sim=yes tests/testapp
3993+ cg_annotate tests/cachegrind.out.* --auto=yes > tests/cachegrind.out
3994
3995+PHONY += callgrind
3996+CLEANFILES += tests/callgrind.out
3997 callgrind:
3998- rm -f callgrind.out.*
3999- $(LIBTOOL) --mode=execute valgrind --tool=callgrind testapp
4000- callgrind_annotate callgrind.out.* --auto=yes > /tmp/callgrind.out
4001+ rm -f tests/callgrind.out.*
4002+ $(LIBTOOL) --mode=execute valgrind --tool=callgrind --callgrind-out-file=tests/callgrind.out.%p tests/testapp
4003+ callgrind_annotate tests/callgrind.out.* --auto=yes > tests/callgrind.out
4004
4005+PHONY += helgrind
4006+CLEANFILES+= helgrind.out.*
4007 helgrind:
4008 rm -f helgrind.out.*
4009- $(LIBTOOL) --mode=execute valgrind --tool=helgrind testapp
4010+ $(LIBTOOL) --mode=execute valgrind --tool=helgrind tests/testapp
4011
4012+PHONY += helgrind-slap
4013 helgrind-slap:
4014- $(LIBTOOL) --mode=execute valgrind --tool=helgrind ${top_builddir}/clients/memslap --server=localhost --concurrency=30
4015+ $(LIBTOOL) --mode=execute valgrind --tool=helgrind clients/memslap --server=localhost --concurrency=30
4016
4017 test-no-outputdiff: test
4018
4019 hudson-valgrind:
4020- $(LIBTOOL) --mode=execute valgrind --leak-check=yes --show-reachable=yes --log-file=/tmp/valgrind.out testapp
4021+ $(LIBTOOL) --mode=execute valgrind --leak-check=yes --show-reachable=yes --log-file=tests/valgrind.out tests/testapp
4022
4023=== modified file 'tests/test.c'
4024--- tests/test.c 2009-12-16 20:17:21 +0000
4025+++ tests/test.c 2009-12-18 01:27:26 +0000
4026@@ -15,6 +15,7 @@
4027 #include <sys/time.h>
4028 #include <sys/types.h>
4029 #include <sys/stat.h>
4030+#include <sys/wait.h>
4031 #include <unistd.h>
4032 #include <time.h>
4033 #include <fnmatch.h>
4034@@ -62,8 +63,22 @@
4035
4036 void create_core(void)
4037 {
4038- if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL && fork() == 0)
4039- abort();
4040+ if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL)
4041+ {
4042+ pid_t pid= fork();
4043+
4044+ if (pid == 0)
4045+ {
4046+ abort();
4047+ }
4048+ else
4049+ {
4050+ while (waitpid(pid, NULL, 0) != pid)
4051+ {
4052+ ;
4053+ }
4054+ }
4055+ }
4056 }
4057
4058

Subscribers

People subscribed via source and target branches

to all changes: