Skip to content
Browse files

move hash calls outside of cache_lock

been hard to measure while using the intel hash (since it's very fast), but
should help with the software hash.
  • Loading branch information...
1 parent 45e0e95 commit bab9acd115828e44176a3671bd65089d6fdeff85 @dormando dormando committed Oct 2, 2011
Showing with 69 additions and 58 deletions.
  1. +6 −10 assoc.c
  2. +3 −3 assoc.h
  3. +22 −20 items.c
  4. +6 −6 items.h
  5. +9 −8 memcached.c
  6. +3 −3 memcached.h
  7. +20 −8 thread.c
View
16 assoc.c
@@ -73,8 +73,7 @@ void assoc_init(const int hashtable_init) {
STATS_UNLOCK();
}
-item *assoc_find(const char *key, const size_t nkey) {
- uint32_t hv = hash(key, nkey, 0);
+item *assoc_find(const char *key, const size_t nkey, const uint32_t hv) {
item *it;
unsigned int oldbucket;
@@ -103,8 +102,7 @@ item *assoc_find(const char *key, const size_t nkey) {
/* returns the address of the item pointer before the key. if *item == 0,
the item wasn't found */
-static item** _hashitem_before (const char *key, const size_t nkey) {
- uint32_t hv = hash(key, nkey, 0);
+static item** _hashitem_before (const char *key, const size_t nkey, const uint32_t hv) {
item **pos;
unsigned int oldbucket;
@@ -146,13 +144,11 @@ static void assoc_expand(void) {
}
/* Note: this isn't an assoc_update. The key must not already exist to call this */
-int assoc_insert(item *it) {
- uint32_t hv;
+int assoc_insert(item *it, const uint32_t hv) {
unsigned int oldbucket;
- assert(assoc_find(ITEM_key(it), it->nkey) == 0); /* shouldn't have duplicately named things defined */
+// assert(assoc_find(ITEM_key(it), it->nkey) == 0); /* shouldn't have duplicately named things defined */
- hv = hash(ITEM_key(it), it->nkey, 0);
if (expanding &&
(oldbucket = (hv & hashmask(hashpower - 1))) >= expand_bucket)
{
@@ -172,8 +168,8 @@ int assoc_insert(item *it) {
return 1;
}
-void assoc_delete(const char *key, const size_t nkey) {
- item **before = _hashitem_before(key, nkey);
+void assoc_delete(const char *key, const size_t nkey, const uint32_t hv) {
+ item **before = _hashitem_before(key, nkey, hv);
if (*before) {
item *nxt;
View
6 assoc.h
@@ -1,8 +1,8 @@
/* associative array */
void assoc_init(const int hashpower_init);
-item *assoc_find(const char *key, const size_t nkey);
-int assoc_insert(item *item);
-void assoc_delete(const char *key, const size_t nkey);
+item *assoc_find(const char *key, const size_t nkey, const uint32_t hv);
+int assoc_insert(item *item, const uint32_t hv);
+void assoc_delete(const char *key, const size_t nkey, const uint32_t hv);
void do_assoc_move_next_bucket(void);
int start_assoc_maintenance_thread(void);
void stop_assoc_maintenance_thread(void);
View
42 items.c
@@ -125,7 +125,7 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim
}
it->refcount = 1;
slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it), ntotal);
- do_item_unlink(it);
+ do_item_unlink(it, hash(ITEM_key(it), it->nkey, 0));
/* Initialize the item block: */
it->slabs_clsid = 0;
it->refcount = 0;
@@ -189,7 +189,7 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim
itemstats[id].expired_unfetched++;
}
}
- do_item_unlink(search);
+ do_item_unlink(search, hash(ITEM_key(search), search->nkey, 0));
break;
}
}
@@ -208,7 +208,7 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim
if (search->refcount != 0 && search->time + TAIL_REPAIR_TIME < current_time) {
itemstats[id].tailrepairs++;
search->refcount = 0;
- do_item_unlink(search);
+ do_item_unlink(search, hash(ITEM_key(search), search->nkey, 0));
break;
}
}
@@ -312,12 +312,12 @@ static void item_unlink_q(item *it) {
return;
}
-int do_item_link(item *it) {
+int do_item_link(item *it, const uint32_t hv) {
MEMCACHED_ITEM_LINK(ITEM_key(it), it->nkey, it->nbytes);
assert((it->it_flags & (ITEM_LINKED|ITEM_SLABBED)) == 0);
it->it_flags |= ITEM_LINKED;
it->time = current_time;
- assoc_insert(it);
+ assoc_insert(it, hv);
STATS_LOCK();
stats.curr_bytes += ITEM_ntotal(it);
@@ -333,15 +333,15 @@ int do_item_link(item *it) {
return 1;
}
-void do_item_unlink(item *it) {
+void do_item_unlink(item *it, const uint32_t hv) {
MEMCACHED_ITEM_UNLINK(ITEM_key(it), it->nkey, it->nbytes);
if ((it->it_flags & ITEM_LINKED) != 0) {
it->it_flags &= ~ITEM_LINKED;
STATS_LOCK();
stats.curr_bytes -= ITEM_ntotal(it);
stats.curr_items -= 1;
STATS_UNLOCK();
- assoc_delete(ITEM_key(it), it->nkey);
+ assoc_delete(ITEM_key(it), it->nkey, hv);
item_unlink_q(it);
if (it->refcount == 0) item_free(it);
}
@@ -372,13 +372,13 @@ void do_item_update(item *it) {
}
}
-int do_item_replace(item *it, item *new_it) {
+int do_item_replace(item *it, item *new_it, const uint32_t hv) {
MEMCACHED_ITEM_REPLACE(ITEM_key(it), it->nkey, it->nbytes,
ITEM_key(new_it), new_it->nkey, new_it->nbytes);
assert((it->it_flags & ITEM_SLABBED) == 0);
- do_item_unlink(it);
- return do_item_link(new_it);
+ do_item_unlink(it, hv);
+ return do_item_link(new_it, hv);
}
/*@null@*/
@@ -439,7 +439,8 @@ void do_item_stats(ADD_STAT add_stats, void *c) {
tails[i]->exptime < current_time))) {
--search;
if (tails[i]->refcount == 0) {
- do_item_unlink(tails[i]);
+ do_item_unlink(tails[i], hash(ITEM_key(tails[i]),
+ tails[i]->nkey, 0));
} else {
break;
}
@@ -510,8 +511,8 @@ void do_item_stats_sizes(ADD_STAT add_stats, void *c) {
}
/** wrapper around assoc_find which does the lazy expiration logic */
-item *do_item_get(const char *key, const size_t nkey) {
- item *it = assoc_find(key, nkey);
+item *do_item_get(const char *key, const size_t nkey, const uint32_t hv) {
+ item *it = assoc_find(key, nkey, hv);
int was_found = 0;
if (settings.verbose > 2) {
@@ -525,7 +526,7 @@ item *do_item_get(const char *key, const size_t nkey) {
if (it != NULL && settings.oldest_live != 0 && settings.oldest_live <= current_time &&
it->time <= settings.oldest_live) {
- do_item_unlink(it); /* MTSAFE - cache_lock held */
+ do_item_unlink(it, hv); /* MTSAFE - cache_lock held */
it = NULL;
}
@@ -535,7 +536,7 @@ item *do_item_get(const char *key, const size_t nkey) {
}
if (it != NULL && it->exptime != 0 && it->exptime <= current_time) {
- do_item_unlink(it); /* MTSAFE - cache_lock held */
+ do_item_unlink(it, hv); /* MTSAFE - cache_lock held */
it = NULL;
}
@@ -556,17 +557,18 @@ item *do_item_get(const char *key, const size_t nkey) {
return it;
}
-item *do_item_touch(const char *key, size_t nkey, uint32_t exptime) {
- item *it = do_item_get(key, nkey);
+item *do_item_touch(const char *key, size_t nkey, uint32_t exptime,
+ const uint32_t hv) {
+ item *it = do_item_get(key, nkey, hv);
if (it != NULL) {
it->exptime = exptime;
}
return it;
}
/** returns an item whether or not it's expired. */
-item *do_item_get_nocheck(const char *key, const size_t nkey) {
- item *it = assoc_find(key, nkey);
+item *do_item_get_nocheck(const char *key, const size_t nkey, const uint32_t hv) {
+ item *it = assoc_find(key, nkey, hv);
if (it) {
it->refcount++;
DEBUG_REFCNT(it, '+');
@@ -590,7 +592,7 @@ void do_item_flush_expired(void) {
if (iter->time >= settings.oldest_live) {
next = iter->next;
if ((iter->it_flags & ITEM_SLABBED) == 0) {
- do_item_unlink(iter);
+ do_item_unlink(iter, hash(ITEM_key(iter), iter->nkey, 0));
}
} else {
/* We've hit the first old item. Continue to the next queue. */
View
12 items.h
@@ -6,11 +6,11 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim
void item_free(item *it);
bool item_size_ok(const size_t nkey, const int flags, const int nbytes);
-int do_item_link(item *it); /** may fail if transgresses limits */
-void do_item_unlink(item *it);
+int do_item_link(item *it, const uint32_t hv); /** may fail if transgresses limits */
+void do_item_unlink(item *it, const uint32_t hv);
void do_item_remove(item *it);
void do_item_update(item *it); /** update LRU time to current and reposition */
-int do_item_replace(item *it, item *new_it);
+int do_item_replace(item *it, item *new_it, const uint32_t hv);
/*@null@*/
char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes);
@@ -19,8 +19,8 @@ void do_item_stats(ADD_STAT add_stats, void *c);
void do_item_stats_sizes(ADD_STAT add_stats, void *c);
void do_item_flush_expired(void);
-item *do_item_get(const char *key, const size_t nkey);
-item *do_item_get_nocheck(const char *key, const size_t nkey);
-item *do_item_touch(const char *key, const size_t nkey, uint32_t exptime);
+item *do_item_get(const char *key, const size_t nkey, const uint32_t hv);
+item *do_item_get_nocheck(const char *key, const size_t nkey, const uint32_t hv);
+item *do_item_touch(const char *key, const size_t nkey, uint32_t exptime, const uint32_t hv);
void item_stats_reset(void);
extern pthread_mutex_t cache_lock;
View
17 memcached.c
@@ -2242,9 +2242,9 @@ static void complete_nread(conn *c) {
*
* Returns the state of storage.
*/
-enum store_item_type do_store_item(item *it, int comm, conn *c) {
+enum store_item_type do_store_item(item *it, int comm, conn *c, const uint32_t hv) {
char *key = ITEM_key(it);
- item *old_it = do_item_get(key, it->nkey);
+ item *old_it = do_item_get(key, it->nkey, hv);
enum store_item_type stored = NOT_STORED;
item *new_it = NULL;
@@ -2274,7 +2274,7 @@ enum store_item_type do_store_item(item *it, int comm, conn *c) {
c->thread->stats.slab_stats[old_it->slabs_clsid].cas_hits++;
pthread_mutex_unlock(&c->thread->stats.mutex);
- item_replace(old_it, it);
+ item_replace(old_it, it, hv);
stored = STORED;
} else {
pthread_mutex_lock(&c->thread->stats.mutex);
@@ -2337,9 +2337,9 @@ enum store_item_type do_store_item(item *it, int comm, conn *c) {
if (stored == NOT_STORED) {
if (old_it != NULL)
- item_replace(old_it, it);
+ item_replace(old_it, it, hv);
else
- do_item_link(it);
+ do_item_link(it, hv);
c->cas = ITEM_get_cas(it);
@@ -3032,13 +3032,14 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt
*/
enum delta_result_type do_add_delta(conn *c, const char *key, const size_t nkey,
const bool incr, const int64_t delta,
- char *buf, uint64_t *cas) {
+ char *buf, uint64_t *cas,
+ const uint32_t hv) {
char *ptr;
uint64_t value;
int res;
item *it;
- it = do_item_get(key, nkey);
+ it = do_item_get(key, nkey, hv);
if (!it) {
return DELTA_ITEM_NOT_FOUND;
}
@@ -3086,7 +3087,7 @@ enum delta_result_type do_add_delta(conn *c, const char *key, const size_t nkey,
}
memcpy(ITEM_data(new_it), buf, res);
memcpy(ITEM_data(new_it) + res, "\r\n", 2);
- item_replace(it, new_it);
+ item_replace(it, new_it, hv);
// Overwrite the older item's CAS with our new CAS since we're
// returning the CAS of the old item below.
ITEM_set_cas(it, (settings.use_cas) ? ITEM_get_cas(new_it) : 0);
View
6 memcached.h
@@ -459,8 +459,8 @@ void do_accept_new_conns(const bool do_accept);
enum delta_result_type do_add_delta(conn *c, const char *key,
const size_t nkey, const bool incr,
const int64_t delta, char *buf,
- uint64_t *cas);
-enum store_item_type do_store_item(item *item, int comm, conn* c);
+ uint64_t *cas, const uint32_t hv);
+enum store_item_type do_store_item(item *item, int comm, conn* c, const uint32_t hv);
conn *conn_new(const int sfd, const enum conn_states init_state, const int event_flags, const int read_buffer_size, enum network_transport transport, struct event_base *base);
extern int daemonize(int nochdir, int noclose);
@@ -507,7 +507,7 @@ item *item_get(const char *key, const size_t nkey);
item *item_touch(const char *key, const size_t nkey, uint32_t exptime);
int item_link(item *it);
void item_remove(item *it);
-int item_replace(item *it, item *new_it);
+int item_replace(item *it, item *new_it, const uint32_t hv);
void item_stats(ADD_STAT add_stats, void *c);
void item_stats_sizes(ADD_STAT add_stats, void *c);
void item_unlink(item *it);
View
28 thread.c
@@ -340,16 +340,20 @@ item *item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbyt
*/
item *item_get(const char *key, const size_t nkey) {
item *it;
+ uint32_t hv;
+ hv = hash(key, nkey, 0);
mutex_lock(&cache_lock);
- it = do_item_get(key, nkey);
+ it = do_item_get(key, nkey, hv);
pthread_mutex_unlock(&cache_lock);
return it;
}
item *item_touch(const char *key, size_t nkey, uint32_t exptime) {
item *it;
+ uint32_t hv;
+ hv = hash(key, nkey, 0);
mutex_lock(&cache_lock);
- it = do_item_touch(key, nkey, exptime);
+ it = do_item_touch(key, nkey, exptime, hv);
pthread_mutex_unlock(&cache_lock);
return it;
}
@@ -359,9 +363,11 @@ item *item_touch(const char *key, size_t nkey, uint32_t exptime) {
*/
int item_link(item *item) {
int ret;
+ uint32_t hv;
+ hv = hash(ITEM_key(item), item->nkey, 0);
mutex_lock(&cache_lock);
- ret = do_item_link(item);
+ ret = do_item_link(item, hv);
pthread_mutex_unlock(&cache_lock);
return ret;
}
@@ -381,16 +387,18 @@ void item_remove(item *item) {
* Unprotected by a mutex lock since the core server does not require
* it to be thread-safe.
*/
-int item_replace(item *old_it, item *new_it) {
- return do_item_replace(old_it, new_it);
+int item_replace(item *old_it, item *new_it, const uint32_t hv) {
+ return do_item_replace(old_it, new_it, hv);
}
/*
* Unlinks an item from the LRU and hashtable.
*/
void item_unlink(item *item) {
+ uint32_t hv;
+ hv = hash(ITEM_key(item), item->nkey, 0);
mutex_lock(&cache_lock);
- do_item_unlink(item);
+ do_item_unlink(item, hv);
pthread_mutex_unlock(&cache_lock);
}
@@ -411,9 +419,11 @@ enum delta_result_type add_delta(conn *c, const char *key,
const int64_t delta, char *buf,
uint64_t *cas) {
enum delta_result_type ret;
+ uint32_t hv;
+ hv = hash(key, nkey, 0);
mutex_lock(&cache_lock);
- ret = do_add_delta(c, key, nkey, incr, delta, buf, cas);
+ ret = do_add_delta(c, key, nkey, incr, delta, buf, cas, hv);
pthread_mutex_unlock(&cache_lock);
return ret;
}
@@ -423,9 +433,11 @@ enum delta_result_type add_delta(conn *c, const char *key,
*/
enum store_item_type store_item(item *item, int comm, conn* c) {
enum store_item_type ret;
+ uint32_t hv;
+ hv = hash(ITEM_key(item), item->nkey, 0);
mutex_lock(&cache_lock);
- ret = do_store_item(item, comm, c);
+ ret = do_store_item(item, comm, c, hv);
pthread_mutex_unlock(&cache_lock);
return ret;
}

0 comments on commit bab9acd

Please sign in to comment.
Something went wrong with that request. Please try again.