60 #define HASH_TABLE_SIZE 256 119 static unsigned long _num_allocs = 0u;
144 const unsigned char* p = (
const unsigned char*)
key;
145 unsigned int h = 2166136261u;
148 for (
i = 0;
i <
len;
i++) {
149 h = (h*16777619u) ^ p[
i];
166 int n = (len1 < len2) ? len1 : len2;
167 return memcmp(key1, key2, n);
185 if (c(
key, nkey,
i->key,
i->nkey) == 0) {
187 if (prev) (*prev) = p;
193 if (prev) (*prev) = NULL;
232 if ((*t)->table[
i])
_release_bucket(&((*t)->table[
i]), (*t)->ownsKeys, (*t)->ownsValues);
263 int h = t->
hash(
i->key,
i->nkey);
304 return HASH_NewTable(ownsKeys, ownsValues, duplicateOverwrite, h, c,
nullptr,
nullptr,
nullptr);
389 memcpy (
i->value, value, nvalue);
392 i->value =
const_cast<void*
>(value);
401 memcpy (
i->key,
key, nkey);
404 i->key =
const_cast<void*
>(
key);
409 memcpy (
i->value, value, nvalue);
412 i->value =
const_cast<void*
>(value);
442 prev->
next =
i->next;
473 if (
i)
return i->value;
507 result = result && (table == NULL);
508 if (!result)
return false;
510 result = result && (_num_allocs == 0);
511 if (!result)
return false;
523 result = result && (table == NULL);
524 if (!result)
return false;
526 result = result && (_num_allocs == 0);
527 if (!result)
return false;
539 result = result && (table == NULL);
540 if (!result)
return false;
542 result = result && (_num_allocs == 0);
543 if (!result)
return false;
552 char* aaa = (
char*)
HASH_Get(table,
"AAA", 4);
553 if (strncmp (aaa,
"AAA", 4) != 0)
return false;
554 char* bbb = (
char*)
HASH_Get(table,
"BBB", 4);
555 if (strncmp (bbb,
"BBB", 4) != 0)
return false;
556 char* ccc = (
char*)
HASH_Get(table,
"CCC", 4);
557 if (strncmp (ccc,
"CCC", 4) != 0)
return false;
564 result = result && (table == NULL);
565 if (!result)
return false;
567 result = result && (_num_allocs == 0);
568 if (!result)
return false;
571 const char AZ[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
576 for(
int i=0;
i < 4000;
i++) {
578 int len = 4 + (rand() % 20);
579 memset (buffer, 0,
sizeof(buffer));
580 for (
int j=0; j <
len; j++) {
581 int v = rand() %
sizeof(AZ);
590 int avg = (total / 4000);
594 if ( !((idx_low <= avg) && (idx_high >= avg)) )
return false;
598 char item1[] =
"AAA";
599 char item2[] =
"BBB";
600 char item3[] =
"CCC";
605 aaa = (
char*)
HASH_Get(table,
"AAA", 4);
606 if (aaa != item1)
return false;
607 bbb = (
char*)
HASH_Get(table,
"BBB", 4);
608 if (bbb != item2)
return false;
609 ccc = (
char*)
HASH_Get(table,
"CCC", 4);
610 if (ccc != item3)
return false;
613 result = result && (table == NULL);
614 if (!result)
return false;
616 result = result && (_num_allocs == 0);
617 if (!result)
return false;
static void * _hash_alloc(memPool_t *pool, int n, size_t s)
hashTable_compare compare
Memory handling with sentinel checking and pools with tags for grouped free'ing.
static hashItem_s * _iterator_next(hashTable_s *t, hashItem_s *i)
iterate to next item
unsigned short int HASH_INDEX
static void _release_entry(hashItem_s **i, bool ownsKeys, bool ownsValues)
Internal function, release an entry including key and value if owned.
static void _release_table(hashTable_s **t, bool full)
Internal function, releases entire table.
#define Mem_PoolAlloc(size, pool, tagNum)
hashBucket_s * table[HASH_TABLE_SIZE]
int(* hashTable_compare)(const void *key1, int len1, const void *key2, int len2)
void HASH_DeleteTable(hashTable_s **t)
Deletes a hash table and sets the pointer to NULL.
hashTable_s * HASH_NewTable(bool ownsKeys, bool ownsValues, bool duplicateOverwrite)
Creates a new hash table and sets it initial capacity.
static HASH_INDEX default_hash(const void *key, int len)
Default hash function to map keys into a 0..255 index.
static hashItem_s * _find_bucket_entry(hashBucket_s *b, hashTable_compare c, const void *key, int nkey, hashItem_s **prev)
Internal function to scan the list of entries in the bucket for an exact match.
void * HASH_Remove(hashTable_s *t, const void *key, int nkey)
Removes an existing value with given key from the hash table.
static hashItem_s * _iterator_first(hashTable_s *t)
start iterating with the first item.
int HASH_Count(hashTable_s *t)
Returns the number of entries in the hash table.
void HASH_Clear(hashTable_s *t)
Clears the hash table.
void * HASH_Get(hashTable_s *t, const void *key, int nkey)
Returns the value for a given key.
static int default_compare(const void *key1, int len1, const void *key2, int len2)
Default compare function for comparing key values.
static void _hash_free(void *p)
QGL_EXTERN GLuint GLchar GLuint * len
The hash bucket structure, contains a linked list of items.
unsigned short int(* hashTable_hash)(const void *key, int len)
hashTable_s * HASH_CloneTable(hashTable_s *source)
static void _release_bucket(hashBucket_s **b, bool ownsKeys, bool ownsValues)
Internal function, releases bucket including entries.
definitions common between client and server, but not game lib
The hash table structure, contains an array of buckets being indexed by the hash function.
QGL_EXTERN int GLboolean GLfloat * v
Header file for hashtable.
bool HASH_Insert(hashTable_s *t, const void *key, int nkey, const void *value, int nvalue)
Inserts a new value with given key into the hash table.