xref: /titanic_50/usr/src/uts/common/smbsrv/hash_table.h (revision da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0)
1*da6c28aaSamw /*
2*da6c28aaSamw  * CDDL HEADER START
3*da6c28aaSamw  *
4*da6c28aaSamw  * The contents of this file are subject to the terms of the
5*da6c28aaSamw  * Common Development and Distribution License (the "License").
6*da6c28aaSamw  * You may not use this file except in compliance with the License.
7*da6c28aaSamw  *
8*da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10*da6c28aaSamw  * See the License for the specific language governing permissions
11*da6c28aaSamw  * and limitations under the License.
12*da6c28aaSamw  *
13*da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14*da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16*da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17*da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18*da6c28aaSamw  *
19*da6c28aaSamw  * CDDL HEADER END
20*da6c28aaSamw  */
21*da6c28aaSamw /*
22*da6c28aaSamw  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*da6c28aaSamw  * Use is subject to license terms.
24*da6c28aaSamw  */
25*da6c28aaSamw 
26*da6c28aaSamw #ifndef _SMBSRV_HASH_TABLE_H
27*da6c28aaSamw #define	_SMBSRV_HASH_TABLE_H
28*da6c28aaSamw 
29*da6c28aaSamw #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*da6c28aaSamw 
31*da6c28aaSamw /*
32*da6c28aaSamw  *
33*da6c28aaSamw  * Interface definition for the hash table library. The hash table is a
34*da6c28aaSamw  * user-specified array of pointers to items. Hash collisions are handled
35*da6c28aaSamw  * using linked lists from the table entries. A handle is associated with
36*da6c28aaSamw  * each table, which is used to maintain the hash table.
37*da6c28aaSamw  *
38*da6c28aaSamw  * +------+     +-------+    +----+    +----+
39*da6c28aaSamw  * |handle|---> |index 0|--->|item|--->|item|--->
40*da6c28aaSamw  * | ...  |     +-------+    +----+    +----+
41*da6c28aaSamw  * | ...  |     |index 1|--->
42*da6c28aaSamw  * +------+     +-------+    +----+    +----+    +----+
43*da6c28aaSamw  *              |index 2|--->|item|--->|item|--->|item|--->
44*da6c28aaSamw  *              +-------+    +----+    +----+    +----+
45*da6c28aaSamw  *              | ...   |--->
46*da6c28aaSamw  *              +-------+
47*da6c28aaSamw  *              | ...   |--->
48*da6c28aaSamw  *              +-------+
49*da6c28aaSamw  *              |index n|--->
50*da6c28aaSamw  *              +-------+
51*da6c28aaSamw  *
52*da6c28aaSamw  */
53*da6c28aaSamw 
54*da6c28aaSamw #include <sys/types.h>
55*da6c28aaSamw 
56*da6c28aaSamw #ifdef __cplusplus
57*da6c28aaSamw extern "C" {
58*da6c28aaSamw #endif
59*da6c28aaSamw 
60*da6c28aaSamw /*
61*da6c28aaSamw  * This is the hash multiplier value.
62*da6c28aaSamw  */
63*da6c28aaSamw #define	HASH_MESH_VALUE		77
64*da6c28aaSamw 
65*da6c28aaSamw /*
66*da6c28aaSamw  * Each entry (item) in the hash table has a linked-list pointer, a key,
67*da6c28aaSamw  * a pointer to some user defined data (which may be null) and some flags.
68*da6c28aaSamw  * The key is a user provided key and is used to position the item within
69*da6c28aaSamw  * the table. The linked-list is used to store items whose hash values
70*da6c28aaSamw  * collide. The data pointer is never dereferenced in the hash code so
71*da6c28aaSamw  * it may be a null pointer.
72*da6c28aaSamw  *
73*da6c28aaSamw  * The item bit flags are:
74*da6c28aaSamw  *
75*da6c28aaSamw  * HTIF_DELETE:    Specifies that an item is marked for deletion (see
76*da6c28aaSamw  *               ht_mark_delete and ht_clean_table).
77*da6c28aaSamw  */
78*da6c28aaSamw #define	HTIF_MARKED_DELETED	0x01
79*da6c28aaSamw #define	HT_DELETE		HTIF_MARKED_DELETED
80*da6c28aaSamw 
81*da6c28aaSamw typedef struct ht_item {
82*da6c28aaSamw 	struct ht_item *hi_next;
83*da6c28aaSamw 	char *hi_key;
84*da6c28aaSamw 	void *hi_data;
85*da6c28aaSamw 	size_t hi_flags;
86*da6c28aaSamw } HT_ITEM;
87*da6c28aaSamw 
88*da6c28aaSamw /*
89*da6c28aaSamw  * HT_TABLE_ENTRY is an opaque structure (to the public) used to maintain
90*da6c28aaSamw  * a pointer to the hash table and the number of items in the table entry.
91*da6c28aaSamw  * This number shows number of both available items and those are marked
92*da6c28aaSamw  * as deleted.
93*da6c28aaSamw  */
94*da6c28aaSamw typedef struct ht_table_entry {
95*da6c28aaSamw 	HT_ITEM *he_head;
96*da6c28aaSamw 	size_t he_count;
97*da6c28aaSamw } HT_TABLE_ENTRY;
98*da6c28aaSamw 
99*da6c28aaSamw /*
100*da6c28aaSamw  * The HT_HANDLE is an opaque handle that associates each request with
101*da6c28aaSamw  * a hash table. A handle is generated when a hash table is created and
102*da6c28aaSamw  * it is used to maintain all global data associated with the table.
103*da6c28aaSamw  *
104*da6c28aaSamw  * The handle bit flags are:
105*da6c28aaSamw  *
106*da6c28aaSamw  * HTHF_FIXED_KEY:    Specifies that keys are fixed length and should
107*da6c28aaSamw  *                    not be assumed to be null terminated.
108*da6c28aaSamw  */
109*da6c28aaSamw #define	HTHF_FIXED_KEY		0x01
110*da6c28aaSamw 
111*da6c28aaSamw typedef struct ht_handle {
112*da6c28aaSamw 	HT_TABLE_ENTRY *ht_table;
113*da6c28aaSamw 	size_t ht_sequence;
114*da6c28aaSamw 	size_t ht_table_size;
115*da6c28aaSamw 	size_t ht_table_mask;
116*da6c28aaSamw 	size_t ht_key_size;
117*da6c28aaSamw 	size_t ht_total_items;	/* show total number of available items */
118*da6c28aaSamw 	size_t ht_flags;
119*da6c28aaSamw 	size_t (*ht_hash)(struct ht_handle *handle, const char *key);
120*da6c28aaSamw 	void (*ht_callback)(HT_ITEM *item);
121*da6c28aaSamw 	int (*ht_cmp)(const char *key1, const char *key2, size_t n);
122*da6c28aaSamw } HT_HANDLE;
123*da6c28aaSamw 
124*da6c28aaSamw /*
125*da6c28aaSamw  * Typedefs for the optional user-installable functions.
126*da6c28aaSamw  */
127*da6c28aaSamw typedef void (*HT_CALLBACK)(HT_ITEM *item);
128*da6c28aaSamw 
129*da6c28aaSamw /*
130*da6c28aaSamw  * Compare function cast to make all compare
131*da6c28aaSamw  * functions look like strncmp.
132*da6c28aaSamw  */
133*da6c28aaSamw typedef	int (*HT_CMP)(const char *, const char *, size_t);
134*da6c28aaSamw 
135*da6c28aaSamw /*
136*da6c28aaSamw  * Iterator used with ht_findfirst and ht_findnext to walk through
137*da6c28aaSamw  * all the items in a hash table. The iterator should be treated as
138*da6c28aaSamw  * an opaque handle. The sequence number in the iterator is used
139*da6c28aaSamw  * to maintain consistency with the table on which the iteration
140*da6c28aaSamw  * is being performed. If the table sequence number changes, the
141*da6c28aaSamw  * iterator becomes invalid.
142*da6c28aaSamw  */
143*da6c28aaSamw typedef struct ht_iterator {
144*da6c28aaSamw 	HT_HANDLE *hti_handle;
145*da6c28aaSamw 	HT_ITEM *hti_item;
146*da6c28aaSamw 	size_t hti_index;
147*da6c28aaSamw 	size_t hti_sequence;
148*da6c28aaSamw } HT_ITERATOR;
149*da6c28aaSamw 
150*da6c28aaSamw /*
151*da6c28aaSamw  * Public API to create and destroy hash tables, to change the hash
152*da6c28aaSamw  * function and to find out how many items are in a hash table.
153*da6c28aaSamw  */
154*da6c28aaSamw extern HT_HANDLE *ht_create_table(size_t table_size, size_t key_size,
155*da6c28aaSamw     size_t flags);
156*da6c28aaSamw extern void ht_destroy_table(HT_HANDLE *handle);
157*da6c28aaSamw extern void ht_set_cmpfn(HT_HANDLE *handle, HT_CMP cmpfn);
158*da6c28aaSamw extern size_t ht_get_total_items(HT_HANDLE *handle);
159*da6c28aaSamw 
160*da6c28aaSamw /*
161*da6c28aaSamw  * Public API to add, remove, replace or find specific items
162*da6c28aaSamw  * in a hash table.
163*da6c28aaSamw  */
164*da6c28aaSamw extern HT_ITEM *ht_add_item(HT_HANDLE *handle, const char *key,
165*da6c28aaSamw     const void *data);
166*da6c28aaSamw extern HT_ITEM *ht_replace_item(HT_HANDLE *handle, const char *key,
167*da6c28aaSamw     const void *data);
168*da6c28aaSamw extern void *ht_remove_item(HT_HANDLE *handle, const char *key);
169*da6c28aaSamw extern HT_ITEM *ht_find_item(HT_HANDLE *handle, const char *key);
170*da6c28aaSamw 
171*da6c28aaSamw /*
172*da6c28aaSamw  * Public API to iterate over a hash table. A mechanism is provided to
173*da6c28aaSamw  * mark items for deletion while searching the table so that the table
174*da6c28aaSamw  * is not modified during the search. When the search is complete, all
175*da6c28aaSamw  * of the marked items can be deleted by calling ht_clean_table. If
176*da6c28aaSamw  * the item data has been dynamically allocated, a callback can be
177*da6c28aaSamw  * registered to free the memory. The callback will be invoked with a
178*da6c28aaSamw  * pointer to each item as it is removed from the hash table.
179*da6c28aaSamw  */
180*da6c28aaSamw extern HT_ITEM *ht_findfirst(HT_HANDLE *handle, HT_ITERATOR *iterator);
181*da6c28aaSamw extern HT_ITEM *ht_findnext(HT_ITERATOR *iterator);
182*da6c28aaSamw extern void ht_mark_delete(HT_HANDLE *handle, HT_ITEM *item);
183*da6c28aaSamw extern void ht_clear_delete(HT_HANDLE *handle, HT_ITEM *item);
184*da6c28aaSamw extern size_t ht_clean_table(HT_HANDLE *handle);
185*da6c28aaSamw extern HT_CALLBACK ht_register_callback(HT_HANDLE *handle,
186*da6c28aaSamw     HT_CALLBACK callback);
187*da6c28aaSamw 
188*da6c28aaSamw #ifdef __cplusplus
189*da6c28aaSamw }
190*da6c28aaSamw #endif
191*da6c28aaSamw 
192*da6c28aaSamw #endif /* _SMBSRV_HASH_TABLE_H */
193