From: Ripduman Sohan <[email protected]>

Basic idea - compute hash and store within item_hash, reduces
computation overhead in subsequent operations.  Also reduces the time
spent in the cu_op_recs.lock.

Signed-off-by: Ripduman Sohan <[email protected]>
---
 engines/default_engine/items.c |  100 ++++++++++++++++++++--------------------
 engines/default_engine/items.h |   10 ++--
 2 files changed, 54 insertions(+), 56 deletions(-)

diff --git a/engines/default_engine/items.c b/engines/default_engine/items.c
index 3b623fa..86b78b9 100644
--- a/engines/default_engine/items.c
+++ b/engines/default_engine/items.c
@@ -15,12 +15,12 @@
 static void item_link_q(struct default_engine *engine, hash_item *it);
 static void item_unlink_q(struct default_engine *engine, hash_item *it);
 static hash_item *do_item_alloc(struct default_engine *engine,
-                                const void *key, const size_t nkey,
+                                uint32_t hash, const void *key, const size_t 
nkey,
                                 const int flags, const rel_time_t exptime,
                                 const int nbytes,
                                 const void *cookie);
 static hash_item *do_item_get(struct default_engine *engine,
-                              const char *key, const size_t nkey);
+                              uint32_t hash, const char *key, const size_t 
nkey);
 static int do_item_link(struct default_engine *engine, hash_item *it);
 static void do_item_unlink(struct default_engine *engine, hash_item *it);
 static void do_item_release(struct default_engine *engine, hash_item *it);
@@ -28,8 +28,8 @@ static void do_item_update(struct default_engine *engine, 
hash_item *it);
 static int do_item_replace(struct default_engine *engine,
                             hash_item *it, hash_item *new_it);
 static void item_free(struct default_engine *engine, hash_item *it);
-static void acquire_key_operation_mutex(struct default_engine *engine, const 
char *key, size_t nkey);
-static void release_key_operation_mutex(struct default_engine *engine, const 
char *key, size_t nkey);
+static void acquire_key_operation_mutex(struct default_engine *engine, 
uint32_t hash);
+static void release_key_operation_mutex(struct default_engine *engine, 
uint32_t hash);
 
 /* Macros to clarify the items datastructure LRU list acquisition and release  
*/
 #define lock_lru_list(engine, listid) 
pthread_mutex_lock(&engine->items.lock[listid])
@@ -84,6 +84,7 @@ static uint64_t get_cas_id(void) {
 
 /*@null@*/
 hash_item *do_item_alloc(struct default_engine *engine,
+                         const uint32_t hash,
                          const void *key,
                          const size_t nkey,
                          const int flags,
@@ -247,6 +248,7 @@ hash_item *do_item_alloc(struct default_engine *engine,
     it->flags = flags;
     memcpy((void*)item_get_key(it), key, nkey);
     it->exptime = exptime;
+    it->hash = hash;
     return it;
 }
 
@@ -313,9 +315,7 @@ int do_item_link(struct default_engine *engine, hash_item 
*it) {
     assert(it->nbytes < (1024 * 1024));  /* 1MB max size */
     it->iflag |= ITEM_LINKED;
     it->time = engine->server.core->get_current_time();
-    assoc_insert(engine, engine->server.core->hash(item_get_key(it),
-                                                        it->nkey, 0),
-                 it);
+    assoc_insert(engine, it->hash, it);
 
     pthread_mutex_lock(&engine->stats.lock);
     engine->stats.curr_bytes += ITEM_ntotal(engine, it);
@@ -339,9 +339,7 @@ void do_item_unlink(struct default_engine *engine, 
hash_item *it) {
         engine->stats.curr_bytes -= ITEM_ntotal(engine, it);
         engine->stats.curr_items -= 1;
         pthread_mutex_unlock(&engine->stats.lock);
-        assoc_delete(engine, engine->server.core->hash(item_get_key(it),
-                                                            it->nkey, 0),
-                     item_get_key(it), it->nkey);
+        assoc_delete(engine, it->hash, item_get_key(it), it->nkey);
         item_unlink_q(engine, it);
         if (it->refcount == 0) {
             item_free(engine, it);
@@ -537,11 +535,9 @@ static void do_item_stats_sizes(struct default_engine 
*engine,
 
 /** wrapper around assoc_find which does the lazy expiration logic */
 hash_item *do_item_get(struct default_engine *engine,
-                       const char *key, const size_t nkey) {
+                       uint32_t hash, const char *key, const size_t nkey) {
     rel_time_t current_time = engine->server.core->get_current_time();
-    hash_item *it = assoc_find(engine, engine->server.core->hash(key,
-                                                                      nkey, 0),
-                               key, nkey);
+    hash_item *it = assoc_find(engine, hash, key, nkey);
     int was_found = 0;
 
     if (engine->config.verbose > 2) {
@@ -610,7 +606,7 @@ static ENGINE_ERROR_CODE do_store_item(struct 
default_engine *engine,
                                        ENGINE_STORE_OPERATION operation,
                                        const void *cookie) {
     const char *key = item_get_key(it);
-    hash_item *old_it = do_item_get(engine, key, it->nkey);
+    hash_item *old_it = do_item_get(engine, it->hash, key, it->nkey);
     ENGINE_ERROR_CODE stored = ENGINE_NOT_STORED;
 
     hash_item *new_it = NULL;
@@ -663,7 +659,7 @@ static ENGINE_ERROR_CODE do_store_item(struct 
default_engine *engine,
 
             if (stored == ENGINE_NOT_STORED) {
                 /* we have it and old_it here - alloc memory to hold both */
-                new_it = do_item_alloc(engine, key, it->nkey,
+                new_it = do_item_alloc(engine, it->hash, key, it->nkey,
                                        old_it->flags,
                                        old_it->exptime,
                                        it->nbytes + old_it->nbytes,
@@ -777,7 +773,7 @@ static ENGINE_ERROR_CODE do_add_delta(struct default_engine 
*engine,
         item_set_cas(NULL, NULL, it, get_cas_id());
         *rcas = item_get_cas(it);
     } else {
-        hash_item *new_it = do_item_alloc(engine, item_get_key(it),
+        hash_item *new_it = do_item_alloc(engine, it->hash, item_get_key(it),
                                           it->nkey, it->flags,
                                           it->exptime, res,
                                           cookie);
@@ -805,9 +801,10 @@ hash_item *item_alloc(struct default_engine *engine,
                       const void *key, size_t nkey, int flags,
                       rel_time_t exptime, int nbytes, const void *cookie) {
     hash_item *it;
-    acquire_key_operation_mutex(engine, key, nkey);
-    it = do_item_alloc(engine, key, nkey, flags, exptime, nbytes, cookie);
-    release_key_operation_mutex(engine, key, nkey);
+    uint32_t hash = engine->server.core->hash(key, nkey, 0);
+    acquire_key_operation_mutex(engine, hash);
+    it = do_item_alloc(engine, hash, key, nkey, flags, exptime, nbytes, 
cookie);
+    release_key_operation_mutex(engine, hash);
     return it;
 }
 
@@ -818,9 +815,10 @@ hash_item *item_alloc(struct default_engine *engine,
 hash_item *item_get(struct default_engine *engine,
                     const void *key, const size_t nkey) {
     hash_item *it;
-    acquire_key_operation_mutex(engine, key, nkey);
-    it = do_item_get(engine, key, nkey);
-    release_key_operation_mutex(engine, key, nkey);
+    uint32_t hash = engine->server.core->hash(key, nkey, 0);
+    acquire_key_operation_mutex(engine, hash);
+    it = do_item_get(engine, hash, key, nkey);
+    release_key_operation_mutex(engine, hash);
     return it;
 }
 
@@ -829,24 +827,25 @@ hash_item *item_get(struct default_engine *engine,
  * needed.
  */
 void item_release(struct default_engine *engine, hash_item *item) {
-    acquire_key_operation_mutex(engine, item_get_key(item), item->nkey);
+    acquire_key_operation_mutex(engine, item->hash);
     do_item_release(engine, item);
-    release_key_operation_mutex(engine, item_get_key(item), item->nkey);
+    release_key_operation_mutex(engine, item->hash);
 }
 
 /*
  * Unlinks an item from the LRU and hashtable.
  */
 void item_unlink(struct default_engine *engine, hash_item *item) {
-    acquire_key_operation_mutex(engine, item_get_key(item), item->nkey);
+    acquire_key_operation_mutex(engine, item->hash);
     lock_lru_list(engine, item->slabs_clsid);
     do_item_unlink(engine, item);
     unlock_lru_list(engine, item->slabs_clsid);
-    release_key_operation_mutex(engine, item_get_key(item), item->nkey);
+    release_key_operation_mutex(engine, item->hash);
 }
 
 static ENGINE_ERROR_CODE do_arithmetic(struct default_engine *engine,
                                        const void* cookie,
+                                       const uint32_t hash,
                                        const void* key,
                                        const int nkey,
                                        const bool increment,
@@ -857,7 +856,7 @@ static ENGINE_ERROR_CODE do_arithmetic(struct 
default_engine *engine,
                                        uint64_t *cas,
                                        uint64_t *result)
 {
-   hash_item *item = do_item_get(engine, key, nkey);
+    hash_item *item = do_item_get(engine, hash, key, nkey);
    ENGINE_ERROR_CODE ret;
 
    if (item == NULL) {
@@ -868,7 +867,7 @@ static ENGINE_ERROR_CODE do_arithmetic(struct 
default_engine *engine,
          int len = snprintf(buffer, sizeof(buffer), "%"PRIu64,
                             (uint64_t)initial);
 
-         item = do_item_alloc(engine, key, nkey, 0, exptime, len, cookie);
+         item = do_item_alloc(engine, hash, key, nkey, 0, exptime, len, 
cookie);
          if (item == NULL) {
             return ENGINE_ENOMEM;
          }
@@ -901,12 +900,12 @@ ENGINE_ERROR_CODE arithmetic(struct default_engine 
*engine,
                              uint64_t *result)
 {
     ENGINE_ERROR_CODE ret;
-
-    acquire_key_operation_mutex(engine, key, nkey);
-    ret = do_arithmetic(engine, cookie, key, nkey, increment,
+    uint32_t hash = engine->server.core->hash(key, nkey, 0);
+    acquire_key_operation_mutex(engine, hash);
+    ret = do_arithmetic(engine, cookie, hash, key, nkey, increment,
                         create, delta, initial, exptime, cas,
                         result);
-    release_key_operation_mutex(engine, key, nkey);
+    release_key_operation_mutex(engine, hash);
     return ret;
 }
 
@@ -919,18 +918,19 @@ ENGINE_ERROR_CODE store_item(struct default_engine 
*engine,
                              const void *cookie) {
     ENGINE_ERROR_CODE ret;
 
-    acquire_key_operation_mutex(engine, item_get_key(item), item->nkey);
+    acquire_key_operation_mutex(engine, item->hash);
     ret = do_store_item(engine, item, cas, operation, cookie);
-    release_key_operation_mutex(engine, item_get_key(item), item->nkey);
+    release_key_operation_mutex(engine, item->hash);
     return ret;
 }
 
 static hash_item *do_touch_item(struct default_engine *engine,
+                                     uint32_t hash,
                                      const void *key,
                                      uint16_t nkey,
                                      uint32_t exptime)
 {
-   hash_item *item = do_item_get(engine, key, nkey);
+   hash_item *item = do_item_get(engine, hash, key, nkey);
    if (item != NULL) {
        item->exptime = exptime;
    }
@@ -943,10 +943,10 @@ hash_item *touch_item(struct default_engine *engine,
                            uint32_t exptime)
 {
     hash_item *ret;
-
-    acquire_key_operation_mutex(engine, key, nkey);
-    ret = do_touch_item(engine, key, nkey, exptime);
-    release_key_operation_mutex(engine, key, nkey);
+    uint32_t hash = engine->server.core->hash(key, nkey, 0);
+    acquire_key_operation_mutex(engine, hash);
+    ret = do_touch_item(engine, hash, key, nkey, exptime);
+    release_key_operation_mutex(engine, hash);
     return ret;
 }
 
@@ -1279,10 +1279,13 @@ ENGINE_ERROR_CODE items_init(struct default_engine 
*engine, uint32_t num_threads
 
     engine->cur_op_recs.num_recs = num_threads;
 
+    for (int i = 0; i < engine->cur_op_recs.num_recs; i++)
+        engine->cur_op_recs.keys[i].hash = -1;
+
     return ENGINE_SUCCESS;
 }
 
-static void acquire_key_operation_mutex(struct default_engine *engine, const 
char *key, size_t nkey)
+static void acquire_key_operation_mutex(struct default_engine *engine, 
uint32_t hash)
 {
     int i;
     int zero_index;
@@ -1295,11 +1298,10 @@ start:
 
     for (i = 0; i < cur_op_recs->num_recs; i++)
     {
-        if (cur_op_recs->keys[i].nkey == 0)
+        if (cur_op_recs->keys[i].hash == -1)
             zero_index = i;
 
-        if (cur_op_recs->keys[i].nkey == nkey &&
-            memcmp(cur_op_recs->keys[i].key, key, nkey) == 0) {
+        if (cur_op_recs->keys[i].hash == hash) {
             pthread_cond_wait(&cur_op_recs->key_wait_cv, &cur_op_recs->lock);
             goto start;
         }
@@ -1308,12 +1310,11 @@ start:
 
     assert(zero_index != cur_op_recs->num_recs);
 
-    cur_op_recs->keys[zero_index].nkey = nkey;
-    memcpy(cur_op_recs->keys[zero_index].key, key, nkey);
+    cur_op_recs->keys[zero_index].hash = hash;
     pthread_mutex_unlock(&cur_op_recs->lock);
 }
 
-static void release_key_operation_mutex(struct default_engine *engine, const 
char *key, size_t nkey)
+static void release_key_operation_mutex(struct default_engine *engine, 
uint32_t hash)
 {
     int i;
     struct cur_op_recs *cur_op_recs = &engine->cur_op_recs;
@@ -1322,10 +1323,9 @@ static void release_key_operation_mutex(struct 
default_engine *engine, const cha
 
     for (i = 0; i < cur_op_recs->num_recs; i++)
     {
-        if (cur_op_recs->keys[i].nkey == nkey &&
-            memcmp(cur_op_recs->keys[i].key, key, nkey) == 0)
+        if (cur_op_recs->keys[i].hash == hash)
         {
-            cur_op_recs->keys[i].nkey = 0;
+            cur_op_recs->keys[i].hash = -1;
             break;
         }
     }
diff --git a/engines/default_engine/items.h b/engines/default_engine/items.h
index 6b02624..4ed6ea9 100644
--- a/engines/default_engine/items.h
+++ b/engines/default_engine/items.h
@@ -22,6 +22,7 @@ typedef struct _hash_item {
                      * implementation. */
     unsigned short refcount;
     uint8_t slabs_clsid;/* which slab class we're in */
+    uint32_t hash;      /* Hash of associated key */
 } hash_item;
 
 typedef struct {
@@ -42,16 +43,13 @@ struct items {
    pthread_mutex_t itemstats_lock;
 };
 
-struct cur_key_rec {
-    char key[KEY_MAX_LENGTH];
-    size_t nkey;
-};
-
 struct cur_op_recs {
     pthread_mutex_t lock;
     pthread_cond_t  key_wait_cv;
     int num_recs;
-    struct cur_key_rec *keys; /* Dynamically allocated at runtime */
+    struct {
+        int64_t hash;
+    } *keys; /* Dynamically allocated at runtime */
 };
 
 /**
-- 
1.7.1

Reply via email to