From: Trond Norbye Date: Fri, 6 Nov 2009 10:04:53 +0000 (+0100) Subject: Add mget as a test to memslap X-Git-Tag: 0.35~3^2 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=df6e5c0b31eb13ad2db5a040b3177514553448c8;p=m6w6%2Flibmemcached Add mget as a test to memslap --- diff --git a/clients/execute.c b/clients/execute.c index 7255d37e..30fb5f18 100644 --- a/clients/execute.c +++ b/clients/execute.c @@ -19,7 +19,7 @@ unsigned int execute_set(memcached_st *memc, pairs_st *pairs, unsigned int numbe pairs[x].value, pairs[x].value_length, 0, 0); if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) - fprintf(stderr, "Failured on insert of %.*s\n", + fprintf(stderr, "Failured on insert of %.*s\n", (unsigned int)pairs[x].key_length, pairs[x].key); else pairs_sent++; @@ -52,7 +52,7 @@ unsigned int execute_get(memcached_st *memc, pairs_st *pairs, unsigned int numbe &value_length, &flags, &rc); if (rc != MEMCACHED_SUCCESS) - fprintf(stderr, "Failured on read of %.*s\n", + fprintf(stderr, "Failured on read of %.*s\n", (unsigned int)pairs[fetch_key].key_length, pairs[fetch_key].key); else retrieved++; @@ -62,3 +62,61 @@ unsigned int execute_get(memcached_st *memc, pairs_st *pairs, unsigned int numbe return retrieved; } + +/** + * Callback function to count the number of results + */ +static memcached_return callback_counter(memcached_st *ptr, + memcached_result_st *result, + void *context) +{ + (void)ptr; + (void)result; + unsigned int *counter= (unsigned int *)context; + *counter= *counter + 1; + + return MEMCACHED_SUCCESS; +} + +/** + * Try to run a large mget to get all of the keys + * @param memc memcached handle + * @param keys the keys to get + * @param key_length the length of the keys + * @param number_of the number of keys to try to get + * @return the number of keys received + */ +unsigned int execute_mget(memcached_st *memc, + const char * const *keys, + size_t *key_length, + unsigned int number_of) +{ + unsigned int retrieved= 0; + memcached_execute_function callbacks[1]= { [0]= &callback_counter }; + memcached_return rc; + rc= memcached_mget_execute(memc, keys, key_length, + (size_t)number_of, callbacks, &retrieved, 1); + + likely (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOTFOUND || + rc == MEMCACHED_BUFFERED || rc == MEMCACHED_END) + { + rc= memcached_fetch_execute(memc, callbacks, (void *)&retrieved, 1); + unlikely (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_NOTFOUND && + rc != MEMCACHED_END) + { + fprintf(stderr, "Failed to execute mget: %s\n", + memcached_strerror(memc, rc)); + memcached_quit(memc); + return 0; + } + } + else + { + fprintf(stderr, "Failed to execute mget: %s\n", + memcached_strerror(memc, rc)); + memcached_quit(memc); + return 0; + } + + return retrieved; +} diff --git a/clients/execute.h b/clients/execute.h index 75ab66c5..7a2c5511 100644 --- a/clients/execute.h +++ b/clients/execute.h @@ -1,5 +1,11 @@ +#ifndef CLIENTS_EXECUTE_H +#define CLIENTS_EXECUTE_H #include "libmemcached/memcached.h" #include "generator.h" unsigned int execute_set(memcached_st *memc, pairs_st *pairs, unsigned int number_of); unsigned int execute_get(memcached_st *memc, pairs_st *pairs, unsigned int number_of); +unsigned int execute_mget(memcached_st *memc, const char * const *keys, size_t *key_length, + unsigned int number_of); +#endif + diff --git a/clients/memslap.c b/clients/memslap.c index 4e3d6813..aff2de1b 100644 --- a/clients/memslap.c +++ b/clients/memslap.c @@ -42,6 +42,7 @@ typedef struct thread_context_st thread_context_st; typedef enum { SET_TEST, GET_TEST, + MGET_TEST } test_type; struct thread_context_st { @@ -50,6 +51,8 @@ struct thread_context_st { unsigned int initial_number; pairs_st *execute_pairs; unsigned int execute_number; + char **keys; + size_t *key_lengths; test_type test; memcached_st *memc; }; @@ -65,7 +68,7 @@ struct conclusions_st { void options_parse(int argc, char *argv[]); void conclusions_print(conclusions_st *conclusion); void scheduler(memcached_server_st *servers, conclusions_st *conclusion); -pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, +pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, unsigned int *actual_loaded); void flush_all(memcached_st *memc); @@ -155,12 +158,29 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, (uint64_t)opt_binary); - + if (opt_flush) flush_all(memc); if (opt_createial_load) pairs= load_create_data(memc, opt_createial_load, &actual_loaded); + char **keys= calloc(actual_loaded, sizeof(char*)); + size_t *key_lengths= calloc(actual_loaded, sizeof(size_t)); + + if (keys == NULL || key_lengths == NULL) + { + free(keys); + free(key_lengths); + keys= NULL; + key_lengths= NULL; + } else { + for (x= 0; x < actual_loaded; ++x) + { + keys[x]= pairs[x].key; + key_lengths[x]= pairs[x].key_length; + } + } + /* We set this after we have loaded */ { if (opt_non_blocking_io) @@ -169,7 +189,6 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1); } - pthread_mutex_lock(&counter_mutex); thread_counter= 0; @@ -187,6 +206,8 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) context->initial_pairs= pairs; context->initial_number= actual_loaded; + context->keys= keys; + context->key_lengths= key_lengths; if (opt_test == SET_TEST) { @@ -225,6 +246,8 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) conclusion->load_time= timedif(end_time, start_time); conclusion->read_time= timedif(end_time, start_time); + free(keys); + free(key_lengths); pairs_free(pairs); memcached_free(memc); } @@ -259,7 +282,7 @@ void options_parse(int argc, char *argv[]) int option_index= 0; int option_rv; - while (1) + while (1) { option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index); if (option_rv == -1) break; @@ -307,7 +330,11 @@ void options_parse(int argc, char *argv[]) } else if (!strcmp(optarg, "set")) opt_test= SET_TEST; - else + else if (!strcmp(optarg, "mget")) + { + opt_test= MGET_TEST; + } + else { fprintf(stderr, "Your test, %s, is not a known test\n", optarg); exit(1); @@ -330,7 +357,7 @@ void options_parse(int argc, char *argv[]) } } - if (opt_test == GET_TEST && opt_createial_load == 0) + if ((opt_test == GET_TEST || opt_test == MGET_TEST) && opt_createial_load == 0) opt_createial_load= DEFAULT_INITIAL_LOAD; if (opt_execute_number == 0) @@ -348,10 +375,10 @@ void conclusions_print(conclusions_st *conclusion) printf("\tRead %u rows\n", conclusion->rows_read); #endif if (opt_test == SET_TEST) - printf("\tTook %ld.%03ld seconds to load data\n", conclusion->load_time / 1000, + printf("\tTook %ld.%03ld seconds to load data\n", conclusion->load_time / 1000, conclusion->load_time % 1000); else - printf("\tTook %ld.%03ld seconds to read data\n", conclusion->read_time / 1000, + printf("\tTook %ld.%03ld seconds to read data\n", conclusion->read_time / 1000, conclusion->read_time % 1000); } @@ -366,7 +393,7 @@ void *run_task(void *p) while (master_wakeup) { pthread_cond_wait(&sleep_threshhold, &sleeper_mutex); - } + } pthread_mutex_unlock(&sleeper_mutex); /* Do Stuff */ @@ -379,6 +406,10 @@ void *run_task(void *p) case GET_TEST: execute_get(memc, context->initial_pairs, context->initial_number); break; + case MGET_TEST: + execute_mget(memc, (const char*const*)context->keys, context->key_lengths, + context->initial_number); + break; default: WATCHPOINT_ASSERT(context->test); break; @@ -404,7 +435,7 @@ void flush_all(memcached_st *memc) memcached_flush(memc, 0); } -pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, +pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, unsigned int *actual_loaded) { memcached_st *memc_clone;