146368Sbostic /*- 246368Sbostic * Copyright (c) 1990 The Regents of the University of California. 346368Sbostic * 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*57586Sbostic static char sccsid[] = "@(#)hash_func.c 5.3 (Berkeley) 01/17/93"; 1346368Sbostic #endif /* LIBC_SCCS and not lint */ 1446368Sbostic 1550997Sbostic #include <sys/types.h> 16*57586Sbostic 1750997Sbostic #include <db.h> 18*57586Sbostic 1950997Sbostic #include "hash.h" 2050997Sbostic #include "page.h" 2150997Sbostic #include "extern.h" 2250997Sbostic 2350997Sbostic static int hash1 __P((u_char *, int)); 2450997Sbostic static int hash2 __P((u_char *, int)); 2550997Sbostic static int hash3 __P((u_char *, int)); 2650997Sbostic static int hash4 __P((u_char *, int)); 2750997Sbostic 2846368Sbostic /* Global default hash function */ 29*57586Sbostic int (*__default_hash) __P((u_char *, int)) = hash4; 3046368Sbostic 3146368Sbostic /******************************* HASH FUNCTIONS **************************/ 3246368Sbostic /* 3350997Sbostic * Assume that we've already split the bucket to which this key hashes, 3450997Sbostic * calculate that bucket, and check that in fact we did already split it. 3550997Sbostic * 3650997Sbostic * This came from ejb's hsearch. 3750997Sbostic */ 3846368Sbostic 3950997Sbostic #define PRIME1 37 4050997Sbostic #define PRIME2 1048583 4146368Sbostic 4246368Sbostic static int 4350997Sbostic hash1(key, len) 4450997Sbostic register u_char *key; 4550997Sbostic register int len; 4646368Sbostic { 4746368Sbostic register int h; 4846368Sbostic 4946368Sbostic h = 0; 5050997Sbostic /* Convert string to integer */ 5150997Sbostic while (len--) 5250997Sbostic h = h * PRIME1 ^ (*key++ - ' '); 5346368Sbostic h %= PRIME2; 5446368Sbostic return (h); 5546368Sbostic } 5646368Sbostic 5746368Sbostic /* 5850997Sbostic * Phong's linear congruential hash 5950997Sbostic */ 6046368Sbostic #define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) 6146368Sbostic 6246368Sbostic static int 6350997Sbostic hash2(key, len) 6450997Sbostic register u_char *key; 6550997Sbostic int len; 6646368Sbostic { 6750997Sbostic register u_char *e, c; 6846368Sbostic register int h; 6946368Sbostic 7050997Sbostic e = key + len; 7150997Sbostic for (h = 0; key != e;) { 7250997Sbostic c = *key++; 7350997Sbostic if (!c && key > e) 7446368Sbostic break; 7550997Sbostic dcharhash(h, c); 7646368Sbostic } 7750997Sbostic return (h); 7846368Sbostic } 7946368Sbostic 8046368Sbostic /* 8150997Sbostic * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte 8250997Sbostic * units. On the first time through the loop we get the "leftover bytes" 8350997Sbostic * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle 8450997Sbostic * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If 8550997Sbostic * this routine is heavily used enough, it's worth the ugly coding. 8650997Sbostic * 8746368Sbostic * OZ's original sdbm hash 8846368Sbostic */ 8946368Sbostic static int 9050997Sbostic hash3(key, len) 9150997Sbostic register u_char *key; 9250997Sbostic register int len; 9346368Sbostic { 9450997Sbostic register int n, loop; 9546368Sbostic 9650997Sbostic #define HASHC n = *key++ + 65599 * n 9746368Sbostic 9850997Sbostic n = 0; 9950997Sbostic if (len > 0) { 10050997Sbostic loop = (len + 8 - 1) >> 3; 10146368Sbostic 10250997Sbostic switch (len & (8 - 1)) { 10350997Sbostic case 0: 10450997Sbostic do { /* All fall throughs */ 10550997Sbostic HASHC; 10650997Sbostic case 7: 10750997Sbostic HASHC; 10850997Sbostic case 6: 10950997Sbostic HASHC; 11050997Sbostic case 5: 11150997Sbostic HASHC; 11250997Sbostic case 4: 11350997Sbostic HASHC; 11450997Sbostic case 3: 11550997Sbostic HASHC; 11650997Sbostic case 2: 11750997Sbostic HASHC; 11850997Sbostic case 1: 11950997Sbostic HASHC; 12050997Sbostic } while (--loop); 12150997Sbostic } 12246368Sbostic 12350997Sbostic } 12450997Sbostic return (n); 12546368Sbostic } 12646368Sbostic 12750997Sbostic /* Hash function from Chris Torek. */ 12846368Sbostic static int 12950997Sbostic hash4(key, len) 13050997Sbostic register u_char *key; 13150997Sbostic register int len; 13246368Sbostic { 13350997Sbostic register int h, loop; 13446368Sbostic 13550997Sbostic #define HASH4a h = (h << 5) - h + *key++; 13650997Sbostic #define HASH4b h = (h << 5) + h + *key++; 13746368Sbostic #define HASH4 HASH4b 13846368Sbostic 13950997Sbostic h = 0; 14050997Sbostic if (len > 0) { 14150997Sbostic loop = (len + 8 - 1) >> 3; 14246368Sbostic 14350997Sbostic switch (len & (8 - 1)) { 14450997Sbostic case 0: 14550997Sbostic do { /* All fall throughs */ 14650997Sbostic HASH4; 14750997Sbostic case 7: 14850997Sbostic HASH4; 14950997Sbostic case 6: 15050997Sbostic HASH4; 15150997Sbostic case 5: 15250997Sbostic HASH4; 15350997Sbostic case 4: 15450997Sbostic HASH4; 15550997Sbostic case 3: 15650997Sbostic HASH4; 15750997Sbostic case 2: 15850997Sbostic HASH4; 15950997Sbostic case 1: 16050997Sbostic HASH4; 16150997Sbostic } while (--loop); 16250997Sbostic } 16346368Sbostic 16450997Sbostic } 16550997Sbostic return (h); 16646368Sbostic } 167