]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - lib/libc/db/hash/hash_func.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / lib / libc / db / hash / hash_func.c
1 /*-
2  * Copyright (c) 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Margo Seltzer.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #if defined(LIBC_SCCS) && !defined(lint)
34 static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
35 #endif /* LIBC_SCCS and not lint */
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38
39 #include <sys/types.h>
40
41 #include <db.h>
42 #include "hash.h"
43 #include "page.h"
44 #include "extern.h"
45
46 #ifdef notdef
47 static u_int32_t hash1(const void *, size_t) __unused;
48 static u_int32_t hash2(const void *, size_t) __unused;
49 static u_int32_t hash3(const void *, size_t) __unused;
50 #endif
51 static u_int32_t hash4(const void *, size_t);
52
53 /* Default hash function. */
54 u_int32_t (*__default_hash)(const void *, size_t) = hash4;
55
56 #ifdef notdef
57 /*
58  * Assume that we've already split the bucket to which this key hashes,
59  * calculate that bucket, and check that in fact we did already split it.
60  *
61  * EJB's original hsearch hash.
62  */
63 #define PRIME1          37
64 #define PRIME2          1048583
65
66 u_int32_t
67 hash1(const void *key, size_t len)
68 {
69         u_int32_t h;
70         u_int8_t *k;
71
72         h = 0;
73         k = (u_int8_t *)key;
74         /* Convert string to integer */
75         while (len--)
76                 h = h * PRIME1 ^ (*k++ - ' ');
77         h %= PRIME2;
78         return (h);
79 }
80
81 /*
82  * Phong Vo's linear congruential hash
83  */
84 #define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
85
86 u_int32_t
87 hash2(const void *key, size_t len)
88 {
89         u_int32_t h;
90         u_int8_t *e, c, *k;
91
92         k = (u_int8_t *)key;
93         e = k + len;
94         for (h = 0; k != e;) {
95                 c = *k++;
96                 if (!c && k > e)
97                         break;
98                 dcharhash(h, c);
99         }
100         return (h);
101 }
102
103 /*
104  * This is INCREDIBLY ugly, but fast.  We break the string up into 8 byte
105  * units.  On the first time through the loop we get the "leftover bytes"
106  * (strlen % 8).  On every other iteration, we perform 8 HASHC's so we handle
107  * all 8 bytes.  Essentially, this saves us 7 cmp & branch instructions.  If
108  * this routine is heavily used enough, it's worth the ugly coding.
109  *
110  * Ozan Yigit's original sdbm hash.
111  */
112 u_int32_t
113 hash3(const void *key, size_t len)
114 {
115         u_int32_t n, loop;
116         u_int8_t *k;
117
118 #define HASHC   n = *k++ + 65599 * n
119
120         n = 0;
121         k = (u_int8_t *)key;
122         if (len > 0) {
123                 loop = (len + 8 - 1) >> 3;
124
125                 switch (len & (8 - 1)) {
126                 case 0:
127                         do {    /* All fall throughs */
128                                 HASHC;
129                 case 7:
130                                 HASHC;
131                 case 6:
132                                 HASHC;
133                 case 5:
134                                 HASHC;
135                 case 4:
136                                 HASHC;
137                 case 3:
138                                 HASHC;
139                 case 2:
140                                 HASHC;
141                 case 1:
142                                 HASHC;
143                         } while (--loop);
144                 }
145
146         }
147         return (n);
148 }
149 #endif /* notdef */
150
151 /* Chris Torek's hash function. */
152 u_int32_t
153 hash4(const void *key, size_t len)
154 {
155         u_int32_t h, loop;
156         const u_int8_t *k;
157
158 #define HASH4a   h = (h << 5) - h + *k++;
159 #define HASH4b   h = (h << 5) + h + *k++;
160 #define HASH4 HASH4b
161
162         h = 0;
163         k = key;
164         if (len > 0) {
165                 loop = (len + 8 - 1) >> 3;
166
167                 switch (len & (8 - 1)) {
168                 case 0:
169                         do {    /* All fall throughs */
170                                 HASH4;
171                 case 7:
172                                 HASH4;
173                 case 6:
174                                 HASH4;
175                 case 5:
176                                 HASH4;
177                 case 4:
178                                 HASH4;
179                 case 3:
180                                 HASH4;
181                 case 2:
182                                 HASH4;
183                 case 1:
184                                 HASH4;
185                         } while (--loop);
186                 }
187
188         }
189         return (h);
190 }