146368Sbostic /*- 2*61202Sbostic * Copyright (c) 1990, 1993 3*61202Sbostic * The Regents of the University of California. All rights reserved. 446368Sbostic * 546368Sbostic * This code is derived from software contributed to Berkeley by 646368Sbostic * Margo Seltzer. 746368Sbostic * 846368Sbostic * %sccs.include.redist.c% 946368Sbostic */ 1046368Sbostic 1146368Sbostic #if defined(LIBC_SCCS) && !defined(lint) 12*61202Sbostic static char sccsid[] = "@(#)hash_func.c 8.1 (Berkeley) 06/04/93"; 1346368Sbostic #endif /* LIBC_SCCS and not lint */ 1446368Sbostic 1550997Sbostic #include <sys/types.h> 1657586Sbostic 1750997Sbostic #include <db.h> 1850997Sbostic #include "hash.h" 1950997Sbostic #include "page.h" 2050997Sbostic #include "extern.h" 2150997Sbostic 2250997Sbostic static int hash1 __P((u_char *, int)); 2350997Sbostic static int hash2 __P((u_char *, int)); 2450997Sbostic static int hash3 __P((u_char *, int)); 2550997Sbostic static int hash4 __P((u_char *, int)); 2650997Sbostic 2746368Sbostic /* Global default hash function */ 2857586Sbostic int (*__default_hash) __P((u_char *, int)) = hash4; 2946368Sbostic 3046368Sbostic /******************************* HASH FUNCTIONS **************************/ 3146368Sbostic /* 3250997Sbostic * Assume that we've already split the bucket to which this key hashes, 3350997Sbostic * calculate that bucket, and check that in fact we did already split it. 3450997Sbostic * 3550997Sbostic * This came from ejb's hsearch. 3650997Sbostic */ 3746368Sbostic 3850997Sbostic #define PRIME1 37 3950997Sbostic #define PRIME2 1048583 4046368Sbostic 4146368Sbostic static int 4250997Sbostic hash1(key, len) 4350997Sbostic register u_char *key; 4450997Sbostic register int len; 4546368Sbostic { 4646368Sbostic register int h; 4746368Sbostic 4846368Sbostic h = 0; 4950997Sbostic /* Convert string to integer */ 5050997Sbostic while (len--) 5150997Sbostic h = h * PRIME1 ^ (*key++ - ' '); 5246368Sbostic h %= PRIME2; 5346368Sbostic return (h); 5446368Sbostic } 5546368Sbostic 5646368Sbostic /* 5750997Sbostic * Phong's linear congruential hash 5850997Sbostic */ 5946368Sbostic #define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) 6046368Sbostic 6146368Sbostic static int 6250997Sbostic hash2(key, len) 6350997Sbostic register u_char *key; 6450997Sbostic int len; 6546368Sbostic { 6650997Sbostic register u_char *e, c; 6746368Sbostic register int h; 6846368Sbostic 6950997Sbostic e = key + len; 7050997Sbostic for (h = 0; key != e;) { 7150997Sbostic c = *key++; 7250997Sbostic if (!c && key > e) 7346368Sbostic break; 7450997Sbostic dcharhash(h, c); 7546368Sbostic } 7650997Sbostic return (h); 7746368Sbostic } 7846368Sbostic 7946368Sbostic /* 8050997Sbostic * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte 8150997Sbostic * units. On the first time through the loop we get the "leftover bytes" 8250997Sbostic * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle 8350997Sbostic * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If 8450997Sbostic * this routine is heavily used enough, it's worth the ugly coding. 8550997Sbostic * 8646368Sbostic * OZ's original sdbm hash 8746368Sbostic */ 8846368Sbostic static int 8950997Sbostic hash3(key, len) 9050997Sbostic register u_char *key; 9150997Sbostic register int len; 9246368Sbostic { 9350997Sbostic register int n, loop; 9446368Sbostic 9550997Sbostic #define HASHC n = *key++ + 65599 * n 9646368Sbostic 9750997Sbostic n = 0; 9850997Sbostic if (len > 0) { 9950997Sbostic loop = (len + 8 - 1) >> 3; 10046368Sbostic 10150997Sbostic switch (len & (8 - 1)) { 10250997Sbostic case 0: 10350997Sbostic do { /* All fall throughs */ 10450997Sbostic HASHC; 10550997Sbostic case 7: 10650997Sbostic HASHC; 10750997Sbostic case 6: 10850997Sbostic HASHC; 10950997Sbostic case 5: 11050997Sbostic HASHC; 11150997Sbostic case 4: 11250997Sbostic HASHC; 11350997Sbostic case 3: 11450997Sbostic HASHC; 11550997Sbostic case 2: 11650997Sbostic HASHC; 11750997Sbostic case 1: 11850997Sbostic HASHC; 11950997Sbostic } while (--loop); 12050997Sbostic } 12146368Sbostic 12250997Sbostic } 12350997Sbostic return (n); 12446368Sbostic } 12546368Sbostic 12650997Sbostic /* Hash function from Chris Torek. */ 12746368Sbostic static int 12850997Sbostic hash4(key, len) 12950997Sbostic register u_char *key; 13050997Sbostic register int len; 13146368Sbostic { 13250997Sbostic register int h, loop; 13346368Sbostic 13450997Sbostic #define HASH4a h = (h << 5) - h + *key++; 13550997Sbostic #define HASH4b h = (h << 5) + h + *key++; 13646368Sbostic #define HASH4 HASH4b 13746368Sbostic 13850997Sbostic h = 0; 13950997Sbostic if (len > 0) { 14050997Sbostic loop = (len + 8 - 1) >> 3; 14146368Sbostic 14250997Sbostic switch (len & (8 - 1)) { 14350997Sbostic case 0: 14450997Sbostic do { /* All fall throughs */ 14550997Sbostic HASH4; 14650997Sbostic case 7: 14750997Sbostic HASH4; 14850997Sbostic case 6: 14950997Sbostic HASH4; 15050997Sbostic case 5: 15150997Sbostic HASH4; 15250997Sbostic case 4: 15350997Sbostic HASH4; 15450997Sbostic case 3: 15550997Sbostic HASH4; 15650997Sbostic case 2: 15750997Sbostic HASH4; 15850997Sbostic case 1: 15950997Sbostic HASH4; 16050997Sbostic } while (--loop); 16150997Sbostic } 16246368Sbostic 16350997Sbostic } 16450997Sbostic return (h); 16546368Sbostic } 166