Permalink
Please sign in to comment.
Browse files
CCBC-17 Implement ketama distribution algorithm
Use ketama consistent hashing algorithm for memcached nodes. It is conform to libketama. Change-Id: I7c4d5fbaa0eecb276f90d68ec3d412fe9aa7be73 Reviewed-on: http://review.couchbase.org/9718 Tested-by: Sergey Avseyev <sergey.avseyev@gmail.com> Reviewed-by: Matt Ingenthron <matt@couchbase.com> Tested-by: Matt Ingenthron <matt@couchbase.com>
- Loading branch information...
Showing
with
1,914 additions
and 197 deletions.
- +1 −0 .gitignore
- +11 −2 Makefile.am
- +6 −3 NMakefile
- +85 −18 README.markdown
- +37 −0 include/libvbucket/vbucket.h
- +7 −1 src/hash.h
- +55 −0 src/ketama.c
- +32 −0 src/rfc1321/global.h
- +35 −0 src/rfc1321/md5.h
- +335 −0 src/rfc1321/md5c.c
- +299 −157 src/vbucket.c
- +24 −16 src/vbuckettool.c
- +269 −0 tests/config/ketama-eight-nodes
- +1 −0 tests/config/ketama-eight-nodes.md5sum
- +269 −0 tests/config/ketama-ordered-eight-nodes
- +1 −0 tests/config/ketama-ordered-eight-nodes.md5sum
- +367 −0 tests/config/vbucket-eight-nodes
- +79 −0 tests/testketama.c
- +1 −0 win32/strings.h
13
Makefile.am
103
README.markdown
55
src/ketama.c
@@ -0,0 +1,55 @@ | ||
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ | ||
+ | ||
+#include "hash.h" | ||
+ | ||
+/* Force md5 functions to be static. The compiler could show warnings but | ||
+ * it ok, we did it because we need to keep files in vendor/ directory | ||
+ * unmodified. */ | ||
+static void MD5Init(); | ||
+static void MD5Update(); | ||
+static void MD5Final(); | ||
+ | ||
+/* This library uses the reference MD5 implementation from [RFC1321] */ | ||
+#define PROTOTYPES 1 | ||
+#include "rfc1321/md5c.c" | ||
+#undef PROTOTYPES | ||
+ | ||
+void hash_md5(const char *key, size_t key_length, unsigned char *result) | ||
+{ | ||
+ MD5_CTX ctx; | ||
+ | ||
+ MD5Init(&ctx); | ||
+ MD5Update(&ctx, (unsigned char *)key, key_length); | ||
+ MD5Final(result, &ctx); | ||
+} | ||
+ | ||
+void* hash_md5_update(void *ctx, const char *key, size_t key_length) | ||
+{ | ||
+ if (ctx == NULL) { | ||
+ ctx = calloc(1, sizeof(MD5_CTX)); | ||
+ MD5Init(ctx); | ||
+ } | ||
+ MD5Update(ctx, (unsigned char *)key, key_length); | ||
+ return ctx; | ||
+} | ||
+ | ||
+void hash_md5_final(void *ctx, unsigned char *result) | ||
+{ | ||
+ if (ctx == NULL) { | ||
+ return; | ||
+ } | ||
+ MD5Final(result, ctx); | ||
+ free(ctx); | ||
+} | ||
+ | ||
+uint32_t hash_ketama(const char *key, size_t key_length) | ||
+{ | ||
+ unsigned char digest[16]; | ||
+ | ||
+ hash_md5(key, key_length, digest); | ||
+ | ||
+ return (uint32_t) ( (digest[3] << 24) | ||
+ |(digest[2] << 16) | ||
+ |(digest[1] << 8) | ||
+ | digest[0]); | ||
+} |
@@ -0,0 +1,32 @@ | ||
+/* GLOBAL.H - RSAREF types and constants | ||
+*/ | ||
+ | ||
+/* PROTOTYPES should be set to one if and only if the compiler supports | ||
+ function argument prototyping. | ||
+ The following makes PROTOTYPES default to 0 if it has not already | ||
+ been defined with C compiler flags. | ||
+ */ | ||
+#ifndef PROTOTYPES | ||
+#define PROTOTYPES 0 | ||
+#endif | ||
+ | ||
+#include <stdint.h> | ||
+ | ||
+/* POINTER defines a generic pointer type */ | ||
+typedef unsigned char *POINTER; | ||
+ | ||
+/* UINT2 defines a two byte word */ | ||
+typedef uint16_t UINT2; | ||
+ | ||
+/* UINT4 defines a four byte word */ | ||
+typedef uint32_t UINT4; | ||
+ | ||
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. | ||
+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it | ||
+ returns an empty list. | ||
+ */ | ||
+#if PROTOTYPES | ||
+#define PROTO_LIST(list) list | ||
+#else | ||
+#define PROTO_LIST(list) () | ||
+#endif |

Oops, something went wrong.
0 comments on commit
8e8a491