Update for keys
authorBrian Aker <brian@tangent.org>
Sun, 29 Jan 2012 00:31:49 +0000 (16:31 -0800)
committerBrian Aker <brian@tangent.org>
Sun, 29 Jan 2012 00:31:49 +0000 (16:31 -0800)
13 files changed:
libmemcached-1.0/struct/result.h
libmemcached/auto.cc
libmemcached/delete.cc
libmemcached/get.cc
libmemcached/response.cc
libmemcached/response.h
libmemcached/result.cc
libmemcached/server.cc
libmemcached/storage.cc
m4/visibility.m4
tests/libmemcached-1.0/mem_functions.cc
tests/libmemcached-1.0/replication.cc
tests/replication.h

index 2b2f49960d70ef046291b50264ec3c69869be162..c3bfddb5e9d3334e8103a793da696bb4bf162ac7 100644 (file)
@@ -44,6 +44,7 @@ struct memcached_result_st {
   uint64_t item_cas;
   struct memcached_st *root;
   memcached_string_st value;
+  uint64_t numeric_value;
   uint64_t count;
   char item_key[MEMCACHED_MAX_KEY];
   struct {
index c64ccda45067d79983f9ceae6e72df5804826822..9d85ad434858897556244f0447f0564cfddadaf5 100644 (file)
 
 #include <libmemcached/common.h>
 
+static void auto_response(memcached_server_write_instance_st instance, const bool reply,  memcached_return_t& rc, uint64_t* value)
+{
+  // If the message was successfully sent, then get the response, otherwise
+  // fail.
+  if (memcached_success(rc))
+  {
+    if (reply == false)
+    {
+      *value= UINT64_MAX;
+      return;
+    }
+
+    rc= memcached_response(instance, &instance->root->result);
+  }
+
+  if (memcached_success(rc))
+  {
+    *value= instance->root->result.numeric_value;
+  }
+  else
+  {
+    *value= UINT64_MAX;
+  }
+}
+
 static memcached_return_t text_incr_decr(memcached_server_write_instance_st instance,
                                          const bool is_incr,
                                          const char *key, size_t key_length,
                                          const uint64_t offset,
-                                         const bool reply,
-                                         uint64_t& numeric_value)
+                                         const bool reply)
 {
   char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
 
@@ -69,22 +93,7 @@ static memcached_return_t text_incr_decr(memcached_server_write_instance_st inst
     vector[1].buffer= "decr ";
   }
 
-  memcached_return_t rc= memcached_vdo(instance, vector, 7, true);
-
-  if (reply == false)
-  {
-    return MEMCACHED_SUCCESS;
-  }
-
-  if (memcached_failed(rc))
-  {
-    numeric_value= UINT64_MAX;
-    return rc;
-  }
-
-  rc= memcached_response(instance, buffer, sizeof(buffer), NULL, numeric_value);
-
-  return memcached_set_error(*instance, rc, MEMCACHED_AT);
+  return memcached_vdo(instance, vector, 7, true);
 }
 
 static memcached_return_t binary_incr_decr(memcached_server_write_instance_st instance,
@@ -93,8 +102,7 @@ static memcached_return_t binary_incr_decr(memcached_server_write_instance_st in
                                            const uint64_t offset,
                                            const uint64_t initial,
                                            const uint32_t expiration,
-                                           const bool reply,
-                                           uint64_t *value)
+                                           const bool reply)
 {
   if (reply == false)
   {
@@ -128,89 +136,76 @@ static memcached_return_t binary_incr_decr(memcached_server_write_instance_st in
     { key, key_length }
   };
 
-  memcached_return_t rc;
-  if (memcached_failed(rc= memcached_vdo(instance, vector, 4, true)))
-  {
-    memcached_io_reset(instance);
-    return MEMCACHED_WRITE_FAILURE;
-  }
-
-  if (reply == false)
-  {
-    return MEMCACHED_SUCCESS;
-  }
-
-  return memcached_response(instance, (char*)value, sizeof(*value), NULL);
+  return memcached_vdo(instance, vector, 4, true);
 }
 
-memcached_return_t memcached_increment(memcached_st *ptr,
+memcached_return_t memcached_increment(memcached_st *memc,
                                        const char *key, size_t key_length,
                                        uint32_t offset,
                                        uint64_t *value)
 {
-  return memcached_increment_by_key(ptr, key, key_length, key, key_length, offset, value);
+  return memcached_increment_by_key(memc, key, key_length, key, key_length, offset, value);
 }
 
-memcached_return_t memcached_decrement(memcached_st *ptr,
-                                       const char *key, size_t key_length,
-                                       uint32_t offset,
-                                       uint64_t *value)
+static memcached_return_t increment_decrement_by_key(const protocol_binary_command command,
+                                                     memcached_st *memc,
+                                                     const char *group_key, size_t group_key_length,
+                                                     const char *key, size_t key_length,
+                                                     uint64_t offset,
+                                                     uint64_t *value)
 {
-  return memcached_decrement_by_key(ptr, key, key_length, key, key_length, offset, value);
-}
-
-memcached_return_t memcached_increment_by_key(memcached_st *ptr,
-                                              const char *group_key, size_t group_key_length,
-                                              const char *key, size_t key_length,
-                                              uint64_t offset,
-                                              uint64_t *value)
-{
-  memcached_return_t rc;
   uint64_t local_value;
   if (value == NULL)
   {
     value= &local_value;
   }
 
-  if (memcached_failed(rc= initialize_query(ptr, true)))
+  memcached_return_t rc;
+  if (memcached_failed(rc= initialize_query(memc, true)))
   {
     return rc;
   }
 
-  if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+  if (memcached_failed(rc= memcached_key_test(*memc, (const char **)&key, &key_length, 1)))
   {
-    return rc;
+    return memcached_last_error(memc);
   }
 
-  uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
-  memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+  uint32_t server_key= memcached_generate_hash_with_redistribution(memc, group_key, group_key_length);
+  memcached_server_write_instance_st instance= memcached_server_instance_fetch(memc, server_key);
 
   bool reply= memcached_is_replying(instance->root);
 
-  LIBMEMCACHED_MEMCACHED_INCREMENT_START();
-  if (memcached_is_binary(ptr))
+  if (memcached_is_binary(memc))
   {
-    rc= binary_incr_decr(instance, PROTOCOL_BINARY_CMD_INCREMENT,
+    rc= binary_incr_decr(instance, command,
                          key, key_length,
                          uint64_t(offset), 0, MEMCACHED_EXPIRATION_NOT_ADD,
-                         reply,
-                         value);
+                         reply);
   }
   else
   {
-    rc= text_incr_decr(instance, true, key, key_length, offset, reply, *value);
+    rc= text_incr_decr(instance,
+                       command == PROTOCOL_BINARY_CMD_INCREMENT ? true : false,
+                       key, key_length,
+                       offset, reply);
   }
 
-  LIBMEMCACHED_MEMCACHED_INCREMENT_END();
+  auto_response(instance, reply, rc, value);
 
   return rc;
 }
 
-memcached_return_t memcached_decrement_by_key(memcached_st *ptr,
-                                              const char *group_key, size_t group_key_length,
-                                              const char *key, size_t key_length,
-                                              uint64_t offset,
-                                              uint64_t *value)
+static memcached_return_t increment_decrement_with_initial_by_key(const protocol_binary_command command,
+                                                                  memcached_st *memc,
+                                                                  const char *group_key,
+                                                                  size_t group_key_length,
+                                                                  const char *key,
+                                                                  size_t key_length,
+                                                                  uint64_t offset,
+                                                                  uint64_t initial,
+                                                                  time_t expiration,
+                                                                  uint64_t *value)
 {
   uint64_t local_value;
   if (value == NULL)
@@ -219,42 +214,85 @@ memcached_return_t memcached_decrement_by_key(memcached_st *ptr,
   }
 
   memcached_return_t rc;
-  if (memcached_failed(rc= initialize_query(ptr, true)))
+  if (memcached_failed(rc= initialize_query(memc, true)))
   {
     return rc;
   }
 
-  if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+  if (memcached_failed(rc= memcached_key_test(*memc, (const char **)&key, &key_length, 1)))
   {
-    return rc;
+    return memcached_last_error(memc);
   }
 
-
-  uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
-  memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
+  uint32_t server_key= memcached_generate_hash_with_redistribution(memc, group_key, group_key_length);
+  memcached_server_write_instance_st instance= memcached_server_instance_fetch(memc, server_key);
 
   bool reply= memcached_is_replying(instance->root);
 
-  LIBMEMCACHED_MEMCACHED_DECREMENT_START();
-  if (memcached_is_binary(ptr))
+  if (memcached_is_binary(memc))
   {
-    rc= binary_incr_decr(instance, PROTOCOL_BINARY_CMD_DECREMENT,
+    rc= binary_incr_decr(instance, command,
                          key, key_length,
-                         offset, 0, MEMCACHED_EXPIRATION_NOT_ADD,
-                         reply,
-                         value);
+                         offset, initial, uint32_t(expiration),
+                         reply);
+        
   }
   else
   {
-    rc= text_incr_decr(instance, false, key, key_length, offset, reply, *value);
+    rc=  memcached_set_error(*memc, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
+                             memcached_literal_param("memcached_increment_with_initial_by_key() is not supported via the ASCII protocol"));
   }
 
+  auto_response(instance, reply, rc, value);
+
+  return rc;
+}
+
+memcached_return_t memcached_decrement(memcached_st *memc,
+                                       const char *key, size_t key_length,
+                                       uint32_t offset,
+                                       uint64_t *value)
+{
+  return memcached_decrement_by_key(memc, key, key_length, key, key_length, offset, value);
+}
+
+
+memcached_return_t memcached_increment_by_key(memcached_st *memc,
+                                              const char *group_key, size_t group_key_length,
+                                              const char *key, size_t key_length,
+                                              uint64_t offset,
+                                              uint64_t *value)
+{
+  LIBMEMCACHED_MEMCACHED_INCREMENT_START();
+  memcached_return_t rc= increment_decrement_by_key(PROTOCOL_BINARY_CMD_INCREMENT,
+                                                    memc,
+                                                    group_key, group_key_length,
+                                                    key, key_length,
+                                                    offset, value);
+
+  LIBMEMCACHED_MEMCACHED_INCREMENT_END();
+
+  return rc;
+}
+
+memcached_return_t memcached_decrement_by_key(memcached_st *memc,
+                                              const char *group_key, size_t group_key_length,
+                                              const char *key, size_t key_length,
+                                              uint64_t offset,
+                                              uint64_t *value)
+{
+  LIBMEMCACHED_MEMCACHED_DECREMENT_START();
+  memcached_return_t rc= increment_decrement_by_key(PROTOCOL_BINARY_CMD_DECREMENT,
+                                                    memc,
+                                                    group_key, group_key_length,
+                                                    key, key_length,
+                                                    offset, value);
   LIBMEMCACHED_MEMCACHED_DECREMENT_END();
 
   return rc;
 }
 
-memcached_return_t memcached_increment_with_initial(memcached_st *ptr,
+memcached_return_t memcached_increment_with_initial(memcached_st *memc,
                                                     const char *key,
                                                     size_t key_length,
                                                     uint64_t offset,
@@ -262,64 +300,33 @@ memcached_return_t memcached_increment_with_initial(memcached_st *ptr,
                                                     time_t expiration,
                                                     uint64_t *value)
 {
-  return memcached_increment_with_initial_by_key(ptr, key, key_length,
+  return memcached_increment_with_initial_by_key(memc, key, key_length,
                                                  key, key_length,
                                                  offset, initial, expiration, value);
 }
 
-memcached_return_t memcached_increment_with_initial_by_key(memcached_st *ptr,
-                                                         const char *group_key,
-                                                         size_t group_key_length,
-                                                         const char *key,
-                                                         size_t key_length,
-                                                         uint64_t offset,
-                                                         uint64_t initial,
-                                                         time_t expiration,
-                                                         uint64_t *value)
+memcached_return_t memcached_increment_with_initial_by_key(memcached_st *memc,
+                                                           const char *group_key,
+                                                           size_t group_key_length,
+                                                           const char *key,
+                                                           size_t key_length,
+                                                           uint64_t offset,
+                                                           uint64_t initial,
+                                                           time_t expiration,
+                                                           uint64_t *value)
 {
-  uint64_t local_value;
-  if (value == NULL)
-  {
-    value= &local_value;
-  }
-
-  memcached_return_t rc;
-  if (memcached_failed(rc= initialize_query(ptr, true)))
-  {
-    return rc;
-  }
-
-  if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
-  {
-    return rc;
-  }
-
-  uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
-  memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
-
-  bool reply= memcached_is_replying(instance->root);
-
   LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_START();
-  if (memcached_is_binary(ptr))
-  {
-    rc= binary_incr_decr(instance, PROTOCOL_BINARY_CMD_INCREMENT,
-                         key, key_length,
-                         offset, initial, uint32_t(expiration),
-                         reply,
-                         value);
-  }
-  else
-  {
-    rc=  memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
-                             memcached_literal_param("memcached_increment_with_initial_by_key() is not supported via the ASCII protocol"));
-  }
-
+  memcached_return_t rc= increment_decrement_with_initial_by_key(PROTOCOL_BINARY_CMD_INCREMENT, 
+                                                                 memc,
+                                                                 group_key, group_key_length,
+                                                                 key, key_length,
+                                                                 offset, initial, expiration, value);
   LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_END();
 
   return rc;
 }
 
-memcached_return_t memcached_decrement_with_initial(memcached_st *ptr,
+memcached_return_t memcached_decrement_with_initial(memcached_st *memc,
                                                     const char *key,
                                                     size_t key_length,
                                                     uint64_t offset,
@@ -327,12 +334,12 @@ memcached_return_t memcached_decrement_with_initial(memcached_st *ptr,
                                                     time_t expiration,
                                                     uint64_t *value)
 {
-  return memcached_decrement_with_initial_by_key(ptr, key, key_length,
+  return memcached_decrement_with_initial_by_key(memc, key, key_length,
                                                  key, key_length,
                                                  offset, initial, expiration, value);
 }
 
-memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *ptr,
+memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *memc,
                                                            const char *group_key,
                                                            size_t group_key_length,
                                                            const char *key,
@@ -342,43 +349,12 @@ memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *ptr,
                                                            time_t expiration,
                                                            uint64_t *value)
 {
-  uint64_t local_value;
-  if (value == NULL)
-  {
-    value= &local_value;
-  }
-
-  memcached_return_t rc;
-  if (memcached_failed(rc= initialize_query(ptr, true)))
-  {
-    return rc;
-  }
-
-  if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
-  {
-    return rc;
-  }
-
-  uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
-  memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server_key);
-
-  bool reply= memcached_is_replying(instance->root);
-
-
   LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_START();
-  if (memcached_is_binary(ptr))
-  {
-    rc= binary_incr_decr(instance, PROTOCOL_BINARY_CMD_DECREMENT,
-                         key, key_length,
-                         offset, initial, uint32_t(expiration),
-                         reply,
-                         value);
-  }
-  else
-  {
-    rc=  memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
-                             memcached_literal_param("memcached_decrement_with_initial_by_key() is not supported via the ASCII protocol"));
-  }
+  memcached_return_t rc= increment_decrement_with_initial_by_key(PROTOCOL_BINARY_CMD_DECREMENT, 
+                                                                 memc,
+                                                                 group_key, group_key_length,
+                                                                 key, key_length,
+                                                                 offset, initial, expiration, value);
 
   LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_END();
 
index 1ffdbfac336dd0b0438a0d47fa3b29fdcaae9a74..ea339169707e9c442948d913e8e7736ff7e8ec46 100644 (file)
@@ -146,7 +146,7 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr,
 
   if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
   {
-    return rc;
+    return memcached_last_error(ptr);
   }
 
   if (expiration)
index a6fe4034e7a4416caa23005e01cf86668f5b2a27..9ed7296f32d996d9806561650d730ca4e45347c6 100644 (file)
@@ -237,11 +237,6 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr,
   bool is_group_key_set= false;
   if (group_key and group_key_length)
   {
-    if (memcached_failed(memcached_key_test(*ptr, (const char * const *)&group_key, &group_key_length, 1)))
-    {
-      return memcached_set_error(*ptr, MEMCACHED_BAD_KEY_PROVIDED, MEMCACHED_AT, memcached_literal_param("A bad group key was provided."));
-    }
-
     master_server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
     is_group_key_set= true;
   }
@@ -254,8 +249,7 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr,
   */
   for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
   {
-    memcached_server_write_instance_st instance=
-      memcached_server_instance_fetch(ptr, x);
+    memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
 
     if (memcached_server_response_count(instance))
     {
@@ -273,7 +267,7 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr,
     }
   }
 
-  if (ptr->flags.binary_protocol)
+  if (memcached_is_binary(ptr))
   {
     return binary_mget_by_key(ptr, master_server_key, is_group_key_set, keys,
                               key_length, number_of_keys, mget_mode);
index ac1fb057124b59360b65652b4b38415315e09825..437c4cc9e5d0b76d4c86670f157bb82a7f9a8dfc 100644 (file)
@@ -182,10 +182,8 @@ read_error:
 
 static memcached_return_t textual_read_one_response(memcached_server_write_instance_st ptr,
                                                     char *buffer, const size_t buffer_length,
-                                                    memcached_result_st *result,
-                                                    uint64_t& numeric_value)
+                                                    memcached_result_st *result)
 {
-  numeric_value= UINT64_MAX;
   size_t total_read;
   memcached_return_t rc= memcached_io_readline(ptr, buffer, buffer_length, total_read);
 
@@ -381,16 +379,18 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
 
       if (auto_return_value == ULLONG_MAX and errno == ERANGE)
       {
+        result->numeric_value= UINT64_MAX;
         return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT,
                                    memcached_literal_param("Numeric response was out of range"));
       }
       else if (errno == EINVAL)
       {
+        result->numeric_value= UINT64_MAX;
         return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT,
                                    memcached_literal_param("Numeric response was out of range"));
       }
 
-      numeric_value= uint64_t(auto_return_value);
+      result->numeric_value= uint64_t(auto_return_value);
 
       WATCHPOINT_STRING(buffer);
       return MEMCACHED_SUCCESS;
@@ -509,21 +509,20 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan
     case PROTOCOL_BINARY_CMD_INCREMENT:
     case PROTOCOL_BINARY_CMD_DECREMENT:
       {
-        if (bodylen != sizeof(uint64_t) or buffer_length != sizeof(uint64_t))
+        if (bodylen != sizeof(uint64_t))
         {
+          result->numeric_value= UINT64_MAX;
           return memcached_set_error(*ptr, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT);
         }
 
-        WATCHPOINT_ASSERT(bodylen == buffer_length);
         uint64_t val;
         if ((rc= memcached_safe_read(ptr, &val, sizeof(val))) != MEMCACHED_SUCCESS)
         {
-          WATCHPOINT_ERROR(rc);
+          result->numeric_value= UINT64_MAX;
           return MEMCACHED_UNKNOWN_READ_FAILURE;
         }
 
-        val= memcached_ntohll(val);
-        memcpy(buffer, &val, sizeof(val));
+        result->numeric_value= memcached_ntohll(val);
       }
       break;
 
@@ -694,8 +693,7 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan
 
 static memcached_return_t _read_one_response(memcached_server_write_instance_st ptr,
                                              char *buffer, const size_t buffer_length,
-                                             memcached_result_st *result,
-                                             uint64_t& numeric_value)
+                                             memcached_result_st *result)
 {
   memcached_server_response_decrement(ptr);
 
@@ -712,7 +710,7 @@ static memcached_return_t _read_one_response(memcached_server_write_instance_st
   }
   else
   {
-    rc= textual_read_one_response(ptr, buffer, buffer_length, result, numeric_value);
+    rc= textual_read_one_response(ptr, buffer, buffer_length, result);
     assert(rc != MEMCACHED_PROTOCOL_ERROR);
   }
 
@@ -727,7 +725,6 @@ static memcached_return_t _read_one_response(memcached_server_write_instance_st
 memcached_return_t memcached_read_one_response(memcached_server_write_instance_st ptr,
                                                memcached_result_st *result)
 {
-  uint64_t numeric_value;
   char buffer[SMALL_STRING_LEN];
 
   if (memcached_is_udp(ptr->root))
@@ -736,22 +733,20 @@ memcached_return_t memcached_read_one_response(memcached_server_write_instance_s
   }
 
 
-  return _read_one_response(ptr, buffer, sizeof(buffer), result, numeric_value);
+  return _read_one_response(ptr, buffer, sizeof(buffer), result);
 }
 
 memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
-                                      char *buffer, size_t buffer_length,
                                       memcached_result_st *result)
 {
-  uint64_t numeric_value;
+  char buffer[1024];
 
-  return memcached_response(ptr, buffer, buffer_length, result, numeric_value);
+  return memcached_response(ptr, buffer, sizeof(buffer), result);
 }
 
 memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
                                       char *buffer, size_t buffer_length,
-                                      memcached_result_st *result,
-                                      uint64_t& numeric_value)
+                                      memcached_result_st *result)
 {
   if (memcached_is_udp(ptr->root))
   {
@@ -778,7 +773,7 @@ memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
 
     while (memcached_server_response_count(ptr) > 1)
     {
-      memcached_return_t rc= _read_one_response(ptr, buffer, buffer_length, junked_result_ptr, numeric_value);
+      memcached_return_t rc= _read_one_response(ptr, buffer, buffer_length, junked_result_ptr);
 
       // @TODO should we return an error on another but a bad read case?
       if (
@@ -805,5 +800,5 @@ memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
     memcached_result_free(junked_result_ptr);
   }
 
-  return _read_one_response(ptr, buffer, buffer_length, result, numeric_value);
+  return _read_one_response(ptr, buffer, buffer_length, result);
 }
index d9abdb8a3d31d685f118705daf7986873f202d7a..8827aea043a84a9a60661010f07387865cf223ba 100644 (file)
@@ -42,10 +42,8 @@ memcached_return_t memcached_read_one_response(memcached_server_write_instance_s
                                                memcached_result_st *result);
 
 memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
-                                      char *buffer, size_t buffer_length,
                                       memcached_result_st *result);
 
 memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
                                       char *buffer, size_t buffer_length,
-                                      memcached_result_st *result,
-                                      uint64_t& numeric_value);
+                                      memcached_result_st *result);
index a3438c08c9b0f2ed07a73296c474ebb601e91607..444a75f4135091b88589c925eb4f76f4e76dac35 100644 (file)
@@ -52,6 +52,7 @@ static inline void _result_init(memcached_result_st *self,
   self->key_length= 0;
   self->item_cas= 0;
   self->root= memc;
+  self->numeric_value= UINT64_MAX;
   self->count= 0;
   self->item_key[0]= 0;
 }
@@ -97,6 +98,7 @@ void memcached_result_reset(memcached_result_st *ptr)
   ptr->item_flags= 0;
   ptr->item_cas= 0;
   ptr->item_expiration= 0;
+  ptr->numeric_value= UINT64_MAX;
 }
 
 void memcached_result_free(memcached_result_st *ptr)
@@ -107,6 +109,7 @@ void memcached_result_free(memcached_result_st *ptr)
   }
 
   memcached_string_free(&ptr->value);
+  ptr->numeric_value= UINT64_MAX;
 
   if (memcached_is_allocated(ptr))
   {
index 2f41584419ad337d35d6c6b3572453b405b5506e..b742f7ef1695cde1da2fe736b7b12e0dc120e609 100644 (file)
@@ -285,9 +285,9 @@ memcached_server_instance_st memcached_server_by_key(memcached_st *ptr,
     return NULL;
   }
 
-  if (memcached_failed(rc= (memcached_key_test(*ptr, (const char **)&key, &key_length, 1))))
+  if (memcached_failed((memcached_key_test(*ptr, (const char **)&key, &key_length, 1))))
   {
-    *error= rc;
+    *error= memcached_last_error(ptr);
     return NULL;
   }
 
index e5f67dbcd2e50b7f07118aaa4db10dad3f877bec..1b3dbcddd7cd15e220db0b11d5884ef54820931a 100644 (file)
@@ -342,9 +342,9 @@ static inline memcached_return_t memcached_send(memcached_st *ptr,
     return rc;
   }
 
-  if (memcached_failed(rc= memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
+  if (memcached_failed(memcached_key_test(*ptr, (const char **)&key, &key_length, 1)))
   {
-    return rc;
+    return memcached_last_error(ptr);
   }
 
   uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
index 077c4765ec2252f796d90b8848ef199860b7789d..75c34b6e151f04f7793e65b96e2f208eb3f7dd6e 100644 (file)
@@ -1,5 +1,5 @@
-# visibility.m4 serial 3 (gettext-0.18)
-dnl Copyright (C) 2005, 2008-2010 Free Software Foundation, Inc.
+# visibility.m4 serial 4 (gettext-0.18.2)
+dnl Copyright (C) 2005, 2008, 2010-2011 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -33,7 +33,8 @@ AC_DEFUN([gl_VISIBILITY],
     AC_CACHE_VAL([gl_cv_cc_vis_werror], [
       gl_save_CFLAGS="$CFLAGS"
       CFLAGS="$CFLAGS -Werror"
-      AC_TRY_COMPILE([], [],
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM([[]], [[]])],
         [gl_cv_cc_vis_werror=yes],
         [gl_cv_cc_vis_werror=no])
       CFLAGS="$gl_save_CFLAGS"])
@@ -51,13 +52,15 @@ AC_DEFUN([gl_VISIBILITY],
       if test $gl_cv_cc_vis_werror = yes; then
         CFLAGS="$CFLAGS -Werror"
       fi
-      AC_TRY_COMPILE(
-        [extern __attribute__((__visibility__("hidden"))) int hiddenvar;
-         extern __attribute__((__visibility__("default"))) int exportedvar;
-         extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
-         extern __attribute__((__visibility__("default"))) int exportedfunc (void);
-         void dummyfunc (void) {}],
-        [],
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
+             extern __attribute__((__visibility__("default"))) int exportedvar;
+             extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
+             extern __attribute__((__visibility__("default"))) int exportedfunc (void);
+             void dummyfunc (void) {}
+           ]],
+           [[]])],
         [gl_cv_cc_visibility=yes],
         [gl_cv_cc_visibility=no])
       CFLAGS="$gl_save_CFLAGS"])
index 0256588dcba108750bbe76fcb8aa1666cd9fdebf..dfd7d21e2171e3993d43cafacacaafd4e325fe43 100644 (file)
@@ -922,7 +922,8 @@ static test_return_t bad_key_test(memcached_st *memc)
     test_compare(query_id +1, memcached_query_id(memc_clone));
 
     query_id= memcached_query_id(memc_clone);
-    test_compare(MEMCACHED_BAD_KEY_PROVIDED,
+    // Grouping keys are not required to follow normal key behaviors
+    test_compare(MEMCACHED_SUCCESS,
                  memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1));
     test_compare(query_id +1, memcached_query_id(memc_clone));
 
@@ -5778,6 +5779,7 @@ test_st replication_tests[]= {
   {"mget", false, (test_callback_fn*)replication_mget_test },
   {"delete", true, (test_callback_fn*)replication_delete_test },
   {"rand_mget", false, (test_callback_fn*)replication_randomize_mget_test },
+  {"miss", false, (test_callback_fn*)replication_miss_test },
   {"fail", false, (test_callback_fn*)replication_randomize_mget_fail_test },
   {0, 0, (test_callback_fn*)0}
 };
index be1fd7e2bfb24d5dce52a6f2776e105598168e3a..60c62b8504b4382715b21f31bb71263f5c1449f9 100644 (file)
@@ -327,3 +327,92 @@ test_return_t replication_randomize_mget_fail_test(memcached_st *memc)
   memcached_free(memc_clone);
   return TEST_SUCCESS;
 }
+
+/* Test that single miss does not cause replica reads to fail */
+test_return_t replication_miss_test(memcached_st *memc)
+{
+  test_skip(true, false);
+
+  memcached_st *memc_repl= memcached_clone(NULL, memc);
+  test_true(memc_repl);
+  memcached_st *memc_single= memcached_clone(NULL, memc);
+  test_true(memc_single);
+
+  const char *value = "my_value";
+  size_t vlen;
+  uint32_t flags;
+
+  /* this test makes sense only with 2 or more servers */
+  test_true(memcached_server_count(memc_repl) > 1);
+
+  /* Consistent hash */
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_behavior_set_distribution(memc_repl, MEMCACHED_DISTRIBUTION_CONSISTENT));
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_behavior_set_distribution(memc_single, MEMCACHED_DISTRIBUTION_CONSISTENT));
+
+  /* The first clone writes to all servers */
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_behavior_set(memc_repl, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
+  test_compare(MEMCACHED_SUCCESS,
+               memcached_behavior_set(memc_repl, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 
+                                      memcached_server_count(memc_repl)));
+
+  /* Write to servers */
+  {
+    memcached_return_t rc= memcached_set(memc_repl,
+                                         test_literal_param(__func__),
+                                         value, strlen(value), 
+                                         time_t(1200), uint32_t(0));
+    test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
+  }
+
+  /* Use the second clone to remove the key from primary server.
+    This should remove the key from only one server */
+  {
+    memcached_return_t rc= memcached_delete(memc_single, 
+                                            test_literal_param(__func__),
+                                            0);
+    test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
+  }
+
+  /* Remove the server where the key was deleted */
+  {
+#if 0
+    memcached_return_t rc;
+    const memcached_server_st *instance= memcached_server_by_key(memc_single,
+                                                                 test_literal_param(__func__),
+                                                                 &rc);
+    test_compare(MEMCACHED_SUCCESS, rc);
+    test_compare(MEMCACHED_SUCCESS,
+                 memcached_server_remove(instance));
+#endif
+  }
+
+  /* Test that others still have it */
+  {
+    memcached_return_t rc;
+    char *get_value= memcached_get(memc_single,
+                                   test_literal_param(__func__),
+                                   &vlen, &flags, &rc);
+    test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
+    test_true(get_value and strcmp(get_value, value) == 0);
+    free(get_value);
+  }
+
+  /* This read should still return the value as we have it on other servers */
+  {
+    memcached_return_t rc;
+    char *get_value= memcached_get(memc_repl,
+                                   test_literal_param(__func__),
+                                   &vlen, &flags, &rc);
+    test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+    test_true(get_value and strcmp(get_value, value) == 0);
+    free(get_value);
+  }
+
+  memcached_free(memc_repl);
+  memcached_free(memc_single);
+
+  return TEST_SUCCESS;
+}
index 1bf4e499b6d22841c8f4796768a5d753f97f5f06..f287a624e1470f1c50c484d744dc4aff42b4d460 100644 (file)
 
 #pragma once
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBTEST_LOCAL
 test_return_t replication_set_test(memcached_st *memc);
 
-LIBTEST_LOCAL
 test_return_t replication_get_test(memcached_st *memc);
 
-LIBTEST_LOCAL
 test_return_t replication_mget_test(memcached_st *memc);
 
-LIBTEST_LOCAL
 test_return_t replication_delete_test(memcached_st *memc);
 
-LIBTEST_LOCAL
 test_return_t replication_randomize_mget_test(memcached_st *memc);
 
-LIBTEST_LOCAL
 test_return_t replication_randomize_mget_fail_test(memcached_st *memc);
 
-#ifdef __cplusplus
-}
-#endif
+test_return_t replication_miss_test(memcached_st *memc);