diff options
author | dormando <dormando@rydia.net> | 2018-02-12 15:08:51 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2018-02-12 15:08:51 -0800 |
commit | 5c0face158f1d0f9c6add22b8f027e468bbe5368 (patch) | |
tree | 8cc67d11311601f0640593ada76622d4717feaef | |
parent | 37bfa412de11c4a69e7fca0a88fd2759958647b2 (diff) | |
download | memcached-5c0face158f1d0f9c6add22b8f027e468bbe5368.tar.gz |
remove redundant counter/lock from hash table1.5.5
curr_items tracks how many items are linked in the hash table. internally to
the hash table, hash_items tracked how many items were in the hash table.
on every insert/delete, hash_items had to be locked and checked to see if th
table should be expanded. rip that all out, and call a check with the
once-per-second clock event to check for hash table expansion.
this actually ends up fixing an obscure bug: if you burst a bunch of sets
then stop, the hash table won't attempt to expand a second time until the
next insert. with this change, every second the hash table has a chance of
expanding again.
-rw-r--r-- | assoc.c | 28 | ||||
-rw-r--r-- | assoc.h | 1 | ||||
-rw-r--r-- | memcached.c | 4 | ||||
-rw-r--r-- | trace.h | 4 |
4 files changed, 15 insertions, 22 deletions
@@ -27,7 +27,6 @@ static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t maintenance_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t hash_items_counter_lock = PTHREAD_MUTEX_INITIALIZER; typedef unsigned long int ub4; /* unsigned 4-byte quantities */ typedef unsigned char ub1; /* unsigned 1-byte quantities */ @@ -47,9 +46,6 @@ static item** primary_hashtable = 0; */ static item** old_hashtable = 0; -/* Number of items in the hash table. */ -static unsigned int hash_items = 0; - /* Flag: Are we in the middle of expanding now? */ static bool expanding = false; static bool started_expanding = false; @@ -144,12 +140,15 @@ static void assoc_expand(void) { } } -static void assoc_start_expand(void) { +void assoc_start_expand(uint64_t curr_items) { if (started_expanding) return; - started_expanding = true; - pthread_cond_signal(&maintenance_cond); + if (curr_items > (hashsize(hashpower) * 3) / 2 && + hashpower < HASHPOWER_MAX) { + started_expanding = true; + pthread_cond_signal(&maintenance_cond); + } } /* Note: this isn't an assoc_update. The key must not already exist to call this */ @@ -168,15 +167,7 @@ int assoc_insert(item *it, const uint32_t hv) { primary_hashtable[hv & hashmask(hashpower)] = it; } - pthread_mutex_lock(&hash_items_counter_lock); - hash_items++; - if (! expanding && hash_items > (hashsize(hashpower) * 3) / 2 && - hashpower < HASHPOWER_MAX) { - assoc_start_expand(); - } - pthread_mutex_unlock(&hash_items_counter_lock); - - MEMCACHED_ASSOC_INSERT(ITEM_key(it), it->nkey, hash_items); + MEMCACHED_ASSOC_INSERT(ITEM_key(it), it->nkey); return 1; } @@ -185,13 +176,10 @@ void assoc_delete(const char *key, const size_t nkey, const uint32_t hv) { if (*before) { item *nxt; - pthread_mutex_lock(&hash_items_counter_lock); - hash_items--; - pthread_mutex_unlock(&hash_items_counter_lock); /* The DTrace probe cannot be triggered as the last instruction * due to possible tail-optimization by the compiler */ - MEMCACHED_ASSOC_DELETE(key, nkey, hash_items); + MEMCACHED_ASSOC_DELETE(key, nkey); nxt = (*before)->h_next; (*before)->h_next = 0; /* probably pointless, but whatever. */ *before = nxt; @@ -6,5 +6,6 @@ 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); +void assoc_start_expand(uint64_t curr_items); extern unsigned int hashpower; extern unsigned int item_lock_hashpower; diff --git a/memcached.c b/memcached.c index 595814c..0e60c40 100644 --- a/memcached.c +++ b/memcached.c @@ -6127,6 +6127,10 @@ static void clock_handler(const int fd, const short which, void *arg) { #endif } + // While we're here, check for hash table expansion. + // This function should be quick to avoid delaying the timer. + assoc_start_expand(stats_state.curr_items); + evtimer_set(&clockevent, clock_handler, 0); event_base_set(main_base, &clockevent); evtimer_add(&clockevent, &t); @@ -4,11 +4,11 @@ #ifdef ENABLE_DTRACE #include "memcached_dtrace.h" #else -#define MEMCACHED_ASSOC_DELETE(arg0, arg1, arg2) +#define MEMCACHED_ASSOC_DELETE(arg0, arg1) #define MEMCACHED_ASSOC_DELETE_ENABLED() (0) #define MEMCACHED_ASSOC_FIND(arg0, arg1, arg2) #define MEMCACHED_ASSOC_FIND_ENABLED() (0) -#define MEMCACHED_ASSOC_INSERT(arg0, arg1, arg2) +#define MEMCACHED_ASSOC_INSERT(arg0, arg1) #define MEMCACHED_ASSOC_INSERT_ENABLED() (0) #define MEMCACHED_COMMAND_ADD(arg0, arg1, arg2, arg3, arg4) #define MEMCACHED_COMMAND_ADD_ENABLED() (0) |