From 3e08799c9d80873a66e7e0b08c6524b0d5c47c28 Mon Sep 17 00:00:00 2001 From: Date: Wed, 26 Sep 2007 02:34:23 -0700 Subject: [PATCH] NEw string type. Better multi get keysupport. --- include/memcached.h | 24 ++++++++++ lib/Makefile.am | 1 + lib/memcached_connect.c | 23 +++++++-- lib/memcached_flush.c | 1 + lib/memcached_get.c | 56 ++++++++++++++++------ lib/memcached_stats.c | 8 ++++ lib/memcached_string.c | 103 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 197 insertions(+), 19 deletions(-) create mode 100644 lib/memcached_string.c diff --git a/include/memcached.h b/include/memcached.h index fc732c27..3e8cea88 100644 --- a/include/memcached.h +++ b/include/memcached.h @@ -30,10 +30,12 @@ extern "C" { typedef struct memcached_st memcached_st; typedef struct memcached_stat_st memcached_stat_st; +typedef struct memcached_string_st memcached_string_st; typedef struct memcached_host_st memcached_host_st; #define MEMCACHED_DEFAULT_PORT 11211 #define MEMCACHED_DEFAULT_COMMAND_SIZE 350 +#define SMALL_STRING_LEN 1024 #define HUGE_STRING_LEN 8196 #define MEMCACHED_MAX_KEY 251 /* We add one to have it null terminated */ @@ -101,6 +103,13 @@ struct memcached_stat_st { unsigned int limit_maxbytes; }; +struct memcached_string_st { + char *string; + char *end; + size_t current_size; + size_t block_size; +}; + struct memcached_st { memcached_allocated is_allocated; memcached_host_st *hosts; @@ -165,6 +174,21 @@ memcached_return memcached_stat_get_value(memcached_stat_st *stat, char *key, char *value, size_t value_length); char ** memcached_stat_get_keys(memcached_stat_st *stat, memcached_return *error); +/* String Struct */ +#define memcached_string_length(A, B) (size_t)(B->end - B->string) +#define memcached_string_size(A, B) B->current_size +#define memcached_string_value(A, B) B->string + +memcached_string_st *memcached_string_init(memcached_st *ptr, size_t initial_size); +memcached_return memcached_string_append_character(memcached_st *ptr, + memcached_string_st *string, + char character); +memcached_return memcached_string_append(memcached_st *ptr, memcached_string_st *string, + char *value, size_t length); +size_t memcached_string_backspace(memcached_st *ptr, memcached_string_st *string, size_t remove); +memcached_return memcached_string_reset(memcached_st *ptr, memcached_string_st *string); +void memcached_string_free(memcached_st *ptr, memcached_string_st *string); + #ifdef __cplusplus } #endif diff --git a/lib/Makefile.am b/lib/Makefile.am index 93ab95ed..f6597186 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -14,4 +14,5 @@ libmemcached_la_SOURCES = memcached.c \ memcached_verbosity.c \ memcached_quit.c \ memcached_flush.c \ + memcached_string.c \ memcached_stats.c diff --git a/lib/memcached_connect.c b/lib/memcached_connect.c index a0c8737c..d0658f33 100644 --- a/lib/memcached_connect.c +++ b/lib/memcached_connect.c @@ -2,6 +2,9 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port) { + memcached_host_st *new_host_list; + char *new_hostname; + if (!port) port= MEMCACHED_DEFAULT_PORT; @@ -9,11 +12,23 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigne hostname= "localhost"; - ptr->hosts= (memcached_host_st *)realloc(ptr->hosts, sizeof(memcached_host_st) * (ptr->number_of_hosts+1)); - ptr->hosts[ptr->number_of_hosts].hostname= + new_host_list= (memcached_host_st *)realloc(ptr->hosts, sizeof(memcached_host_st) * (ptr->number_of_hosts+1)); + memset((new_host_list + (sizeof(memcached_host_st) * ptr->number_of_hosts)) - sizeof(memcached_host_st), + 0, sizeof(memcached_host_st)); + + if (!new_host_list) + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + + ptr->hosts= new_host_list; + + new_hostname= (char *)malloc(sizeof(char) * (strlen(hostname)+1)); - memset(ptr->hosts[ptr->number_of_hosts].hostname, 0, strlen(hostname)+1); - memcpy(ptr->hosts[ptr->number_of_hosts].hostname, hostname, strlen(hostname)); + if (!new_hostname) + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + + memset(new_hostname, 0, strlen(hostname)+1); + memcpy(new_hostname, hostname, strlen(hostname)); + ptr->hosts[ptr->number_of_hosts].hostname= new_hostname; ptr->hosts[ptr->number_of_hosts].port= port; ptr->hosts[ptr->number_of_hosts].fd= -1; ptr->number_of_hosts++; diff --git a/lib/memcached_flush.c b/lib/memcached_flush.c index 58372c6a..a822f4ad 100644 --- a/lib/memcached_flush.c +++ b/lib/memcached_flush.c @@ -12,6 +12,7 @@ memcached_return memcached_flush(memcached_st *ptr, time_t expiration) if (rc != MEMCACHED_SUCCESS) rc= MEMCACHED_SOME_ERRORS; + memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE); for (x= 0; x < ptr->number_of_hosts; x++) { if (expiration) diff --git a/lib/memcached_get.c b/lib/memcached_get.c index a29deab3..b920df3f 100644 --- a/lib/memcached_get.c +++ b/lib/memcached_get.c @@ -117,9 +117,9 @@ memcached_return memcached_mget(memcached_st *ptr, unsigned int number_of_keys) { char buffer[HUGE_STRING_LEN]; - char *buffer_ptr; unsigned int x; memcached_return rc; + memcached_string_st **cursor_key_exec; ptr->cursor_server= 0; memset(buffer, 0, HUGE_STRING_LEN); @@ -129,34 +129,60 @@ memcached_return memcached_mget(memcached_st *ptr, if (rc != MEMCACHED_SUCCESS) return rc; - memcpy(buffer, "get", strlen("get")); - buffer_ptr= buffer; - buffer_ptr+=strlen("get"); + cursor_key_exec= (memcached_string_st **)malloc(sizeof(memcached_string_st *) * ptr->number_of_hosts); + memset(cursor_key_exec, 0, sizeof(memcached_string_st *) * ptr->number_of_hosts); + for (x= 0; x < number_of_keys; x++) { - *buffer_ptr= ' '; - buffer_ptr++; - memcpy(buffer_ptr, keys[x], key_length[x]); - buffer_ptr+= key_length[x]; + unsigned int server_key; + + server_key= memcached_generate_hash(keys[x], key_length[x]) % ptr->number_of_hosts; + + if (cursor_key_exec[server_key]) + { + memcached_string_st *string= cursor_key_exec[server_key]; + + memcached_string_append_character(ptr, string, ' '); + memcached_string_append(ptr, string, keys[x], key_length[x]); + } + else + { + memcached_string_st *string= memcached_string_init(ptr, SMALL_STRING_LEN); + + if (!string) + assert(0); + + memcached_string_append(ptr, string, "get ", 4); + memcached_string_append(ptr, string, keys[x], key_length[x]); + + cursor_key_exec[server_key]= string; + } } - memcpy(buffer_ptr, "\r\n", 2); - buffer_ptr+=2; /* - This must be fixed. Right now we hit every server, and send keys - to all servers. We should fix this quickly. + Should we muddle on if some servers are dead? */ for (x= 0; x < ptr->number_of_hosts; x++) { - if ((write(ptr->hosts[x].fd, buffer, (size_t)(buffer_ptr - buffer)) == -1)) + if (cursor_key_exec[x]) { - memcached_quit(ptr); - rc= MEMCACHED_SOME_ERRORS; + memcached_string_st *string= cursor_key_exec[x]; + memcached_string_append(ptr, string, "\r\n", 2); + + if ((write(ptr->hosts[x].fd, string->string, + memcached_string_length(ptr, string)) == -1)) + { + memcached_quit(ptr); + rc= MEMCACHED_SOME_ERRORS; + } + memcached_string_free(ptr, string); } } + free(cursor_key_exec); + return rc; } diff --git a/lib/memcached_stats.c b/lib/memcached_stats.c index 48e62cce..5b917fca 100644 --- a/lib/memcached_stats.c +++ b/lib/memcached_stats.c @@ -385,7 +385,15 @@ char ** memcached_stat_get_keys(memcached_stat_st *stat, memcached_return *error { char **list= (char **)malloc(sizeof(memcached_stat_keys)); + if (!list) + { + *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + return NULL; + } + memcpy(list, memcached_stat_keys, sizeof(memcached_stat_keys)); + *error= MEMCACHED_SUCCESS; + return list; } diff --git a/lib/memcached_string.c b/lib/memcached_string.c new file mode 100644 index 00000000..5b2b9d50 --- /dev/null +++ b/lib/memcached_string.c @@ -0,0 +1,103 @@ +#include + +memcached_return memcached_string_check(memcached_string_st *string, size_t need) +{ + if (need > (string->current_size - (string->end - string->string))) + { + size_t current_offset= string->end - string->string; + char *new_value; + + new_value= (char *)realloc(string->string, sizeof(char) * string->block_size); + + if (!new_value) + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + + string->string= new_value; + string->end= string->string + current_offset; + + string->current_size+= string->block_size; + + /* We zero the block structure we just realloced */ + memset((string + string->current_size) - string->block_size , 0, + sizeof(char) * string->block_size); + } + + return MEMCACHED_SUCCESS; +} + +memcached_string_st *memcached_string_init(memcached_st *ptr, size_t initial_size) +{ + memcached_string_st *string; + + /* Saving malloc calls :) */ + string= (memcached_string_st *)malloc(sizeof(memcached_string_st) + (sizeof(char) * initial_size)); + if (!string) + return NULL; + memset(string, 0, sizeof(memcached_string_st)); + string->block_size= initial_size; + memcached_string_check(string, initial_size); + + return string; +} + +memcached_return memcached_string_append_character(memcached_st *ptr, + memcached_string_st *string, + char character) +{ + memcached_string_check(string, 1); + *string->end= ' '; + string->end++; + + return MEMCACHED_SUCCESS; +} + +memcached_return memcached_string_append(memcached_st *ptr, memcached_string_st *string, + char *value, size_t length) +{ + memcached_string_check(string, length); + memcpy(string->end, value, length); + string->end+= length; + + return MEMCACHED_SUCCESS; +} + +#ifdef CRAP +size_t memcached_string_length(memcached_st *ptr, memcached_string_st *string) +{ + return (size_t)(string->end - string->string); +} + +size_t memcached_string_size(memcached_st *ptr, memcached_string_st *string) +{ + return string->current_size; +} +#endif + +size_t memcached_string_backspace(memcached_st *ptr, memcached_string_st *string, size_t remove) +{ + if (string->end - string->string > remove) + { + size_t difference; + + difference= string->end - string->string; + string->end= string->string; + + return difference; + } + string->end-= remove; + + return remove; +} + +memcached_return memcached_string_reset(memcached_st *ptr, memcached_string_st *string) +{ + string->end= string->string; + + return MEMCACHED_SUCCESS; +} + +void memcached_string_free(memcached_st *ptr, memcached_string_st *string) +{ + free(string->string); + free(string); +} -- 2.30.2