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