From a839a04ae135e6a92b8be858e9c6605d7514c394 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Thu, 4 Oct 2007 20:47:17 -0700 Subject: [PATCH] Found bug in multi get where key size was not being calculated. All mem commands can now used environmental variable MEMCACHED_SERVERS to get a list of servers they should be commincating with. server parse string method was removed from utilities and added to main library. Its a little to handy not to have it in the library :) --- ChangeLog | 2 + include/memcached.h | 1 + lib/Makefile.am | 1 + lib/memcached_get.c | 3 ++ lib/memcached_parse.c | 62 ++++++++++++++++++++++ src/memcat.c | 14 +++-- src/memcp.c | 13 +++-- src/memflush.c | 11 +++- src/memrm.c | 11 +++- src/memslap.c | 11 +++- src/memstat.c | 11 +++- src/utilities.c | 54 ------------------- src/utilities.h | 1 - tests/test.c | 118 ++++++++++-------------------------------- 14 files changed, 153 insertions(+), 160 deletions(-) create mode 100644 lib/memcached_parse.c diff --git a/ChangeLog b/ChangeLog index 2c8f12ac..42a319c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ * Updated memslap to support --flush (aka dump memcache servers before testing) * Fixed bug in multiple hosts not being activated + * Added environmental variable MEMCACHED_SERVERS which can be used to + set the servers list. 0.4 Wed Oct 3 10:28:50 PDT 2007 * Added buffered IO to write calls for keys diff --git a/include/memcached.h b/include/memcached.h index 594b4ade..431975c1 100644 --- a/include/memcached.h +++ b/include/memcached.h @@ -208,6 +208,7 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, void memcached_server_list_free(memcached_server_st *ptr); memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list); unsigned int memcached_server_list_count(memcached_server_st *ptr); +memcached_server_st *memcached_servers_parse(char *server_strings); /* These are all private, do not use. */ memcached_return memcached_connect(memcached_st *ptr); diff --git a/lib/Makefile.am b/lib/Makefile.am index 8ff7b139..ab12b0a9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -36,6 +36,7 @@ libmemcached_la_SOURCES = memcached.c \ memcached_hosts.c \ memcached_io.c \ memcached_quit.c \ + memcached_parse.c \ memcached_response.c \ memcached_storage.c \ memcached_string.c \ diff --git a/lib/memcached_get.c b/lib/memcached_get.c index 49b64f3b..201cfcdf 100644 --- a/lib/memcached_get.c +++ b/lib/memcached_get.c @@ -34,10 +34,13 @@ static char *memcached_value_fetch(memcached_st *ptr, char *key, size_t *key_len if (load_key) { memset(key, 0, MEMCACHED_MAX_KEY); + *key_length= 0; + for (; end_ptr == string_ptr || *string_ptr != ' '; string_ptr++) { *key= *string_ptr; key++; + (*key_length)++; } } else /* Skip characters */ diff --git a/lib/memcached_parse.c b/lib/memcached_parse.c new file mode 100644 index 00000000..2a58d535 --- /dev/null +++ b/lib/memcached_parse.c @@ -0,0 +1,62 @@ +/* + I debated about putting this in the client library since it does an + action I don't really believe belongs in the library. + + Frankly its too damn useful not to be here though. +*/ + +#include + +memcached_server_st *memcached_servers_parse(char *server_strings) +{ + char *string; + unsigned int port; + char *begin_ptr; + char *end_ptr; + memcached_server_st *servers= NULL; + memcached_return rc; + + assert(server_strings); + + end_ptr= server_strings + strlen(server_strings); + + for (begin_ptr= server_strings, string= index(server_strings, ','); + begin_ptr != end_ptr; + string= index(begin_ptr, ',')) + { + char buffer[HUGE_STRING_LEN]; + char *ptr; + port= 0; + + memset(buffer, 0, HUGE_STRING_LEN); + if (string) + { + memcpy(buffer, begin_ptr, string - begin_ptr); + begin_ptr= string+1; + } + else + { + size_t length= strlen(begin_ptr); + memcpy(buffer, begin_ptr, length); + begin_ptr= end_ptr; + } + + ptr= index(buffer, ':'); + + if (ptr) + { + ptr[0]= 0; + + ptr++; + + port= strtol(ptr, (char **)NULL, 10); + } + + servers= memcached_server_list_append(servers, buffer, port, &rc); + + if (isspace(*begin_ptr)) + begin_ptr++; + } + + return servers; +} diff --git a/src/memcat.c b/src/memcat.c index bb00ca66..1c9082f5 100644 --- a/src/memcat.c +++ b/src/memcat.c @@ -29,11 +29,19 @@ int main(int argc, char *argv[]) options_parse(argc, argv); if (!opt_servers) - return 0; + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + exit(1); + } memc= memcached_create(NULL); - servers= parse_opt_servers(opt_servers); + servers= memcached_servers_parse(opt_servers); + memcached_server_push(memc, servers); memcached_server_list_free(servers); @@ -58,7 +66,7 @@ int main(int argc, char *argv[]) free(string); } } - else + else if (rc != MEMCACHED_NOTFOUND) { fprintf(stderr, "memcat: %s: memcache error %s\n", argv[optind], memcached_strerror(memc, rc)); diff --git a/src/memcp.c b/src/memcp.c index 62c60207..f51c93cb 100644 --- a/src/memcp.c +++ b/src/memcp.c @@ -35,12 +35,19 @@ int main(int argc, char *argv[]) memc= memcached_create(NULL); if (!opt_servers) - return 0; + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + exit(1); + } if (opt_servers) - servers= parse_opt_servers(opt_servers); + servers= memcached_servers_parse(opt_servers); else - servers= parse_opt_servers(argv[--argc]); + servers= memcached_servers_parse(argv[--argc]); memcached_server_push(memc, servers); memcached_server_list_free(servers); diff --git a/src/memflush.c b/src/memflush.c index af7ab353..84db8b42 100644 --- a/src/memflush.c +++ b/src/memflush.c @@ -24,11 +24,18 @@ int main(int argc, char *argv[]) options_parse(argc, argv); if (!opt_servers) - return 0; + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + exit(1); + } memc= memcached_create(NULL); - servers= parse_opt_servers(opt_servers); + servers= memcached_servers_parse(opt_servers); memcached_server_push(memc, servers); memcached_server_list_free(servers); diff --git a/src/memrm.c b/src/memrm.c index 2df86838..b8d07ba4 100644 --- a/src/memrm.c +++ b/src/memrm.c @@ -24,11 +24,18 @@ int main(int argc, char *argv[]) options_parse(argc, argv); if (!opt_servers) - return 0; + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + exit(1); + } memc= memcached_create(NULL); - servers= parse_opt_servers(opt_servers); + servers= memcached_servers_parse(opt_servers); memcached_server_push(memc, servers); memcached_server_list_free(servers); diff --git a/src/memslap.c b/src/memslap.c index ff01ddc1..280e4c9d 100644 --- a/src/memslap.c +++ b/src/memslap.c @@ -88,9 +88,16 @@ int main(int argc, char *argv[]) options_parse(argc, argv); if (!opt_servers) - exit(0); + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + exit(1); + } - servers= parse_opt_servers(opt_servers); + servers= memcached_servers_parse(opt_servers); pthread_mutex_init(&counter_mutex, NULL); pthread_cond_init(&count_threshhold, NULL); diff --git a/src/memstat.c b/src/memstat.c index 0d7bef07..40aade20 100644 --- a/src/memstat.c +++ b/src/memstat.c @@ -33,11 +33,18 @@ int main(int argc, char *argv[]) options_parse(argc, argv); if (!opt_servers) - return 0; + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + exit(1); + } memc= memcached_create(NULL); - servers= parse_opt_servers(opt_servers); + servers= memcached_servers_parse(opt_servers); memcached_server_push(memc, servers); memcached_server_list_free(servers); diff --git a/src/utilities.c b/src/utilities.c index ed0dbb30..e6db318b 100644 --- a/src/utilities.c +++ b/src/utilities.c @@ -2,60 +2,6 @@ #include #include "utilities.h" -memcached_server_st *parse_opt_servers(char *server_strings) -{ - char *string; - unsigned int port; - char *begin_ptr; - char *end_ptr; - memcached_server_st *servers= NULL; - memcached_return rc; - - assert(server_strings); - - end_ptr= server_strings + strlen(server_strings); - - for (begin_ptr= server_strings, string= index(server_strings, ','); - begin_ptr != end_ptr; - string= index(begin_ptr, ',')) - { - char buffer[HUGE_STRING_LEN]; - char *ptr; - port= 0; - - memset(buffer, 0, HUGE_STRING_LEN); - if (string) - { - memcpy(buffer, begin_ptr, string - begin_ptr); - begin_ptr= string+1; - } - else - { - size_t length= strlen(begin_ptr); - memcpy(buffer, begin_ptr, length); - begin_ptr= end_ptr; - } - - ptr= index(buffer, ':'); - - if (ptr) - { - ptr[0]= 0; - - ptr++; - - port= strtol(ptr, (char **)NULL, 10); - } - - servers= memcached_server_list_append(servers, buffer, port, &rc); - - if (isspace(*begin_ptr)) - begin_ptr++; - } - - return servers; -} - long int timedif(struct timeval a, struct timeval b) { register int us, s; diff --git a/src/utilities.h b/src/utilities.h index b9ac7f1c..5a1b916d 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -8,7 +8,6 @@ struct memcached_programs_help_st char *not_used_yet; }; -memcached_server_st *parse_opt_servers(char *server_strings); char *strdup_cleanup(const char *str); void cleanup(void); long int timedif(struct timeval a, struct timeval b); diff --git a/tests/test.c b/tests/test.c index f43793ee..e0f50adb 100644 --- a/tests/test.c +++ b/tests/test.c @@ -47,8 +47,6 @@ void set_test(memcached_st *memc) char *key= "foo"; char *value= "when we sanitize"; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint16_t)0); @@ -61,8 +59,6 @@ void add_test(memcached_st *memc) char *key= "foo"; char *value= "when we sanitize"; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); rc= memcached_add(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint16_t)0); @@ -75,8 +71,6 @@ void replace_test(memcached_st *memc) char *key= "foo"; char *value= "when we sanitize"; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); rc= memcached_replace(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint16_t)0); @@ -89,8 +83,6 @@ void delete_test(memcached_st *memc) char *key= "foo"; char *value= "when we sanitize"; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint16_t)0); @@ -104,8 +96,6 @@ void flush_test(memcached_st *memc) { memcached_return rc; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); rc= memcached_flush(memc, 0); assert(rc == MEMCACHED_SUCCESS); } @@ -118,9 +108,6 @@ void get_test(memcached_st *memc) size_t string_length; uint16_t flags; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - string= memcached_get(memc, key, strlen(key), &string_length, &flags, &rc); @@ -138,9 +125,6 @@ void get_test2(memcached_st *memc) size_t string_length; uint16_t flags; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint16_t)0); @@ -165,9 +149,6 @@ void set_test2(memcached_st *memc) size_t value_length= strlen(value); unsigned int x; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - for (x= 0; x < 10; x++) { rc= memcached_set(memc, key, strlen(key), @@ -191,9 +172,6 @@ void set_test3(memcached_st *memc) for (x= 0; x < value_length; x++) value[x] = (char) (x % 127); - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - for (x= 0; x < 1; x++) { rc= memcached_set(memc, key, strlen(key), @@ -222,9 +200,6 @@ void get_test3(memcached_st *memc) for (x= 0; x < value_length; x++) value[x] = (char) (x % 127); - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - rc= memcached_set(memc, key, strlen(key), value, value_length, (time_t)0, (uint16_t)0); @@ -259,9 +234,6 @@ void get_test4(memcached_st *memc) for (x= 0; x < value_length; x++) value[x] = (char) (x % 127); - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - rc= memcached_set(memc, key, strlen(key), value, value_length, (time_t)0, (uint16_t)0); @@ -298,9 +270,6 @@ void increment_test(memcached_st *memc) char *key= "number"; char *value= "0"; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint16_t)0); @@ -324,9 +293,6 @@ void decrement_test(memcached_st *memc) char *key= "number"; char *value= "3"; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint16_t)0); @@ -349,9 +315,6 @@ void quit_test(memcached_st *memc) char *key= "fudge"; char *value= "sanford and sun"; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)10, (uint16_t)3); @@ -377,9 +340,6 @@ void mget_test(memcached_st *memc) char *return_value; size_t return_value_length; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - /* We need to empty the server before continueing test */ rc= memcached_flush(memc, 0); assert(rc == MEMCACHED_SUCCESS); @@ -413,8 +373,8 @@ void mget_test(memcached_st *memc) { assert(return_value); assert(rc == MEMCACHED_SUCCESS); - assert(key_length[x] == return_value_length); - assert(!memcmp(return_value, keys[x], return_value_length)); + assert(return_key_length == return_value_length); + assert(!memcmp(return_value, return_key, return_value_length)); free(return_value); x++; } @@ -443,41 +403,6 @@ void get_stats(memcached_st *memc) memcached_return rc; memcached_stat_st *stat; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - - stat= memcached_stat(memc, NULL, &rc); - assert(rc == MEMCACHED_SUCCESS); - - assert(rc == MEMCACHED_SUCCESS); - assert(stat); - - for (x= 0; x < memcached_server_count(memc); x++) - { - list= memcached_stat_get_keys(memc, &stat[x], &rc); - assert(rc == MEMCACHED_SUCCESS); - for (ptr= list; *ptr; ptr++) - printf("Found key %s\n", *ptr); - - free(list); - } - - free(stat); -} - -void get_stats_multiple(memcached_st *memc) -{ - unsigned int x; - char **list; - char **ptr; - memcached_return rc; - memcached_stat_st *stat; - - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - rc= memcached_server_add(memc, "localhost", 5555); - assert(rc == MEMCACHED_SUCCESS); - stat= memcached_stat(memc, NULL, &rc); assert(rc == MEMCACHED_SUCCESS); @@ -504,9 +429,6 @@ void add_host_test(memcached_st *memc) memcached_return rc; char servername[]= "0.example.com"; - rc= memcached_server_add(memc, "localhost", 0); - assert(rc == MEMCACHED_SUCCESS); - servers= memcached_server_list_append(NULL, servername, 400, &rc); assert(servers); assert(1 == memcached_server_list_count(servers)); @@ -571,6 +493,16 @@ struct test_st { int main(int argc, char *argv[]) { unsigned int x; + char *server_list; + memcached_server_st *servers; + + if (!(server_list= getenv("MEMCACHED_SERVERS"))) + server_list= "localhost"; + + printf("servers %s\n", server_list); + + servers= memcached_servers_parse(server_list); + assert(servers); /* Clean the server before beginning testing */ test_st tests[] ={ @@ -603,8 +535,13 @@ int main(int argc, char *argv[]) for (x= 0; tests[x].function_name; x++) { memcached_st *memc; + memcached_return rc; memc= memcached_create(NULL); assert(memc); + + rc= memcached_server_push(memc, servers); + assert(rc == MEMCACHED_SUCCESS); + fprintf(stderr, "Testing %s", tests[x].function_name); tests[x].function(memc); fprintf(stderr, "\t\t\t\t\t[ ok ]\n"); @@ -616,8 +553,13 @@ int main(int argc, char *argv[]) for (x= 0; tests[x].function_name; x++) { memcached_st *memc; + memcached_return rc; memc= memcached_create(NULL); assert(memc); + + rc= memcached_server_push(memc, servers); + assert(rc == MEMCACHED_SUCCESS); + fprintf(stderr, "Testing %s", tests[x].function_name); memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL); tests[x].function(memc); @@ -630,8 +572,13 @@ int main(int argc, char *argv[]) for (x= 0; tests[x].function_name; x++) { memcached_st *memc; + memcached_return rc; memc= memcached_create(NULL); assert(memc); + + rc= memcached_server_push(memc, servers); + assert(rc == MEMCACHED_SUCCESS); + fprintf(stderr, "Testing %s", tests[x].function_name); memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL); memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, NULL); @@ -641,17 +588,6 @@ int main(int argc, char *argv[]) memcached_free(memc); } - - /* The multiple tests */ - if (argc == 2) - { - memcached_st *memc; - memc= memcached_create(NULL); - assert(memc); - get_stats_multiple(memc); - memcached_free(memc); - } - /* Clean up whatever we might have left */ { memcached_st *memc; -- 2.30.2