4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
36 * This file implements functions that add, search or remove an object
37 * from the hash table. The object is opaque to the hash functions. To add
38 * an object to the hash table, the caller provides the hash table,
39 * the object and the index into the hash table. To search an object,
40 * the caller provides the hash table, the digest (opaque), the index into
41 * the hash table and the function that does the actual match. Similarly,
42 * for removing an object, the caller provides the hash table, the digest
43 * (opaque), the index into the hash table and the function that does
44 * the acutal deletion of the object - if the deletion is successful,
45 * the object is taken off of the hash table.
49 * Given an object and the hash index, add it to the given hash table
52 sip_hash_add(sip_hash_t
*sip_hash
, void *obj
, int hindex
)
54 sip_hash_obj_t
*new_obj
;
55 sip_hash_t
*hash_entry
;
59 new_obj
= (sip_hash_obj_t
*)malloc(sizeof (*new_obj
));
62 new_obj
->sip_obj
= obj
;
63 new_obj
->next_obj
= NULL
;
64 new_obj
->prev_obj
= NULL
;
65 hash_entry
= &sip_hash
[hindex
];
66 (void) pthread_mutex_lock(&hash_entry
->sip_hash_mutex
);
67 if (hash_entry
->hash_count
== 0) {
68 assert(hash_entry
->hash_head
== NULL
);
69 assert(hash_entry
->hash_tail
== NULL
);
70 hash_entry
->hash_head
= new_obj
;
72 hash_entry
->hash_tail
->next_obj
= new_obj
;
73 new_obj
->prev_obj
= hash_entry
->hash_tail
;
75 hash_entry
->hash_tail
= new_obj
;
76 hash_entry
->hash_count
++;
77 (void) pthread_mutex_unlock(&hash_entry
->sip_hash_mutex
);
82 * Given the hash table, the digest to be searched for, index into the hash
83 * table and the function to do the actual matching, return the object,
87 sip_hash_find(sip_hash_t
*sip_hash
, void *digest
, int hindex
,
88 boolean_t (*match_func
)(void *, void *))
92 sip_hash_t
*hash_entry
;
94 hash_entry
= &sip_hash
[hindex
];
95 (void) pthread_mutex_lock(&hash_entry
->sip_hash_mutex
);
96 tmp
= hash_entry
->hash_head
;
97 for (count
= 0; count
< hash_entry
->hash_count
; count
++) {
98 if (match_func(tmp
->sip_obj
, digest
)) {
99 (void) pthread_mutex_unlock(
100 &hash_entry
->sip_hash_mutex
);
101 return (tmp
->sip_obj
);
105 (void) pthread_mutex_unlock(&hash_entry
->sip_hash_mutex
);
110 * Walk the hash table and invoke func on each object. 'arg' is passed
114 sip_walk_hash(sip_hash_t
*sip_hash
, void (*func
)(void *, void *), void *arg
)
116 sip_hash_t
*hash_entry
;
121 for (count
= 0; count
< SIP_HASH_SZ
; count
++) {
122 hash_entry
= &sip_hash
[count
];
123 (void) pthread_mutex_lock(&hash_entry
->sip_hash_mutex
);
124 tmp
= hash_entry
->hash_head
;
125 for (hcount
= 0; hcount
< hash_entry
->hash_count
; hcount
++) {
126 assert(tmp
->sip_obj
!= NULL
);
127 func(tmp
->sip_obj
, arg
);
130 (void) pthread_mutex_unlock(&hash_entry
->sip_hash_mutex
);
135 * Given the hash table, the digest to be searched for, the index into the
136 * hash table and the delete function provided to do the actual deletion,
137 * remove the object from the hash table (i.e. only if the object is deleted).
140 sip_hash_delete(sip_hash_t
*sip_hash
, void *digest
, int hindex
,
141 boolean_t (*del_func
)(void *, void *, int *))
143 sip_hash_t
*hash_entry
;
148 hash_entry
= &sip_hash
[hindex
];
149 (void) pthread_mutex_lock(&hash_entry
->sip_hash_mutex
);
150 tmp
= hash_entry
->hash_head
;
151 for (count
= 0; count
< hash_entry
->hash_count
; count
++) {
152 if (del_func(tmp
->sip_obj
, digest
, &found
)) {
153 if (tmp
== hash_entry
->hash_head
) {
154 if (tmp
->next_obj
!= NULL
) {
155 hash_entry
->hash_head
= tmp
->next_obj
;
156 tmp
->next_obj
->prev_obj
= NULL
;
158 assert(hash_entry
->hash_tail
==
159 hash_entry
->hash_head
);
160 hash_entry
->hash_head
= NULL
;
161 hash_entry
->hash_tail
= NULL
;
164 sip_hash_obj_t
*next
= tmp
->next_obj
;
167 tmp
->prev_obj
->next_obj
= next
;
168 next
->prev_obj
= tmp
->prev_obj
;
170 assert(hash_entry
->hash_tail
== tmp
);
171 tmp
->prev_obj
->next_obj
= NULL
;
172 hash_entry
->hash_tail
=
176 tmp
->prev_obj
= NULL
;
177 tmp
->next_obj
= NULL
;
179 hash_entry
->hash_count
--;
180 (void) pthread_mutex_unlock(
181 &hash_entry
->sip_hash_mutex
);
184 * If we found the object, we are done
186 } else if (found
== 1) {
187 (void) pthread_mutex_unlock(
188 &hash_entry
->sip_hash_mutex
);
193 (void) pthread_mutex_unlock(&hash_entry
->sip_hash_mutex
);