106 static const char rcsid[] =
"$Id: hash.c,v 1.2 2002/03/11 00:51:44 jick Exp $";
107 static const char right[] =
"Copyright (C) 1997 Kaz Kylheku";
170 while( (arg & 0x01) == 0 )
175 return arg == 1?
true:
false;
194 while( (mask & 0x01) == 0 )
219 size_t numbits, rshift, lshift;
225 for(rshift=0, lshift=0; rshift<numbits; ++rshift)
233 minsize = lshift>0? (((
hashcount_t)(0x01)) << lshift):
242 if( maxsize < minsize )
252 LOGDIAG4(
"minsize=%lu, maxsize=%lu, lowmark=%lu, highmark=%lu",
265 static unsigned long randbox[] =
267 0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
268 0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU,
269 0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU,
270 0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
273 const unsigned char *str = (
const unsigned char *)key;
278 acc ^= randbox[(*str + acc) & 0xf];
279 acc = (acc << 1) | (acc >> 31);
281 acc ^= randbox[((*str++ >> 4) + acc) & 0xf];
282 acc = (acc << 2) | (acc >> 30);
299 return strcmp((
const char *)key1, (
const char *)key2);
413 assert(mask != hash->
mask);
416 for(chain = 0; chain < hash->
nchains; chain++)
419 hnode_t *hptr = newtable[chain];
425 hptr->
pself = &newtable[chain];
431 if((hptr->
hkey & exposed_bit))
446 hptr->
next = newchain;
452 hptr->
pself = &newchain;
461 newtable[chain + hash->
nchains] = newchain;
469 hash->
table = newtable;
549 hnode_t **newtable, *lo_tail, *lo_chain, *hi_chain;
560 for(chain = 0; chain < nchains; chain++)
562 lo_chain = hash->
table[chain];
563 hi_chain = hash->
table[chain + nchains];
566 for(lo_tail=lo_chain; lo_tail && lo_tail->
next; lo_tail=lo_tail->
next)
575 lo_tail->
next = hi_chain;
587 hash->
table[chain] = hi_chain;
598 size =
sizeof(
hnode_t *) * nchains;
604 hash->
table = newtable;
608 for(chain = 0; chain < nchains; chain++)
610 if(hash->
table[chain])
738 LOGDIAG4(
"min=%lu, max=%lu, high=%lu, low=%lu, nchains=%lu, mask=0x%lx\n",
864 LOGDIAG4(
"min=%lu, max=%lu, high=%lu, low=%lu, nchains=%lu, mask=0x%lx\n",
903 for(chain = 0; chain < hash->
nchains; chain++)
905 for(npp = hash->
table + chain; *npp; npp = &(*npp)->
next)
945 for(chain = 0; chain < nchains && hash->
table[chain] == 0; chain++);
1018 while(chain < nchains && hash->table[chain] == 0)
1023 if (chain < nchains)
1025 scan->
chain = chain;
1079 hkey = hash->
hash(key);
1080 chain = hkey & hash->
mask;
1090 hash->
table[chain] = node;
1251 hkey = hash->
hash(key);
1252 chain = hkey & hash->
mask;
1255 for(nptr = hash->
table[chain]; nptr; nptr = nptr->
next)
1378 if( freedatafun !=
NULL )
1380 freedatafun(node->
key, node->
data);
void hash_node_insert(hash_t *hash, hnode_t *node, void *key)
Insert a node into the hash table.
int(* hash_comp_t)(const void *key1, const void *key2)
User comparison function override type.
static void compute_bits()
Compute the number of bits in the hash_val_t type.
struct hnode_t ** pself
Note 3.
hnode_t * hash_scan_next(hscan_t *scan)
Retrieve the next node from the hash table.
hashcount_t nchains
Note 6.
hashcount_t maxsize
Note 3.
hashcount_t minsize
Note 2.
static void clear_table(hash_t *hash)
Initialize the table of pointers to null.
General purpose hash data and function declarations.
#define _TULONG(var)
unsigned long int (decimal)
hnode_t * hash_node_fast_unlink(hash_t *hash, hnode_t *node)
Fast version to unlink the given node from the hash table.
#define CHKEXPR_PTR(val, expr,...)
check pointer
Memory allocation and deallocation declarations.
hnode_t * hash_lookup(hash_t *hash, const void *key)
Find a node in the hash table and return a pointer to it.
hash_comp_t compare
Note 9.
static hash_val_t hash_fun_default(const void *key)
Default hashing function over null-terminated string keys.
hash_val_t(* hash_fun_t)(const void *key)
User hashing function type.
static void grow_table(hash_t *hash)
Double the size of a dynamic table.
struct hnode_t * next
<Note 1
bool_t hash_delete(hash_t *hash, void *key)
Unlink and delete a hash node with the given key from the hash table.
hashcount_t highmark
Note 4.
void hash_set_self_verify(bool_t selfverify)
Enable (disable) automatic self-checks during hash table modification operatations.
void hash_table_delete(hash_t *hash)
Frees a dynamic hash table structure.
#define HASH_MIN_SIZE
Minimum and initial size of hash table.
unsigned long hashcount_t
maximum hash table size type
static int hash_val_t_bit
Number of bits in hashed value. Must be a power of 2.
static bool_t hash_self_verify
Do [not] perform auto-verification after hash table operations.
void(* hnode_data_free_t)(void *key, void *data)
User node data deallocator function.
#define LOGDIAG4(fmt,...)
Standard Diagnostic Level 4 logging.
hnode_t * hash_node_unlink(hash_t *hash, hnode_t *node)
Unlink the given node from the hash table.
unsigned long hash_val_t
hashed value return type
#define NEW(T)
Allocate new type.
#define _VARFMT(var, fmt)
log Variable Format.
void * new_overs(void *pSrc, size_t sizeDup, size_t sizeNew)
Allocate and duplicate.
hashcount_t lowmark
Note 5.
void hash_scan_begin(hscan_t *scan, hash_t *hash)
Reset the hash scanner (iterator).
hnode_t * hnode_init(hnode_t *node, void *data)
Initialize a client-supplied hash node.
RoadNarrows Robotics common configuration file.
#define _TBOOL(var)
boolean
hash_t * hash_table_init(hash_t *hash, hashcount_t minsize, hashcount_t maxsize, hash_comp_t compfun, hash_fun_t hashfun, hnode_data_free_t freedatafun, hnode_t **table, hashcount_t nchains)
Initialize a user supplied hash table.
static hash_val_t compute_mask(hashcount_t size)
Compute a mask for a given table size.
hash_t * hash_table_create(bool_t isdynamic, hashcount_t minsize, hashcount_t maxsize, hash_comp_t compfun, hash_fun_t hashfun, hnode_data_free_t freedatafun)
Create a dynamic hash table.
#define _TPTR(var)
pointer
#define LOGDIAG4CALL(...)
Standard Diagnostic Level 4 function call tracing.
hnode_data_free_t freenodedata
Note 11.
hnode_t * hnode_create(void *data)
Create a hash table node dynamically and assign it the given data.
static void shrink_table(hash_t *hash)
Cut a dynamic table size in half.
Hash table control structure.
Hash chain node structure.
void hash_node_delete(hash_t *hash, hnode_t *node)
Unlink and delete a hash node from the hash table.
bool_t hash_table_verify(hash_t *hash)
Verify hash table consistency.
void hnode_destroy(hnode_t *node, hnode_data_free_t freedatafun)
Hash node and user data deallocator.
static bool_t is_power_of_two(hash_val_t arg)
Verify whether the given argument is a power of two.
bool_t hash_insert(hash_t *hash, void *key, void *data)
Insert user data with the given key into the hash table.
#define HASH_VAL_T_MAX
Maximum hashed value (a Mersenne number 2^N-1)
static void init_hash_sizes(hash_t *hash, hashcount_t minsize, hashcount_t maxsize)
Initialize the table size values.
void hnode_delete(hnode_t *node)
Destroy a dynamically allocated node.
void hash_table_destroy(hash_t *hash)
Delete the hash table, all of its entries, and all of the user data.
#define CHKEXPR_ULONG(val, expr,...)
check unsigned long integer
static int hash_comp_default(const void *key1, const void *key2)
Default hash key comparator function of null-terminated key strings.
#define hash_isempty(H)
Returns true if table is empty, false otherwise.