1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
/*
* (c) Thomas Pornin 2002
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. The name of the authors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef UCPP__NHASH__
#define UCPP__NHASH__
#include "tune.h"
/*
* Each item stored in the hash table should be a structure beginning
* with the following header.
*/
typedef struct hash_item_header_ {
char *ident;
struct hash_item_header_ *left, *right;
} hash_item_header;
/*
* This macro takes as argument a pointer to a hash table item (a
* structure beginning with `hash_item_header') and returns a pointer to
* the item name. This name should be considered as read-only. The
* retrieved pointer can become invalid whenever a new item is inserted
* in or removed from the table.
*/
#define HASH_ITEM_NAME(s) (((hash_item_header *)(s))->ident + sizeof(unsigned))
/*
* Number of lists for the primary hash step. Can be reduced to save more
* memory, or increased to speed things up. It should be a power of 2
* greater or equal than 2 and smaller than UINT_MAX.
*/
#define HTT_NUM_TREES 128
/*
* Type for a hash table.
*/
typedef struct {
void (*deldata)(void *);
#ifdef UCPP_CLONE
void *(*clonedata)(const void *);
#endif
hash_item_header *tree[HTT_NUM_TREES];
} HTT;
/*
* Type for a reduced version of HTT with only two binary trees. That
* version has a lower initialization time and is suitable for situation
* where only a limited number of elements will be stored, but new tables
* need frequent initializations.
*/
typedef struct {
void (*deldata)(void *);
#ifdef UCPP_CLONE
void *(*clonedata)(const void *);
#endif
hash_item_header *tree[2];
} HTT2;
#ifdef UCPP_CLONE
#define _pCLONEDATA , void *(*clonedata)(const void *)
#define _aCLONEDATA , clonedata
#define _aCLONE(fun) , fun
#else
#define _pCLONEDATA
#define _aCLONEDATA
#define _aCLONE(fun)
#endif
/*
* Initialize a hash table. The `deldata' parameter should point to a
* function which will be invoked on any item removed from the table;
* that function should take care of the release of memory allocated for
* that item (except the hash_item_header contents, which are handled
* internally).
* The (optional) `clonedata' parameter should point to a function
* which will be invoked on any item that is cloned to another table.
*/
#define HTT_init UCPP_PRIVATE(HTT_init)
void HTT_init(HTT *htt, void (*deldata)(void *) _pCLONEDATA);
/*
* Link an item into the hash table under the given name. If another
* item of identical name is already present in the table, a pointer to
* that item is returned; otherwise, the new item is linked into the
* table and NULL is returned. The object pointed to by `item' is
* linked from the table, but not the string pointed to by `name'.
*/
#define HTT_put UCPP_PRIVATE(HTT_put)
void *HTT_put(HTT *htt, void *item, const char *name);
/*
* Retrieve an item by name from the hash table. NULL is returned if
* the object is not found.
*/
#define HTT_get UCPP_PRIVATE(HTT_get)
void *HTT_get(HTT *htt, const char *name);
/*
* Remove an item from the hash table. 1 is returned if the item was
* removed, 0 if it was not found.
*/
#define HTT_del UCPP_PRIVATE(HTT_del)
int HTT_del(HTT *htt, const char *name);
/*
* For all items stored within the hash table, invoke the provided
* function with the item as parameter. The function may abort the
* scan by performing a longjmp() to a context encapsulating the
* call to that function.
*/
#define HTT_scan UCPP_PRIVATE(HTT_scan)
#define HTT_scan_arg UCPP_PRIVATE(HTT_scan_arg)
void HTT_scan(HTT *htt, void (*action)(void *));
void HTT_scan_arg(HTT *htt, void (*action)(void *, void *), void *arg);
/*
* Release the whole table contents. After a call to this function,
* the table is ready to accept new items.
*/
#define HTT_kill UCPP_PRIVATE(HTT_kill)
void HTT_kill(HTT *htt);
#ifdef UCPP_CLONE
/*
* Clone the whole table contents.
*/
#define HTT_clone UCPP_PRIVATE(HTT_clone)
void HTT_clone(HTT *ctt, const HTT *htt);
#endif /* UCPP_CLONE */
/*
* The following functions are identical to the HTT_*() functions, except
* that they operate on the reduced HTT2 tables.
*/
#define HTT2_init UCPP_PRIVATE(HTT2_init)
#define HTT2_put UCPP_PRIVATE(HTT2_put)
#define HTT2_get UCPP_PRIVATE(HTT2_get)
#define HTT2_del UCPP_PRIVATE(HTT2_del)
#define HTT2_scan UCPP_PRIVATE(HTT2_scan)
#define HTT2_scan_arg UCPP_PRIVATE(HTT2_scan_arg)
#define HTT2_kill UCPP_PRIVATE(HTT2_kill)
void HTT2_init(HTT2 *htt, void (*deldata)(void *) _pCLONEDATA);
void *HTT2_put(HTT2 *htt, void *item, const char *name);
void *HTT2_get(HTT2 *htt, const char *name);
int HTT2_del(HTT2 *htt, const char *name);
void HTT2_scan(HTT2 *htt, void (*action)(void *));
void HTT2_scan_arg(HTT2 *htt, void (*action)(void *, void *), void *);
void HTT2_kill(HTT2 *htt);
#ifdef UCPP_CLONE
#define HTT2_clone UCPP_PRIVATE(HTT_clone)
void HTT2_clone(HTT2 *ctt, const HTT2 *htt);
#endif
#endif
|