xref: /titanic_53/usr/src/cmd/sh/hash.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.3.2.1	*/
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate #include	"hash.h"
29*7c478bd9Sstevel@tonic-gate #include	"defs.h"
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #define STRCMP(A, B)	(cf(A, B) != 0)
32*7c478bd9Sstevel@tonic-gate #define FACTOR 	 		035761254233	/* Magic multiplication factor */
33*7c478bd9Sstevel@tonic-gate #define TABLENGTH		64				/* must be multiple of 2 */
34*7c478bd9Sstevel@tonic-gate #define LOG2LEN			6				/* log2 of TABLENGTH */
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate /*
37*7c478bd9Sstevel@tonic-gate     NOTE: The following algorithm only works on machines where
38*7c478bd9Sstevel@tonic-gate     the results of multiplying two integers is the least
39*7c478bd9Sstevel@tonic-gate     significant part of the double word integer required to hold
40*7c478bd9Sstevel@tonic-gate     the result.  It is adapted from Knuth, Volume 3, section 6.4.
41*7c478bd9Sstevel@tonic-gate */
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #define hash(str)		(int)(((unsigned)(crunch(str) * FACTOR)) >> shift)
44*7c478bd9Sstevel@tonic-gate struct node
45*7c478bd9Sstevel@tonic-gate {
46*7c478bd9Sstevel@tonic-gate 	ENTRY item;
47*7c478bd9Sstevel@tonic-gate 	struct node *next;
48*7c478bd9Sstevel@tonic-gate };
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate static struct node	**last;
51*7c478bd9Sstevel@tonic-gate static struct node	*next;
52*7c478bd9Sstevel@tonic-gate static struct node 	**table;
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate static unsigned int 	bitsper;		/* Bits per byte */
55*7c478bd9Sstevel@tonic-gate static unsigned int	shift;
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate static unsigned int crunch();
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate hcreate()
60*7c478bd9Sstevel@tonic-gate {
61*7c478bd9Sstevel@tonic-gate 	unsigned char c = (unsigned char)~0;			/* A byte full of 1's */
62*7c478bd9Sstevel@tonic-gate 	int j;
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate 	table = (struct node **)alloc(TABLENGTH * sizeof(struct node *));
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate 	for (j=0; j < TABLENGTH; ++j)
67*7c478bd9Sstevel@tonic-gate 	{
68*7c478bd9Sstevel@tonic-gate 		table[j] = 0;
69*7c478bd9Sstevel@tonic-gate 	}
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate 	bitsper = 0;
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate 	while (c)
74*7c478bd9Sstevel@tonic-gate 	{
75*7c478bd9Sstevel@tonic-gate 		c = (unsigned int)c >> 1;
76*7c478bd9Sstevel@tonic-gate 		bitsper++;
77*7c478bd9Sstevel@tonic-gate 	}
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	shift = (bitsper * sizeof(int)) - LOG2LEN;
80*7c478bd9Sstevel@tonic-gate }
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate void hscan(uscan)
84*7c478bd9Sstevel@tonic-gate 	void	(*uscan)();
85*7c478bd9Sstevel@tonic-gate {
86*7c478bd9Sstevel@tonic-gate 	struct node		*p, *nxt;
87*7c478bd9Sstevel@tonic-gate 	int				j;
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	for (j=0; j < TABLENGTH; ++j)
90*7c478bd9Sstevel@tonic-gate 	{
91*7c478bd9Sstevel@tonic-gate 		p = table[j];
92*7c478bd9Sstevel@tonic-gate 		while (p)
93*7c478bd9Sstevel@tonic-gate 		{
94*7c478bd9Sstevel@tonic-gate 			nxt = p->next;
95*7c478bd9Sstevel@tonic-gate 			(*uscan)(&p->item);
96*7c478bd9Sstevel@tonic-gate 			p = nxt;
97*7c478bd9Sstevel@tonic-gate 		}
98*7c478bd9Sstevel@tonic-gate 	}
99*7c478bd9Sstevel@tonic-gate }
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate ENTRY *
104*7c478bd9Sstevel@tonic-gate hfind(str)
105*7c478bd9Sstevel@tonic-gate 	unsigned char	*str;
106*7c478bd9Sstevel@tonic-gate {
107*7c478bd9Sstevel@tonic-gate 	struct node 	*p;
108*7c478bd9Sstevel@tonic-gate 	struct node 	**q;
109*7c478bd9Sstevel@tonic-gate 	unsigned int 	i;
110*7c478bd9Sstevel@tonic-gate 	int 			res;
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate 	i = hash(str);
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate 	if(table[i] == 0)
115*7c478bd9Sstevel@tonic-gate 	{
116*7c478bd9Sstevel@tonic-gate 		last = &table[i];
117*7c478bd9Sstevel@tonic-gate 		next = 0;
118*7c478bd9Sstevel@tonic-gate 		return(0);
119*7c478bd9Sstevel@tonic-gate 	}
120*7c478bd9Sstevel@tonic-gate 	else
121*7c478bd9Sstevel@tonic-gate 	{
122*7c478bd9Sstevel@tonic-gate 		q = &table[i];
123*7c478bd9Sstevel@tonic-gate 		p = table[i];
124*7c478bd9Sstevel@tonic-gate 		while (p != 0 && (res = STRCMP(str, p->item.key)))
125*7c478bd9Sstevel@tonic-gate 		{
126*7c478bd9Sstevel@tonic-gate 			q = &(p->next);
127*7c478bd9Sstevel@tonic-gate 			p = p->next;
128*7c478bd9Sstevel@tonic-gate 		}
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 		if (p != 0 && res == 0)
131*7c478bd9Sstevel@tonic-gate 			return(&(p->item));
132*7c478bd9Sstevel@tonic-gate 		else
133*7c478bd9Sstevel@tonic-gate 		{
134*7c478bd9Sstevel@tonic-gate 			last = q;
135*7c478bd9Sstevel@tonic-gate 			next = p;
136*7c478bd9Sstevel@tonic-gate 			return(0);
137*7c478bd9Sstevel@tonic-gate 		}
138*7c478bd9Sstevel@tonic-gate 	}
139*7c478bd9Sstevel@tonic-gate }
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate ENTRY *
142*7c478bd9Sstevel@tonic-gate henter(item)
143*7c478bd9Sstevel@tonic-gate 	ENTRY item;
144*7c478bd9Sstevel@tonic-gate {
145*7c478bd9Sstevel@tonic-gate 	struct node	*p = (struct node *)alloc(sizeof(struct node));
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	p->item = item;
148*7c478bd9Sstevel@tonic-gate 	*last = p;
149*7c478bd9Sstevel@tonic-gate 	p->next = next;
150*7c478bd9Sstevel@tonic-gate 	return(&(p->item));
151*7c478bd9Sstevel@tonic-gate }
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate static unsigned int
155*7c478bd9Sstevel@tonic-gate crunch(key)
156*7c478bd9Sstevel@tonic-gate 	unsigned char	*key;
157*7c478bd9Sstevel@tonic-gate {
158*7c478bd9Sstevel@tonic-gate 	unsigned int 	sum = 0;
159*7c478bd9Sstevel@tonic-gate 	int s;
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 	for (s = 0; *key; s++)				/* Simply add up the bytes */
162*7c478bd9Sstevel@tonic-gate 		sum += *key++;
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate 	return(sum + s);
165*7c478bd9Sstevel@tonic-gate }
166*7c478bd9Sstevel@tonic-gate 
167