Add mget as a test to memslap
authorTrond Norbye <tn202803@tor01>
Fri, 6 Nov 2009 10:04:53 +0000 (11:04 +0100)
committerTrond Norbye <tn202803@tor01>
Fri, 6 Nov 2009 10:04:53 +0000 (11:04 +0100)
clients/execute.c
clients/execute.h
clients/memslap.c

index 7255d37ede3522dcc15a97a239aed387c898d1fb..30fb5f180cca0cf0d1983d665f87d3c6438881f9 100644 (file)
@@ -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;
+}
index 75ab66c59fcd3f9b18ce59b5f1871bf7c930ed17..7a2c5511704b3e237ff0139edc6ad326560875c5 100644 (file)
@@ -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
+
index 4e3d6813f05742cc6ba4a26a7f64446d306e62bf..aff2de1ba6b95bec7e0a8cafdada969e935e28a3 100644 (file)
@@ -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;