Added new memcached_dump() command.
author <brian@localhost.localdomain> <>
Tue, 19 May 2009 20:32:02 +0000 (13:32 -0700)
committer <brian@localhost.localdomain> <>
Tue, 19 May 2009 20:32:02 +0000 (13:32 -0700)
19 files changed:
.hgignore
ChangeLog
clients/Makefile.am
clients/memdump.c [new file with mode: 0644]
docs/Makefile.am
docs/libmemcached.pod
docs/memcached_dump.pod [new file with mode: 0644]
docs/memdump.pod [new file with mode: 0644]
libmemcached/Makefile.am
libmemcached/memcached.h
libmemcached/memcached_connect.c
libmemcached/memcached_constants.h
libmemcached/memcached_dump.c [new file with mode: 0644]
libmemcached/memcached_fetch.c
libmemcached/memcached_io.c
libmemcached/memcached_response.c
libmemcached/memcached_types.h
tests/function.c
tests/output.res

index ad0a989f835b39bcae23662b4d9fa1ba95921f0b..531b2e2addce9da3ef1283cf26758705f22ae395 100644 (file)
--- a/.hgignore
+++ b/.hgignore
 ^lib/libmemcachedPlus.la$
 ^tests/testplus$
 
+# Don't bother with TAGS files
+TAGS
+clients/TAGS
+clients/memdump
+libmemcached/TAGS
+libmemcachedutil/TAGS
+tests/TAGS
+
+
 
 # Build artifacts
 ^libmemcached/libmemcached.la$
index 5687084db7e07cde79d789830dc7fbfd88b411e1..6cd6b00e68f0e896551e7f0f02b65ef8b032bb00 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+0.30
+  * Added memcachd_dump command (and framework for memdump tool)
+
 0.29 Tue May 19 08:26:48 PDT 2009
   * Fixed malloc usage to calloc for spots where we need zero filled memory. 
   * All code warnings now treated as errors.
index 05082b16004cfeca1342ede8335cd1f271c5872d..9cb343182c722aecc5d5306a4382b4afee62b725 100644 (file)
@@ -1,6 +1,6 @@
 LDADDS = $(top_builddir)/libmemcached/libmemcached.la
 
-bin_PROGRAMS = memcat memcp memstat memrm memflush memslap memerror
+bin_PROGRAMS = memcat memdump memcp memstat memrm memflush memslap memerror
 
 noinst_HEADERS = client_options.h \
                utilities.h \
@@ -15,6 +15,10 @@ memcp_SOURCES = memcp.c utilities.c
 memcp_LDADD = $(LDADDS)
 memcp_LDFLAGS = -rpath $(pkglibdir)
 
+memdump_SOURCES = memdump.c utilities.c
+memdump_LDADD = $(LDADDS)
+memdump_LDFLAGS = -rpath $(pkglibdir)
+
 memstat_SOURCES = memstat.c utilities.c
 memstat_LDADD = $(LDADDS)
 memstat_LDFLAGS = -rpath $(pkglibdir)
diff --git a/clients/memdump.c b/clients/memdump.c
new file mode 100644 (file)
index 0000000..dd00d8b
--- /dev/null
@@ -0,0 +1,152 @@
+#include "libmemcached/common.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <strings.h>
+#include <string.h>
+
+#include <libmemcached/memcached.h>
+
+#include "client_options.h"
+#include "utilities.h"
+
+#define PROGRAM_NAME "memdump"
+#define PROGRAM_DESCRIPTION "Dump all values from one or many servers."
+
+/* Prototypes */
+void options_parse(int argc, char *argv[]);
+
+static int opt_binary=0;
+static int opt_verbose= 0;
+static char *opt_servers= NULL;
+static char *opt_hash= NULL;
+
+/* Print the keys and counter how many were found */
+static memcached_return key_printer(memcached_st *ptr __attribute__((unused)),  
+                                              const char *key, size_t key_length, 
+                                              void *context __attribute__((unused)))
+{
+  printf("%.*s\n", (uint32_t)key_length, key);
+
+  return MEMCACHED_SUCCESS;
+}
+
+int main(int argc, char *argv[])
+{
+  memcached_st *memc;
+  memcached_return rc;
+  memcached_server_st *servers;
+  memcached_dump_func callbacks[1];
+
+  callbacks[0]= &key_printer;
+
+  options_parse(argc, argv);
+
+  memc= memcached_create(NULL);
+  process_hash_option(memc, opt_hash);
+
+  if (!opt_servers)
+  {
+    char *temp;
+
+    if ((temp= getenv("MEMCACHED_SERVERS")))
+      opt_servers= strdup(temp);
+    else
+    {
+      fprintf(stderr, "No Servers provided\n");
+      exit(1);
+    }
+  }
+
+  if (opt_servers)
+    servers= memcached_servers_parse(opt_servers);
+  else
+    servers= memcached_servers_parse(argv[--argc]);
+
+  memcached_server_push(memc, servers);
+  memcached_server_list_free(servers);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, opt_binary);
+
+  rc= memcached_dump(memc, callbacks, NULL, 1);
+
+  if (rc != MEMCACHED_SUCCESS)
+  {
+    fprintf(stderr, "memdump: memcache error %s", memcached_strerror(memc, rc));
+    if (memc->cached_errno)
+      fprintf(stderr, " system error %s", strerror(memc->cached_errno));
+    fprintf(stderr, "\n");
+  }
+
+  memcached_free(memc);
+
+  if (opt_servers)
+    free(opt_servers);
+  if (opt_hash)
+    free(opt_hash);
+
+  return 0;
+}
+
+void options_parse(int argc, char *argv[])
+{
+  int option_index= 0;
+  int option_rv;
+
+  static struct option long_options[]=
+    {
+      {"version", no_argument, NULL, OPT_VERSION},
+      {"help", no_argument, NULL, OPT_HELP},
+      {"verbose", no_argument, &opt_verbose, OPT_VERBOSE},
+      {"debug", no_argument, &opt_verbose, OPT_DEBUG},
+      {"servers", required_argument, NULL, OPT_SERVERS},
+      {"hash", required_argument, NULL, OPT_HASH},
+      {"binary", no_argument, NULL, OPT_BINARY},
+      {0, 0, 0, 0}
+    };
+
+  while (1) 
+  {
+    option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
+
+    if (option_rv == -1) break;
+
+    switch (option_rv)
+    {
+    case 0:
+      break;
+    case OPT_BINARY:
+      opt_binary = 1;
+      break;
+    case OPT_VERBOSE: /* --verbose or -v */
+      opt_verbose = OPT_VERBOSE;
+      break;
+    case OPT_DEBUG: /* --debug or -d */
+      opt_verbose = OPT_DEBUG;
+      break;
+    case OPT_VERSION: /* --version or -V */
+      version_command(PROGRAM_NAME);
+      break;
+    case OPT_HELP: /* --help or -h */
+      help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, NULL);
+      break;
+    case OPT_SERVERS: /* --servers or -s */
+      opt_servers= strdup(optarg);
+      break;
+    case OPT_HASH:
+      opt_hash= strdup(optarg);
+      break;
+    case '?':
+      /* getopt_long already printed an error message. */
+      exit(1);
+    default:
+      abort();
+    }
+  }
+}
index 5b051580e1979a02d72a7097fc57da5bce56dd4c..1ac9b2fae2cc3aff3922dd6a63461029162319e8 100644 (file)
@@ -4,6 +4,7 @@ CLEANFILES= *.1 *.3
 EXTRA_DIST = libmemcached.pod\
        libmemcachedutil.pod\
        memcached_flush.pod\
+       memcached_dump.pod\
        memcached_stats.pod\
        memrm.pod\
        memerror.pod\
@@ -27,6 +28,7 @@ EXTRA_DIST = libmemcached.pod\
        memcached_set.pod\
        memcached_version.pod\
        memflush.pod\
+       memdump.pod\
        memcached_flush_buffers.pod\
         memcached_analyze.pod\
         memcached_generate_hash_value.pod
@@ -37,6 +39,7 @@ man_MANS = libmemcached.3\
        memcp.1\
        memerror.1\
        memflush.1\
+       memdump.1\
        memrm.1\
        memslap.1\
        memstat.1\
@@ -91,6 +94,7 @@ man_MANS = libmemcached.3\
        memcached_lib_version.3\
        memcached_version.3\
         memcached_flush_buffers.3\
+        memcached_dump.3\
         memcached_generate_hash_value.3
 
 if BUILD_LIBMEMCACHEDUTIL
@@ -174,6 +178,9 @@ memcached_decrement.3:
 memcached_decrement_with_initial.3:
        @POD2MAN@ -c "libmemcached" -r "" -s 3 ${top_srcdir}/docs/memcached_auto.pod > memcached_decrement_with_initial.3
 
+memcached_dump.3: memcached_dump.pod
+       @POD2MAN@ -c "libmemcached" -r "" -s 3 ${top_srcdir}/docs/memcached_dump.pod > memcached_dump.3
+
 memcached_flush.3: memcached_flush.pod
        @POD2MAN@ -c "libmemcached" -r "" -s 3 ${top_srcdir}/docs/memcached_flush.pod > memcached_flush.3
 
@@ -330,6 +337,9 @@ memrm.1: memrm.pod
 memerror.1: memerror.pod
        @POD2MAN@ -c "libmemcached" -r "" -s 1 ${top_srcdir}/docs/memerror.pod > memerror.1
 
+memdump.1: memdump.pod
+       @POD2MAN@ -c "libmemcached" -r "" -s 1 ${top_srcdir}/docs/memdump.pod > memdump.1
+
 memflush.1: memflush.pod
        @POD2MAN@ -c "libmemcached" -r "" -s 1 ${top_srcdir}/docs/memflush.pod > memflush.1
 
index 6ebb7c423d15d5c15da0023c06d535ee1800c760..2ee593a8c8fb23d3caaa29e4fd1a6d0a69d27d59 100644 (file)
@@ -121,7 +121,7 @@ Brian Aker, E<lt>brian@tangent.orgE<gt>
 
 =head1 SEE ALSO
 
-memcached(1) libmemcached_examples(3) libmemcached(1) memcat(1) memcp(1) memflush(1) memrm(1) memslap(1) memstat(1) memcached_fetch(3) memcached_replace(3) memcached_server_list_free(3) libmemcached_examples(3) memcached_clone(3) memcached_free(3) memcached_server_add(3) memcached_server_push(3) memcached_add(3) memcached_get(3) memcached_server_count(3) memcached_servers_parse(3) memcached_create(3) memcached_increment(3) memcached_server_list(3) memcached_set(3) memcached_decrement(3) memcached_mget(3) memcached_server_list_append(3) memcached_strerror(3) memcached_delete(3) memcached_quit(3) memcached_server_list_count(3) memcached_verbosity(3) memcached_server_add_unix_socket(3) memcached_result_create(3)  memcached_result_free(3)  memcached_result_key_value(3)  memcached_result_key_length(3)  memcached_result_value(3)  memcached_result_length(3)  memcached_result_flags(3)  memcached_result_cas(3) memcached_result_st(3) memcached_append(3) memcached_prepend(3) memcached_fetch_result(3) memerror(1) memcached_get_by_key(3) memcached_mget_by_key(3) memcached_delete_by_key(3) memcached_fetch_execute(3) memcached_callback_get(3) memcached_callback_set(3) memcached_version(3) memcached_lib_version(3) memcached_result_set_value(3)
+memcached(1) libmemcached_examples(3) libmemcached(1) memcat(1) memcp(1) memflush(1) memrm(1) memslap(1) memstat(1) memcached_fetch(3) memcached_replace(3) memcached_server_list_free(3) libmemcached_examples(3) memcached_clone(3) memcached_free(3) memcached_server_add(3) memcached_server_push(3) memcached_add(3) memcached_get(3) memcached_server_count(3) memcached_servers_parse(3) memcached_create(3) memcached_increment(3) memcached_server_list(3) memcached_set(3) memcached_decrement(3) memcached_mget(3) memcached_server_list_append(3) memcached_strerror(3) memcached_delete(3) memcached_quit(3) memcached_server_list_count(3) memcached_verbosity(3) memcached_server_add_unix_socket(3) memcached_result_create(3)  memcached_result_free(3)  memcached_result_key_value(3)  memcached_result_key_length(3)  memcached_result_value(3)  memcached_result_length(3)  memcached_result_flags(3)  memcached_result_cas(3) memcached_result_st(3) memcached_append(3) memcached_prepend(3) memcached_fetch_result(3) memerror(1) memcached_get_by_key(3) memcached_mget_by_key(3) memcached_delete_by_key(3) memcached_fetch_execute(3) memcached_callback_get(3) memcached_callback_set(3) memcached_version(3) memcached_lib_version(3) memcached_result_set_value(3) memcached_dump(3) memdump(1)
 
 =cut
 
diff --git a/docs/memcached_dump.pod b/docs/memcached_dump.pod
new file mode 100644 (file)
index 0000000..3653e3f
--- /dev/null
@@ -0,0 +1,53 @@
+=head1 NAME
+
+memcached_dump
+
+=head1 LIBRARY
+
+C Client Library for memcached (libmemcached, -lmemcached)
+
+=head1 SYNOPSIS
+
+  #include <memcached.h>
+
+  memcached_return
+    memcached_dump (memcached_st *ptr, 
+                    memcached_dump_func *function, 
+                    void *context, 
+                    uint32_t number_of_callbacks);
+
+  typedef memcached_return (*memcached_dump_func)(memcached_st *ptr,  
+                                                  const char *key, 
+                                                  size_t key_length, 
+                                                  void *context);
+
+=head1 DESCRIPTION
+
+memcached_dump() is used to get a list of keys found  memcached(1) servers.
+Because memcached(1) does not guarentee to dump all keys you can not assume
+you have fetched all keys from the server. The function takes an array
+of callbacks that it will use to execute on keys as they are found.
+
+Currently the binar protocol is not supported.
+
+=head1 RETURN
+
+A value of type C<memcached_return> is returned
+On success that value will be C<MEMCACHED_SUCCESS>.
+Use memcached_strerror() to translate this value to a printable string.
+
+=head1 HOME
+
+To find out more information please check:
+L<http://tangent.org/552/libmemcached.html>
+
+=head1 AUTHOR
+
+Brian Aker, E<lt>brian@tangent.orgE<gt>
+
+=head1 SEE ALSO
+
+memcached(1) libmemcached(3) memcached_strerror(3)
+
+=cut
+
diff --git a/docs/memdump.pod b/docs/memdump.pod
new file mode 100644 (file)
index 0000000..97fe435
--- /dev/null
@@ -0,0 +1,31 @@
+=head1 NAME
+
+memdump - Dump a list of keys from a server.
+
+=head1 SYNOPSIS
+
+  memdump [options]
+
+=head1 DESCRIPTION
+
+B<memdump> currently dumps a list of "keys" from all servers that 
+it is told to fetch from. Because memcached does not guarentee to
+provide all keys it is not possible to get a complete "dump".
+
+For a full list of operations run the tool with the B<--help> option.
+
+=head1 HOME
+
+To find out more information please check:
+L<http://tangent.org/552/libmemcached.html>
+
+=head1 AUTHOR
+
+Brian Aker, E<lt>brian@tangent.orgE<gt>
+
+=head1 SEE ALSO
+
+memcached(1) libmemcached(3)
+
+=cut
+
index a7c0b29451c1df3ee83f5bc9b8d8ef3508b809fe..ebb31be57790ad1974af46d183f5aa20fe152346 100644 (file)
@@ -38,6 +38,7 @@ libmemcached_la_SOURCES = crc.c \
                          memcached_connect.c \
                          memcached_delete.c \
                          memcached_do.c \
+                         memcached_dump.c \
                          memcached_fetch.c \
                          memcached_flush.c \
                          memcached_get.c \
index a9c6a6835719d7ab5df623b8997d0f6212e8a59f..5e57f9ca3d9a1084c474998df72a465d05c6a5b0 100644 (file)
@@ -223,6 +223,8 @@ void *memcached_callback_get(memcached_st *ptr,
                              memcached_callback flag,
                              memcached_return *error);
 
+memcached_return memcached_dump(memcached_st *ptr, memcached_dump_func *function, void *context, uint32_t number_of_callbacks);
+
 
 #ifdef __cplusplus
 }
index 66525183c4a114c5800de32a027e9a0ce6b76b0d..0d61f847bab0996e2de08a41ba333b47851b720c 100644 (file)
@@ -306,6 +306,7 @@ memcached_return memcached_connect(memcached_server_st *ptr)
   LIBMEMCACHED_MEMCACHED_CONNECT_START();
 
   /* both retry_timeout and server_failure_limit must be set in order to delay retrying a server on error. */
+  WATCHPOINT_ASSERT(ptr->root);
   if (ptr->root->retry_timeout && ptr->root->server_failure_limit)
   {
     struct timeval next_time;
index db9c2a73dcdc03e6e022705c70728011bfee9754..970fd0b48e3992e900e618c81000263086cf760a 100644 (file)
@@ -54,6 +54,7 @@ typedef enum {
   MEMCACHED_DELETED,
   MEMCACHED_VALUE,
   MEMCACHED_STAT,
+  MEMCACHED_ITEM,
   MEMCACHED_ERRNO,
   MEMCACHED_FAIL_UNIX_SOCKET,
   MEMCACHED_NOT_SUPPORTED,
diff --git a/libmemcached/memcached_dump.c b/libmemcached/memcached_dump.c
new file mode 100644 (file)
index 0000000..4899df5
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+  We use this to dump all keys.
+
+  At this point we only support a callback method. This could be optimized by first
+  calling items and finding active slabs. For the moment though we just loop through
+  all slabs on servers and "grab" the keys.
+*/
+
+#include "common.h"
+static memcached_return ascii_dump(memcached_st *ptr, memcached_dump_func *callback, void *context, uint32_t number_of_callbacks)
+{
+  memcached_return rc;
+  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+  size_t send_length;
+  uint32_t server_key;
+  uint32_t x;
+
+  unlikely (ptr->number_of_hosts == 0)
+    return MEMCACHED_NO_SERVERS;
+
+  for (server_key= 0; server_key < ptr->number_of_hosts; server_key++)
+  {
+    /* 256 I BELIEVE is the upper limit of slabs */
+    for (x= 0; x < 256; x++)
+    {
+      send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
+                            "stats cachedump %u 0 0\r\n", x);
+
+      rc= memcached_do(&ptr->hosts[server_key], buffer, send_length, 1);
+
+      unlikely (rc != MEMCACHED_SUCCESS)
+        goto error;
+
+      while (1)
+      {
+        uint32_t callback_counter;
+        rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
+
+        if (rc == MEMCACHED_ITEM)
+        {
+          char *string_ptr, *end_ptr;
+          char *key;
+
+          string_ptr= buffer;
+          string_ptr+= 5; /* Move past ITEM */
+          for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++);
+          key= string_ptr;
+          key[(size_t)(end_ptr-string_ptr)]= 0;
+          for (callback_counter= 0; callback_counter < number_of_callbacks; callback_counter++)
+          {
+            rc= (*callback[callback_counter])(ptr, key, (size_t)(end_ptr-string_ptr), context);
+            if (rc != MEMCACHED_SUCCESS)
+              break;
+          }
+        }
+        else if (rc == MEMCACHED_END)
+          break;
+        else
+          goto error;
+      }
+    }
+  }
+
+error:
+  if (rc == MEMCACHED_END)
+    return MEMCACHED_SUCCESS;
+  else
+    return rc;
+}
+
+memcached_return memcached_dump(memcached_st *ptr, memcached_dump_func *callback, void *context, uint32_t number_of_callbacks)
+{
+  /* No support for Binary protocol yet */
+  if (ptr->flags & MEM_BINARY_PROTOCOL)
+    return MEMCACHED_FAILURE;
+
+  return ascii_dump(ptr, callback, context, number_of_callbacks);
+}
+
index 8afdfd045693a82111bde92947dffe93c448b027..d3f012197d6a177a30356b90161650c4739c7653 100644 (file)
@@ -86,7 +86,8 @@ memcached_return memcached_fetch_execute(memcached_st *ptr,
   memcached_return rc= MEMCACHED_FAILURE;
   unsigned int x;
 
-  while ((result= memcached_fetch_result(ptr, result, &rc)) != NULL) {
+  while ((result= memcached_fetch_result(ptr, result, &rc)) != NULL) 
+  {
     if (rc == MEMCACHED_SUCCESS)
     {
       for (x= 0; x < number_of_callbacks; x++)
index 3566dd2cc9dd5b8666b6a95e3c9cf874343a12b0..7bdb7238fa7737d6cbd8619bc33f65dce2ad98e3 100644 (file)
@@ -227,9 +227,9 @@ ssize_t memcached_io_write(memcached_server_st *ptr,
         return -1;
 
       /* If io_flush calls memcached_purge, sent_length may be 0 */
-      if (sent_length != 0)
+      unlikely (sent_length != 0)
       {
-        WATCHPOINT_ASSERT(sent_length == buffer_end);
+        WATCHPOINT_ASSERT(sent_length == (ssize_t)buffer_end);
       }
     }
   }
index 193bfd8c2c3b3ad6f5fafd469504688e24cfcace..32321c23471b0189fa25fbf6ea37128927cb5259 100644 (file)
@@ -270,6 +270,10 @@ static memcached_return textual_read_one_response(memcached_server_st *ptr,
       else
         return MEMCACHED_UNKNOWN_READ_FAILURE;
     }
+  case 'I': /* CLIENT ERROR */
+      /* We add back in one because we will need to search for END */
+      memcached_server_response_increment(ptr);
+    return MEMCACHED_ITEM;
   case 'C': /* CLIENT ERROR */
     return MEMCACHED_CLIENT_ERROR;
   default:
index 98ba5775956b9a2dd09f85c038c3e82144065f9a..538ab4bf15b0a09e9ccdc1f63be3d227d4f222f1 100644 (file)
@@ -33,6 +33,9 @@ typedef memcached_return (*memcached_trigger_key)(memcached_st *ptr,
 typedef memcached_return (*memcached_trigger_delete_key)(memcached_st *ptr,  
                                                          const char *key, size_t key_length);
 
+typedef memcached_return (*memcached_dump_func)(memcached_st *ptr,  
+                                                const char *key, size_t key_length, void *context);
+
 #ifdef __cplusplus
 }
 #endif
index 86a255ba326a3bd956fa6b839e7dd27399b45bcb..9d557b3ef740739ce8941c47403da3f6f9971132 100644 (file)
@@ -872,7 +872,6 @@ static test_return  set_test2(memcached_st *memc)
 static test_return  set_test3(memcached_st *memc)
 {
   memcached_return rc;
-  char *key= "foo";
   char *value;
   size_t value_length= 8191;
   unsigned int x;
@@ -883,8 +882,13 @@ static test_return  set_test3(memcached_st *memc)
   for (x= 0; x < value_length; x++)
     value[x] = (char) (x % 127);
 
-  for (x= 0; x < 1; x++)
+  /* The dump test relies on there being at least 32 items in memcached */
+  for (x= 0; x < 32; x++)
   {
+    char key[16];
+
+    sprintf(key, "foo%u", x);
+
     rc= memcached_set(memc, key, strlen(key), 
                       value, value_length,
                       (time_t)0, (uint32_t)0);
@@ -3390,6 +3394,45 @@ static test_return analyzer_test(memcached_st *memc)
   return TEST_SUCCESS;
 }
 
+/* Count the objects */
+static memcached_return callback_dump_counter(memcached_st *ptr __attribute__((unused)),  
+                                              const char *key __attribute__((unused)), 
+                                              size_t key_length __attribute__((unused)), 
+                                              void *context)
+{
+  uint32_t *counter= (uint32_t *)context;
+
+  *counter= *counter + 1;
+
+  return MEMCACHED_SUCCESS;
+}
+
+static test_return dump_test(memcached_st *memc)
+{
+  memcached_return rc;
+  uint32_t counter= 0;
+  memcached_dump_func callbacks[1];
+  test_return main_rc;
+
+  callbacks[0]= &callback_dump_counter;
+
+  /* No support for Binary protocol yet */
+  if (memc->flags & MEM_BINARY_PROTOCOL)
+    return TEST_SUCCESS;
+
+  main_rc= set_test3(memc);
+
+  assert (main_rc == TEST_SUCCESS);
+
+  rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
+  assert(rc == MEMCACHED_SUCCESS);
+
+  /* We may have more then 32 if our previous flush has not completed */
+  assert(counter >= 32);
+
+  return TEST_SUCCESS;
+}
+
 #ifdef HAVE_LIBMEMCACHEDUTIL
 static void* connection_release(void *arg) {
   struct {
@@ -3832,6 +3875,7 @@ test_st tests[] ={
   {"set", 0, set_test },
   {"set2", 0, set_test2 },
   {"set3", 0, set_test3 },
+  {"dump", 1, dump_test},
   {"add", 1, add_test },
   {"replace", 1, replace_test },
   {"delete", 1, delete_test },
index bfb54fbcaedc59106e294091891bebab9a94bcf7..a14f45e4d283eae4854e93d714773c73c61eed74 100644 (file)
@@ -30,16 +30,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -65,16 +67,17 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -100,16 +103,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -135,16 +140,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -170,16 +177,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -205,16 +214,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -240,16 +251,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -275,16 +288,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -310,16 +325,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -345,16 +362,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -380,16 +399,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -415,16 +436,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -450,16 +473,41 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
+ketama_weighted:10.0.1.1|11211|600|176
+ketama_weighted:10.0.1.2|11211|300|88
+ketama_weighted:10.0.1.3|11211|200|56
+ketama_weighted:10.0.1.4|11211|350|104
+ketama_weighted:10.0.1.5|11211|1000|296
+ketama_weighted:10.0.1.6|11211|800|236
+ketama_weighted:10.0.1.7|11211|950|280
+ketama_weighted:10.0.1.8|11211|100|28
+ketama_weighted:10.0.1.1|11211|600|160
+ketama_weighted:10.0.1.2|11211|300|80
+ketama_weighted:10.0.1.4|11211|350|92
+ketama_weighted:10.0.1.5|11211|1000|272
+ketama_weighted:10.0.1.6|11211|800|216
+ketama_weighted:10.0.1.7|11211|950|256
+ketama_weighted:10.0.1.8|11211|100|24
+ketama_weighted:10.0.1.1|11211|600|176
+ketama_weighted:10.0.1.2|11211|300|88
+ketama_weighted:10.0.1.3|11211|200|56
+ketama_weighted:10.0.1.4|11211|350|104
+ketama_weighted:10.0.1.5|11211|1000|296
+ketama_weighted:10.0.1.6|11211|800|236
+ketama_weighted:10.0.1.7|11211|950|280
+ketama_weighted:10.0.1.8|11211|100|28
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -485,16 +533,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -520,16 +570,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -555,16 +607,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -590,16 +644,18 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key foo
 Error 0 -> SUCCESS
 Error 1 -> FAILURE
 Error 2 -> HOSTNAME LOOKUP FAILURE
@@ -625,23 +681,89 @@ Error 21 -> SERVER END
 Error 22 -> SERVER DELETE
 Error 23 -> SERVER VALUE
 Error 24 -> STAT VALUE
-Error 25 -> SYSTEM ERROR
-Error 26 -> COULD NOT OPEN UNIX SOCKET
-Error 27 -> ACTION NOT SUPPORTED
-Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED
-Error 29 -> FETCH WAS NOT COMPLETED
-Error 30 -> A TIMEOUT OCCURRED
-Error 31 -> ACTION QUEUED
-Error 32 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
-Error 33 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
-Error 34 -> SERVER IS MARKED DEAD
+Error 25 -> Gibberish returned!
+Error 26 -> SYSTEM ERROR
+Error 27 -> COULD NOT OPEN UNIX SOCKET
+Error 28 -> ACTION NOT SUPPORTED
+Error 29 -> A KEY LENGTH OF ZERO WAS PROVIDED
+Error 30 -> FETCH WAS NOT COMPLETED
+Error 31 -> A TIMEOUT OCCURRED
+Error 32 -> ACTION QUEUED
+Error 33 -> A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE
+Error 34 -> THE HOST TRANSPORT PROTOCOL DOES NOT MATCH THAT OF THE CLIENT
+Error 35 -> SERVER IS MARKED DEAD
+Key Thisismorethentheallottednumberofcharactersfoo
+ketama_weighted:10.0.1.1|11211|600|176
+ketama_weighted:10.0.1.2|11211|300|88
+ketama_weighted:10.0.1.3|11211|200|56
+ketama_weighted:10.0.1.4|11211|350|104
+ketama_weighted:10.0.1.5|11211|1000|296
+ketama_weighted:10.0.1.6|11211|800|236
+ketama_weighted:10.0.1.7|11211|950|280
+ketama_weighted:10.0.1.8|11211|100|28
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
 
-server 0|localhost|11221 bytes: 2651938
+server 0|localhost|11221 bytes: 3257982
 
-server 1|localhost|11222 bytes: 2772996
+server 1|localhost|11222 bytes: 3099222
 
-server 2|localhost|11223 bytes: 3305941
+server 2|localhost|11223 bytes: 3503809
 
-server 3|localhost|11224 bytes: 3426764
+server 3|localhost|11224 bytes: 3780740
 
-server 4|localhost|11225 bytes: 2795684
+server 4|localhost|11225 bytes: 3124164
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|6666|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160
+ketama_weighted:localhost|11221|1|160
+ketama_weighted:localhost|11222|1|160
+ketama_weighted:localhost|11223|1|160
+ketama_weighted:localhost|11224|1|160
+ketama_weighted:localhost|11225|1|160