Refactor of response code. All of it has been streamlined to allow for multi
authorBrian Aker <brian@tangent.org>
Mon, 17 Dec 2007 21:16:08 +0000 (13:16 -0800)
committerBrian Aker <brian@tangent.org>
Mon, 17 Dec 2007 21:16:08 +0000 (13:16 -0800)
delete/set operations.

18 files changed:
include/memcached.h
lib/common.h
lib/memcached.c
lib/memcached_auto.c
lib/memcached_connect.c
lib/memcached_delete.c
lib/memcached_do.c
lib/memcached_fetch.c
lib/memcached_flush.c
lib/memcached_get.c
lib/memcached_io.c
lib/memcached_quit.c
lib/memcached_response.c
lib/memcached_stats.c
lib/memcached_storage.c
lib/memcached_verbosity.c
lib/memcached_version.c
tests/test.c

index 1e2d3b3fd74652cee586e9580c892efdacbce74e..8e90d6edb1d813746a31eb0c38ec72c4395fbc88 100644 (file)
@@ -119,7 +119,6 @@ struct memcached_server_st {
   char hostname[MEMCACHED_MAX_HOST_LENGTH];
   unsigned int port;
   int fd;
-  unsigned int stack_responses;
   unsigned int cursor_active;
   char write_buffer[MEMCACHED_MAX_BUFFER];
   size_t write_buffer_offset;
@@ -195,7 +194,7 @@ struct memcached_st {
   int send_size;
   int recv_size;
   int32_t poll_timeout;
-  memcached_string_st result_buffer;
+  memcached_result_st result;
   memcached_hash hash;
   memcached_server_distribution distribution;
   unsigned int wheel[MEMCACHED_WHEEL_SIZE];
@@ -281,7 +280,7 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
 #define memcached_server_name(A,B) (B).hostname
 #define memcached_server_port(A,B) (B).port
 #define memcached_server_list(A) (A)->hosts
-#define memcached_server_response_count(A,B) (A)->hosts[B].stack_responses
+#define memcached_server_response_count(A,B) (A)->hosts[B].cursor_active
 
 memcached_return memcached_server_add_udp(memcached_st *ptr, 
                                           char *hostname,
@@ -367,17 +366,17 @@ memcached_return memcached_delete_by_key(memcached_st *ptr,
 void memcached_result_free(memcached_result_st *result);
 memcached_result_st *memcached_result_create(memcached_st *ptr, 
                                              memcached_result_st *result);
-#define memcached_result_key_value(A) A->key
-#define memcached_result_key_length(A) A->key_length
+#define memcached_result_key_value(A) (A)->key
+#define memcached_result_key_length(A) (A)->key_length
 #ifdef FIX
-#define memcached_result_value(A) memcached_string_value(A->value)
-#define memcached_result_length(A) memcached_string_length(A->value)
+#define memcached_result_value(A) memcached_string_value((A)->value)
+#define memcached_result_length(A) memcached_string_length((A)->value)
 #else
 char *memcached_result_value(memcached_result_st *ptr);
 size_t memcached_result_length(memcached_result_st *ptr);
 #endif
-#define memcached_result_flags(A) A->flags
-#define memcached_result_cas(A) A->cas
+#define memcached_result_flags(A) (A)->flags
+#define memcached_result_cas(A) (A)->cas
 
 
 #ifndef __WATCHPOINT_H__
index c49b3b9614783e834f49f25a6ee1d3d81d33fef5..76c734ed1fe25c4c7bd7ab294818ea07bfc174ab 100644 (file)
@@ -60,18 +60,20 @@ uint32_t hsieh_hash(char *key, size_t key_length);
 memcached_return memcached_connect(memcached_st *ptr, unsigned int server_key);
 memcached_return memcached_response(memcached_st *ptr, 
                                     char *buffer, size_t buffer_length,
+                                    memcached_result_st *result,
                                     unsigned int server_key);
 unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_length);
 void memcached_quit_server(memcached_st *ptr, unsigned int server_key, uint8_t io_death);
 
-#define memcached_server_response_increment(A,B) A->hosts[B].stack_responses++
-#define memcached_server_response_decrement(A,B) A->hosts[B].stack_responses--
+#define memcached_server_response_increment(A,B) A->hosts[B].cursor_active++
+#define memcached_server_response_decrement(A,B) A->hosts[B].cursor_active--
+#define memcached_server_response_reset(A,B) A->hosts[B].cursor_active=0
 
 /* String Struct */
-#define memcached_string_length(A) (size_t)(A->end - A->string)
-#define memcached_string_set_length(A, B) A->end= A->string + B
-#define memcached_string_size(A) A->current_size
-#define memcached_string_value(A) A->string
+#define memcached_string_length(A) (size_t)((A)->end - (A)->string)
+#define memcached_string_set_length(A, B) (A)->end= (A)->string + B
+#define memcached_string_size(A) (A)->current_size
+#define memcached_string_value(A) (A)->string
 
 memcached_string_st *memcached_string_create(memcached_st *ptr, 
                                              memcached_string_st *string, 
@@ -88,9 +90,10 @@ void memcached_string_free(memcached_string_st *string);
 memcached_return memcached_do(memcached_st *ptr, unsigned int server_key, char *commmand, 
                               size_t command_length, char with_flush);
 memcached_return memcached_version(memcached_st *ptr);
-memcached_return memcached_finish_server(memcached_st *ptr, unsigned int server_key);
-void memcached_finish(memcached_st *ptr);
-
+memcached_return value_fetch(memcached_st *ptr,
+                             char *buffer,
+                             memcached_result_st *result,
+                             unsigned int server_key);
 
 
 #endif /* __COMMON_H__ */
index 30099c39ff7a2f643f2edd9caaaddb0ee5b0d979..24c3b8bc4048198c60e10e581f371461490a3563 100644 (file)
@@ -5,7 +5,7 @@
 
 memcached_st *memcached_create(memcached_st *ptr)
 {
-  memcached_string_st *string_ptr;
+  memcached_result_st *result_ptr;
   if (!ptr)
   {
     ptr= (memcached_st *)malloc(sizeof(memcached_st));
@@ -20,8 +20,8 @@ memcached_st *memcached_create(memcached_st *ptr)
   {
     memset(ptr, 0, sizeof(memcached_st));
   }
-  string_ptr= memcached_string_create(ptr, &ptr->result_buffer, 0);
-  WATCHPOINT_ASSERT(string_ptr);
+  result_ptr= memcached_result_create(ptr, &ptr->result);
+  WATCHPOINT_ASSERT(result_ptr);
   ptr->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT;
   ptr->distribution= MEMCACHED_DISTRIBUTION_MODULA;
 
@@ -33,7 +33,7 @@ void memcached_free(memcached_st *ptr)
   /* If we have anything open, lets close it now */
   memcached_quit(ptr);
   memcached_server_list_free(ptr->hosts);
-  memcached_string_free(&ptr->result_buffer);
+  memcached_result_free(&ptr->result);
 
   if (ptr->is_allocated == MEMCACHED_ALLOCATED)
     free(ptr);
index b9b74628810a9f7e96dc8df5d61f6290ceb4856d..aa8cde3295dd953399da706a37ab426219e15f4a 100644 (file)
@@ -30,7 +30,7 @@ static memcached_return memcached_auto(memcached_st *ptr,
   if (rc != MEMCACHED_SUCCESS)
     return rc;
 
-  rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
+  rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL, server_key);
 
   /* 
     So why recheck responce? Because the protocol is brain dead :)
index 98d7630f589dd9194dbbd64cfb50887716404c70..0bb28177f060b6ff9f8b6d17e33a22aa1c8d0dbf 100644 (file)
@@ -77,7 +77,7 @@ static memcached_return udp_connect(memcached_st *ptr, unsigned int server_key)
   if (ptr->hosts[server_key].fd == -1)
   {
     /* Old connection junk still is in the structure */
-    WATCHPOINT_ASSERT(ptr->hosts[server_key].stack_responses == 0);
+    WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0);
 
     /*
       If we have not allocated the hosts object.
@@ -111,7 +111,7 @@ static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
   if (ptr->hosts[server_key].fd == -1)
   {
     /* Old connection junk still is in the structure */
-    WATCHPOINT_ASSERT(ptr->hosts[server_key].stack_responses == 0);
+    WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0);
     struct addrinfo *use;
 
     if (ptr->hosts[server_key].sockaddr_inited == MEMCACHED_NOT_ALLOCATED || 
@@ -223,7 +223,7 @@ test_connect:
       ptr->connected++;
     }
 
-    WATCHPOINT_ASSERT(ptr->hosts[server_key].stack_responses == 0);
+    WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0);
   }
 
   return MEMCACHED_SUCCESS;
index f68d73403a9601e70f4b2d57cdb750f6e37684f0..519e52bec6fea58f6d304bf187d289f61559acec 100644 (file)
@@ -57,7 +57,7 @@ memcached_return memcached_delete_by_key(memcached_st *ptr,
   }
   else
   {
-    rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
+    rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL, server_key);
     if (rc == MEMCACHED_DELETED)
       rc= MEMCACHED_SUCCESS;
   }
index a929927c59a7a478ac29bd1ba9cabe97de66f7ac..cfc00ccdcc2683f44138fcae34706fa93a525b22 100644 (file)
@@ -9,9 +9,6 @@ memcached_return memcached_do(memcached_st *ptr, unsigned int server_key, char *
   WATCHPOINT_ASSERT(command_length);
   WATCHPOINT_ASSERT(command);
 
-  if (ptr->hosts[server_key].cursor_active)
-    (void)memcached_finish_server(ptr, server_key);
-
   if ((rc= memcached_connect(ptr, server_key)) != MEMCACHED_SUCCESS)
     return rc;
 
index b6161845385e6f917cbfc879f272c8d99977bab2..673388359cb0d6d53e39f61304d81af3e57c02ae 100644 (file)
 #include "common.h"
 #include "memcached_io.h"
 
-static memcached_return memcached_value_fetch(memcached_st *ptr, char *key, size_t *key_length, 
-                                              memcached_string_st *value,
-                                              uint32_t *flags,
-                                              uint64_t *cas,
-                                              unsigned int server_key)
+memcached_return value_fetch(memcached_st *ptr,
+                             char *buffer,
+                             memcached_result_st *result,
+                             unsigned int server_key)
 {
   memcached_return rc;
-  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
   char *string_ptr;
   char *end_ptr;
+  char *next_ptr;
+  size_t value_length;
 
   end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE;
 
-  if (flags)
-    *flags= 0;
+  result->key_length= 0;
+  result->flags= 0;
+  memcached_string_reset(&result->value);
 
-  memcached_string_reset(value);
+  string_ptr= buffer;
+  string_ptr+= 6; /* "VALUE " */
 
-  rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
 
-  if (rc == MEMCACHED_SUCCESS)
+  /* We load the key */
   {
-    char *next_ptr;
-    size_t value_length;
+    char *key;
 
-    string_ptr= buffer;
-    string_ptr+= 6; /* "VALUE " */
+    key= result->key;
+    result->key_length= 0;
 
-    /* We load the key */
-    if (key)
+    for (; isgraph(*string_ptr); string_ptr++)
     {
-      *key_length= 0;
-
-      for (; isgraph(*string_ptr); string_ptr++)
-      {
-        *key= *string_ptr;
-        key++;
-        (*key_length)++;
-      }
+      *key= *string_ptr;
+      key++;
+      result->key_length++;
     }
-    else /* Skip characters */
-      for (; isgraph(*string_ptr); string_ptr++);
+  }
 
-    if (end_ptr == string_ptr)
-        goto read_error;
+  if (end_ptr == string_ptr)
+    goto read_error;
 
-    /* Flags fetch move past space */
-    string_ptr++;
-    if (end_ptr == string_ptr)
-        goto read_error;
-    for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
-    if (flags)
-      *flags= (uint32_t)strtol(next_ptr, &string_ptr, 10);
+  /* Flags fetch move past space */
+  string_ptr++;
+  if (end_ptr == string_ptr)
+    goto read_error;
+  for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
+  result->flags= (uint32_t)strtol(next_ptr, &string_ptr, 10);
 
-    if (end_ptr == string_ptr)
-        goto read_error;
+  if (end_ptr == string_ptr)
+    goto read_error;
 
-    /* Length fetch move past space*/
-    string_ptr++;
-    if (end_ptr == string_ptr)
-        goto read_error;
+  /* Length fetch move past space*/
+  string_ptr++;
+  if (end_ptr == string_ptr)
+    goto read_error;
 
-    for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
-    value_length= (size_t)strtoll(next_ptr, &string_ptr, 10);
+  for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
+  value_length= (size_t)strtoll(next_ptr, &string_ptr, 10);
 
-    if (end_ptr == string_ptr)
-        goto read_error;
+  if (end_ptr == string_ptr)
+    goto read_error;
 
-    /* Skip spaces */
-    if (*string_ptr == '\r')
-    {
-      /* Skip past the \r\n */
-      string_ptr+= 2;
-    }
-    else
-    {
-      string_ptr++;
-      for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
-      if (cas)
-        *cas= (size_t)strtoll(next_ptr, &string_ptr, 10);
-    }
-
-    if (end_ptr < string_ptr)
-        goto read_error;
+  /* Skip spaces */
+  if (*string_ptr == '\r')
+  {
+    /* Skip past the \r\n */
+    string_ptr+= 2;
+    result->cas= 0;
+  }
+  else
+  {
+    string_ptr++;
+    for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++);
+    result->cas= (size_t)strtoll(next_ptr, &string_ptr, 10);
+  }
 
-    if (value_length)
-    {
-      size_t read_length;
-      size_t to_read;
-      char *value_ptr;
+  if (end_ptr < string_ptr)
+    goto read_error;
 
-      /* We add two bytes so that we can walk the \r\n */
-      rc= memcached_string_check(value, value_length+2);
-      if (rc != MEMCACHED_SUCCESS)
-      {
-        value_length= 0;
-        return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-      }
+  if (value_length)
+  {
+    size_t read_length;
+    size_t to_read;
+    char *value_ptr;
 
-      value_ptr= memcached_string_value(value);
-      read_length= 0;
-      /* 
-        We read the \r\n into the string since not doing so is more 
-        cycles then the waster of memory to do so.
+    /* We add two bytes so that we can walk the \r\n */
+    rc= memcached_string_check(&result->value, value_length+2);
+    if (rc != MEMCACHED_SUCCESS)
+    {
+      value_length= 0;
+      return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+    }
 
-        We are null terminating through, which will most likely make
-        some people lazy about using the return length.
-      */
-      to_read= (value_length) + 2;
+    value_ptr= memcached_string_value(&result->value);
+    read_length= 0;
+    /* 
+      We read the \r\n into the string since not doing so is more 
+      cycles then the waster of memory to do so.
 
-      read_length= memcached_io_read(ptr, server_key,
-                                     value_ptr, to_read);
+      We are null terminating through, which will most likely make
+      some people lazy about using the return length.
+    */
+    to_read= (value_length) + 2;
 
-      if (read_length != (size_t)(value_length + 2))
-      {
-        goto read_error;
-      }
+    read_length= memcached_io_read(ptr, server_key,
+                                   value_ptr, to_read);
 
-      /* This next bit blows the API, but this is internal....*/
-      {
-        char *char_ptr;
-        char_ptr= memcached_string_value(value);;
-        char_ptr[value_length]= 0;
-        char_ptr[value_length + 1]= 0;
-        memcached_string_set_length(value, value_length);
-      }
+    if (read_length != (size_t)(value_length + 2))
+    {
+      goto read_error;
+    }
 
-      return MEMCACHED_SUCCESS;
+    /* This next bit blows the API, but this is internal....*/
+    {
+      char *char_ptr;
+      char_ptr= memcached_string_value(&result->value);;
+      char_ptr[value_length]= 0;
+      char_ptr[value_length + 1]= 0;
+      memcached_string_set_length(&result->value, value_length);
     }
+
+    return MEMCACHED_SUCCESS;
   }
 
   return rc;
@@ -143,34 +134,44 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length,
                     uint32_t *flags,
                     memcached_return *error)
 {
-  memcached_string_st *result_buffer;
-  result_buffer= &ptr->result_buffer;
-
-  if (ptr->flags & MEM_NO_BLOCK)
-    memcached_io_preread(ptr);
+  memcached_result_st *result_buffer= &ptr->result;
 
   while (ptr->cursor_server < ptr->number_of_hosts)
   {
-    if (!ptr->hosts[ptr->cursor_server].cursor_active)
+    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+
+    if (memcached_server_response_count(ptr, ptr->cursor_server) == 0)
     {
       ptr->cursor_server++;
       continue;
     }
 
-    *error = memcached_value_fetch(ptr, key, key_length, result_buffer, 
-                                   flags, NULL, ptr->cursor_server);
-    *value_length= memcached_string_length(result_buffer);
-    
+  *error= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result_buffer, ptr->cursor_server);
+
     if (*error == MEMCACHED_END) /* END means that we move on to the next */
     {
-      ptr->hosts[ptr->cursor_server].cursor_active= 0;
+      memcached_server_response_reset(ptr, ptr->cursor_server);
       ptr->cursor_server++;
       continue;
     }
     else if (*error == MEMCACHED_SUCCESS)
-      return  memcached_string_c_copy(result_buffer);
+    {
+      *value_length= memcached_string_length(&result_buffer->value);
+    
+      if (key)
+      {
+        strncpy(key, result_buffer->key, result_buffer->key_length);
+        *key_length= result_buffer->key_length;
+      }
+      *flags= result_buffer->flags;
+
+      return  memcached_string_c_copy(&result_buffer->value);
+    }
     else
+    {
+      *value_length= 0;
       return NULL;
+    }
   }
 
   ptr->cursor_server= 0;
@@ -192,22 +193,19 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
 
   while (ptr->cursor_server < ptr->number_of_hosts)
   {
-    if (!ptr->hosts[ptr->cursor_server].cursor_active)
+    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+
+    if (memcached_server_response_count(ptr, ptr->cursor_server) == 0)
     {
       ptr->cursor_server++;
       continue;
     }
 
-    result->cas= 0; /* We do this so we do not send in any junk */
-    *error= memcached_value_fetch(ptr, result->key, &result->key_length, 
-                                       &result->value, 
-                                       &result->flags,
-                                       &result->cas,
-                                       ptr->cursor_server);
+    *error= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result, ptr->cursor_server);
     
     if (*error == MEMCACHED_END) /* END means that we move on to the next */
     {
-      ptr->hosts[ptr->cursor_server].cursor_active= 0;
+      memcached_server_response_reset(ptr, ptr->cursor_server);
       ptr->cursor_server++;
       continue;
     }
@@ -226,34 +224,3 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
   ptr->cursor_server= 0;
   return NULL;
 }
-
-memcached_return memcached_finish_server(memcached_st *ptr, unsigned int server_key)
-{
-  memcached_return rc;
-  memcached_string_st *result_buffer;
-
-  result_buffer= &ptr->result_buffer;
-
-  rc= MEMCACHED_SUCCESS;
-  while (rc == MEMCACHED_SUCCESS)
-  {
-    rc= memcached_value_fetch(ptr, NULL, NULL, result_buffer, 
-                               NULL, NULL, server_key);
-  }
-  ptr->hosts[server_key].cursor_active= 0;
-
-  return rc;
-}
-
-void memcached_finish(memcached_st *ptr)
-{
-  unsigned int x;
-
-  for (x= 0; x < ptr->number_of_hosts; x++)
-  {
-    if (ptr->hosts[x].cursor_active)
-      (void)memcached_finish_server(ptr, x);
-  }
-
-  ptr->cursor_server= 0;
-}
index 5fa5d960264ed02a54e4a83777104b5f612d759a..33cc6eb65ce378ebba3e32d8178c751cb70ce4ce 100644 (file)
@@ -23,7 +23,7 @@ memcached_return memcached_flush(memcached_st *ptr, time_t expiration)
     rc= memcached_do(ptr, x, buffer, send_length, 1);
 
     if (rc == MEMCACHED_SUCCESS)
-      (void)memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, x);
+      (void)memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL, x);
   }
 
   LIBMEMCACHED_MEMCACHED_FLUSH_END();
index ffb2c5f6203b1b6b63b30c0f86307bc2e770f2d5..b4266130e652f4baa2fb9b33e2ef6a825feecdcd 100644 (file)
@@ -21,6 +21,9 @@ char *memcached_get_by_key(memcached_st *ptr,
                            memcached_return *error)
 {
   char *value;
+  size_t dummy_length;
+  uint32_t dummy_flags;
+  memcached_return dummy_error;
 
   /* Request the key */
   *error= memcached_mget_by_key(ptr, 
@@ -30,7 +33,6 @@ char *memcached_get_by_key(memcached_st *ptr,
 
   value= memcached_fetch(ptr, NULL, NULL, 
                          value_length, flags, error);
-
   /* This is for historical reasons */
   if (*error == MEMCACHED_END)
     *error= MEMCACHED_NOTFOUND;
@@ -38,7 +40,9 @@ char *memcached_get_by_key(memcached_st *ptr,
   if (value == NULL)
     return NULL;
 
-  memcached_finish(ptr);
+  (void)memcached_fetch(ptr, NULL, NULL, 
+                        &dummy_length, &dummy_flags, 
+                        &dummy_error);
 
   return value;
 }
@@ -76,11 +80,29 @@ memcached_return memcached_mget_by_key(memcached_st *ptr,
     get_command_length= 5;
   }
 
-  memcached_finish(ptr);
-
   if (master_key && master_key_length)
     master_server_key= memcached_generate_hash(ptr, master_key, master_key_length);
 
+  /* 
+    Here is where we pay for the non-block API. We need to remove any data sitting
+    in the queue before we start our get.
+
+    It might be optimum to bounce the connection if count > some number.
+  */
+  for (x= 0; x < ptr->number_of_hosts; x++)
+  {
+    if (memcached_server_response_count(ptr, x))
+    {
+      char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+
+      if (ptr->flags & MEM_NO_BLOCK)
+        (void)memcached_io_write(ptr, x, NULL, 0, 1);
+
+      while(memcached_server_response_count(ptr, x))
+        (void)memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result, x);
+    }
+  }
+
   /* 
     If a server fails we warn about errors and start all over with sending keys
     to the server.
@@ -94,7 +116,7 @@ memcached_return memcached_mget_by_key(memcached_st *ptr,
     else
       server_key= memcached_generate_hash(ptr, keys[x], key_length[x]);
 
-    if (ptr->hosts[server_key].cursor_active == 0)
+    if (memcached_server_response_count(ptr, server_key) == 0)
     {
       rc= memcached_connect(ptr, server_key);
 
@@ -103,19 +125,21 @@ memcached_return memcached_mget_by_key(memcached_st *ptr,
         rc= MEMCACHED_SOME_ERRORS;
         continue;
       }
-      ptr->hosts[server_key].cursor_active++;
+      WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0);
+      memcached_server_response_increment(ptr, server_key);
+      WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 1);
     }
 
     if ((memcached_io_write(ptr, server_key, keys[x], key_length[x], 0)) == -1)
     {
-      ptr->hosts[server_key].cursor_active= 0;
+      memcached_server_response_reset(ptr, server_key);
       rc= MEMCACHED_SOME_ERRORS;
       continue;
     }
 
     if ((memcached_io_write(ptr, server_key, " ", 1, 0)) == -1)
     {
-      ptr->hosts[server_key].cursor_active= 0;
+      memcached_server_response_reset(ptr, server_key);
       rc= MEMCACHED_SOME_ERRORS;
       continue;
     }
@@ -126,14 +150,13 @@ memcached_return memcached_mget_by_key(memcached_st *ptr,
   */
   for (x= 0; x < ptr->number_of_hosts; x++)
   {
-    if (ptr->hosts[x].cursor_active)
+    if (memcached_server_response_count(ptr, x))
     {
-      /* We need to doo something about non-connnected hosts in the future */
+      /* We need to do something about non-connnected hosts in the future */
       if ((memcached_io_write(ptr, x, "\r\n", 2, 1)) == -1)
       {
         rc= MEMCACHED_SOME_ERRORS;
       }
-      memcached_server_response_increment(ptr, x);
     }
   }
 
index 84928d2b40b5459e42acd1c7160d2e4d0a0acd31..38580638d7f197c81d373373954cb299b8aabc98 100644 (file)
@@ -57,7 +57,7 @@ void memcached_io_preread(memcached_st *ptr)
 
   for (x= 0; x < ptr->number_of_hosts; x++)
   {
-    if (ptr->hosts[x].cursor_active &&
+    if (memcached_server_response_count(ptr, x) &&
         ptr->hosts[x].read_data_length < MEMCACHED_MAX_BUFFER )
     {
       size_t data_read;
index 44f435c480b91fa5db4483dba0ab722620d16161..fdc86b6c7abce98d86c9b4dab90a4d49693cece4 100644 (file)
@@ -29,12 +29,11 @@ void memcached_quit_server(memcached_st *ptr, unsigned int server_key, uint8_t i
     }
 
     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->hosts[server_key].write_ptr= ptr->hosts[server_key].write_buffer;
+    memcached_server_response_reset(ptr, server_key);
   }
 
   ptr->connected--;
@@ -43,6 +42,7 @@ void memcached_quit_server(memcached_st *ptr, unsigned int server_key, uint8_t i
 void memcached_quit(memcached_st *ptr)
 {
   unsigned int x;
+
   if (ptr->hosts == NULL || 
       ptr->number_of_hosts == 0)
     return;
index a695e9d8c40881eb40ec7f589c6d29407c45eeb2..6ec120c8662208e2ed7a8eb1f7ba2f1c7dc0eab1 100644 (file)
@@ -10,6 +10,7 @@
 
 memcached_return memcached_response(memcached_st *ptr, 
                                     char *buffer, size_t buffer_length,
+                                    memcached_result_st *result,
                                     unsigned int server_key)
 {
   unsigned int x;
@@ -20,6 +21,10 @@ memcached_return memcached_response(memcached_st *ptr,
 
   send_length= 0;
 
+  /* We may have old commands in the buffer not set, first purge */
+  if (ptr->flags & MEM_NO_BLOCK)
+    (void)memcached_io_write(ptr, server_key, NULL, 0, 1);
+
   max_messages= memcached_server_response_count(ptr, server_key);
   for (x= 0; x <  max_messages; x++)
   {
@@ -58,9 +63,16 @@ memcached_return memcached_response(memcached_st *ptr,
   case 'V': /* VALUE || VERSION */
     if (buffer[1] == 'A') /* VALUE */
     {
+      memcached_return rc;
+
       /* We add back in one because we will need to search for END */
       memcached_server_response_increment(ptr, server_key);
-      return MEMCACHED_SUCCESS;
+      if (result)
+        rc= value_fetch(ptr, buffer, result, server_key);
+      else
+        rc= value_fetch(ptr, buffer, &ptr->result, server_key);
+
+      return rc;
     }
     else if (buffer[1] == 'E') /* VERSION */
     {
index decf22b614c8a864634c3abdaabba95d1ba1e31e..a20426a6339a7059cd4d14ae9d7d7a15e6ccd630 100644 (file)
@@ -221,7 +221,7 @@ static memcached_return memcached_stats_fetch(memcached_st *ptr,
 
   while (1)
   {
-    rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
+    rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL, server_key);
 
     if (rc == MEMCACHED_STAT)
     {
index 5f69413564dcdcc9dc1f9d20becedc8b40f013dc..4c36edc6dfc8ff2b8af9222410eef0b4aba3fab3 100644 (file)
@@ -110,7 +110,7 @@ static inline memcached_return memcached_send(memcached_st *ptr,
   if (to_write == 0)
     rc= MEMCACHED_SUCCESS;
   else
-    rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
+    rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL, server_key);
 
   if (rc == MEMCACHED_STORED)
     return MEMCACHED_SUCCESS;
index 1ee9d070160711a93444afd81c02dd5236d6e312..44c28012a7069353b009924c49e8e0cc320d4f35 100644 (file)
@@ -24,7 +24,7 @@ memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity)
       continue;
     }
 
-    rrc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, x);
+    rrc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL, x);
     if (rrc != MEMCACHED_SUCCESS)
       rc= MEMCACHED_SOME_ERRORS;
   }
index a463dfc4789dc5d0db6b6a556218de87be8a45a8..2863b76bf921bb69f3976ac9fabf594e994fa393 100644 (file)
@@ -23,7 +23,7 @@ memcached_return memcached_version(memcached_st *ptr)
       continue;
     }
 
-    rrc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, x);
+    rrc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL, x);
     if (rrc != MEMCACHED_SUCCESS)
       rc= MEMCACHED_SOME_ERRORS;
 
index f8cde94ddf5b3ecb8b0a5448b7108f7901ac09ef..60db54cbd8969269d3dad0b6468a4f6be50dc9f6 100644 (file)
@@ -107,7 +107,6 @@ int main(int argc, char *argv[])
   for (x= 0; x < memcached_server_list_count(servers); x++)
   {
     printf("\t%s : %u\n", servers[x].hostname, servers[x].port);
-    assert(servers[x].stack_responses == 0);
     assert(servers[x].fd == -1);
     assert(servers[x].cursor_active == 0);
   }
@@ -151,7 +150,6 @@ int main(int argc, char *argv[])
 
       for (loop= 0; loop < memcached_server_list_count(servers); loop++)
       {
-        assert(memc->hosts[loop].stack_responses == 0);
         assert(memc->hosts[loop].fd == -1);
         assert(memc->hosts[loop].cursor_active == 0);
       }