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