added qse_raddic_addvendor(), qse_raddic_findvendorbyvalue(), qse_raddic_findvendorbyname()

This commit is contained in:
2017-12-08 08:12:24 +00:00
parent 5db7ddc770
commit 4266d8026c
18 changed files with 565 additions and 634 deletions

View File

@ -25,7 +25,7 @@
*/
/*
* hash.c Non-thread-safe split-ordered hash table.
* hash.c Non-thread-safe split-ordered hash table.
*
* The weird "reverse" function is based on an idea from
* "Split-Ordered Lists - Lock-free Resizable Hash Tables", with
@ -58,6 +58,7 @@
#include <qse/cmn/htl.h>
#include <qse/cmn/chr.h>
#include "mem-prv.h"
/*
@ -176,20 +177,19 @@ static qse_uint32_t parent_of (qse_uint32_t key)
}
static qse_htl_node_t *list_find (qse_htl_t* ht, qse_htl_node_t* head, qse_uint32_t reversed, const void* data)
static qse_htl_node_t* __list_find (qse_htl_t* ht, qse_htl_node_t* head, qse_uint32_t reversed, const void* data, qse_htl_comper_t comper)
{
qse_htl_node_t *cur;
if (!/*ht->*/comper) return QSE_NULL;
for (cur = head; cur != &ht->null; cur = cur->next)
{
if (cur->reversed == reversed)
{
if (ht->comper)
{
int cmp = ht->comper(ht, data, cur->data);
if (cmp > 0) break;
if (cmp < 0) continue;
}
int cmp = /*ht->*/comper(ht, data, cur->data);
if (cmp > 0) break;
if (cmp < 0) continue;
return cur;
}
if (cur->reversed > reversed) break;
@ -199,6 +199,11 @@ static qse_htl_node_t *list_find (qse_htl_t* ht, qse_htl_node_t* head, qse_uint3
}
QSE_INLINE static qse_htl_node_t *list_find (qse_htl_t* ht, qse_htl_node_t* head, qse_uint32_t reversed, const void* data)
{
return __list_find (ht, head, reversed, data, ht->comper);
}
/*
* Inserts a new entry into the list, in order.
*/
@ -254,7 +259,7 @@ static int list_delete (qse_htl_t* ht, qse_htl_node_t** head, qse_htl_node_t* no
/* ------------------------------------------------------------------------- */
static QSE_INLINE_ALWAYS qse_size_t default_hasher (qse_htl_t* htl, const void* data)
static QSE_INLINE_ALWAYS qse_uint32_t default_hasher (qse_htl_t* htl, const void* data)
{
#if 0
qse_size_t h = 5381;
@ -263,7 +268,7 @@ static QSE_INLINE_ALWAYS qse_size_t default_hasher (qse_htl_t* htl, const void*
while (p < bound) h = ((h << 5) + h) + *p++;
return h ;
#else
return qse_genhash (data, htl->keysize);
return qse_genhash32 (data, htl->keysize);
#endif
}
@ -426,7 +431,7 @@ static void fixup (qse_htl_t *ht, qse_uint32_t entry)
/*
* Grow the hash table.
*/
static void grow (qse_htl_t *ht)
static void grow (qse_htl_t*ht)
{
qse_htl_node_t **buckets;
@ -443,7 +448,7 @@ static void grow (qse_htl_t *ht)
ht->mask = ht->num_buckets - 1;
}
qse_htl_node_t *qse_htl_search (qse_htl_t* ht, void* data)
qse_htl_node_t *qse_htl_search (qse_htl_t* ht, const void* data)
{
qse_uint32_t key;
qse_uint32_t entry;
@ -457,6 +462,20 @@ qse_htl_node_t *qse_htl_search (qse_htl_t* ht, void* data)
return list_find(ht, ht->buckets[entry], reversed, data);
}
qse_htl_node_t *qse_htl_heterosearch (qse_htl_t* ht, const void* data, qse_htl_hasher_t hasher, qse_htl_comper_t comper)
{
qse_uint32_t key;
qse_uint32_t entry;
qse_uint32_t reversed;
key = /*ht->*/hasher(ht, data);
entry = key & ht->mask;
reversed = reverse(key);
if (!ht->buckets[entry]) fixup(ht, entry);
return __list_find(ht, ht->buckets[entry], reversed, data, comper);
}
/*
* Insert data.
*/
@ -564,7 +583,7 @@ qse_htl_node_t* qse_htl_ensert (qse_htl_t* ht, void* data)
qse_htl_node_t *node;
node = qse_htl_search(ht, data);
if (!node) return qse_htl_insert(ht, data);
if (!node) node = qse_htl_insert(ht, data);
return node;
}
@ -754,7 +773,7 @@ int qse_htl_info(qse_htl_t *ht)
/*
* Continue hashing data.
*/
QSE_INLINE qse_uint32_t qse_genhash_update (const void* data, qse_size_t size, qse_uint32_t hash)
QSE_INLINE qse_uint32_t qse_genhash32_update (const void* data, qse_size_t size, qse_uint32_t hash)
{
const qse_uint8_t *p = data;
const qse_uint8_t *q = p + size;
@ -785,15 +804,15 @@ QSE_INLINE qse_uint32_t qse_genhash_update (const void* data, qse_size_t size, q
return hash;
}
qse_uint32_t qse_genhash (const void *data, qse_size_t size)
qse_uint32_t qse_genhash32 (const void *data, qse_size_t size)
{
return qse_genhash_update (data, size, FNV_MAGIC_INIT);
return qse_genhash32_update (data, size, FNV_MAGIC_INIT);
}
/*
* Hash a C string, so we loop over it once.
*/
qse_uint32_t qse_mbshash (const qse_mchar_t* p)
qse_uint32_t qse_mbshash32 (const qse_mchar_t* p)
{
qse_uint32_t hash = FNV_MAGIC_INIT;
@ -806,25 +825,58 @@ qse_uint32_t qse_mbshash (const qse_mchar_t* p)
return hash;
}
qse_uint32_t qse_wcshash (const qse_wchar_t* p)
qse_uint32_t qse_wcshash32 (const qse_wchar_t* p)
{
qse_uint32_t hash = FNV_MAGIC_INIT;
while (*p)
{
#if (QSE_SIZEOF_WCHAR_T <= QSE_SIZEOF_UINT32_T)
#if (QSE_SIZEOF_WCHAR_T <= QSE_SIZEOF_UINT32_T)
hash ^= (qse_uint32_t)(*p);
hash *= FNV_MAGIC_PRIME;
#else
#else
hash = qse_genhash_update (*p, QSE_SIZEOF(*p), hash);
#endif
#endif
p++;
}
return hash;
}
qse_uint32_t qse_mbscasehash32 (const qse_mchar_t* p)
{
qse_uint32_t hash = FNV_MAGIC_INIT;
while (*p)
{
qse_mchar_t mc = *p++;
mc = QSE_TOMLOWER(mc);
hash ^= (qse_uint32_t)mc;
hash *= FNV_MAGIC_PRIME;
}
return hash;
}
qse_uint32_t qse_wcscasehash32 (const qse_wchar_t* p)
{
qse_uint32_t hash = FNV_MAGIC_INIT;
while (*p)
{
qse_wchar_t wc = *p++;
wc = QSE_TOWLOWER(wc);
#if (QSE_SIZEOF_WCHAR_T <= QSE_SIZEOF_UINT32_T)
hash ^= (qse_uint32_t)(wc);
hash *= FNV_MAGIC_PRIME;
#else
hash = qse_genhash_update (&wc, QSE_SIZEOF(wc), hash);
#endif
}
return hash;
}
#if 0
/*
@ -833,7 +885,7 @@ qse_uint32_t qse_wcshash (const qse_wchar_t* p)
*
* If you need a non-power-of-two hash, cope.
*/
qse_uint32_t qse_foldhash (qse_uint32_t hash, int bits)
qse_uint32_t qse_foldhash32 (qse_uint32_t hash, int bits)
{
int count;
qse_uint32_t result;