From 86969ea43d6718411cc3653faeb0c49090a1c4cf Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 4 Sep 2006 04:08:03 +0000 Subject: restore blank lines I over-zealously destroyed earlier. git-svn-id: http://code.sixapart.com/svn/memcached/trunk/server@335 b0b603af-a30f-0410-a34e-baf09ae79d0b --- assoc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'assoc.c') diff --git a/assoc.c b/assoc.c index 4476d2c..c3ca035 100644 --- a/assoc.c +++ b/assoc.c @@ -27,13 +27,18 @@ #include #include #include + #include "memcached.h" + typedef unsigned long int ub4; /* unsigned 4-byte quantities */ typedef unsigned char ub1; /* unsigned 1-byte quantities */ + /* hard-code one million buckets, for now (2**20 == 4MB hash) */ #define HASHPOWER 20 + #define hashsize(n) ((ub4)1<<(n)) #define hashmask(n) (hashsize(n)-1) + #define mix(a,b,c) \ { \ a -= b; a -= c; a ^= (c>>13); \ @@ -46,6 +51,7 @@ typedef unsigned char ub1; /* unsigned 1-byte quantities */ b -= c; b -= a; b ^= (a<<10); \ c -= a; c -= b; c ^= (b>>15); \ } + /* -------------------------------------------------------------------- hash() -- hash a variable-length key into a 32-bit value @@ -55,30 +61,37 @@ hash() -- hash a variable-length key into a 32-bit value Returns a 32-bit value. Every bit of the key affects every bit of the return value. Every 1-bit and 2-bit delta achieves avalanche. About 6*len+35 instructions. + The best hash table sizes are powers of 2. There is no need to do mod a prime (mod is sooo slow!). If you need less than 32 bits, use a bitmask. For example, if you need only 10 bits, do h = (h & hashmask(10)); In which case, the hash table should have hashsize(10) elements. + If you are hashing n strings (ub1 **)k, do it like this: for (i=0, h=0; i= 12) { @@ -88,6 +101,7 @@ ub4 hash( k, length, initval) mix(a,b,c); k += 12; len -= 12; } + /*------------------------------------- handle the last 11 bytes */ c += length; switch(len) /* all the case statements fall through */ @@ -110,7 +124,9 @@ ub4 hash( k, length, initval) /*-------------------------------------------- report the result */ return c; } + static item** hashtable = 0; + void assoc_init(void) { unsigned int hash_size = hashsize(HASHPOWER) * sizeof(void*); hashtable = malloc(hash_size); @@ -120,9 +136,11 @@ void assoc_init(void) { } memset(hashtable, 0, hash_size); } + item *assoc_find(char *key) { ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER); item *it = hashtable[hv]; + while (it) { if (strcmp(key, ITEM_key(it)) == 0) return it; @@ -130,16 +148,20 @@ item *assoc_find(char *key) { } return 0; } + /* returns the address of the item pointer before the key. if *item == 0, the item wasn't found */ + static item** _hashitem_before (char *key) { ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER); item **pos = &hashtable[hv]; + while (*pos && strcmp(key, ITEM_key(*pos))) { pos = &(*pos)->h_next; } return pos; } + /* Note: this isn't an assoc_update. The key must not already exist to call this */ int assoc_insert(char *key, item *it) { ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER); @@ -147,6 +169,7 @@ int assoc_insert(char *key, item *it) { hashtable[hv] = it; return 1; } + void assoc_delete(char *key) { item **before = _hashitem_before(key); if (*before) { -- cgit v1.2.1