1
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
5
* The hash function used here is by Bob Jenkins, 1996:
6
* <http://burtleburtle.net/bob/hash/doobs.html>
7
* "By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net.
8
* You may use this code any way you wish, private, educational,
9
* or commercial. It's free."
11
* The rest of the file is licensed under the BSD license. See LICENSE.
13
* $Id: assoc.c,v 1.6 2003/08/11 05:44:26 bradfitz Exp $
16
#include <sys/types.h>
19
#include <sys/socket.h>
20
#include <sys/signal.h>
21
#include <sys/resource.h>
27
#include <netinet/in.h>
32
#include "memcached.h"
34
typedef unsigned long int ub4; /* unsigned 4-byte quantities */
35
typedef unsigned char ub1; /* unsigned 1-byte quantities */
37
/* hard-code one million buckets, for now (2**20 == 4MB hash) */
40
#define hashsize(n) ((ub4)1<<(n))
41
#define hashmask(n) (hashsize(n)-1)
45
a -= b; a -= c; a ^= (c>>13); \
46
b -= c; b -= a; b ^= (a<<8); \
47
c -= a; c -= b; c ^= (b>>13); \
48
a -= b; a -= c; a ^= (c>>12); \
49
b -= c; b -= a; b ^= (a<<16); \
50
c -= a; c -= b; c ^= (b>>5); \
51
a -= b; a -= c; a ^= (c>>3); \
52
b -= c; b -= a; b ^= (a<<10); \
53
c -= a; c -= b; c ^= (b>>15); \
57
--------------------------------------------------------------------
58
hash() -- hash a variable-length key into a 32-bit value
59
k : the key (the unaligned variable-length array of bytes)
60
len : the length of the key, counting by bytes
61
initval : can be any 4-byte value
62
Returns a 32-bit value. Every bit of the key affects every bit of
63
the return value. Every 1-bit and 2-bit delta achieves avalanche.
64
About 6*len+35 instructions.
66
The best hash table sizes are powers of 2. There is no need to do
67
mod a prime (mod is sooo slow!). If you need less than 32 bits,
68
use a bitmask. For example, if you need only 10 bits, do
69
h = (h & hashmask(10));
70
In which case, the hash table should have hashsize(10) elements.
72
If you are hashing n strings (ub1 **)k, do it like this:
73
for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
75
By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
76
code any way you wish, private, educational, or commercial. It's free.
78
See http://burtleburtle.net/bob/hash/evahash.html
79
Use for hash table lookup, or anything where one collision in 2^^32 is
80
acceptable. Do NOT use for cryptographic purposes.
81
--------------------------------------------------------------------
84
ub4 hash( k, length, initval)
85
register ub1 *k; /* the key */
86
register ub4 length; /* the length of the key */
87
register ub4 initval; /* the previous hash, or an arbitrary value */
89
register ub4 a,b,c,len;
91
/* Set up the internal state */
93
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
94
c = initval; /* the previous hash value */
96
/*---------------------------------------- handle most of the key */
99
a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
100
b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
101
c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
106
/*------------------------------------- handle the last 11 bytes */
108
switch(len) /* all the case statements fall through */
110
case 11: c+=((ub4)k[10]<<24);
111
case 10: c+=((ub4)k[9]<<16);
112
case 9 : c+=((ub4)k[8]<<8);
113
/* the first byte of c is reserved for the length */
114
case 8 : b+=((ub4)k[7]<<24);
115
case 7 : b+=((ub4)k[6]<<16);
116
case 6 : b+=((ub4)k[5]<<8);
118
case 4 : a+=((ub4)k[3]<<24);
119
case 3 : a+=((ub4)k[2]<<16);
120
case 2 : a+=((ub4)k[1]<<8);
122
/* case 0: nothing left to add */
125
/*-------------------------------------------- report the result */
129
static item** hashtable = 0;
131
void assoc_init(void) {
132
unsigned int hash_size = hashsize(HASHPOWER) * sizeof(void*);
133
hashtable = malloc(hash_size);
135
fprintf(stderr, "Failed to init hashtable.\n");
138
memset(hashtable, 0, hash_size);
141
item *assoc_find(char *key) {
142
ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER);
143
item *it = hashtable[hv];
146
if (strcmp(key, ITEM_key(it)) == 0)
153
/* returns the address of the item pointer before the key. if *item == 0,
154
the item wasn't found */
156
static item** _hashitem_before (char *key) {
157
ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER);
158
item **pos = &hashtable[hv];
160
while (*pos && strcmp(key, ITEM_key(*pos))) {
161
pos = &(*pos)->h_next;
166
/* Note: this isn't an assoc_update. The key must not already exist to call this */
167
int assoc_insert(char *key, item *it) {
168
ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER);
169
it->h_next = hashtable[hv];
174
void assoc_delete(char *key) {
175
item **before = _hashitem_before(key);
177
item *nxt = (*before)->h_next;
178
(*before)->h_next = 0; /* probably pointless, but whatever. */
182
/* Note: we never actually get here. the callers don't delete things
184
assert(*before != 0);