From 90c4182ab1eb7f2da203258f62cf33a229ba1346 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Tue, 11 Dec 2007 14:45:07 -0800 Subject: [PATCH] Performance improvements in get operations --- ChangeLog | 3 ++- docs/libmemcached.pod | 2 +- docs/memcached_behavior.pod | 4 ++- include/memcached.h | 1 + lib/memcached_fetch.c | 6 +++++ lib/memcached_io.c | 53 +++++++++++++++++++++++++++++++++---- lib/memcached_io.h | 1 + lib/memcached_response.c | 2 +- 8 files changed, 63 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79cb10c7..dc92bbe5 100644 --- 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. diff --git a/docs/libmemcached.pod b/docs/libmemcached.pod index ab043477..c46ad157 100755 --- a/docs/libmemcached.pod +++ b/docs/libmemcached.pod @@ -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 structure. These structures can either be dynamically allocated or statically diff --git a/docs/memcached_behavior.pod b/docs/memcached_behavior.pod index b1545534..e5058de3 100755 --- a/docs/memcached_behavior.pod +++ b/docs/memcached_behavior.pod @@ -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 diff --git a/include/memcached.h b/include/memcached.h index 7bd4df84..a6b342c6 100644 --- a/include/memcached.h +++ b/include/memcached.h @@ -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; diff --git a/lib/memcached_fetch.c b/lib/memcached_fetch.c index b8954748..8d281f35 100644 --- a/lib/memcached_fetch.c +++ b/lib/memcached_fetch.c @@ -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) diff --git a/lib/memcached_io.c b/lib/memcached_io.c index 2c1bb14c..84928d2b 100644 --- a/lib/memcached_io.c +++ b/lib/memcached_io.c @@ -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); diff --git a/lib/memcached_io.h b/lib/memcached_io.h index c6ddd974..a95b6c84 100644 --- a/lib/memcached_io.h +++ b/lib/memcached_io.h @@ -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); diff --git a/lib/memcached_response.c b/lib/memcached_response.c index 076b0a6f..7402975f 100644 --- a/lib/memcached_response.c +++ b/lib/memcached_response.c @@ -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; -- 2.30.2