xref: /openbsd/gnu/usr.bin/perl/ext/SDBM_File/hash.c (revision 76d0caae)
1 /*
2  * sdbm - ndbm work-alike hashed database library
3  * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
4  * author: oz@nexus.yorku.ca
5  * status: public domain. keep it that way.
6  *
7  * hashing routine
8  */
9 
10 #include "config.h"
11 #include "EXTERN.h"
12 #include "sdbm.h"
13 /*
14  * polynomial conversion ignoring overflows
15  * [this seems to work remarkably well, in fact better
16  * then the ndbm hash function. Replace at your own risk]
17  * use: 65599   nice.
18  *      65587   even better.
19  */
20 long
21 sdbm_hash(const char *str, int len)
22 {
23         unsigned long n = 0;
24 
25 #ifdef DUFF
26 
27 #define HASHC   n = *str++ + 65599 * n
28 
29         if (len > 0) {
30                 int loop = (len + 8 - 1) >> 3;
31 
32                 switch(len & (8 - 1)) {
33                 case 0: do {
34                         HASHC; /* FALLTHROUGH */ case 7: HASHC; /* FALLTHROUGH */
35                 case 6: HASHC; /* FALLTHROUGH */ case 5: HASHC; /* FALLTHROUGH */
36                 case 4: HASHC; /* FALLTHROUGH */ case 3: HASHC; /* FALLTHROUGH */
37                 case 2: HASHC; /* FALLTHROUGH */ case 1: HASHC;
38                         } while (--loop);
39                 }
40 
41         }
42 #else
43         while (len--)
44                 n = *str++ + 65599 * n;
45 #endif
46         return n;
47 }
48