Merge in code for improving fetch operation.
authorBrian Aker <brian@tangent.org>
Sat, 18 Jun 2011 01:48:02 +0000 (18:48 -0700)
committerBrian Aker <brian@tangent.org>
Sat, 18 Jun 2011 01:48:02 +0000 (18:48 -0700)
ChangeLog
libmemcached/fetch.cc
libmemcached/get.cc
tests/mem_functions.cc

index afbfce1af91ab5235b5e40b2b0bf4371249c0abf..2589ceb7d160e145a055dc138bb29ab9497f7948 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
+0.50
+
  * Updates to C++ interface 
  * Custom free allocators need to now check for value before calling free.
 
+ * memcached_fetch_result() now uses the internal result when available (about 25 to 50% faster).
+
 0.49 Thu Apr 14 08:43:37 PDT 2011
   * Fix calls to auto methods so that if value is not passed in nothing bad happens.
   * New parser calls for generating memcached_st objects.
index e947ddb20bee5d9acce4f04933738034c8530c12..dd0b036d8433cecc7177e54f9c40912f1a2a5b0c 100644 (file)
@@ -128,6 +128,12 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
   if (not error)
     error= &unused;
 
+  if (not ptr)
+  {
+    *error= MEMCACHED_INVALID_ARGUMENTS;
+    return NULL;
+  }
+
   if (ptr->flags.use_udp)
   {
     *error= MEMCACHED_NOT_SUPPORTED;
@@ -136,10 +142,19 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
 
   if (not result)
   {
-    if (not (result= memcached_result_create(ptr, NULL)))
+    // If we have already initialized (ie it is in use) our internal, we
+    // create one.
+    if (memcached_is_initialized(&ptr->result))
     {
-      *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-      return NULL;
+      if (not (result= memcached_result_create(ptr, NULL)))
+      {
+        *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+        return NULL;
+      }
+    }
+    else
+    {
+      result= memcached_result_create(ptr, &ptr->result);
     }
   }
 
index b95aa0c121c5ef01e1e99b36f72a38513ce934e4..0cef87f5120021a1ce5be905d02699c894c4d0c2 100644 (file)
@@ -131,7 +131,9 @@ char *memcached_get_by_key(memcached_st *ptr,
                             (memcached_result_flags(&ptr->result)));
 
           if (rc == MEMCACHED_BUFFERED && latch == 0)
+          {
             memcached_behavior_set(ptr, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0);
+          }
         }
         else
         {
index 589d5cb3d19e5d490decf74d5d534070fb9a0654..f963582eddff8308c9a24419a7b1887c143d37d5 100644 (file)
@@ -3471,6 +3471,71 @@ static test_return_t mget_read_result(memcached_st *memc)
   return TEST_SUCCESS;
 }
 
+static test_return_t mget_read_internal_result(memcached_st *memc)
+{
+
+  test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
+
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_mget(memc, global_keys, global_keys_length, global_count));
+  {
+    memcached_result_st *results= NULL;
+    memcached_return_t rc;
+    while ((results= memcached_fetch_result(memc, results, &rc)))
+    {
+      test_true(results);
+      test_compare(MEMCACHED_SUCCESS, rc);
+    }
+    test_compare(MEMCACHED_END, rc);
+
+    memcached_result_free(results);
+  }
+
+  return TEST_SUCCESS;
+}
+
+static test_return_t mget_read_partial_result(memcached_st *memc)
+{
+
+  test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
+
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_mget(memc, global_keys, global_keys_length, global_count));
+
+  // We will scan for just one key
+  {
+    memcached_result_st results_obj;
+    memcached_result_st *results= memcached_result_create(memc, &results_obj);
+
+    memcached_return_t rc;
+    results= memcached_fetch_result(memc, results, &rc);
+    test_true(results);
+    test_compare(MEMCACHED_SUCCESS, rc);
+
+    memcached_result_free(&results_obj);
+  }
+
+  // We already have a read happening, lets start up another one.
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_mget(memc, global_keys, global_keys_length, global_count));
+  {
+    memcached_result_st results_obj;
+    memcached_result_st *results= memcached_result_create(memc, &results_obj);
+
+    memcached_return_t rc;
+    while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
+    {
+      test_true(results);
+      test_compare(MEMCACHED_SUCCESS, rc);
+    }
+    test_compare(MEMCACHED_END, rc);
+
+    memcached_result_free(&results_obj);
+  }
+
+  return TEST_SUCCESS;
+}
+
 static test_return_t mget_read_function(memcached_st *memc)
 {
   test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
@@ -6265,6 +6330,8 @@ test_st generate_tests[] ={
   {"generate_data", 1, (test_callback_fn)generate_data },
   {"mget_read", 0, (test_callback_fn)mget_read },
   {"mget_read_result", 0, (test_callback_fn)mget_read_result },
+  {"memcached_fetch_result() use internal result", 0, (test_callback_fn)mget_read_internal_result },
+  {"memcached_fetch_result() partial read", 0, (test_callback_fn)mget_read_partial_result },
   {"mget_read_function", 0, (test_callback_fn)mget_read_function },
   {"cleanup", 1, (test_callback_fn)cleanup_pairs },
   {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },