Adding comments to memcached_mget() that you need to call fetch methods
authorBrian Aker <brian@tangent.org>
Tue, 13 Nov 2007 06:43:00 +0000 (22:43 -0800)
committerBrian Aker <brian@tangent.org>
Tue, 13 Nov 2007 06:43:00 +0000 (22:43 -0800)
until all data is recieved. Found partial bug in quit() call with open data.

ChangeLog
docs/memcached_get.pod
lib/memcached_quit.c
tests/function.c

index 136a58df8a31789a47ff28d9bd999136bb3b6661..bda930f29944717776a82129633076fdeb9efbfd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@
     speed up async efforts
   * Modified increment/decrement functions to return uint64_t values
   * Fixed bug in cases where zero length keys were provided
+  * Thread cleanup issue in memslap
 
 0.8 Mon Nov  5 10:40:41 PST 2007
   * Adding support for CRC hash method 
index 458a55a9571479a6ea58bfe382ad9d27e4bd011e..6de4b5eb4af15ed0402da032d13a2b218401b496 100755 (executable)
@@ -22,9 +22,9 @@ C Client Library for memcached (libmemcached, -lmemcached)
                        memcached_return *error);
 
   memcached_return
-    memcached_mget (memcached_st *ptr, 
-                    char **keys, size_t *key_length, 
-                    unsigned int number_of_keys);
+  memcached_mget (memcached_st *ptr, 
+                  char **keys, size_t *key_length, 
+                  unsigned int number_of_keys);
 
   char *memcached_fetch (memcached_st *ptr,
                          char *key, size_t *key_length, 
@@ -45,7 +45,12 @@ upon success and NULL will be returned on failure.
 memcached_mget() is used to select multiple keys at once. For multiple key
 operations it is always faster to use this function. This function always
 works asynchronously. memcached_fetch() is then used to retrieve any keys
-found. No error is given on keys that are not found.
+found. No error is given on keys that are not found. You must call either
+memcached_fetch() or memcached_fetch_result() after a successful call to
+memcached_mget(). You should continue to call these functions until they
+return NULL (aka no more values). If you need to quit in the middle of a
+memcached_get() call, execute a memcached_quit(). After you do this, you can
+issue new queries against the server.
 
 memcached_fetch() is used to fetch an individual value from the server. 
 memcached_mget() must always be called before using this method.  You
index 20a76e2915e3eb482c9db123f7c289ce4c56fb8a..e51692fcd7fbf9fc99170f818a03f01321145c4a 100644 (file)
@@ -27,6 +27,9 @@ void memcached_quit_server(memcached_st *ptr, unsigned int server_key)
     ptr->hosts[server_key].fd= -1;
     ptr->hosts[server_key].stack_responses= 0;
     ptr->hosts[server_key].cursor_active= 0;
+    ptr->hosts[server_key].write_buffer_offset= 0;
+    ptr->hosts[server_key].read_buffer_length= 0;
+    ptr->hosts[server_key].read_ptr= ptr->hosts[server_key].read_buffer;
   }
 
   ptr->connected--;
index 12dfd34f829501345dc7095af1ae8fad388df9d0..d5291eae3c72fbc7fe67761555bf5264d00a9b65 100644 (file)
@@ -933,6 +933,65 @@ uint8_t user_supplied_bug4(memcached_st *memc)
   return 0;
 }
 
+#define VALUE_SIZE_BUG5 1048064
+uint8_t user_supplied_bug5(memcached_st *memc)
+{
+  memcached_return rc;
+  char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
+  size_t key_length[]=  {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
+  char return_key[MEMCACHED_MAX_KEY];
+  size_t return_key_length;
+  char *value;
+  size_t value_length;
+  uint16_t flags;
+  unsigned int count;
+  unsigned int x;
+  char insert_data[VALUE_SIZE_BUG5];
+
+  for (x= 0; x < VALUE_SIZE_BUG5; x++)
+    insert_data[x]= rand();
+
+  memcached_flush(memc, 0);
+  value= memcached_get(memc, keys[0], key_length[0],
+                        &value_length, &flags, &rc);           
+  assert(value == NULL);
+  rc= memcached_mget(memc, keys, key_length, 4);
+
+  count= 0;
+  while ((value= memcached_fetch(memc, return_key, &return_key_length, 
+                                        &value_length, &flags, &rc)))
+    count++;
+  assert(count == 0);
+
+  for (x= 0; x < 4; x++)
+  {
+    rc= memcached_set(memc, keys[x], key_length[x], 
+                      insert_data, VALUE_SIZE_BUG5,
+                      (time_t)0, (uint16_t)0);
+    assert(rc == MEMCACHED_SUCCESS);
+  }
+
+  for (x= 0; x < 10; x++)
+  {
+    value= memcached_get(memc, keys[0], key_length[0],
+                         &value_length, &flags, &rc);          
+    assert(value);
+    free(value);
+
+    rc= memcached_mget(memc, keys, key_length, 4);
+    count= 0;
+    while ((value= memcached_fetch(memc, return_key, &return_key_length, 
+                                          &value_length, &flags, &rc)))
+    {
+      count++;
+      free(value);
+    }
+    assert(count == 4);
+  }
+
+  return 0;
+}
+
 uint8_t result_static(memcached_st *memc)
 {
   memcached_result_st result;
@@ -1322,6 +1381,7 @@ test_st user_tests[] ={
   {"user_supplied_bug2", 0, user_supplied_bug2 },
   {"user_supplied_bug3", 0, user_supplied_bug3 },
   {"user_supplied_bug4", 0, user_supplied_bug4 },
+  {"user_supplied_bug5", 1, user_supplied_bug5 },
   {0, 0, 0}
 };