Performance improvements in get operations
authorBrian Aker <brian@tangent.org>
Tue, 11 Dec 2007 22:45:07 +0000 (14:45 -0800)
committerBrian Aker <brian@tangent.org>
Tue, 11 Dec 2007 22:45:07 +0000 (14:45 -0800)
ChangeLog
docs/libmemcached.pod
docs/memcached_behavior.pod
include/memcached.h
lib/memcached_fetch.c
lib/memcached_io.c
lib/memcached_io.h
lib/memcached_response.c

index 79cb10c7cfded8da24d39b60c8d541bd584aff5e..dc92bbe54a4b9ba1c56ed6597b75644a5afc4a62 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,7 +10,8 @@
   * Fixed bug where key could be out of range of characters
   * Added _by_key() methods to allow partitioning of values to particular
     servers.
-  * MEMCACHED_DEFAILT_TIMEOUT is now set to 100 microseconds.
+  * MEMCACHED_DEFAILT_TIMEOUT is now set to a non -1 value.
+  * Performance improvements in get operations.
 
 0.11 Mon Nov 26 01:05:52 PST 2007
   * Added option to memcache_behavior_set() so that poll() can be timed out.
index ab0434777856ef9927fc75a1c62de6a545afe747..c46ad1579c789cc61d78b0e572aafb82443ed9b8 100755 (executable)
@@ -24,7 +24,7 @@ matched based on server order as supplied by you). It implements both
 a modula and consistent method of object distribution.
 
 There are multiple implemented routing and hashing methods. See the
-memcached_behavior page.
+memcached_behavior_set() manpage.
 
 All operations are performed against a C<memcached_st> structure.
 These structures can either be dynamically allocated or statically
index b1545534e70e9f07c6251b51ca007263185c009f..e5058de353efa627bce1a0e453cd53bb2a71f732 100755 (executable)
@@ -40,7 +40,9 @@ memcached_behavior_set() will flush and reset all connections.
 =item MEMCACHED_BEHAVIOR_NO_BLOCK
 
 Causes libmemcached(3) to use asychronous IO. This is the fastest transport
-available.
+available for storage functions. For read operations it is currently 
+similar in performance to the non-blocking method (this is being
+looked into).
 
 =item MEMCACHED_BEHAVIOR_TCP_NODELAY
 
index 7bd4df84548117bb3297767f25692ca836bcad87..a6b342c65d11dd1b45f97df7675b94b4e2836f18 100644 (file)
@@ -125,6 +125,7 @@ struct memcached_server_st {
   size_t write_buffer_offset;
   char *write_ptr;
   char read_buffer[MEMCACHED_MAX_BUFFER];
+  size_t read_data_length;
   size_t read_buffer_length;
   char *read_ptr;
   memcached_allocated sockaddr_inited;
index b8954748735e1cd99d2cc6a4fccff382ad4fb904..8d281f35d182dd0758df03425cad4c7b24cdea0d 100644 (file)
@@ -147,6 +147,9 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length,
   memcached_string_st *result_buffer;
   result_buffer= &ptr->result_buffer;
 
+  if (ptr->flags & MEM_NO_BLOCK)
+    memcached_io_preread(ptr);
+
   while (ptr->cursor_server < ptr->number_of_hosts)
   {
     if (!ptr->hosts[ptr->cursor_server].cursor_active)
@@ -185,6 +188,9 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
 
   WATCHPOINT_ASSERT(result->value.is_allocated != MEMCACHED_USED);
 
+  if (ptr->flags & MEM_NO_BLOCK)
+    memcached_io_preread(ptr);
+
   while (ptr->cursor_server < ptr->number_of_hosts)
   {
     if (!ptr->hosts[ptr->cursor_server].cursor_active)
index 2c1bb14c3860df761f6011fe799bb9ebdf0d6793..84928d2b40b5459e42acd1c7160d2e4d0a0acd31 100644 (file)
@@ -44,10 +44,36 @@ static memcached_return io_wait(memcached_st *ptr, unsigned int server_key,
   /* Imposssible for anything other then -1 */
   WATCHPOINT_ASSERT(error == -1);
   memcached_quit_server(ptr, server_key, 1);
+
   return MEMCACHED_FAILURE;
 
 }
 
+void memcached_io_preread(memcached_st *ptr)
+{
+  unsigned int x;
+
+  return;
+
+  for (x= 0; x < ptr->number_of_hosts; x++)
+  {
+    if (ptr->hosts[x].cursor_active &&
+        ptr->hosts[x].read_data_length < MEMCACHED_MAX_BUFFER )
+    {
+      size_t data_read;
+
+      data_read= read(ptr->hosts[x].fd,
+                      ptr->hosts[x].read_ptr + ptr->hosts[x].read_data_length,
+                      MEMCACHED_MAX_BUFFER - ptr->hosts[x].read_data_length);
+      if (data_read == -1)
+        continue;
+
+      ptr->hosts[x].read_buffer_length+= data_read;
+      ptr->hosts[x].read_data_length+= data_read;
+    }
+  }
+}
+
 ssize_t memcached_io_read(memcached_st *ptr, unsigned  int server_key,
                           char *buffer, size_t length)
 {
@@ -73,6 +99,7 @@ ssize_t memcached_io_read(memcached_st *ptr, unsigned  int server_key,
           case EAGAIN:
             {
               memcached_return rc;
+
               rc= io_wait(ptr, server_key, MEM_READ);
 
               if (rc == MEMCACHED_SUCCESS)
@@ -94,15 +121,31 @@ ssize_t memcached_io_read(memcached_st *ptr, unsigned  int server_key,
         /* If zero, just keep looping */
       }
 
+      ptr->hosts[server_key].read_data_length= data_read;
       ptr->hosts[server_key].read_buffer_length= data_read;
       ptr->hosts[server_key].read_ptr= ptr->hosts[server_key].read_buffer;
     }
 
-    *buffer_ptr= *ptr->hosts[server_key].read_ptr;
-    length--;
-    ptr->hosts[server_key].read_ptr++;
-    ptr->hosts[server_key].read_buffer_length--;
-    buffer_ptr++;
+    if (length > 1)
+    {
+      size_t difference;
+
+      difference= (length > ptr->hosts[server_key].read_buffer_length) ? ptr->hosts[server_key].read_buffer_length : length;
+
+      memcpy(buffer_ptr, ptr->hosts[server_key].read_ptr, difference);
+      length -= difference;
+      ptr->hosts[server_key].read_ptr+= difference;
+      ptr->hosts[server_key].read_buffer_length-= difference;
+      buffer_ptr+= difference;
+    }
+    else
+    {
+      *buffer_ptr= *ptr->hosts[server_key].read_ptr;
+      length--;
+      ptr->hosts[server_key].read_ptr++;
+      ptr->hosts[server_key].read_buffer_length--;
+      buffer_ptr++;
+    }
   }
 
   return (size_t)(buffer_ptr - buffer);
index c6ddd9745a1343f33856d1717ddf4db393de61d4..a95b6c84d56e5de99a54dc866ef4099c1f804c1e 100644 (file)
@@ -7,3 +7,4 @@ void memcached_io_reset(memcached_st *ptr, unsigned int server_key);
 ssize_t memcached_io_read(memcached_st *ptr, unsigned  int server_key,
                           char *buffer, size_t length);
 memcached_return memcached_io_close(memcached_st *ptr, unsigned int server_key);
+void memcached_io_preread(memcached_st *ptr);
index 076b0a6fc2bd67a49c3d5d22e50f9405102c0553..7402975f895761ade88c41864174b074e630c433 100644 (file)
@@ -42,7 +42,7 @@ memcached_return memcached_response(memcached_st *ptr,
         buffer_ptr++;
 
       total_length++;
-      WATCHPOINT_ASSERT(total_length < buffer_length);
+      WATCHPOINT_ASSERT(total_length <= buffer_length);
 
       if (total_length >= buffer_length)
         return MEMCACHED_PROTOCOL_ERROR;