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*50997Sbostic static char sccsid[] = "@(#)hash_func.c 5.2 (Berkeley) 09/04/91"; 1346368Sbostic #endif /* LIBC_SCCS and not lint */ 1446368Sbostic 15*50997Sbostic #include <sys/types.h> 16*50997Sbostic #include <db.h> 17*50997Sbostic #include "hash.h" 18*50997Sbostic #include "page.h" 19*50997Sbostic #include "extern.h" 20*50997Sbostic 21*50997Sbostic static int hash1 __P((u_char *, int)); 22*50997Sbostic static int hash2 __P((u_char *, int)); 23*50997Sbostic static int hash3 __P((u_char *, int)); 24*50997Sbostic static int hash4 __P((u_char *, int)); 25*50997Sbostic 2646368Sbostic /* Global default hash function */ 27*50997Sbostic int (*default_hash) __P((u_char *, int)) = hash4; 2846368Sbostic 2946368Sbostic /******************************* HASH FUNCTIONS **************************/ 3046368Sbostic /* 31*50997Sbostic * Assume that we've already split the bucket to which this key hashes, 32*50997Sbostic * calculate that bucket, and check that in fact we did already split it. 33*50997Sbostic * 34*50997Sbostic * This came from ejb's hsearch. 35*50997Sbostic */ 3646368Sbostic 37*50997Sbostic #define PRIME1 37 38*50997Sbostic #define PRIME2 1048583 3946368Sbostic 4046368Sbostic static int 41*50997Sbostic hash1(key, len) 42*50997Sbostic register u_char *key; 43*50997Sbostic register int len; 4446368Sbostic { 4546368Sbostic register int h; 4646368Sbostic 4746368Sbostic h = 0; 48*50997Sbostic /* Convert string to integer */ 49*50997Sbostic while (len--) 50*50997Sbostic h = h * PRIME1 ^ (*key++ - ' '); 5146368Sbostic h %= PRIME2; 5246368Sbostic return (h); 5346368Sbostic } 5446368Sbostic 5546368Sbostic /* 56*50997Sbostic * Phong's linear congruential hash 57*50997Sbostic */ 5846368Sbostic #define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) 5946368Sbostic 6046368Sbostic static int 61*50997Sbostic hash2(key, len) 62*50997Sbostic register u_char *key; 63*50997Sbostic int len; 6446368Sbostic { 65*50997Sbostic register u_char *e, c; 6646368Sbostic register int h; 6746368Sbostic 68*50997Sbostic e = key + len; 69*50997Sbostic for (h = 0; key != e;) { 70*50997Sbostic c = *key++; 71*50997Sbostic if (!c && key > e) 7246368Sbostic break; 73*50997Sbostic dcharhash(h, c); 7446368Sbostic } 75*50997Sbostic return (h); 7646368Sbostic } 7746368Sbostic 7846368Sbostic /* 79*50997Sbostic * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte 80*50997Sbostic * units. On the first time through the loop we get the "leftover bytes" 81*50997Sbostic * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle 82*50997Sbostic * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If 83*50997Sbostic * this routine is heavily used enough, it's worth the ugly coding. 84*50997Sbostic * 8546368Sbostic * OZ's original sdbm hash 8646368Sbostic */ 8746368Sbostic static int 88*50997Sbostic hash3(key, len) 89*50997Sbostic register u_char *key; 90*50997Sbostic register int len; 9146368Sbostic { 92*50997Sbostic register int n, loop; 9346368Sbostic 94*50997Sbostic #define HASHC n = *key++ + 65599 * n 9546368Sbostic 96*50997Sbostic n = 0; 97*50997Sbostic if (len > 0) { 98*50997Sbostic loop = (len + 8 - 1) >> 3; 9946368Sbostic 100*50997Sbostic switch (len & (8 - 1)) { 101*50997Sbostic case 0: 102*50997Sbostic do { /* All fall throughs */ 103*50997Sbostic HASHC; 104*50997Sbostic case 7: 105*50997Sbostic HASHC; 106*50997Sbostic case 6: 107*50997Sbostic HASHC; 108*50997Sbostic case 5: 109*50997Sbostic HASHC; 110*50997Sbostic case 4: 111*50997Sbostic HASHC; 112*50997Sbostic case 3: 113*50997Sbostic HASHC; 114*50997Sbostic case 2: 115*50997Sbostic HASHC; 116*50997Sbostic case 1: 117*50997Sbostic HASHC; 118*50997Sbostic } while (--loop); 119*50997Sbostic } 12046368Sbostic 121*50997Sbostic } 122*50997Sbostic return (n); 12346368Sbostic } 12446368Sbostic 125*50997Sbostic /* Hash function from Chris Torek. */ 12646368Sbostic static int 127*50997Sbostic hash4(key, len) 128*50997Sbostic register u_char *key; 129*50997Sbostic register int len; 13046368Sbostic { 131*50997Sbostic register int h, loop; 13246368Sbostic 133*50997Sbostic #define HASH4a h = (h << 5) - h + *key++; 134*50997Sbostic #define HASH4b h = (h << 5) + h + *key++; 13546368Sbostic #define HASH4 HASH4b 13646368Sbostic 137*50997Sbostic h = 0; 138*50997Sbostic if (len > 0) { 139*50997Sbostic loop = (len + 8 - 1) >> 3; 14046368Sbostic 141*50997Sbostic switch (len & (8 - 1)) { 142*50997Sbostic case 0: 143*50997Sbostic do { /* All fall throughs */ 144*50997Sbostic HASH4; 145*50997Sbostic case 7: 146*50997Sbostic HASH4; 147*50997Sbostic case 6: 148*50997Sbostic HASH4; 149*50997Sbostic case 5: 150*50997Sbostic HASH4; 151*50997Sbostic case 4: 152*50997Sbostic HASH4; 153*50997Sbostic case 3: 154*50997Sbostic HASH4; 155*50997Sbostic case 2: 156*50997Sbostic HASH4; 157*50997Sbostic case 1: 158*50997Sbostic HASH4; 159*50997Sbostic } while (--loop); 160*50997Sbostic } 16146368Sbostic 162*50997Sbostic } 163*50997Sbostic return (h); 16446368Sbostic } 165