annotate assoc.c @ 3:0b6ac95a09bb default tip

Fix unix sockets support under FreeBSD.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 03 Oct 2007 05:34:42 +0400
parents 30782bb1fc04
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
2 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
3 * Hash table
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
4 *
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
5 * The hash function used here is by Bob Jenkins, 1996:
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
6 * <http://burtleburtle.net/bob/hash/doobs.html>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
7 * "By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
8 * You may use this code any way you wish, private, educational,
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
9 * or commercial. It's free."
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
10 *
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
11 * The rest of the file is licensed under the BSD license. See LICENSE.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
12 *
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
13 * $Id: assoc.c 551 2007-05-07 21:24:31Z plindner $
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
14 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
15
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
16 #include "memcached.h"
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
17 #include <sys/stat.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
18 #include <sys/socket.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
19 #include <sys/signal.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
20 #include <sys/resource.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
21 #include <fcntl.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
22 #include <netinet/in.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
23 #include <errno.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
24 #include <stdlib.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
25 #include <stdio.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
26 #include <string.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
27 #include <assert.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
28
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
29 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
30 * Since the hash function does bit manipulation, it needs to know
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
31 * whether it's big or little-endian. ENDIAN_LITTLE and ENDIAN_BIG
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
32 * are set in the configure script.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
33 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
34 #if ENDIAN_BIG == 1
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
35 # define HASH_LITTLE_ENDIAN 0
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
36 # define HASH_BIG_ENDIAN 1
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
37 #else
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
38 # if ENDIAN_LITTLE == 1
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
39 # define HASH_LITTLE_ENDIAN 1
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
40 # define HASH_BIG_ENDIAN 0
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
41 # else
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
42 # define HASH_LITTLE_ENDIAN 0
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
43 # define HASH_BIG_ENDIAN 0
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
44 # endif
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
45 #endif
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
46
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
47 #define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k))))
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
48
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
49 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
50 -------------------------------------------------------------------------------
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
51 mix -- mix 3 32-bit values reversibly.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
52
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
53 This is reversible, so any information in (a,b,c) before mix() is
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
54 still in (a,b,c) after mix().
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
55
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
56 If four pairs of (a,b,c) inputs are run through mix(), or through
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
57 mix() in reverse, there are at least 32 bits of the output that
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
58 are sometimes the same for one pair and different for another pair.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
59 This was tested for:
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
60 * pairs that differed by one bit, by two bits, in any combination
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
61 of top bits of (a,b,c), or in any combination of bottom bits of
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
62 (a,b,c).
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
63 * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
64 the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
65 is commonly produced by subtraction) look like a single 1-bit
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
66 difference.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
67 * the base values were pseudorandom, all zero but one bit set, or
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
68 all zero plus a counter that starts at zero.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
69
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
70 Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
71 satisfy this are
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
72 4 6 8 16 19 4
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
73 9 15 3 18 27 15
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
74 14 9 3 7 17 3
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
75 Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
76 for "differ" defined as + with a one-bit base and a two-bit delta. I
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
77 used http://burtleburtle.net/bob/hash/avalanche.html to choose
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
78 the operations, constants, and arrangements of the variables.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
79
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
80 This does not achieve avalanche. There are input bits of (a,b,c)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
81 that fail to affect some output bits of (a,b,c), especially of a. The
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
82 most thoroughly mixed value is c, but it doesn't really even achieve
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
83 avalanche in c.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
84
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
85 This allows some parallelism. Read-after-writes are good at doubling
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
86 the number of bits affected, so the goal of mixing pulls in the opposite
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
87 direction as the goal of parallelism. I did what I could. Rotates
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
88 seem to cost as much as shifts on every machine I could lay my hands
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
89 on, and rotates are much kinder to the top and bottom bits, so I used
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
90 rotates.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
91 -------------------------------------------------------------------------------
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
92 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
93 #define mix(a,b,c) \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
94 { \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
95 a -= c; a ^= rot(c, 4); c += b; \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
96 b -= a; b ^= rot(a, 6); a += c; \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
97 c -= b; c ^= rot(b, 8); b += a; \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
98 a -= c; a ^= rot(c,16); c += b; \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
99 b -= a; b ^= rot(a,19); a += c; \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
100 c -= b; c ^= rot(b, 4); b += a; \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
101 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
102
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
103 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
104 -------------------------------------------------------------------------------
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
105 final -- final mixing of 3 32-bit values (a,b,c) into c
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
106
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
107 Pairs of (a,b,c) values differing in only a few bits will usually
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
108 produce values of c that look totally different. This was tested for
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
109 * pairs that differed by one bit, by two bits, in any combination
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
110 of top bits of (a,b,c), or in any combination of bottom bits of
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
111 (a,b,c).
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
112 * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
113 the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
114 is commonly produced by subtraction) look like a single 1-bit
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
115 difference.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
116 * the base values were pseudorandom, all zero but one bit set, or
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
117 all zero plus a counter that starts at zero.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
118
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
119 These constants passed:
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
120 14 11 25 16 4 14 24
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
121 12 14 25 16 4 14 24
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
122 and these came close:
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
123 4 8 15 26 3 22 24
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
124 10 8 15 26 3 22 24
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
125 11 8 15 26 3 22 24
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
126 -------------------------------------------------------------------------------
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
127 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
128 #define final(a,b,c) \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
129 { \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
130 c ^= b; c -= rot(b,14); \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
131 a ^= c; a -= rot(c,11); \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
132 b ^= a; b -= rot(a,25); \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
133 c ^= b; c -= rot(b,16); \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
134 a ^= c; a -= rot(c,4); \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
135 b ^= a; b -= rot(a,14); \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
136 c ^= b; c -= rot(b,24); \
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
137 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
138
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
139 #if HASH_LITTLE_ENDIAN == 1
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
140 uint32_t hash(
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
141 const void *key, /* the key to hash */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
142 size_t length, /* length of the key */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
143 const uint32_t initval) /* initval */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
144 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
145 uint32_t a,b,c; /* internal state */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
146 union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
147
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
148 /* Set up the internal state */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
149 a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
150
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
151 u.ptr = key;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
152 if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
153 const uint32_t *k = key; /* read 32-bit chunks */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
154 #ifdef VALGRIND
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
155 const uint8_t *k8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
156 #endif // ifdef VALGRIND
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
157
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
158 /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
159 while (length > 12)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
160 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
161 a += k[0];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
162 b += k[1];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
163 c += k[2];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
164 mix(a,b,c);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
165 length -= 12;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
166 k += 3;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
167 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
168
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
169 /*----------------------------- handle the last (probably partial) block */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
170 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
171 * "k[2]&0xffffff" actually reads beyond the end of the string, but
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
172 * then masks off the part it's not allowed to read. Because the
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
173 * string is aligned, the masked-off tail is in the same word as the
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
174 * rest of the string. Every machine with memory protection I've seen
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
175 * does it on word boundaries, so is OK with this. But VALGRIND will
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
176 * still catch it and complain. The masking trick does make the hash
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
177 * noticably faster for short strings (like English words).
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
178 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
179 #ifndef VALGRIND
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
180
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
181 switch(length)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
182 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
183 case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
184 case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
185 case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
186 case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
187 case 8 : b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
188 case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
189 case 6 : b+=k[1]&0xffff; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
190 case 5 : b+=k[1]&0xff; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
191 case 4 : a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
192 case 3 : a+=k[0]&0xffffff; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
193 case 2 : a+=k[0]&0xffff; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
194 case 1 : a+=k[0]&0xff; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
195 case 0 : return c; /* zero length strings require no mixing */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
196 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
197
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
198 #else /* make valgrind happy */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
199
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
200 k8 = (const uint8_t *)k;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
201 switch(length)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
202 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
203 case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
204 case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
205 case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
206 case 9 : c+=k8[8]; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
207 case 8 : b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
208 case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
209 case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
210 case 5 : b+=k8[4]; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
211 case 4 : a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
212 case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
213 case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
214 case 1 : a+=k8[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
215 case 0 : return c; /* zero length strings require no mixing */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
216 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
217
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
218 #endif /* !valgrind */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
219
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
220 } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
221 const uint16_t *k = key; /* read 16-bit chunks */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
222 const uint8_t *k8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
223
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
224 /*--------------- all but last block: aligned reads and different mixing */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
225 while (length > 12)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
226 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
227 a += k[0] + (((uint32_t)k[1])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
228 b += k[2] + (((uint32_t)k[3])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
229 c += k[4] + (((uint32_t)k[5])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
230 mix(a,b,c);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
231 length -= 12;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
232 k += 6;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
233 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
234
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
235 /*----------------------------- handle the last (probably partial) block */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
236 k8 = (const uint8_t *)k;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
237 switch(length)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
238 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
239 case 12: c+=k[4]+(((uint32_t)k[5])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
240 b+=k[2]+(((uint32_t)k[3])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
241 a+=k[0]+(((uint32_t)k[1])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
242 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
243 case 11: c+=((uint32_t)k8[10])<<16; /* @fallthrough */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
244 case 10: c+=k[4]; /* @fallthrough@ */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
245 b+=k[2]+(((uint32_t)k[3])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
246 a+=k[0]+(((uint32_t)k[1])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
247 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
248 case 9 : c+=k8[8]; /* @fallthrough */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
249 case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
250 a+=k[0]+(((uint32_t)k[1])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
251 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
252 case 7 : b+=((uint32_t)k8[6])<<16; /* @fallthrough */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
253 case 6 : b+=k[2];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
254 a+=k[0]+(((uint32_t)k[1])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
255 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
256 case 5 : b+=k8[4]; /* @fallthrough */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
257 case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
258 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
259 case 3 : a+=((uint32_t)k8[2])<<16; /* @fallthrough */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
260 case 2 : a+=k[0];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
261 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
262 case 1 : a+=k8[0];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
263 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
264 case 0 : return c; /* zero length strings require no mixing */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
265 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
266
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
267 } else { /* need to read the key one byte at a time */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
268 const uint8_t *k = key;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
269
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
270 /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
271 while (length > 12)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
272 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
273 a += k[0];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
274 a += ((uint32_t)k[1])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
275 a += ((uint32_t)k[2])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
276 a += ((uint32_t)k[3])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
277 b += k[4];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
278 b += ((uint32_t)k[5])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
279 b += ((uint32_t)k[6])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
280 b += ((uint32_t)k[7])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
281 c += k[8];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
282 c += ((uint32_t)k[9])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
283 c += ((uint32_t)k[10])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
284 c += ((uint32_t)k[11])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
285 mix(a,b,c);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
286 length -= 12;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
287 k += 12;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
288 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
289
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
290 /*-------------------------------- last block: affect all 32 bits of (c) */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
291 switch(length) /* all the case statements fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
292 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
293 case 12: c+=((uint32_t)k[11])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
294 case 11: c+=((uint32_t)k[10])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
295 case 10: c+=((uint32_t)k[9])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
296 case 9 : c+=k[8];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
297 case 8 : b+=((uint32_t)k[7])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
298 case 7 : b+=((uint32_t)k[6])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
299 case 6 : b+=((uint32_t)k[5])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
300 case 5 : b+=k[4];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
301 case 4 : a+=((uint32_t)k[3])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
302 case 3 : a+=((uint32_t)k[2])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
303 case 2 : a+=((uint32_t)k[1])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
304 case 1 : a+=k[0];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
305 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
306 case 0 : return c; /* zero length strings require no mixing */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
307 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
308 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
309
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
310 final(a,b,c);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
311 return c; /* zero length strings require no mixing */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
312 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
313
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
314 #elif HASH_BIG_ENDIAN == 1
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
315 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
316 * hashbig():
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
317 * This is the same as hashword() on big-endian machines. It is different
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
318 * from hashlittle() on all machines. hashbig() takes advantage of
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
319 * big-endian byte ordering.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
320 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
321 uint32_t hash( const void *key, size_t length, const uint32_t initval)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
322 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
323 uint32_t a,b,c;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
324 union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
325
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
326 /* Set up the internal state */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
327 a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
328
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
329 u.ptr = key;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
330 if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
331 const uint32_t *k = key; /* read 32-bit chunks */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
332 #ifdef VALGRIND
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
333 const uint8_t *k8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
334 #endif // ifdef VALGRIND
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
335
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
336 /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
337 while (length > 12)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
338 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
339 a += k[0];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
340 b += k[1];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
341 c += k[2];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
342 mix(a,b,c);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
343 length -= 12;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
344 k += 3;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
345 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
346
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
347 /*----------------------------- handle the last (probably partial) block */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
348 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
349 * "k[2]<<8" actually reads beyond the end of the string, but
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
350 * then shifts out the part it's not allowed to read. Because the
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
351 * string is aligned, the illegal read is in the same word as the
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
352 * rest of the string. Every machine with memory protection I've seen
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
353 * does it on word boundaries, so is OK with this. But VALGRIND will
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
354 * still catch it and complain. The masking trick does make the hash
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
355 * noticably faster for short strings (like English words).
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
356 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
357 #ifndef VALGRIND
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
358
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
359 switch(length)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
360 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
361 case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
362 case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
363 case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
364 case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
365 case 8 : b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
366 case 7 : b+=k[1]&0xffffff00; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
367 case 6 : b+=k[1]&0xffff0000; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
368 case 5 : b+=k[1]&0xff000000; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
369 case 4 : a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
370 case 3 : a+=k[0]&0xffffff00; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
371 case 2 : a+=k[0]&0xffff0000; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
372 case 1 : a+=k[0]&0xff000000; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
373 case 0 : return c; /* zero length strings require no mixing */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
374 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
375
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
376 #else /* make valgrind happy */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
377
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
378 k8 = (const uint8_t *)k;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
379 switch(length) /* all the case statements fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
380 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
381 case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
382 case 11: c+=((uint32_t)k8[10])<<8; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
383 case 10: c+=((uint32_t)k8[9])<<16; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
384 case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
385 case 8 : b+=k[1]; a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
386 case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
387 case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
388 case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
389 case 4 : a+=k[0]; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
390 case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
391 case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
392 case 1 : a+=((uint32_t)k8[0])<<24; break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
393 case 0 : return c;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
394 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
395
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
396 #endif /* !VALGRIND */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
397
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
398 } else { /* need to read the key one byte at a time */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
399 const uint8_t *k = key;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
400
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
401 /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
402 while (length > 12)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
403 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
404 a += ((uint32_t)k[0])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
405 a += ((uint32_t)k[1])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
406 a += ((uint32_t)k[2])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
407 a += ((uint32_t)k[3]);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
408 b += ((uint32_t)k[4])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
409 b += ((uint32_t)k[5])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
410 b += ((uint32_t)k[6])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
411 b += ((uint32_t)k[7]);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
412 c += ((uint32_t)k[8])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
413 c += ((uint32_t)k[9])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
414 c += ((uint32_t)k[10])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
415 c += ((uint32_t)k[11]);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
416 mix(a,b,c);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
417 length -= 12;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
418 k += 12;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
419 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
420
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
421 /*-------------------------------- last block: affect all 32 bits of (c) */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
422 switch(length) /* all the case statements fall through */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
423 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
424 case 12: c+=k[11];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
425 case 11: c+=((uint32_t)k[10])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
426 case 10: c+=((uint32_t)k[9])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
427 case 9 : c+=((uint32_t)k[8])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
428 case 8 : b+=k[7];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
429 case 7 : b+=((uint32_t)k[6])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
430 case 6 : b+=((uint32_t)k[5])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
431 case 5 : b+=((uint32_t)k[4])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
432 case 4 : a+=k[3];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
433 case 3 : a+=((uint32_t)k[2])<<8;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
434 case 2 : a+=((uint32_t)k[1])<<16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
435 case 1 : a+=((uint32_t)k[0])<<24;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
436 break;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
437 case 0 : return c;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
438 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
439 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
440
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
441 final(a,b,c);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
442 return c;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
443 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
444 #else // HASH_XXX_ENDIAN == 1
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
445 #error Must define HASH_BIG_ENDIAN or HASH_LITTLE_ENDIAN
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
446 #endif // hash_XXX_ENDIAN == 1
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
447
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
448 typedef unsigned long int ub4; /* unsigned 4-byte quantities */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
449 typedef unsigned char ub1; /* unsigned 1-byte quantities */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
450
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
451 /* how many powers of 2's worth of buckets we use */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
452 static int hashpower = 16;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
453
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
454 #define hashsize(n) ((ub4)1<<(n))
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
455 #define hashmask(n) (hashsize(n)-1)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
456
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
457 /* Main hash table. This is where we look except during expansion. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
458 static item** primary_hashtable = 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
459
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
460 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
461 * Previous hash table. During expansion, we look here for keys that haven't
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
462 * been moved over to the primary yet.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
463 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
464 static item** old_hashtable = 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
465
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
466 /* Number of items in the hash table. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
467 static int hash_items = 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
468
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
469 /* Flag: Are we in the middle of expanding now? */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
470 static int expanding = 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
471
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
472 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
473 * During expansion we migrate values with bucket granularity; this is how
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
474 * far we've gotten so far. Ranges from 0 .. hashsize(hashpower - 1) - 1.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
475 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
476 static int expand_bucket = 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
477
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
478 void assoc_init(void) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
479 unsigned int hash_size = hashsize(hashpower) * sizeof(void*);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
480 primary_hashtable = malloc(hash_size);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
481 if (! primary_hashtable) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
482 fprintf(stderr, "Failed to init hashtable.\n");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
483 exit(EXIT_FAILURE);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
484 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
485 memset(primary_hashtable, 0, hash_size);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
486 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
487
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
488 item *assoc_find(const char *key, const size_t nkey) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
489 uint32_t hv = hash(key, nkey, 0);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
490 item *it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
491 int oldbucket;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
492
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
493 if (expanding &&
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
494 (oldbucket = (hv & hashmask(hashpower - 1))) >= expand_bucket)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
495 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
496 it = old_hashtable[oldbucket];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
497 } else {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
498 it = primary_hashtable[hv & hashmask(hashpower)];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
499 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
500
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
501 while (it) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
502 if ((nkey == it->nkey) &&
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
503 (memcmp(key, ITEM_key(it), nkey) == 0)) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
504 return it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
505 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
506 it = it->h_next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
507 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
508 return 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
509 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
510
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
511 /* returns the address of the item pointer before the key. if *item == 0,
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
512 the item wasn't found */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
513
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
514 static item** _hashitem_before (const char *key, const size_t nkey) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
515 uint32_t hv = hash(key, nkey, 0);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
516 item **pos;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
517 int oldbucket;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
518
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
519 if (expanding &&
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
520 (oldbucket = (hv & hashmask(hashpower - 1))) >= expand_bucket)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
521 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
522 pos = &old_hashtable[oldbucket];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
523 } else {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
524 pos = &primary_hashtable[hv & hashmask(hashpower)];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
525 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
526
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
527 while (*pos && ((nkey != (*pos)->nkey) || memcmp(key, ITEM_key(*pos), nkey))) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
528 pos = &(*pos)->h_next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
529 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
530 return pos;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
531 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
532
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
533 /* grows the hashtable to the next power of 2. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
534 static void assoc_expand(void) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
535 old_hashtable = primary_hashtable;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
536
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
537 primary_hashtable = calloc(hashsize(hashpower + 1), sizeof(void *));
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
538 if (primary_hashtable) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
539 if (settings.verbose > 1)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
540 fprintf(stderr, "Hash table expansion starting\n");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
541 hashpower++;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
542 expanding = 1;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
543 expand_bucket = 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
544 do_assoc_move_next_bucket();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
545 } else {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
546 primary_hashtable = old_hashtable;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
547 /* Bad news, but we can keep running. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
548 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
549 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
550
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
551 /* migrates the next bucket to the primary hashtable if we're expanding. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
552 void do_assoc_move_next_bucket(void) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
553 item *it, *next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
554 int bucket;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
555
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
556 if (expanding) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
557 for (it = old_hashtable[expand_bucket]; NULL != it; it = next) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
558 next = it->h_next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
559
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
560 bucket = hash(ITEM_key(it), it->nkey, 0) & hashmask(hashpower);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
561 it->h_next = primary_hashtable[bucket];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
562 primary_hashtable[bucket] = it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
563 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
564
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
565 old_hashtable[expand_bucket] = NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
566
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
567 expand_bucket++;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
568 if (expand_bucket == hashsize(hashpower - 1)) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
569 expanding = 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
570 free(old_hashtable);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
571 if (settings.verbose > 1)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
572 fprintf(stderr, "Hash table expansion done\n");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
573 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
574 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
575 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
576
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
577 /* Note: this isn't an assoc_update. The key must not already exist to call this */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
578 int assoc_insert(item *it) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
579 uint32_t hv;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
580 int oldbucket;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
581
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
582 assert(assoc_find(ITEM_key(it), it->nkey) == 0); /* shouldn't have duplicately named things defined */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
583
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
584 hv = hash(ITEM_key(it), it->nkey, 0);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
585 if (expanding &&
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
586 (oldbucket = (hv & hashmask(hashpower - 1))) >= expand_bucket)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
587 {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
588 it->h_next = old_hashtable[oldbucket];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
589 old_hashtable[oldbucket] = it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
590 } else {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
591 it->h_next = primary_hashtable[hv & hashmask(hashpower)];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
592 primary_hashtable[hv & hashmask(hashpower)] = it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
593 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
594
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
595 hash_items++;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
596 if (! expanding && hash_items > (hashsize(hashpower) * 3) / 2) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
597 assoc_expand();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
598 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
599
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
600 return 1;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
601 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
602
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
603 void assoc_delete(const char *key, const size_t nkey) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
604 item **before = _hashitem_before(key, nkey);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
605
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
606 if (*before) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
607 item *nxt = (*before)->h_next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
608 (*before)->h_next = 0; /* probably pointless, but whatever. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
609 *before = nxt;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
610 hash_items--;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
611 return;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
612 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
613 /* Note: we never actually get here. the callers don't delete things
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
614 they can't find. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
615 assert(*before != 0);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
616 }