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