1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 #include <stdlib.h>
31 #include "hash.h"
32
33 #define LOCHWIDTH 3
34 #define HICHWIDTH 3
35 #define CHARWIDTH (LOCHWIDTH+HICHWIDTH)
36 #define LOCHMASK ((1<<LOCHWIDTH)-1)
37
38 /*
39 * if HASHWIDTH + CHARWIDTH < bitsizeof(long)
40 * one could make LOCHWIDTH=6 and HICHWIDTH=0
41 * and simplify accordingly; the hanky-panky
42 * is to avoid overflow in long multiplication
43 */
44 #define NC 30
45
46 static long hashsize = HASHSIZE;
47 static long pow2[NC*2];
48
49 static signed char hashtab[] = {
50 -1, -1, -1, -1, -1, -1, 0, 31, /* &' */
51 -1, -1, -1, -1, 68, -1, 65, -1,
52 2, 25, 20, 35, 54, 61, 40, 39, /* 0-7 */
53 42, 33, 64, 67, -1, -1, -1, 66,
54 -1, 60, 43, 30, 5, 16, 47, 18, /* A-G */
55 41, 36, 51, 6, 13, 56, 55, 58,
56 49, 12, 59, 46, 21, 32, 63, 34,
57 57, 52, 3, -1, -1, -1, -1, -1,
58 -1, 22, 29, 8, 7, 10, 1, 28, /* a-g */
59 11, 62, 37, 48, 15, 50, 9, 4,
60 19, 38, 45, 24, 23, 26, 17, 44,
61 27, 14, 53, -1, -1, -1, -1, -1
62 };
63
64
65 unsigned long
hash(char * s)66 hash(char *s)
67 {
68 int c;
69 long *lp;
70 unsigned long h = 0;
71 for (lp = pow2; (c = *s++) != 0; ) {
72 c = hashtab[c-' '];
73 h += (c&LOCHMASK) * *lp++;
74 h += (c>>LOCHWIDTH) * *lp++;
75 h %= hashsize;
76 }
77 return (h);
78 }
79
80 void
hashinit(void)81 hashinit(void)
82 {
83 #if ((1L << (HASHWIDTH+LOCHWIDTH) == 0) || (1L << (HASHWIDTH+HICHWIDTH) == 0))
84 abort(); /* overflow is imminent */
85 #else
86 int i;
87
88 pow2[0] = 1L<<(HASHWIDTH-CHARWIDTH-2);
89 for (i = 0; i < 2*NC-3; i += 2) {
90 pow2[i+1] = (pow2[i]<<LOCHWIDTH) % hashsize;
91 pow2[i+2] = (pow2[i+1]<<HICHWIDTH) % hashsize;
92 }
93 #endif
94 }
95