Branch merge for fixes in reconnect.
author <brian@gir-2.local> <>
Fri, 29 Feb 2008 07:22:14 +0000 (23:22 -0800)
committer <brian@gir-2.local> <>
Fri, 29 Feb 2008 07:22:14 +0000 (23:22 -0800)
1  2 
ChangeLog
include/memcached.h
lib/memcached_storage.c

diff --combined ChangeLog
index f3cd040bfd5dc30d01b217a02b8f0bd600bfa32d,199536b56e77d4b6f925aa692602ed50c0739dc2..3a9e3afa546f70d09323267cb462d89b464ac58a
+++ b/ChangeLog
@@@ -1,10 -1,10 +1,12 @@@
- 0.17
 +  * Replication support has been added to the library.
 +
+ 0.17 Wed Feb 27 03:33:29 PST 2008
    * MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT added for connect timeout in
      non-block mode.
    * Incompatible change in memcached_behavior_set() api. We now use a
      uint64_t, instead of a pointer.
+   * Fix for storage of values for zero.
+   * memcached_server_cursor() function added to API for cycling through servers.
  
  0.16 Mon Feb 18 00:30:25 PST 2008
    * Work on the UDP protocol
diff --combined include/memcached.h
index 4a283ec6c83c8937bf22860054263cfad94216a2,570404e831f1cd1091a4d2803b268934abdb7026..1c80878dec9b2e2fdfe2f6e75c6067870af92d70
@@@ -29,7 -29,6 +29,7 @@@ extern "C" 
  #define MEMCACHED_MAX_HOST_LENGTH 64
  #define MEMCACHED_WHEEL_SIZE 1024
  #define MEMCACHED_STRIDE 4
 +#define MEMCACHED_MAX_REPLICAS 4
  #define MEMCACHED_DEFAULT_TIMEOUT INT32_MAX
  
  /* string value */
@@@ -105,7 -104,6 +105,7 @@@ typedef enum 
    MEMCACHED_BEHAVIOR_SORT_HOSTS,
    MEMCACHED_BEHAVIOR_VERIFY_KEY,
    MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,
 +  MEMCACHED_BEHAVIOR_REPLICAS,
  } memcached_behavior;
  
  typedef enum {
@@@ -232,8 -230,8 +232,8 @@@ struct memcached_st 
    memcached_free_function call_free;
    memcached_malloc_function call_malloc;
    memcached_realloc_function call_realloc;
 +  uint8_t number_of_replicas;
  #ifdef NOT_USED /* Future Use */
 -  uint8_t replicas;
    memcached_return warning;
  #endif
  };
@@@ -264,7 -262,7 +264,7 @@@ memcached_return memcached_verbosity(me
  void memcached_quit(memcached_st *ptr);
  char *memcached_strerror(memcached_st *ptr, memcached_return rc);
  memcached_return memcached_behavior_set(memcached_st *ptr, memcached_behavior flag, uint64_t data);
- unsigned long long memcached_behavior_get(memcached_st *ptr, memcached_behavior flag);
+ uint64_t memcached_behavior_get(memcached_st *ptr, memcached_behavior flag);
  
  /* All of the functions for adding data to the server */
  memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length, 
diff --combined lib/memcached_storage.c
index 3b1ee242ab087747a5faad00b74281054c4a44ac,0b5a73e10b3d45a0912f13c52ca47babf5cfdae7..2a0f88d493f355df2e862af79dfd1c8d8b2b22af
@@@ -53,14 -53,10 +53,11 @@@ static inline memcached_return memcache
    char to_write;
    size_t write_length;
    ssize_t sent_length;
 -  memcached_return rc;
 +  memcached_return rc[MEMCACHED_MAX_REPLICAS];
    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
    unsigned int server_key;
 +  uint8_t replicas= 0;
  
-   WATCHPOINT_ASSERT(!(value == NULL && value_length > 0));
-   WATCHPOINT_ASSERT(!(value && value_length == 0));
    unlikely (key_length == 0)
      return MEMCACHED_NO_KEY_PROVIDED;
  
                             (unsigned long long)expiration, value_length);
  
    if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
 -  {
 -    rc= MEMCACHED_WRITE_FAILURE;
 -    goto error;
 -  }
 -
 -  rc=  memcached_do(&ptr->hosts[server_key], buffer, write_length, 0);
 -  if (rc != MEMCACHED_SUCCESS)
 -    goto error;
 -
 -  if ((sent_length= memcached_io_write(&ptr->hosts[server_key], value, value_length, 0)) == -1)
 -  {
 -    rc= MEMCACHED_WRITE_FAILURE;
 -    goto error;
 -  }
 +    return MEMCACHED_WRITE_FAILURE;
  
    if ((ptr->flags & MEM_BUFFER_REQUESTS) && verb == SET_OP)
      to_write= 0;
    else
      to_write= 1;
  
 -  if ((sent_length= memcached_io_write(&ptr->hosts[server_key], "\r\n", 2, to_write)) == -1)
 +  do
    {
 -    rc= MEMCACHED_WRITE_FAILURE;
 -    goto error;
 -  }
 +    rc[replicas]=  memcached_do(&ptr->hosts[server_key], buffer, write_length, 0);
 +
 +    if (rc[replicas] != MEMCACHED_SUCCESS)
 +      goto error;
  
 -  if (to_write == 0)
 -    return MEMCACHED_BUFFERED;
 +    if ((sent_length= memcached_io_write(&ptr->hosts[server_key], value, value_length, 0)) == -1)
 +    {
 +      rc[replicas]= MEMCACHED_WRITE_FAILURE;
 +      goto error;
 +    }
  
 -  rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
 +    if ((sent_length= memcached_io_write(&ptr->hosts[server_key], "\r\n", 2, to_write)) == -1)
 +    {
 +      rc[replicas]= MEMCACHED_WRITE_FAILURE;
 +      goto error;
 +    }
  
 -  if (rc == MEMCACHED_STORED)
 -    return MEMCACHED_SUCCESS;
 -  else 
 -    return rc;
 +    if (to_write == 0)
 +      return MEMCACHED_BUFFERED;
 +    else
 +      rc[replicas]= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
  
 +    /* On error we just jump to the next potential server */
  error:
 -  memcached_io_reset(&ptr->hosts[server_key]);
 +    if (replicas > 1 && ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT)
 +    {
 +      if (server_key == (ptr->number_of_hosts - 1))
 +        server_key= 0;
 +      else
 +        server_key++;
 +    }
 +  } while ((++replicas) < ptr->number_of_replicas);
 +
 +  /* As long as one object gets stored, we count this as a success */
 +  while (replicas--)
 +  {
 +    if (rc[replicas] == MEMCACHED_STORED)
 +      return MEMCACHED_SUCCESS;
 +  }
  
 -  return rc;
 +  return rc[0];
  }
  
  memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length,