Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 162 lines (161 sloc) 5.792 kb
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 * Hash table
4 *
5 * The hash function used here is by Bob Jenkins, 1996:
6 * <http://burtleburtle.net/bob/hash/doobs.html>
93c6642 Brad Fitzpatrick whitespace changes only
bradfitz authored
7 * "By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net.
1ea89bd Brad Fitzpatrick remove all trailing whitespace, not just first occurrence. :)
bradfitz authored
8 * You may use this code any way you wish, private, educational,
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
9 * or commercial. It's free."
10 *
11 * The rest of the file is licensed under the BSD license. See LICENSE.
12 *
13 * $Id$
14 */
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/time.h>
18 #include <sys/socket.h>
19 #include <sys/signal.h>
20 #include <sys/resource.h>
21 #include <fcntl.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <netinet/in.h>
27 #include <errno.h>
28 #include <event.h>
18a72ad Brad Fitzpatrick version 1.1.6
bradfitz authored
29 #include <assert.h>
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
30 #include "memcached.h"
31 typedef unsigned long int ub4; /* unsigned 4-byte quantities */
32 typedef unsigned char ub1; /* unsigned 1-byte quantities */
33 /* hard-code one million buckets, for now (2**20 == 4MB hash) */
34 #define HASHPOWER 20
35 #define hashsize(n) ((ub4)1<<(n))
36 #define hashmask(n) (hashsize(n)-1)
37 #define mix(a,b,c) \
38 { \
39 a -= b; a -= c; a ^= (c>>13); \
40 b -= c; b -= a; b ^= (a<<8); \
41 c -= a; c -= b; c ^= (b>>13); \
42 a -= b; a -= c; a ^= (c>>12); \
43 b -= c; b -= a; b ^= (a<<16); \
44 c -= a; c -= b; c ^= (b>>5); \
45 a -= b; a -= c; a ^= (c>>3); \
46 b -= c; b -= a; b ^= (a<<10); \
47 c -= a; c -= b; c ^= (b>>15); \
48 }
49 /*
50 --------------------------------------------------------------------
51 hash() -- hash a variable-length key into a 32-bit value
52 k : the key (the unaligned variable-length array of bytes)
53 len : the length of the key, counting by bytes
54 initval : can be any 4-byte value
55 Returns a 32-bit value. Every bit of the key affects every bit of
56 the return value. Every 1-bit and 2-bit delta achieves avalanche.
57 About 6*len+35 instructions.
58 The best hash table sizes are powers of 2. There is no need to do
59 mod a prime (mod is sooo slow!). If you need less than 32 bits,
60 use a bitmask. For example, if you need only 10 bits, do
61 h = (h & hashmask(10));
62 In which case, the hash table should have hashsize(10) elements.
63 If you are hashing n strings (ub1 **)k, do it like this:
64 for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
65 By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
66 code any way you wish, private, educational, or commercial. It's free.
67 See http://burtleburtle.net/bob/hash/evahash.html
68 Use for hash table lookup, or anything where one collision in 2^^32 is
69 acceptable. Do NOT use for cryptographic purposes.
70 --------------------------------------------------------------------
71 */
72 ub4 hash( k, length, initval)
73 register ub1 *k; /* the key */
74 register ub4 length; /* the length of the key */
75 register ub4 initval; /* the previous hash, or an arbitrary value */
76 {
77 register ub4 a,b,c,len;
78 /* Set up the internal state */
79 len = length;
80 a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
81 c = initval; /* the previous hash value */
82 /*---------------------------------------- handle most of the key */
83 while (len >= 12)
84 {
85 a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
86 b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
87 c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
88 mix(a,b,c);
89 k += 12; len -= 12;
90 }
91 /*------------------------------------- handle the last 11 bytes */
92 c += length;
93 switch(len) /* all the case statements fall through */
94 {
95 case 11: c+=((ub4)k[10]<<24);
96 case 10: c+=((ub4)k[9]<<16);
97 case 9 : c+=((ub4)k[8]<<8);
98 /* the first byte of c is reserved for the length */
99 case 8 : b+=((ub4)k[7]<<24);
100 case 7 : b+=((ub4)k[6]<<16);
101 case 6 : b+=((ub4)k[5]<<8);
102 case 5 : b+=k[4];
103 case 4 : a+=((ub4)k[3]<<24);
104 case 3 : a+=((ub4)k[2]<<16);
105 case 2 : a+=((ub4)k[1]<<8);
106 case 1 : a+=k[0];
107 /* case 0: nothing left to add */
108 }
109 mix(a,b,c);
110 /*-------------------------------------------- report the result */
111 return c;
112 }
f6d334e Brad Fitzpatrick 2003-06-10
bradfitz authored
113 static item** hashtable = 0;
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
114 void assoc_init(void) {
115 unsigned int hash_size = hashsize(HASHPOWER) * sizeof(void*);
116 hashtable = malloc(hash_size);
117 if (! hashtable) {
118 fprintf(stderr, "Failed to init hashtable.\n");
119 exit(1);
120 }
121 memset(hashtable, 0, hash_size);
122 }
123 item *assoc_find(char *key) {
124 ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER);
f6d334e Brad Fitzpatrick 2003-06-10
bradfitz authored
125 item *it = hashtable[hv];
126 while (it) {
127 if (strcmp(key, ITEM_key(it)) == 0)
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
128 return it;
f6d334e Brad Fitzpatrick 2003-06-10
bradfitz authored
129 it = it->h_next;
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
130 }
131 return 0;
132 }
7917af4 Brad Fitzpatrick misc fixes as suggested by avva. lot of comment updates, mostly.
bradfitz authored
133 /* returns the address of the item pointer before the key. if *item == 0,
134 the item wasn't found */
f6d334e Brad Fitzpatrick 2003-06-10
bradfitz authored
135 static item** _hashitem_before (char *key) {
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
136 ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER);
f6d334e Brad Fitzpatrick 2003-06-10
bradfitz authored
137 item **pos = &hashtable[hv];
138 while (*pos && strcmp(key, ITEM_key(*pos))) {
139 pos = &(*pos)->h_next;
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
140 }
141 return pos;
142 }
7917af4 Brad Fitzpatrick misc fixes as suggested by avva. lot of comment updates, mostly.
bradfitz authored
143 /* Note: this isn't an assoc_update. The key must not already exist to call this */
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
144 int assoc_insert(char *key, item *it) {
7917af4 Brad Fitzpatrick misc fixes as suggested by avva. lot of comment updates, mostly.
bradfitz authored
145 ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER);
146 it->h_next = hashtable[hv];
147 hashtable[hv] = it;
f6d334e Brad Fitzpatrick 2003-06-10
bradfitz authored
148 return 1;
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
149 }
150 void assoc_delete(char *key) {
f6d334e Brad Fitzpatrick 2003-06-10
bradfitz authored
151 item **before = _hashitem_before(key);
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
152 if (*before) {
f6d334e Brad Fitzpatrick 2003-06-10
bradfitz authored
153 item *nxt = (*before)->h_next;
154 (*before)->h_next = 0; /* probably pointless, but whatever. */
155 *before = nxt;
156 return;
825db0f Brad Fitzpatrick stop using Judy for string mappings and use a hash table instead, which
bradfitz authored
157 }
1ea89bd Brad Fitzpatrick remove all trailing whitespace, not just first occurrence. :)
bradfitz authored
158 /* Note: we never actually get here. the callers don't delete things
c08383a Brad Fitzpatrick more debug asserts
bradfitz authored
159 they can't find. */
160 assert(*before != 0);
8bdbe4a Brad Fitzpatrick but we do want trailing newline at end of file
bradfitz authored
161 }
Something went wrong with that request. Please try again.