xref: /onnv-gate/usr/src/cmd/isns/isnsd/htable.c (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM 
22*7836SJohn.Forte@Sun.COM /*
23*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
25*7836SJohn.Forte@Sun.COM  */
26*7836SJohn.Forte@Sun.COM 
27*7836SJohn.Forte@Sun.COM #include <stdio.h>
28*7836SJohn.Forte@Sun.COM #include <stdlib.h>
29*7836SJohn.Forte@Sun.COM #include <string.h>
30*7836SJohn.Forte@Sun.COM #include <sys/types.h>
31*7836SJohn.Forte@Sun.COM #include <pthread.h>
32*7836SJohn.Forte@Sun.COM #include <libelf.h>
33*7836SJohn.Forte@Sun.COM #include <libelf.h>
34*7836SJohn.Forte@Sun.COM 
35*7836SJohn.Forte@Sun.COM #include "isns_server.h"
36*7836SJohn.Forte@Sun.COM #include "isns_cache.h"
37*7836SJohn.Forte@Sun.COM #include "isns_htab.h"
38*7836SJohn.Forte@Sun.COM #include "isns_log.h"
39*7836SJohn.Forte@Sun.COM 
40*7836SJohn.Forte@Sun.COM #define	UID_REUSABLE(T, X)	((T) - (X)->t >= ONE_DAY)
41*7836SJohn.Forte@Sun.COM 
42*7836SJohn.Forte@Sun.COM /*
43*7836SJohn.Forte@Sun.COM  * external variables.
44*7836SJohn.Forte@Sun.COM  */
45*7836SJohn.Forte@Sun.COM extern int cache_flag;
46*7836SJohn.Forte@Sun.COM 
47*7836SJohn.Forte@Sun.COM /*
48*7836SJohn.Forte@Sun.COM  * ****************************************************************************
49*7836SJohn.Forte@Sun.COM  * avl_search:
50*7836SJohn.Forte@Sun.COM  *	search a node from an AVL tree.
51*7836SJohn.Forte@Sun.COM  *
52*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
53*7836SJohn.Forte@Sun.COM  * uid	- the object UID.
54*7836SJohn.Forte@Sun.COM  * return - the node which matches the object UID.
55*7836SJohn.Forte@Sun.COM  *
56*7836SJohn.Forte@Sun.COM  * ****************************************************************************
57*7836SJohn.Forte@Sun.COM  */
58*7836SJohn.Forte@Sun.COM static htab_itemx_t *
avl_search(const htab_t * tab,const uint32_t uid)59*7836SJohn.Forte@Sun.COM avl_search(
60*7836SJohn.Forte@Sun.COM 	const htab_t *tab,
61*7836SJohn.Forte@Sun.COM 	const uint32_t uid
62*7836SJohn.Forte@Sun.COM )
63*7836SJohn.Forte@Sun.COM {
64*7836SJohn.Forte@Sun.COM 	htab_itemx_t *x = tab->avlt;
65*7836SJohn.Forte@Sun.COM 
66*7836SJohn.Forte@Sun.COM 	while (x != NULL) {
67*7836SJohn.Forte@Sun.COM 		if (x->uid > uid) {
68*7836SJohn.Forte@Sun.COM 			x = x->l;
69*7836SJohn.Forte@Sun.COM 		} else if (x->uid < uid) {
70*7836SJohn.Forte@Sun.COM 			x = x->r;
71*7836SJohn.Forte@Sun.COM 		} else {
72*7836SJohn.Forte@Sun.COM 			break;
73*7836SJohn.Forte@Sun.COM 		}
74*7836SJohn.Forte@Sun.COM 	}
75*7836SJohn.Forte@Sun.COM 
76*7836SJohn.Forte@Sun.COM 	return (x);
77*7836SJohn.Forte@Sun.COM }
78*7836SJohn.Forte@Sun.COM 
79*7836SJohn.Forte@Sun.COM /*
80*7836SJohn.Forte@Sun.COM  * ****************************************************************************
81*7836SJohn.Forte@Sun.COM  * avl_search_next:
82*7836SJohn.Forte@Sun.COM  *	search a node from an AVL tree, the object UID of the node
83*7836SJohn.Forte@Sun.COM  *	is next to the previous object UID.
84*7836SJohn.Forte@Sun.COM  *
85*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
86*7836SJohn.Forte@Sun.COM  * uid	- the previous object UID.
87*7836SJohn.Forte@Sun.COM  * return - the next node.
88*7836SJohn.Forte@Sun.COM  *
89*7836SJohn.Forte@Sun.COM  * ****************************************************************************
90*7836SJohn.Forte@Sun.COM  */
91*7836SJohn.Forte@Sun.COM static htab_itemx_t *
avl_search_next(const htab_t * tab,const uint32_t uid)92*7836SJohn.Forte@Sun.COM avl_search_next(
93*7836SJohn.Forte@Sun.COM 	const htab_t *tab,
94*7836SJohn.Forte@Sun.COM 	const uint32_t uid
95*7836SJohn.Forte@Sun.COM )
96*7836SJohn.Forte@Sun.COM {
97*7836SJohn.Forte@Sun.COM 	htab_itemx_t *p = NULL;
98*7836SJohn.Forte@Sun.COM 	htab_itemx_t *x = tab->avlt;
99*7836SJohn.Forte@Sun.COM 
100*7836SJohn.Forte@Sun.COM 	while (x != NULL) {
101*7836SJohn.Forte@Sun.COM 		if (x->uid > uid) {
102*7836SJohn.Forte@Sun.COM 			p = x;
103*7836SJohn.Forte@Sun.COM 			x = x->l;
104*7836SJohn.Forte@Sun.COM 		} else if (x->uid <= uid) {
105*7836SJohn.Forte@Sun.COM 			x = x->r;
106*7836SJohn.Forte@Sun.COM 		}
107*7836SJohn.Forte@Sun.COM 	}
108*7836SJohn.Forte@Sun.COM 
109*7836SJohn.Forte@Sun.COM 	return (p);
110*7836SJohn.Forte@Sun.COM }
111*7836SJohn.Forte@Sun.COM 
112*7836SJohn.Forte@Sun.COM /*
113*7836SJohn.Forte@Sun.COM  * ****************************************************************************
114*7836SJohn.Forte@Sun.COM  * avl_ll:
115*7836SJohn.Forte@Sun.COM  *	perform LL balance rotation on an AVL tree (or the subtree).
116*7836SJohn.Forte@Sun.COM  *
117*7836SJohn.Forte@Sun.COM  * a	- the left child.
118*7836SJohn.Forte@Sun.COM  * b	- the right child.
119*7836SJohn.Forte@Sun.COM  * return - the new root.
120*7836SJohn.Forte@Sun.COM  *
121*7836SJohn.Forte@Sun.COM  * ****************************************************************************
122*7836SJohn.Forte@Sun.COM  */
123*7836SJohn.Forte@Sun.COM static htab_itemx_t *
avl_ll(htab_itemx_t * a,htab_itemx_t * b)124*7836SJohn.Forte@Sun.COM avl_ll(
125*7836SJohn.Forte@Sun.COM 	htab_itemx_t *a,
126*7836SJohn.Forte@Sun.COM 	htab_itemx_t *b
127*7836SJohn.Forte@Sun.COM )
128*7836SJohn.Forte@Sun.COM {
129*7836SJohn.Forte@Sun.COM 	/* rotate right */
130*7836SJohn.Forte@Sun.COM 	a->l = b->r;
131*7836SJohn.Forte@Sun.COM 	a->bf = 0;
132*7836SJohn.Forte@Sun.COM 	b->r = a;
133*7836SJohn.Forte@Sun.COM 	b->bf = 0;
134*7836SJohn.Forte@Sun.COM 
135*7836SJohn.Forte@Sun.COM 	return (b);
136*7836SJohn.Forte@Sun.COM }
137*7836SJohn.Forte@Sun.COM 
138*7836SJohn.Forte@Sun.COM /*
139*7836SJohn.Forte@Sun.COM  * ****************************************************************************
140*7836SJohn.Forte@Sun.COM  * avl_rr:
141*7836SJohn.Forte@Sun.COM  *	perform RR balance rotation on an AVL tree (or the subtree).
142*7836SJohn.Forte@Sun.COM  *
143*7836SJohn.Forte@Sun.COM  * a	- the left child.
144*7836SJohn.Forte@Sun.COM  * b	- the right child.
145*7836SJohn.Forte@Sun.COM  * return - the new root.
146*7836SJohn.Forte@Sun.COM  *
147*7836SJohn.Forte@Sun.COM  * ****************************************************************************
148*7836SJohn.Forte@Sun.COM  */
149*7836SJohn.Forte@Sun.COM static htab_itemx_t *
avl_rr(htab_itemx_t * a,htab_itemx_t * b)150*7836SJohn.Forte@Sun.COM avl_rr(
151*7836SJohn.Forte@Sun.COM 	htab_itemx_t *a,
152*7836SJohn.Forte@Sun.COM 	htab_itemx_t *b
153*7836SJohn.Forte@Sun.COM )
154*7836SJohn.Forte@Sun.COM {
155*7836SJohn.Forte@Sun.COM 	/* rotate left */
156*7836SJohn.Forte@Sun.COM 	a->r = b->l;
157*7836SJohn.Forte@Sun.COM 	a->bf = 0;
158*7836SJohn.Forte@Sun.COM 	b->l = a;
159*7836SJohn.Forte@Sun.COM 	b->bf = 0;
160*7836SJohn.Forte@Sun.COM 
161*7836SJohn.Forte@Sun.COM 	return (b);
162*7836SJohn.Forte@Sun.COM }
163*7836SJohn.Forte@Sun.COM 
164*7836SJohn.Forte@Sun.COM /*
165*7836SJohn.Forte@Sun.COM  * ****************************************************************************
166*7836SJohn.Forte@Sun.COM  * avl_lr:
167*7836SJohn.Forte@Sun.COM  *	perform LR balance rotation on an AVL tree (or the subtree).
168*7836SJohn.Forte@Sun.COM  *
169*7836SJohn.Forte@Sun.COM  * a	- the left child.
170*7836SJohn.Forte@Sun.COM  * b	- the right child.
171*7836SJohn.Forte@Sun.COM  * return - the new root.
172*7836SJohn.Forte@Sun.COM  *
173*7836SJohn.Forte@Sun.COM  * ****************************************************************************
174*7836SJohn.Forte@Sun.COM  */
175*7836SJohn.Forte@Sun.COM static htab_itemx_t *
avl_lr(htab_itemx_t * a,htab_itemx_t * b)176*7836SJohn.Forte@Sun.COM avl_lr(
177*7836SJohn.Forte@Sun.COM 	htab_itemx_t *a,
178*7836SJohn.Forte@Sun.COM 	htab_itemx_t *b
179*7836SJohn.Forte@Sun.COM )
180*7836SJohn.Forte@Sun.COM {
181*7836SJohn.Forte@Sun.COM 	htab_itemx_t *c;
182*7836SJohn.Forte@Sun.COM 
183*7836SJohn.Forte@Sun.COM 	c = b->r;
184*7836SJohn.Forte@Sun.COM 
185*7836SJohn.Forte@Sun.COM 	/* rotate left and then right */
186*7836SJohn.Forte@Sun.COM 	a->l = c->r;
187*7836SJohn.Forte@Sun.COM 	c->r = a;
188*7836SJohn.Forte@Sun.COM 	b->r = c->l;
189*7836SJohn.Forte@Sun.COM 	c->l = b;
190*7836SJohn.Forte@Sun.COM 
191*7836SJohn.Forte@Sun.COM 	/* update balance factor */
192*7836SJohn.Forte@Sun.COM 	switch (c->bf) {
193*7836SJohn.Forte@Sun.COM 	case -1:
194*7836SJohn.Forte@Sun.COM 		/* on c's right */
195*7836SJohn.Forte@Sun.COM 		a->bf = 0;
196*7836SJohn.Forte@Sun.COM 		b->bf = 1;
197*7836SJohn.Forte@Sun.COM 		break;
198*7836SJohn.Forte@Sun.COM 	case 0:
199*7836SJohn.Forte@Sun.COM 		/* on c itself */
200*7836SJohn.Forte@Sun.COM 		a->bf = 0;
201*7836SJohn.Forte@Sun.COM 		b->bf = 0;
202*7836SJohn.Forte@Sun.COM 		break;
203*7836SJohn.Forte@Sun.COM 	case 1:
204*7836SJohn.Forte@Sun.COM 		/* on c's left */
205*7836SJohn.Forte@Sun.COM 		a->bf = -1;
206*7836SJohn.Forte@Sun.COM 		b->bf = 0;
207*7836SJohn.Forte@Sun.COM 		break;
208*7836SJohn.Forte@Sun.COM 	}
209*7836SJohn.Forte@Sun.COM 	c->bf = 0;
210*7836SJohn.Forte@Sun.COM 
211*7836SJohn.Forte@Sun.COM 	return (c);
212*7836SJohn.Forte@Sun.COM }
213*7836SJohn.Forte@Sun.COM 
214*7836SJohn.Forte@Sun.COM /*
215*7836SJohn.Forte@Sun.COM  * ****************************************************************************
216*7836SJohn.Forte@Sun.COM  * avl_rl:
217*7836SJohn.Forte@Sun.COM  *	perform RL balance rotation on an AVL tree (or the subtree).
218*7836SJohn.Forte@Sun.COM  *
219*7836SJohn.Forte@Sun.COM  * a	- the left child.
220*7836SJohn.Forte@Sun.COM  * b	- the right child.
221*7836SJohn.Forte@Sun.COM  * return - the new root.
222*7836SJohn.Forte@Sun.COM  *
223*7836SJohn.Forte@Sun.COM  * ****************************************************************************
224*7836SJohn.Forte@Sun.COM  */
225*7836SJohn.Forte@Sun.COM static htab_itemx_t *
avl_rl(htab_itemx_t * a,htab_itemx_t * b)226*7836SJohn.Forte@Sun.COM avl_rl(
227*7836SJohn.Forte@Sun.COM 	htab_itemx_t *a,
228*7836SJohn.Forte@Sun.COM 	htab_itemx_t *b
229*7836SJohn.Forte@Sun.COM )
230*7836SJohn.Forte@Sun.COM {
231*7836SJohn.Forte@Sun.COM 	htab_itemx_t *c;
232*7836SJohn.Forte@Sun.COM 
233*7836SJohn.Forte@Sun.COM 	c = b->l;
234*7836SJohn.Forte@Sun.COM 
235*7836SJohn.Forte@Sun.COM 	/* rotate right and then left */
236*7836SJohn.Forte@Sun.COM 	a->r = c->l;
237*7836SJohn.Forte@Sun.COM 	c->l = a;
238*7836SJohn.Forte@Sun.COM 	b->l = c->r;
239*7836SJohn.Forte@Sun.COM 	c->r = b;
240*7836SJohn.Forte@Sun.COM 
241*7836SJohn.Forte@Sun.COM 	/* update balance factor */
242*7836SJohn.Forte@Sun.COM 	switch (c->bf) {
243*7836SJohn.Forte@Sun.COM 	case -1:
244*7836SJohn.Forte@Sun.COM 		/* on c's right */
245*7836SJohn.Forte@Sun.COM 		a->bf = 1;
246*7836SJohn.Forte@Sun.COM 		b->bf = 0;
247*7836SJohn.Forte@Sun.COM 		break;
248*7836SJohn.Forte@Sun.COM 	case 0:
249*7836SJohn.Forte@Sun.COM 		/* on c itself */
250*7836SJohn.Forte@Sun.COM 		a->bf = 0;
251*7836SJohn.Forte@Sun.COM 		b->bf = 0;
252*7836SJohn.Forte@Sun.COM 		break;
253*7836SJohn.Forte@Sun.COM 	case 1:
254*7836SJohn.Forte@Sun.COM 		/* on c's left */
255*7836SJohn.Forte@Sun.COM 		a->bf = 0;
256*7836SJohn.Forte@Sun.COM 		b->bf = -1;
257*7836SJohn.Forte@Sun.COM 		break;
258*7836SJohn.Forte@Sun.COM 	}
259*7836SJohn.Forte@Sun.COM 	c->bf = 0;
260*7836SJohn.Forte@Sun.COM 
261*7836SJohn.Forte@Sun.COM 	return (c);
262*7836SJohn.Forte@Sun.COM }
263*7836SJohn.Forte@Sun.COM 
264*7836SJohn.Forte@Sun.COM /*
265*7836SJohn.Forte@Sun.COM  * ****************************************************************************
266*7836SJohn.Forte@Sun.COM  * avl_insert:
267*7836SJohn.Forte@Sun.COM  *	insert a node into an AVL tree.
268*7836SJohn.Forte@Sun.COM  *
269*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
270*7836SJohn.Forte@Sun.COM  * x	- the node being added.
271*7836SJohn.Forte@Sun.COM  *
272*7836SJohn.Forte@Sun.COM  * ****************************************************************************
273*7836SJohn.Forte@Sun.COM  */
274*7836SJohn.Forte@Sun.COM static void
avl_insert(htab_t * tab,htab_itemx_t * x)275*7836SJohn.Forte@Sun.COM avl_insert(
276*7836SJohn.Forte@Sun.COM 	htab_t *tab,
277*7836SJohn.Forte@Sun.COM 	htab_itemx_t *x
278*7836SJohn.Forte@Sun.COM )
279*7836SJohn.Forte@Sun.COM {
280*7836SJohn.Forte@Sun.COM 	htab_itemx_t *f, *a, *p, *q, *b, *c;
281*7836SJohn.Forte@Sun.COM 	int d;
282*7836SJohn.Forte@Sun.COM 
283*7836SJohn.Forte@Sun.COM 	/* initialize the new one */
284*7836SJohn.Forte@Sun.COM 	x->bf = 0;
285*7836SJohn.Forte@Sun.COM 	x->l = NULL;
286*7836SJohn.Forte@Sun.COM 	x->r = NULL;
287*7836SJohn.Forte@Sun.COM 
288*7836SJohn.Forte@Sun.COM 	if (tab->avlt == NULL) {
289*7836SJohn.Forte@Sun.COM 		tab->avlt = x;
290*7836SJohn.Forte@Sun.COM 	} else {
291*7836SJohn.Forte@Sun.COM 		/* locate the position */
292*7836SJohn.Forte@Sun.COM 		f = NULL;
293*7836SJohn.Forte@Sun.COM 		a = tab->avlt;
294*7836SJohn.Forte@Sun.COM 		p = tab->avlt;
295*7836SJohn.Forte@Sun.COM 		q = NULL;
296*7836SJohn.Forte@Sun.COM 		while (p != NULL) {
297*7836SJohn.Forte@Sun.COM 			if (p->bf != 0) {
298*7836SJohn.Forte@Sun.COM 				a = p;
299*7836SJohn.Forte@Sun.COM 				f = q;
300*7836SJohn.Forte@Sun.COM 			}
301*7836SJohn.Forte@Sun.COM 			q = p;
302*7836SJohn.Forte@Sun.COM 			if (x->uid < q->uid) {
303*7836SJohn.Forte@Sun.COM 				p = p->l;
304*7836SJohn.Forte@Sun.COM 			} else {
305*7836SJohn.Forte@Sun.COM 				p = p->r;
306*7836SJohn.Forte@Sun.COM 			}
307*7836SJohn.Forte@Sun.COM 		}
308*7836SJohn.Forte@Sun.COM 		/* insert it */
309*7836SJohn.Forte@Sun.COM 		if (x->uid < q->uid) {
310*7836SJohn.Forte@Sun.COM 			q->l = x;
311*7836SJohn.Forte@Sun.COM 		} else {
312*7836SJohn.Forte@Sun.COM 			q->r = x;
313*7836SJohn.Forte@Sun.COM 		}
314*7836SJohn.Forte@Sun.COM 		/* update the balance factor between a to x */
315*7836SJohn.Forte@Sun.COM 		if (x->uid < a->uid) {
316*7836SJohn.Forte@Sun.COM 			p = a->l;
317*7836SJohn.Forte@Sun.COM 			d = 1;
318*7836SJohn.Forte@Sun.COM 		} else {
319*7836SJohn.Forte@Sun.COM 			p = a->r;
320*7836SJohn.Forte@Sun.COM 			d = -1;
321*7836SJohn.Forte@Sun.COM 		}
322*7836SJohn.Forte@Sun.COM 		b = p;
323*7836SJohn.Forte@Sun.COM 		while (p != x) {
324*7836SJohn.Forte@Sun.COM 			if (x->uid < p->uid) {
325*7836SJohn.Forte@Sun.COM 				p->bf = 1;
326*7836SJohn.Forte@Sun.COM 				p = p->l;
327*7836SJohn.Forte@Sun.COM 			} else {
328*7836SJohn.Forte@Sun.COM 				p->bf = -1;
329*7836SJohn.Forte@Sun.COM 				p = p->r;
330*7836SJohn.Forte@Sun.COM 			}
331*7836SJohn.Forte@Sun.COM 		}
332*7836SJohn.Forte@Sun.COM 		/* brance is not broken */
333*7836SJohn.Forte@Sun.COM 		if (a->bf == 0) {
334*7836SJohn.Forte@Sun.COM 			a->bf = d;
335*7836SJohn.Forte@Sun.COM 			goto bal_done;
336*7836SJohn.Forte@Sun.COM 		} else if (a->bf + d == 0) {
337*7836SJohn.Forte@Sun.COM 			a->bf = 0;
338*7836SJohn.Forte@Sun.COM 			goto bal_done;
339*7836SJohn.Forte@Sun.COM 		}
340*7836SJohn.Forte@Sun.COM 		/* rotate the tree */
341*7836SJohn.Forte@Sun.COM 		if (d == 1) {
342*7836SJohn.Forte@Sun.COM 			if (b->bf == 1) {
343*7836SJohn.Forte@Sun.COM 				/* LL rotate */
344*7836SJohn.Forte@Sun.COM 				c = avl_ll(a, b);
345*7836SJohn.Forte@Sun.COM 			} else if (b->bf == -1) {
346*7836SJohn.Forte@Sun.COM 				/* LR rotate */
347*7836SJohn.Forte@Sun.COM 				c = avl_lr(a, b);
348*7836SJohn.Forte@Sun.COM 			}
349*7836SJohn.Forte@Sun.COM 		} else {
350*7836SJohn.Forte@Sun.COM 			if (b->bf == -1) {
351*7836SJohn.Forte@Sun.COM 				/* RR rotate */
352*7836SJohn.Forte@Sun.COM 				c = avl_rr(a, b);
353*7836SJohn.Forte@Sun.COM 			} else if (b->bf == 1) {
354*7836SJohn.Forte@Sun.COM 				/* RL rotate */
355*7836SJohn.Forte@Sun.COM 				c = avl_rl(a, b);
356*7836SJohn.Forte@Sun.COM 			}
357*7836SJohn.Forte@Sun.COM 		}
358*7836SJohn.Forte@Sun.COM 		/* update the parent */
359*7836SJohn.Forte@Sun.COM 		if (f == NULL) {
360*7836SJohn.Forte@Sun.COM 			tab->avlt = c;
361*7836SJohn.Forte@Sun.COM 		} else if (f->l == a) {
362*7836SJohn.Forte@Sun.COM 			f->l = c;
363*7836SJohn.Forte@Sun.COM 		} else if (f->r == a) {
364*7836SJohn.Forte@Sun.COM 			f->r = c;
365*7836SJohn.Forte@Sun.COM 		}
366*7836SJohn.Forte@Sun.COM 	}
367*7836SJohn.Forte@Sun.COM 
368*7836SJohn.Forte@Sun.COM bal_done:
369*7836SJohn.Forte@Sun.COM 	if (x->uid > tab->buid) {
370*7836SJohn.Forte@Sun.COM 		tab->buid = x->uid;
371*7836SJohn.Forte@Sun.COM 	}
372*7836SJohn.Forte@Sun.COM }
373*7836SJohn.Forte@Sun.COM 
374*7836SJohn.Forte@Sun.COM /*
375*7836SJohn.Forte@Sun.COM  * ****************************************************************************
376*7836SJohn.Forte@Sun.COM  * new_uid:
377*7836SJohn.Forte@Sun.COM  *	allocate new node(s) of the avl tree.
378*7836SJohn.Forte@Sun.COM  *
379*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
380*7836SJohn.Forte@Sun.COM  * uid	- the UID of the node.
381*7836SJohn.Forte@Sun.COM  * return - the newly allocated UID node.
382*7836SJohn.Forte@Sun.COM  *
383*7836SJohn.Forte@Sun.COM  * ****************************************************************************
384*7836SJohn.Forte@Sun.COM  */
385*7836SJohn.Forte@Sun.COM static htab_itemx_t *
new_uid(htab_t * tab,uint32_t uid)386*7836SJohn.Forte@Sun.COM new_uid(
387*7836SJohn.Forte@Sun.COM 	htab_t *tab,
388*7836SJohn.Forte@Sun.COM 	uint32_t uid
389*7836SJohn.Forte@Sun.COM )
390*7836SJohn.Forte@Sun.COM {
391*7836SJohn.Forte@Sun.COM 	htab_itemx_t *x = NULL;
392*7836SJohn.Forte@Sun.COM 
393*7836SJohn.Forte@Sun.COM 	uint32_t start, end;
394*7836SJohn.Forte@Sun.COM 
395*7836SJohn.Forte@Sun.COM 	/* overflow happened */
396*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
397*7836SJohn.Forte@Sun.COM 		/* search for an unused one */
398*7836SJohn.Forte@Sun.COM 		uid ++;
399*7836SJohn.Forte@Sun.COM 		while (uid != 0 &&
400*7836SJohn.Forte@Sun.COM 		    avl_search(tab, uid) != NULL) {
401*7836SJohn.Forte@Sun.COM 			uid ++;
402*7836SJohn.Forte@Sun.COM 		}
403*7836SJohn.Forte@Sun.COM 		if (uid == 0) {
404*7836SJohn.Forte@Sun.COM 			/* all are used up, sigh! */
405*7836SJohn.Forte@Sun.COM 			return (NULL);
406*7836SJohn.Forte@Sun.COM 		}
407*7836SJohn.Forte@Sun.COM 	}
408*7836SJohn.Forte@Sun.COM 
409*7836SJohn.Forte@Sun.COM 	/* check if there is a gap and the gap needs to be filled up */
410*7836SJohn.Forte@Sun.COM 	if (uid > tab->buid &&
411*7836SJohn.Forte@Sun.COM 	    (tab->flags & UID_FLAGS_SEQ) != 0) {
412*7836SJohn.Forte@Sun.COM 		start = tab->buid + 1;
413*7836SJohn.Forte@Sun.COM 	} else {
414*7836SJohn.Forte@Sun.COM 		start = uid;
415*7836SJohn.Forte@Sun.COM 	}
416*7836SJohn.Forte@Sun.COM 	end = uid;
417*7836SJohn.Forte@Sun.COM 
418*7836SJohn.Forte@Sun.COM 	/* make new UID(s) */
419*7836SJohn.Forte@Sun.COM 	do {
420*7836SJohn.Forte@Sun.COM 		if (x != NULL) {
421*7836SJohn.Forte@Sun.COM 			x->hval = BAD_HVAL_MASK;
422*7836SJohn.Forte@Sun.COM 			x->t = 0;
423*7836SJohn.Forte@Sun.COM 			/* put it to the start of the fifo list */
424*7836SJohn.Forte@Sun.COM 			x->n = tab->list;
425*7836SJohn.Forte@Sun.COM 			tab->list = x;
426*7836SJohn.Forte@Sun.COM 			if (tab->tail == NULL) {
427*7836SJohn.Forte@Sun.COM 				tab->tail = x;
428*7836SJohn.Forte@Sun.COM 			}
429*7836SJohn.Forte@Sun.COM 		}
430*7836SJohn.Forte@Sun.COM 		x = (htab_itemx_t *)malloc(sizeof (htab_itemx_t));
431*7836SJohn.Forte@Sun.COM 		if (x != NULL) {
432*7836SJohn.Forte@Sun.COM 			x->uid = start;
433*7836SJohn.Forte@Sun.COM 			x->n = NULL;
434*7836SJohn.Forte@Sun.COM 			/* insert it to the tree */
435*7836SJohn.Forte@Sun.COM 			avl_insert(tab, x);
436*7836SJohn.Forte@Sun.COM 		}
437*7836SJohn.Forte@Sun.COM 		start ++;
438*7836SJohn.Forte@Sun.COM 	} while (x != NULL && start <= end && start != 0);
439*7836SJohn.Forte@Sun.COM 
440*7836SJohn.Forte@Sun.COM 	return (x);
441*7836SJohn.Forte@Sun.COM }
442*7836SJohn.Forte@Sun.COM 
443*7836SJohn.Forte@Sun.COM /*
444*7836SJohn.Forte@Sun.COM  * ****************************************************************************
445*7836SJohn.Forte@Sun.COM  * uid_insert:
446*7836SJohn.Forte@Sun.COM  *	insert a new UID node to the avl tree.
447*7836SJohn.Forte@Sun.COM  *
448*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
449*7836SJohn.Forte@Sun.COM  * uid_p- the pointer of the UID.
450*7836SJohn.Forte@Sun.COM  * hval	- the hash value of the new node.
451*7836SJohn.Forte@Sun.COM  * return -	0: no UID value assigned;
452*7836SJohn.Forte@Sun.COM  *		1: assigned an UID.
453*7836SJohn.Forte@Sun.COM  *		-1: no memory.
454*7836SJohn.Forte@Sun.COM  *		-2: invalid UID.
455*7836SJohn.Forte@Sun.COM  *
456*7836SJohn.Forte@Sun.COM  * ****************************************************************************
457*7836SJohn.Forte@Sun.COM  */
458*7836SJohn.Forte@Sun.COM static int
uid_insert(htab_t * tab,uint32_t * const uid_p,const uint32_t hval)459*7836SJohn.Forte@Sun.COM uid_insert(
460*7836SJohn.Forte@Sun.COM 	htab_t *tab,
461*7836SJohn.Forte@Sun.COM 	uint32_t *const uid_p,
462*7836SJohn.Forte@Sun.COM 	const uint32_t hval
463*7836SJohn.Forte@Sun.COM )
464*7836SJohn.Forte@Sun.COM {
465*7836SJohn.Forte@Sun.COM 	int assignx = 0;
466*7836SJohn.Forte@Sun.COM 
467*7836SJohn.Forte@Sun.COM 	uint32_t uid = *uid_p;
468*7836SJohn.Forte@Sun.COM 
469*7836SJohn.Forte@Sun.COM 	htab_itemx_t *x, *n;
470*7836SJohn.Forte@Sun.COM 
471*7836SJohn.Forte@Sun.COM 	if (uid != 0) {
472*7836SJohn.Forte@Sun.COM 		/* search the existing one from the tree */
473*7836SJohn.Forte@Sun.COM 		x = avl_search(tab, uid);
474*7836SJohn.Forte@Sun.COM 		if (x == NULL) {
475*7836SJohn.Forte@Sun.COM 			x = new_uid(tab, uid);
476*7836SJohn.Forte@Sun.COM 		} else if (!BAD_HVAL(x->hval) &&
477*7836SJohn.Forte@Sun.COM 		    x->hval != hval) {
478*7836SJohn.Forte@Sun.COM 			/* the item with this uid will override an */
479*7836SJohn.Forte@Sun.COM 			/* existing item, we treat this as an error */
480*7836SJohn.Forte@Sun.COM 			return (-2);
481*7836SJohn.Forte@Sun.COM 		}
482*7836SJohn.Forte@Sun.COM 	} else {
483*7836SJohn.Forte@Sun.COM 		/* assign a value */
484*7836SJohn.Forte@Sun.COM 		x = tab->list;
485*7836SJohn.Forte@Sun.COM 		/* strip off the used ones */
486*7836SJohn.Forte@Sun.COM 		while (x != NULL &&
487*7836SJohn.Forte@Sun.COM 		    !BAD_HVAL(x->hval)) {
488*7836SJohn.Forte@Sun.COM 			n = x->n;
489*7836SJohn.Forte@Sun.COM 			x->n = NULL;
490*7836SJohn.Forte@Sun.COM 			x = n;
491*7836SJohn.Forte@Sun.COM 		}
492*7836SJohn.Forte@Sun.COM 
493*7836SJohn.Forte@Sun.COM 		if (x == NULL ||
494*7836SJohn.Forte@Sun.COM 		    UID_REUSABLE(tab->c->timestamp(), x) == 0) {
495*7836SJohn.Forte@Sun.COM 			/* none is available, make a new one */
496*7836SJohn.Forte@Sun.COM 			tab->list = x;
497*7836SJohn.Forte@Sun.COM 			x = new_uid(tab, tab->buid + 1);
498*7836SJohn.Forte@Sun.COM 		} else {
499*7836SJohn.Forte@Sun.COM 			n = x->n;
500*7836SJohn.Forte@Sun.COM 			x->n = NULL;
501*7836SJohn.Forte@Sun.COM 			tab->list = n;
502*7836SJohn.Forte@Sun.COM 		}
503*7836SJohn.Forte@Sun.COM 		/* update the available list */
504*7836SJohn.Forte@Sun.COM 		if (tab->list == NULL) {
505*7836SJohn.Forte@Sun.COM 			tab->tail = NULL;
506*7836SJohn.Forte@Sun.COM 		}
507*7836SJohn.Forte@Sun.COM 		assignx = 1;
508*7836SJohn.Forte@Sun.COM 		if (x != NULL) {
509*7836SJohn.Forte@Sun.COM 			*uid_p = x->uid;
510*7836SJohn.Forte@Sun.COM 		}
511*7836SJohn.Forte@Sun.COM 	}
512*7836SJohn.Forte@Sun.COM 
513*7836SJohn.Forte@Sun.COM 	if (x == NULL) {
514*7836SJohn.Forte@Sun.COM 		return (-1); /* no memory */
515*7836SJohn.Forte@Sun.COM 	}
516*7836SJohn.Forte@Sun.COM 
517*7836SJohn.Forte@Sun.COM 	x->hval = hval;
518*7836SJohn.Forte@Sun.COM 	x->t = 0; /* registration initial time */
519*7836SJohn.Forte@Sun.COM 
520*7836SJohn.Forte@Sun.COM 	return (assignx);
521*7836SJohn.Forte@Sun.COM }
522*7836SJohn.Forte@Sun.COM 
523*7836SJohn.Forte@Sun.COM /*
524*7836SJohn.Forte@Sun.COM  * ****************************************************************************
525*7836SJohn.Forte@Sun.COM  * enlarge_htab:
526*7836SJohn.Forte@Sun.COM  *	enlarge the hash table when it gets too full.
527*7836SJohn.Forte@Sun.COM  *
528*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
529*7836SJohn.Forte@Sun.COM  *
530*7836SJohn.Forte@Sun.COM  * ****************************************************************************
531*7836SJohn.Forte@Sun.COM  */
532*7836SJohn.Forte@Sun.COM static void
enlarge_htab(htab_t * tab)533*7836SJohn.Forte@Sun.COM enlarge_htab(
534*7836SJohn.Forte@Sun.COM 	htab_t *tab
535*7836SJohn.Forte@Sun.COM )
536*7836SJohn.Forte@Sun.COM {
537*7836SJohn.Forte@Sun.COM 	htab_item_t **items;
538*7836SJohn.Forte@Sun.COM 	uint16_t logsize;
539*7836SJohn.Forte@Sun.COM 	uint32_t oldsz, newsz, mask;
540*7836SJohn.Forte@Sun.COM 	htab_item_t *item, *tmp, **itemp;
541*7836SJohn.Forte@Sun.COM 	uint16_t i;
542*7836SJohn.Forte@Sun.COM 	uint32_t j;
543*7836SJohn.Forte@Sun.COM 
544*7836SJohn.Forte@Sun.COM 	uint32_t uid;
545*7836SJohn.Forte@Sun.COM 
546*7836SJohn.Forte@Sun.COM 	/* enlarge the logsize by one */
547*7836SJohn.Forte@Sun.COM 	logsize = tab->logsize + 1;
548*7836SJohn.Forte@Sun.COM 	newsz = (1 << logsize);
549*7836SJohn.Forte@Sun.COM 	items = (htab_item_t **)calloc(
550*7836SJohn.Forte@Sun.COM 	    newsz * tab->chunks, sizeof (htab_item_t *));
551*7836SJohn.Forte@Sun.COM 	/* re-hash all items to the new table */
552*7836SJohn.Forte@Sun.COM 	if (items != NULL) {
553*7836SJohn.Forte@Sun.COM 		mask = newsz - 1;
554*7836SJohn.Forte@Sun.COM 		oldsz = (1 << tab->logsize);
555*7836SJohn.Forte@Sun.COM 		i = 0;
556*7836SJohn.Forte@Sun.COM 		while (i < tab->chunks) {
557*7836SJohn.Forte@Sun.COM 			j = 0;
558*7836SJohn.Forte@Sun.COM 			while (j < oldsz) {
559*7836SJohn.Forte@Sun.COM 				item = tab->items[(i * oldsz) + j];
560*7836SJohn.Forte@Sun.COM 				while (item != NULL) {
561*7836SJohn.Forte@Sun.COM 					tmp = item->next;
562*7836SJohn.Forte@Sun.COM 					itemp = &items[(i * newsz) +
563*7836SJohn.Forte@Sun.COM 					    (item->hval & mask)];
564*7836SJohn.Forte@Sun.COM 					uid = tab->c->get_uid(item->p);
565*7836SJohn.Forte@Sun.COM 					while (*itemp != NULL &&
566*7836SJohn.Forte@Sun.COM 					    tab->c->get_uid((*itemp)->p) >
567*7836SJohn.Forte@Sun.COM 					    uid) {
568*7836SJohn.Forte@Sun.COM 						itemp = &(*itemp)->next;
569*7836SJohn.Forte@Sun.COM 					}
570*7836SJohn.Forte@Sun.COM 					item->next = *itemp;
571*7836SJohn.Forte@Sun.COM 					*itemp = item;
572*7836SJohn.Forte@Sun.COM 					item = tmp;
573*7836SJohn.Forte@Sun.COM 				}
574*7836SJohn.Forte@Sun.COM 				j ++;
575*7836SJohn.Forte@Sun.COM 			}
576*7836SJohn.Forte@Sun.COM 			i ++;
577*7836SJohn.Forte@Sun.COM 		}
578*7836SJohn.Forte@Sun.COM 		free(tab->items);
579*7836SJohn.Forte@Sun.COM 		tab->items = items;
580*7836SJohn.Forte@Sun.COM 		tab->logsize = logsize;
581*7836SJohn.Forte@Sun.COM 		tab->mask = mask;
582*7836SJohn.Forte@Sun.COM 	} else {
583*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "enlarge_htab", "calloc() failed.");
584*7836SJohn.Forte@Sun.COM 	}
585*7836SJohn.Forte@Sun.COM }
586*7836SJohn.Forte@Sun.COM 
587*7836SJohn.Forte@Sun.COM /*
588*7836SJohn.Forte@Sun.COM  * ****************************************************************************
589*7836SJohn.Forte@Sun.COM  * htab_init:
590*7836SJohn.Forte@Sun.COM  *	some generic initialization for the hash table.
591*7836SJohn.Forte@Sun.COM  *
592*7836SJohn.Forte@Sun.COM  * ****************************************************************************
593*7836SJohn.Forte@Sun.COM  */
594*7836SJohn.Forte@Sun.COM void
htab_init()595*7836SJohn.Forte@Sun.COM htab_init(
596*7836SJohn.Forte@Sun.COM )
597*7836SJohn.Forte@Sun.COM {
598*7836SJohn.Forte@Sun.COM 	/* do nothing */
599*7836SJohn.Forte@Sun.COM }
600*7836SJohn.Forte@Sun.COM 
601*7836SJohn.Forte@Sun.COM /*
602*7836SJohn.Forte@Sun.COM  * ****************************************************************************
603*7836SJohn.Forte@Sun.COM  * htab_create:
604*7836SJohn.Forte@Sun.COM  *	create a new hash table.
605*7836SJohn.Forte@Sun.COM  *
606*7836SJohn.Forte@Sun.COM  * flags - UID_FLAGS_SEQ: the UID in the table needs to be sequential.
607*7836SJohn.Forte@Sun.COM  * logsize - the hash table logsize.
608*7836SJohn.Forte@Sun.COM  * chunks  - the number of seperated chunks of the table.
609*7836SJohn.Forte@Sun.COM  * return  - the newly created hash table.
610*7836SJohn.Forte@Sun.COM  *
611*7836SJohn.Forte@Sun.COM  * ****************************************************************************
612*7836SJohn.Forte@Sun.COM  */
613*7836SJohn.Forte@Sun.COM htab_t *
htab_create(int flags,uint16_t logsize,uint16_t chunks)614*7836SJohn.Forte@Sun.COM htab_create(
615*7836SJohn.Forte@Sun.COM 	int flags,
616*7836SJohn.Forte@Sun.COM 	uint16_t logsize,
617*7836SJohn.Forte@Sun.COM 	uint16_t chunks
618*7836SJohn.Forte@Sun.COM )
619*7836SJohn.Forte@Sun.COM {
620*7836SJohn.Forte@Sun.COM 	htab_t *tab = NULL;
621*7836SJohn.Forte@Sun.COM 	htab_item_t **items = NULL;
622*7836SJohn.Forte@Sun.COM 	uint32_t count;
623*7836SJohn.Forte@Sun.COM 
624*7836SJohn.Forte@Sun.COM 	/* do not enlarge it if the logsize reaches the maximum */
625*7836SJohn.Forte@Sun.COM 	if (logsize <= MAX_LOGSIZE &&
626*7836SJohn.Forte@Sun.COM 	    chunks > 0) {
627*7836SJohn.Forte@Sun.COM 		tab = (htab_t *)calloc(1, sizeof (htab_t));
628*7836SJohn.Forte@Sun.COM 		if (tab != NULL) {
629*7836SJohn.Forte@Sun.COM 			count = (1 << logsize);
630*7836SJohn.Forte@Sun.COM 			items = (htab_item_t **)calloc(
631*7836SJohn.Forte@Sun.COM 			    count * chunks, sizeof (htab_item_t *));
632*7836SJohn.Forte@Sun.COM 			if (items != NULL) {
633*7836SJohn.Forte@Sun.COM 				tab->flags = flags;
634*7836SJohn.Forte@Sun.COM 				tab->items = items;
635*7836SJohn.Forte@Sun.COM 				tab->logsize = logsize;
636*7836SJohn.Forte@Sun.COM 				tab->chunks = chunks;
637*7836SJohn.Forte@Sun.COM 				tab->mask = count - 1;
638*7836SJohn.Forte@Sun.COM 				tab->count = 1; /* reserve one */
639*7836SJohn.Forte@Sun.COM 				tab->avlt = NULL;
640*7836SJohn.Forte@Sun.COM 				tab->buid = 0;
641*7836SJohn.Forte@Sun.COM 				tab->list = NULL;
642*7836SJohn.Forte@Sun.COM 				tab->tail = NULL;
643*7836SJohn.Forte@Sun.COM 			} else {
644*7836SJohn.Forte@Sun.COM 				free(tab);
645*7836SJohn.Forte@Sun.COM 				tab = NULL;
646*7836SJohn.Forte@Sun.COM 			}
647*7836SJohn.Forte@Sun.COM 		}
648*7836SJohn.Forte@Sun.COM 	}
649*7836SJohn.Forte@Sun.COM 
650*7836SJohn.Forte@Sun.COM 	return (tab);
651*7836SJohn.Forte@Sun.COM }
652*7836SJohn.Forte@Sun.COM 
653*7836SJohn.Forte@Sun.COM /*
654*7836SJohn.Forte@Sun.COM  * ****************************************************************************
655*7836SJohn.Forte@Sun.COM  * htab_compute_hval:
656*7836SJohn.Forte@Sun.COM  *	compute a hash value for the specified key.
657*7836SJohn.Forte@Sun.COM  *
658*7836SJohn.Forte@Sun.COM  * key - the key of the hash.
659*7836SJohn.Forte@Sun.COM  * return - the hash value.
660*7836SJohn.Forte@Sun.COM  *
661*7836SJohn.Forte@Sun.COM  * ****************************************************************************
662*7836SJohn.Forte@Sun.COM  */
663*7836SJohn.Forte@Sun.COM uint32_t
htab_compute_hval(const uchar_t * key)664*7836SJohn.Forte@Sun.COM htab_compute_hval(
665*7836SJohn.Forte@Sun.COM 	const uchar_t *key
666*7836SJohn.Forte@Sun.COM )
667*7836SJohn.Forte@Sun.COM {
668*7836SJohn.Forte@Sun.COM 	/* use classic Dan Bernstein hash alorigthm */
669*7836SJohn.Forte@Sun.COM 	uint32_t hash = 5381;
670*7836SJohn.Forte@Sun.COM 	int c;
671*7836SJohn.Forte@Sun.COM 
672*7836SJohn.Forte@Sun.COM 	while ((c = *key++) != 0) {
673*7836SJohn.Forte@Sun.COM 		hash = ((hash << 5) + hash) + c;
674*7836SJohn.Forte@Sun.COM 	}
675*7836SJohn.Forte@Sun.COM 
676*7836SJohn.Forte@Sun.COM 	return (hash);
677*7836SJohn.Forte@Sun.COM }
678*7836SJohn.Forte@Sun.COM 
679*7836SJohn.Forte@Sun.COM /*
680*7836SJohn.Forte@Sun.COM  * ****************************************************************************
681*7836SJohn.Forte@Sun.COM  * htab_add:
682*7836SJohn.Forte@Sun.COM  *	add an object to the hash table.
683*7836SJohn.Forte@Sun.COM  *
684*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
685*7836SJohn.Forte@Sun.COM  * p	- the object.
686*7836SJohn.Forte@Sun.COM  * flag	- 0: not an association object; otherwise association object.
687*7836SJohn.Forte@Sun.COM  * uid_p- pointer of UID for returning.
688*7836SJohn.Forte@Sun.COM  * update_p - pointer of update flag for returning.
689*7836SJohn.Forte@Sun.COM  * return - error code.
690*7836SJohn.Forte@Sun.COM  *
691*7836SJohn.Forte@Sun.COM  * ****************************************************************************
692*7836SJohn.Forte@Sun.COM  */
693*7836SJohn.Forte@Sun.COM int
htab_add(htab_t * tab,void * p,int flag,uint32_t * uid_p,int * update_p)694*7836SJohn.Forte@Sun.COM htab_add(
695*7836SJohn.Forte@Sun.COM 	htab_t *tab,
696*7836SJohn.Forte@Sun.COM 	void *p,
697*7836SJohn.Forte@Sun.COM 	int flag,
698*7836SJohn.Forte@Sun.COM 	uint32_t *uid_p,
699*7836SJohn.Forte@Sun.COM 	int *update_p
700*7836SJohn.Forte@Sun.COM )
701*7836SJohn.Forte@Sun.COM {
702*7836SJohn.Forte@Sun.COM 	int ec = 0;
703*7836SJohn.Forte@Sun.COM 
704*7836SJohn.Forte@Sun.COM 	htab_item_t *items = NULL, **itemp;
705*7836SJohn.Forte@Sun.COM 	uint32_t chunksz;
706*7836SJohn.Forte@Sun.COM 	uint32_t flags = 0;
707*7836SJohn.Forte@Sun.COM 	uint32_t hval;
708*7836SJohn.Forte@Sun.COM 	uint32_t uid = 0;
709*7836SJohn.Forte@Sun.COM 	int i;
710*7836SJohn.Forte@Sun.COM 
711*7836SJohn.Forte@Sun.COM 	/* compute the hash value */
712*7836SJohn.Forte@Sun.COM 	hval = VALID_HVAL(tab->c->get_hval(p, 0, &flags));
713*7836SJohn.Forte@Sun.COM 
714*7836SJohn.Forte@Sun.COM 	/* check for duplicate */
715*7836SJohn.Forte@Sun.COM 	items = tab->items[hval & tab->mask];
716*7836SJohn.Forte@Sun.COM 	while (items != NULL) {
717*7836SJohn.Forte@Sun.COM 		if (tab->c->cmp(items->p, p, 0) == 0) {
718*7836SJohn.Forte@Sun.COM 			if (flag == 0) {
719*7836SJohn.Forte@Sun.COM 				ec = tab->c->replace_hook(items->p, p, uid_p,
720*7836SJohn.Forte@Sun.COM 				    update_p == NULL ? 1 : 0);
721*7836SJohn.Forte@Sun.COM 			}
722*7836SJohn.Forte@Sun.COM 			if (update_p != NULL) {
723*7836SJohn.Forte@Sun.COM 				*update_p = 1;
724*7836SJohn.Forte@Sun.COM 			}
725*7836SJohn.Forte@Sun.COM 			items = NULL;
726*7836SJohn.Forte@Sun.COM 			goto add_done;
727*7836SJohn.Forte@Sun.COM 		}
728*7836SJohn.Forte@Sun.COM 		items = items->next;
729*7836SJohn.Forte@Sun.COM 	}
730*7836SJohn.Forte@Sun.COM 
731*7836SJohn.Forte@Sun.COM 	/* add new object */
732*7836SJohn.Forte@Sun.COM 	if (update_p != NULL) {
733*7836SJohn.Forte@Sun.COM 		*update_p = 0;
734*7836SJohn.Forte@Sun.COM 	}
735*7836SJohn.Forte@Sun.COM 
736*7836SJohn.Forte@Sun.COM 	/* make new items for the object */
737*7836SJohn.Forte@Sun.COM 	items = (htab_item_t *)calloc(tab->chunks, sizeof (htab_item_t));
738*7836SJohn.Forte@Sun.COM 
739*7836SJohn.Forte@Sun.COM 	if (items == NULL ||
740*7836SJohn.Forte@Sun.COM 	    tab->count == 0 ||
741*7836SJohn.Forte@Sun.COM 	    (++tab->count) == 0) {
742*7836SJohn.Forte@Sun.COM 		/* no memory or table is full */
743*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
744*7836SJohn.Forte@Sun.COM 		goto add_done;
745*7836SJohn.Forte@Sun.COM 	}
746*7836SJohn.Forte@Sun.COM 
747*7836SJohn.Forte@Sun.COM 	/* check if the table needs is too full */
748*7836SJohn.Forte@Sun.COM 	chunksz = (1 << tab->logsize);
749*7836SJohn.Forte@Sun.COM 	if (tab->count >= (chunksz * HASH_RATIO) &&
750*7836SJohn.Forte@Sun.COM 	    tab->logsize < MAX_LOGSIZE) {
751*7836SJohn.Forte@Sun.COM 		enlarge_htab(tab);
752*7836SJohn.Forte@Sun.COM 		chunksz = (1 << tab->logsize);
753*7836SJohn.Forte@Sun.COM 	}
754*7836SJohn.Forte@Sun.COM 
755*7836SJohn.Forte@Sun.COM 	/* put the UID of the object to the avl tree */
756*7836SJohn.Forte@Sun.COM 	uid = tab->c->get_uid(p);
757*7836SJohn.Forte@Sun.COM 	switch (uid_insert(tab, &uid, hval)) {
758*7836SJohn.Forte@Sun.COM 	case -2:
759*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INVALID_REGIS;
760*7836SJohn.Forte@Sun.COM 		goto add_done;
761*7836SJohn.Forte@Sun.COM 	case -1:
762*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
763*7836SJohn.Forte@Sun.COM 		goto add_done;
764*7836SJohn.Forte@Sun.COM 	case 0:
765*7836SJohn.Forte@Sun.COM 		break;
766*7836SJohn.Forte@Sun.COM 	case 1:
767*7836SJohn.Forte@Sun.COM 		tab->c->set_uid(p, uid);
768*7836SJohn.Forte@Sun.COM 		break;
769*7836SJohn.Forte@Sun.COM 	default:
770*7836SJohn.Forte@Sun.COM 		break;
771*7836SJohn.Forte@Sun.COM 	}
772*7836SJohn.Forte@Sun.COM 
773*7836SJohn.Forte@Sun.COM 	/* update data store before putting to hash table */
774*7836SJohn.Forte@Sun.COM 	if (flag == 0) {
775*7836SJohn.Forte@Sun.COM 		/* not association object */
776*7836SJohn.Forte@Sun.COM 		ec = tab->c->add_hook(p);
777*7836SJohn.Forte@Sun.COM 	}
778*7836SJohn.Forte@Sun.COM 
779*7836SJohn.Forte@Sun.COM 	/* put the object to the table */
780*7836SJohn.Forte@Sun.COM 	for (i = 0; ec == 0; ) {
781*7836SJohn.Forte@Sun.COM 		items[i].hval = hval;
782*7836SJohn.Forte@Sun.COM 		items[i].p = p;
783*7836SJohn.Forte@Sun.COM 		itemp = &tab->items[(i * chunksz) + (hval & tab->mask)];
784*7836SJohn.Forte@Sun.COM 		while (*itemp != NULL &&
785*7836SJohn.Forte@Sun.COM 		    tab->c->get_uid((*itemp)->p) > uid) {
786*7836SJohn.Forte@Sun.COM 			itemp = &(*itemp)->next;
787*7836SJohn.Forte@Sun.COM 		}
788*7836SJohn.Forte@Sun.COM 		items[i].next = *itemp;
789*7836SJohn.Forte@Sun.COM 		*itemp = &items[i];
790*7836SJohn.Forte@Sun.COM 		i ++;
791*7836SJohn.Forte@Sun.COM 		if (i < tab->chunks) {
792*7836SJohn.Forte@Sun.COM 			hval = VALID_HVAL(tab->c->get_hval(p, i, &flags));
793*7836SJohn.Forte@Sun.COM 		} else {
794*7836SJohn.Forte@Sun.COM 			break;
795*7836SJohn.Forte@Sun.COM 		}
796*7836SJohn.Forte@Sun.COM 	}
797*7836SJohn.Forte@Sun.COM 
798*7836SJohn.Forte@Sun.COM 	/* cache has been successfully updated */
799*7836SJohn.Forte@Sun.COM 	SET_CACHE_UPDATED();
800*7836SJohn.Forte@Sun.COM 
801*7836SJohn.Forte@Sun.COM 	/* successfully added */
802*7836SJohn.Forte@Sun.COM 	items = NULL;
803*7836SJohn.Forte@Sun.COM 
804*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
805*7836SJohn.Forte@Sun.COM 		/* perform the Default DD behavior */
806*7836SJohn.Forte@Sun.COM 		tab->c->ddd(p, '+');
807*7836SJohn.Forte@Sun.COM 
808*7836SJohn.Forte@Sun.COM 		/* set the return uid */
809*7836SJohn.Forte@Sun.COM 		if (uid_p != NULL) {
810*7836SJohn.Forte@Sun.COM 			*uid_p = uid;
811*7836SJohn.Forte@Sun.COM 		}
812*7836SJohn.Forte@Sun.COM 	}
813*7836SJohn.Forte@Sun.COM add_done:
814*7836SJohn.Forte@Sun.COM 	if (ec != 0 && items != NULL) {
815*7836SJohn.Forte@Sun.COM 		free(items);
816*7836SJohn.Forte@Sun.COM 	}
817*7836SJohn.Forte@Sun.COM 
818*7836SJohn.Forte@Sun.COM 	return (ec);
819*7836SJohn.Forte@Sun.COM }
820*7836SJohn.Forte@Sun.COM 
821*7836SJohn.Forte@Sun.COM /*
822*7836SJohn.Forte@Sun.COM  * ****************************************************************************
823*7836SJohn.Forte@Sun.COM  * htab_remove:
824*7836SJohn.Forte@Sun.COM  *	remove an object from the hash table.
825*7836SJohn.Forte@Sun.COM  *
826*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
827*7836SJohn.Forte@Sun.COM  * p	- the lookup control for the object.
828*7836SJohn.Forte@Sun.COM  * uid	- the UID of the object.
829*7836SJohn.Forte@Sun.COM  * clone_flag - indicate if the removing is for an association object.
830*7836SJohn.Forte@Sun.COM  * return - the removed object.
831*7836SJohn.Forte@Sun.COM  *
832*7836SJohn.Forte@Sun.COM  * ****************************************************************************
833*7836SJohn.Forte@Sun.COM  */
834*7836SJohn.Forte@Sun.COM isns_obj_t *
htab_remove(htab_t * tab,void * p,uint32_t uid,int clone_flag)835*7836SJohn.Forte@Sun.COM htab_remove(
836*7836SJohn.Forte@Sun.COM 	htab_t *tab,
837*7836SJohn.Forte@Sun.COM 	void *p,
838*7836SJohn.Forte@Sun.COM 	uint32_t uid,
839*7836SJohn.Forte@Sun.COM 	int clone_flag
840*7836SJohn.Forte@Sun.COM )
841*7836SJohn.Forte@Sun.COM {
842*7836SJohn.Forte@Sun.COM 	void *zhizi = NULL;
843*7836SJohn.Forte@Sun.COM 	void *clone = NULL;
844*7836SJohn.Forte@Sun.COM 	htab_item_t *items = NULL;
845*7836SJohn.Forte@Sun.COM 	htab_item_t *item, **itemp;
846*7836SJohn.Forte@Sun.COM 	htab_itemx_t *x = NULL;
847*7836SJohn.Forte@Sun.COM 	uint32_t chunksz;
848*7836SJohn.Forte@Sun.COM 	uint32_t flags;
849*7836SJohn.Forte@Sun.COM 	uint32_t hval;
850*7836SJohn.Forte@Sun.COM 	int i;
851*7836SJohn.Forte@Sun.COM 
852*7836SJohn.Forte@Sun.COM 	/* get the object hash value */
853*7836SJohn.Forte@Sun.COM 	if (uid != 0) {
854*7836SJohn.Forte@Sun.COM 		x = avl_search(tab, uid);
855*7836SJohn.Forte@Sun.COM 		if (x != NULL && !BAD_HVAL(x->hval)) {
856*7836SJohn.Forte@Sun.COM 			hval = x->hval;
857*7836SJohn.Forte@Sun.COM 		} else {
858*7836SJohn.Forte@Sun.COM 			goto remove_done;
859*7836SJohn.Forte@Sun.COM 		}
860*7836SJohn.Forte@Sun.COM 	} else {
861*7836SJohn.Forte@Sun.COM 		flags = 0 | FLAGS_CTRL_MASK;
862*7836SJohn.Forte@Sun.COM 		hval = VALID_HVAL(tab->c->get_hval(p, 0, &flags));
863*7836SJohn.Forte@Sun.COM 	}
864*7836SJohn.Forte@Sun.COM 
865*7836SJohn.Forte@Sun.COM 	/* search the object from the table */
866*7836SJohn.Forte@Sun.COM 	flags = 0;
867*7836SJohn.Forte@Sun.COM 	chunksz = (1 << tab->logsize);
868*7836SJohn.Forte@Sun.COM 	for (i = 0; ; ) {
869*7836SJohn.Forte@Sun.COM 		itemp = &tab->items[(i * chunksz) + (hval & tab->mask)];
870*7836SJohn.Forte@Sun.COM 		item = *itemp;
871*7836SJohn.Forte@Sun.COM 		while (item != NULL) {
872*7836SJohn.Forte@Sun.COM 			/* found it */
873*7836SJohn.Forte@Sun.COM 			if (tab->c->cmp(item->p, p, 1) == 0) {
874*7836SJohn.Forte@Sun.COM 				/* make an association object if the object */
875*7836SJohn.Forte@Sun.COM 				/* has membership in user-defined DD(s). */
876*7836SJohn.Forte@Sun.COM 				if (i == 0) {
877*7836SJohn.Forte@Sun.COM 					if ((clone = tab->c->clone(item->p,
878*7836SJohn.Forte@Sun.COM 					    clone_flag)) == NULL) {
879*7836SJohn.Forte@Sun.COM 						tab->c->ddd(item->p, '-');
880*7836SJohn.Forte@Sun.COM 						tab->count --;
881*7836SJohn.Forte@Sun.COM 						items = item;
882*7836SJohn.Forte@Sun.COM 						zhizi = item->p;
883*7836SJohn.Forte@Sun.COM 					}
884*7836SJohn.Forte@Sun.COM 				}
885*7836SJohn.Forte@Sun.COM 				if (clone == NULL) {
886*7836SJohn.Forte@Sun.COM 					/* remove it */
887*7836SJohn.Forte@Sun.COM 					*itemp = item->next;
888*7836SJohn.Forte@Sun.COM 				} else if (clone == item->p) {
889*7836SJohn.Forte@Sun.COM 					/* itself is an association object */
890*7836SJohn.Forte@Sun.COM 					goto remove_done;
891*7836SJohn.Forte@Sun.COM 				} else {
892*7836SJohn.Forte@Sun.COM 					/* replace it with association */
893*7836SJohn.Forte@Sun.COM 					zhizi = item->p;
894*7836SJohn.Forte@Sun.COM 					item->p = clone;
895*7836SJohn.Forte@Sun.COM 				}
896*7836SJohn.Forte@Sun.COM 				if (i == 0) {
897*7836SJohn.Forte@Sun.COM 					/* obj has been removed or updated */
898*7836SJohn.Forte@Sun.COM 					SET_CACHE_UPDATED();
899*7836SJohn.Forte@Sun.COM 				}
900*7836SJohn.Forte@Sun.COM 				break;
901*7836SJohn.Forte@Sun.COM 			}
902*7836SJohn.Forte@Sun.COM 			itemp = &item->next;
903*7836SJohn.Forte@Sun.COM 			item = *itemp;
904*7836SJohn.Forte@Sun.COM 		}
905*7836SJohn.Forte@Sun.COM 		i ++;
906*7836SJohn.Forte@Sun.COM 		if (zhizi != NULL && i < tab->chunks) {
907*7836SJohn.Forte@Sun.COM 			hval = VALID_HVAL(tab->c->get_hval(
908*7836SJohn.Forte@Sun.COM 			    zhizi, i, &flags));
909*7836SJohn.Forte@Sun.COM 		} else {
910*7836SJohn.Forte@Sun.COM 			break;
911*7836SJohn.Forte@Sun.COM 		}
912*7836SJohn.Forte@Sun.COM 	}
913*7836SJohn.Forte@Sun.COM 
914*7836SJohn.Forte@Sun.COM 	/* update the node in the avl tree */
915*7836SJohn.Forte@Sun.COM 	if (items != NULL) {
916*7836SJohn.Forte@Sun.COM 		if (x == NULL) {
917*7836SJohn.Forte@Sun.COM 			uid = tab->c->get_uid(zhizi);
918*7836SJohn.Forte@Sun.COM 			ASSERT(uid != 0);
919*7836SJohn.Forte@Sun.COM 			x = avl_search(tab, uid);
920*7836SJohn.Forte@Sun.COM 		}
921*7836SJohn.Forte@Sun.COM 		ASSERT(x != NULL && !BAD_HVAL(x->hval));
922*7836SJohn.Forte@Sun.COM 		/* mark the uid item as invalid */
923*7836SJohn.Forte@Sun.COM 		x->hval |= BAD_HVAL_MASK;
924*7836SJohn.Forte@Sun.COM 		/* update the timestamp */
925*7836SJohn.Forte@Sun.COM 		x->t = tab->c->timestamp();
926*7836SJohn.Forte@Sun.COM 		/* put it to the end of fifo list */
927*7836SJohn.Forte@Sun.COM 		if (tab->list != NULL) {
928*7836SJohn.Forte@Sun.COM 			tab->tail->n = x;
929*7836SJohn.Forte@Sun.COM 		} else {
930*7836SJohn.Forte@Sun.COM 			tab->list = x;
931*7836SJohn.Forte@Sun.COM 		}
932*7836SJohn.Forte@Sun.COM 		tab->tail = x;
933*7836SJohn.Forte@Sun.COM 	}
934*7836SJohn.Forte@Sun.COM 
935*7836SJohn.Forte@Sun.COM remove_done:
936*7836SJohn.Forte@Sun.COM 	if (items != NULL) {
937*7836SJohn.Forte@Sun.COM 		free(items);
938*7836SJohn.Forte@Sun.COM 	}
939*7836SJohn.Forte@Sun.COM 
940*7836SJohn.Forte@Sun.COM 	return (zhizi);
941*7836SJohn.Forte@Sun.COM }
942*7836SJohn.Forte@Sun.COM 
943*7836SJohn.Forte@Sun.COM /*
944*7836SJohn.Forte@Sun.COM  * ****************************************************************************
945*7836SJohn.Forte@Sun.COM  * htab_lookup:
946*7836SJohn.Forte@Sun.COM  *	lookup an object from the hash table.
947*7836SJohn.Forte@Sun.COM  *
948*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
949*7836SJohn.Forte@Sun.COM  * p	- the lookup control for the item.
950*7836SJohn.Forte@Sun.COM  * uid	- the UID of the object.
951*7836SJohn.Forte@Sun.COM  * uid_p- the pointer of UID for returning.
952*7836SJohn.Forte@Sun.COM  * callback - callback function if the object is found.
953*7836SJohn.Forte@Sun.COM  * rekey - flag that indicates if the callback function will update
954*7836SJohn.Forte@Sun.COM  *		the key of the object.
955*7836SJohn.Forte@Sun.COM  * return - error code.
956*7836SJohn.Forte@Sun.COM  *
957*7836SJohn.Forte@Sun.COM  * ****************************************************************************
958*7836SJohn.Forte@Sun.COM  */
959*7836SJohn.Forte@Sun.COM int
htab_lookup(htab_t * tab,void * p,uint32_t uid,uint32_t * uid_p,int (* callback)(void *,void *),int rekey)960*7836SJohn.Forte@Sun.COM htab_lookup(
961*7836SJohn.Forte@Sun.COM 	htab_t *tab,
962*7836SJohn.Forte@Sun.COM 	void *p,
963*7836SJohn.Forte@Sun.COM 	uint32_t uid,
964*7836SJohn.Forte@Sun.COM 	uint32_t *uid_p,
965*7836SJohn.Forte@Sun.COM 	int (*callback)(void *, void *),
966*7836SJohn.Forte@Sun.COM 	int rekey
967*7836SJohn.Forte@Sun.COM )
968*7836SJohn.Forte@Sun.COM {
969*7836SJohn.Forte@Sun.COM 	uint32_t ret = 0;
970*7836SJohn.Forte@Sun.COM 	void *zhizi = NULL;
971*7836SJohn.Forte@Sun.COM 	htab_item_t *item, **itemp;
972*7836SJohn.Forte@Sun.COM 	htab_itemx_t *x = NULL;
973*7836SJohn.Forte@Sun.COM 	uint32_t chunksz;
974*7836SJohn.Forte@Sun.COM 	uint32_t flags = 0 | FLAGS_CTRL_MASK;
975*7836SJohn.Forte@Sun.COM 	uint32_t hval;
976*7836SJohn.Forte@Sun.COM 	int i;
977*7836SJohn.Forte@Sun.COM 
978*7836SJohn.Forte@Sun.COM 	/* compute the hash value */
979*7836SJohn.Forte@Sun.COM 	if (uid != 0) {
980*7836SJohn.Forte@Sun.COM 		x = avl_search(tab, uid);
981*7836SJohn.Forte@Sun.COM 		if (x != NULL) {
982*7836SJohn.Forte@Sun.COM 			hval = x->hval;
983*7836SJohn.Forte@Sun.COM 		} else {
984*7836SJohn.Forte@Sun.COM 			hval = BAD_HVAL_MASK;
985*7836SJohn.Forte@Sun.COM 		}
986*7836SJohn.Forte@Sun.COM 	} else {
987*7836SJohn.Forte@Sun.COM 		hval = VALID_HVAL(tab->c->get_hval(p, 0, &flags));
988*7836SJohn.Forte@Sun.COM 	}
989*7836SJohn.Forte@Sun.COM 
990*7836SJohn.Forte@Sun.COM 	/* find the object */
991*7836SJohn.Forte@Sun.COM 	if (!BAD_HVAL(hval)) {
992*7836SJohn.Forte@Sun.COM 		i = flags & FLAGS_CHUNK_MASK;
993*7836SJohn.Forte@Sun.COM 		chunksz = (1 << tab->logsize);
994*7836SJohn.Forte@Sun.COM 		itemp = &tab->items[(i * chunksz) + (hval & tab->mask)];
995*7836SJohn.Forte@Sun.COM 		item = *itemp;
996*7836SJohn.Forte@Sun.COM 		while (item != NULL) {
997*7836SJohn.Forte@Sun.COM 			if (tab->c->cmp(item->p, p, 1) == 0) {
998*7836SJohn.Forte@Sun.COM 				zhizi = item->p;
999*7836SJohn.Forte@Sun.COM 				break;
1000*7836SJohn.Forte@Sun.COM 			}
1001*7836SJohn.Forte@Sun.COM 			itemp = &item->next;
1002*7836SJohn.Forte@Sun.COM 			item = *itemp;
1003*7836SJohn.Forte@Sun.COM 		}
1004*7836SJohn.Forte@Sun.COM 	}
1005*7836SJohn.Forte@Sun.COM 
1006*7836SJohn.Forte@Sun.COM 	/* found it */
1007*7836SJohn.Forte@Sun.COM 	if (zhizi != NULL) {
1008*7836SJohn.Forte@Sun.COM 		/* set the return uid */
1009*7836SJohn.Forte@Sun.COM 		if (uid_p != NULL) {
1010*7836SJohn.Forte@Sun.COM 			*uid_p = tab->c->get_uid(zhizi);
1011*7836SJohn.Forte@Sun.COM 		}
1012*7836SJohn.Forte@Sun.COM 		/* invoke callback */
1013*7836SJohn.Forte@Sun.COM 		if (callback != NULL) {
1014*7836SJohn.Forte@Sun.COM 			ret = callback(zhizi, p);
1015*7836SJohn.Forte@Sun.COM 		}
1016*7836SJohn.Forte@Sun.COM 		if (rekey != 0 && ret == 0) {
1017*7836SJohn.Forte@Sun.COM 			/* Rekey works for one-chunk hash table only. */
1018*7836SJohn.Forte@Sun.COM 			ASSERT(tab->chunks == 1 && x != NULL);
1019*7836SJohn.Forte@Sun.COM 			/* remove from previous slot */
1020*7836SJohn.Forte@Sun.COM 			*itemp = item->next;
1021*7836SJohn.Forte@Sun.COM 			/* add it to the new slot */
1022*7836SJohn.Forte@Sun.COM 			flags = 0;
1023*7836SJohn.Forte@Sun.COM 			hval = VALID_HVAL(tab->c->get_hval(zhizi, 0, &flags));
1024*7836SJohn.Forte@Sun.COM 			x->hval = hval;
1025*7836SJohn.Forte@Sun.COM 			item->hval = hval;
1026*7836SJohn.Forte@Sun.COM 			itemp = &tab->items[(hval & tab->mask)];
1027*7836SJohn.Forte@Sun.COM 			while (*itemp != NULL &&
1028*7836SJohn.Forte@Sun.COM 			    (tab->c->get_uid((*itemp)->p) >
1029*7836SJohn.Forte@Sun.COM 			    tab->c->get_uid(zhizi))) {
1030*7836SJohn.Forte@Sun.COM 				itemp = &(*itemp)->next;
1031*7836SJohn.Forte@Sun.COM 			}
1032*7836SJohn.Forte@Sun.COM 			item->next = *itemp;
1033*7836SJohn.Forte@Sun.COM 			*itemp = item;
1034*7836SJohn.Forte@Sun.COM 		}
1035*7836SJohn.Forte@Sun.COM 	} else if (uid_p != NULL) {
1036*7836SJohn.Forte@Sun.COM 		/* set the return uid to 0 */
1037*7836SJohn.Forte@Sun.COM 		*uid_p = 0;
1038*7836SJohn.Forte@Sun.COM 	}
1039*7836SJohn.Forte@Sun.COM 
1040*7836SJohn.Forte@Sun.COM 	return (ret);
1041*7836SJohn.Forte@Sun.COM }
1042*7836SJohn.Forte@Sun.COM 
1043*7836SJohn.Forte@Sun.COM /*
1044*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1045*7836SJohn.Forte@Sun.COM  * htab_get_next:
1046*7836SJohn.Forte@Sun.COM  *	get the next object UID from the hash table.
1047*7836SJohn.Forte@Sun.COM  *
1048*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
1049*7836SJohn.Forte@Sun.COM  * uid	- the previous objet UID.
1050*7836SJohn.Forte@Sun.COM  * return - the next object UID.
1051*7836SJohn.Forte@Sun.COM  *
1052*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1053*7836SJohn.Forte@Sun.COM  */
1054*7836SJohn.Forte@Sun.COM uint32_t
htab_get_next(htab_t * tab,uint32_t uid)1055*7836SJohn.Forte@Sun.COM htab_get_next(
1056*7836SJohn.Forte@Sun.COM 	htab_t *tab,
1057*7836SJohn.Forte@Sun.COM 	uint32_t uid
1058*7836SJohn.Forte@Sun.COM )
1059*7836SJohn.Forte@Sun.COM {
1060*7836SJohn.Forte@Sun.COM 	htab_itemx_t *x;
1061*7836SJohn.Forte@Sun.COM 
1062*7836SJohn.Forte@Sun.COM 	do {
1063*7836SJohn.Forte@Sun.COM 		/* search the next node from the avl tree */
1064*7836SJohn.Forte@Sun.COM 		x = avl_search_next(tab, uid);
1065*7836SJohn.Forte@Sun.COM 		if (x != NULL) {
1066*7836SJohn.Forte@Sun.COM 			uid = x->uid;
1067*7836SJohn.Forte@Sun.COM 			/* validate the node */
1068*7836SJohn.Forte@Sun.COM 			if (!BAD_HVAL(x->hval)) {
1069*7836SJohn.Forte@Sun.COM 				return (uid);
1070*7836SJohn.Forte@Sun.COM 			}
1071*7836SJohn.Forte@Sun.COM 		}
1072*7836SJohn.Forte@Sun.COM 	} while (x != NULL);
1073*7836SJohn.Forte@Sun.COM 
1074*7836SJohn.Forte@Sun.COM 	/* no more node is available */
1075*7836SJohn.Forte@Sun.COM 	return (0);
1076*7836SJohn.Forte@Sun.COM }
1077*7836SJohn.Forte@Sun.COM 
1078*7836SJohn.Forte@Sun.COM /*
1079*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1080*7836SJohn.Forte@Sun.COM  * htab_dump:
1081*7836SJohn.Forte@Sun.COM  *	dump all objects stored in the hash table for debug purpose.
1082*7836SJohn.Forte@Sun.COM  *
1083*7836SJohn.Forte@Sun.COM  * tab	- the hash table.
1084*7836SJohn.Forte@Sun.COM  *
1085*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1086*7836SJohn.Forte@Sun.COM  */
1087*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1088*7836SJohn.Forte@Sun.COM void
htab_dump(htab_t * tab)1089*7836SJohn.Forte@Sun.COM htab_dump(
1090*7836SJohn.Forte@Sun.COM 	htab_t *tab
1091*7836SJohn.Forte@Sun.COM )
1092*7836SJohn.Forte@Sun.COM {
1093*7836SJohn.Forte@Sun.COM 	uint32_t chunksz;
1094*7836SJohn.Forte@Sun.COM 	htab_item_t *items;
1095*7836SJohn.Forte@Sun.COM 
1096*7836SJohn.Forte@Sun.COM 	uint32_t i;
1097*7836SJohn.Forte@Sun.COM 
1098*7836SJohn.Forte@Sun.COM 	chunksz = (1 << tab->logsize);
1099*7836SJohn.Forte@Sun.COM 
1100*7836SJohn.Forte@Sun.COM 	for (i = 0; i < chunksz; i++) {
1101*7836SJohn.Forte@Sun.COM 		items = tab->items[i];
1102*7836SJohn.Forte@Sun.COM 		while (items != NULL) {
1103*7836SJohn.Forte@Sun.COM 			tab->c->dump(items->p);
1104*7836SJohn.Forte@Sun.COM 			items = items->next;
1105*7836SJohn.Forte@Sun.COM 		}
1106*7836SJohn.Forte@Sun.COM 	}
1107*7836SJohn.Forte@Sun.COM }
1108*7836SJohn.Forte@Sun.COM #endif
1109