Cache::Memcached::Fast 0.14を以前のketama algorithmにも対応させる

ketamaの分散を改善するために、全バージョンとアルゴリズムの互換性がなくなったことで有名なCache::Memcache::Fast 0.14ですが以前のアルゴリズムへも対応できるようにpatchつくってみました。


使い方

my $memcached = Cache::Memcached::Fast->new({
    servers => [qw/127.0.0.1:11222 127.0.0.1:11223/],
    old_ketama_algo => 1,
    ketama_points => 150,
});

patch

diff -ur Cache-Memcached-Fast-0.14.orig/Fast.xs Cache-Memcached-Fast-0.14/Fast.xs
--- Cache-Memcached-Fast-0.14.orig/Fast.xs        2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/Fast.xs     2009-05-14 15:12:35.000000000 +0900
@@ -207,6 +207,10 @@
 
   memd->servers = newAV();
 
+  ps = hv_fetch(conf, "old_ketama_algo", 15, 0);
+  if (ps && SvOK(*ps))
+    client_set_old_ketama_algo(c, SvTRUE(*ps));
+
   ps = hv_fetch(conf, "ketama_points", 13, 0);
   if (ps && SvOK(*ps))
     {
diff -ur Cache-Memcached-Fast-0.14.orig/lib/Cache/Memcached/Fast.pm Cache-Memcached-Fast-0.14/lib/Cache/Memcached/Fast.pm
--- Cache-Memcached-Fast-0.14.orig/lib/Cache/Memcached/Fast.pm    2009-02-07 20:34:56.000000000 +0900
+++ Cache-Memcached-Fast-0.14/lib/Cache/Memcached/Fast.pm 2009-05-14 13:35:40.000000000 +0900
@@ -508,6 +508,7 @@
     max_failures => 1,
     failure_timeout => 1,
     ketama_points => 1,
+    old_ketama_algo => 1,
     serialize_methods => 1,
     utf8 => 1,
     max_size => 1,
diff -ur Cache-Memcached-Fast-0.14.orig/src/client.c Cache-Memcached-Fast-0.14/src/client.c
--- Cache-Memcached-Fast-0.14.orig/src/client.c   2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/src/client.c        2009-05-14 15:13:12.000000000 +0900
@@ -293,6 +293,7 @@
   int failure_timeout;          /* 1 sec.  */
   int close_on_error;
   int nowait;
+  int old_ketama_algo;
   int hash_namespace;
 
   struct array index_list;
@@ -398,6 +399,7 @@
   c->failure_timeout = 10;
   c->close_on_error = 1;
   c->nowait = 0;
+  c->old_ketama_algo = 0;
   c->hash_namespace = 0;
 
   c->generation = 1;            /* Different from initial command state.  */
@@ -512,6 +514,11 @@
   c->nowait = enable;
 }
 
+void
+client_set_old_ketama_algo(struct client *c, int enable)
+{
+    c->old_ketama_algo = enable;
+}
 
 void
 client_set_hash_namespace(struct client *c, int enable)
@@ -542,7 +549,7 @@
     return res;
 
   res = dispatch_add_server(&c->dispatch, host, host_len, port, port_len,
-                            weight, array_size(c->servers));
+                            weight, array_size(c->servers), c->old_ketama_algo);
   if (res == -1)
     return MEMCACHED_FAILURE;
 
diff -ur Cache-Memcached-Fast-0.14.orig/src/client.h Cache-Memcached-Fast-0.14/src/client.h
--- Cache-Memcached-Fast-0.14.orig/src/client.h   2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/src/client.h        2009-05-14 16:22:08.000000000 +0900
@@ -155,6 +155,10 @@
 
 extern
 void
+client_set_old_ketama_algo(struct client *c, int enable);
+
+extern
+void
 client_reset(struct client *c, struct result_object *o, int noreply);
 
 extern
diff -ur Cache-Memcached-Fast-0.14.orig/src/dispatch_key.c Cache-Memcached-Fast-0.14/src/dispatch_key.c
--- Cache-Memcached-Fast-0.14.orig/src/dispatch_key.c     2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/src/dispatch_key.c  2009-05-14 15:29:36.000000000 +0900
@@ -158,7 +158,7 @@
 ketama_crc32_add_server(struct dispatch_state *state,
                         const char *host, size_t host_len,
                         const char *port, size_t port_len,
-                        double weight, int index)
+                        double weight, int index, int old_ketama_algo)
 {
   static const char delim = '\0';
   unsigned int crc32, point;
@@ -184,10 +184,19 @@
         We want the same result on all platforms, so we hardcode size
         of int as 4 8-bit bytes.
       */
-      buf[0] = point & 0xff;
-      buf[1] = (point >> 8) & 0xff;
-      buf[2] = (point >> 16) & 0xff;
-      buf[3] = (point >> 24) & 0xff;
+      if ( old_ketama_algo ) {
+          point = 0;
+          buf[0] = i & 0xff;
+          buf[1] = (i >> 8) & 0xff;
+          buf[2] = (i >> 16) & 0xff;
+          buf[3] = (i >> 24) & 0xff;
+      }
+      else {
+          buf[0] = point & 0xff;
+          buf[1] = (point >> 8) & 0xff;
+          buf[2] = (point >> 16) & 0xff;
+          buf[3] = (point >> 24) & 0xff;
+      }
 
       point = compute_crc32_add(crc32, buf, 4);
 
@@ -284,11 +293,11 @@
 dispatch_add_server(struct dispatch_state *state,
                     const char *host, size_t host_len,
                     const char *port, size_t port_len,
-                    double weight, int index)
+                    double weight, int index, int old_ketama_algo)
 {
   if (state->ketama_points > 0)
     return ketama_crc32_add_server(state, host, host_len, port, port_len,
-                                   weight, index);
+                                   weight, index, old_ketama_algo);
   else
     return compatible_add_server(state, weight, index);
 }
diff -ur Cache-Memcached-Fast-0.14.orig/src/dispatch_key.h Cache-Memcached-Fast-0.14/src/dispatch_key.h
--- Cache-Memcached-Fast-0.14.orig/src/dispatch_key.h     2009-02-07 20:34:57.000000000 +0900
+++ Cache-Memcached-Fast-0.14/src/dispatch_key.h  2009-05-14 13:45:45.000000000 +0900
@@ -60,7 +60,7 @@
 dispatch_add_server(struct dispatch_state *state,
                     const char *host, size_t host_len,
                     const char *port, size_t port_len,
-                    double weight, int index);
+                    double weight, int index, int old_ketama_algo);
 
 extern
 int
created by blog.nomadscafe.jp

コメント

コメントはありません

コメントを投稿

コメントを投稿するにはログインが必要です