* 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.
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
=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
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;
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)
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)
/* 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)
{
case EAGAIN:
{
memcached_return rc;
+
rc= io_wait(ptr, server_key, MEM_READ);
if (rc == MEMCACHED_SUCCESS)
/* 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);
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);
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;