[util] Add size limited find and hash functions

Hash_nFind and Hash_nString work like Hash_Find and Hash_String, but
take a maximum string length (like strncmp etc).
This commit is contained in:
Bill Currie 2023-03-03 14:47:38 +09:00
parent d0a3040b26
commit 9146860f70
2 changed files with 58 additions and 0 deletions

View file

@ -119,6 +119,14 @@ int Hash_AddElement (hashtab_t *tab, void *ele);
*/
void *Hash_Find (hashtab_t *tab, const char *key);
/** find an element within a hash table.
\param tab the table to search
\param key the key string identifying the element being searched for
\param sz the maximum length of the key string
\return pointer to the element if found, otherwise 0.
*/
void *Hash_nFind (hashtab_t *tab, const char *key, size_t sz);
/** find an element within a hash table.
\param tab the table to search
\param ele element with info identifying the element being searched for
@ -189,6 +197,15 @@ void Hash_Free (hashtab_t *tab, void *ele);
*/
uintptr_t Hash_String (const char *str) __attribute__((pure));
/** hash a string.
\param str the string to hash
\param sz the maximum length of the string
\return the hash value of the string.
this is the same function as used internally.
*/
uintptr_t Hash_nString (const char *str, size_t sz) __attribute__((pure));
/** hash a buffer.
\param buf the buffer to hash
\param len the size of the buffer

View file

@ -119,6 +119,32 @@ Hash_String (const char *str)
#endif
}
VISIBLE uintptr_t
Hash_nString (const char *str, size_t sz)
{
#if 0
uintptr_t h = 0;
while (*str && sz-- > 0) {
h = (h << 4) + (unsigned char)*str++;
if (h&0xf0000000)
h = (h ^ (h >> 24)) & 0xfffffff;
}
return h;
#else
// dx_hack_hash
// shamelessly stolen from Daniel Phillips <phillips@innominate.de>
// from his post to lkml
uint32_t hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
while (sz-- > 0 && *str) {
uint32_t hash = hash1 + (hash0 ^ ((unsigned char)*str++ * 71523));
if (hash & 0x80000000) hash -= 0x7fffffff;
hash1 = hash0;
hash0 = hash;
}
return hash0;
#endif
}
VISIBLE uintptr_t
Hash_Buffer (const void *_buf, int len)
{
@ -289,6 +315,21 @@ Hash_Find (hashtab_t *tab, const char *key)
return 0;
}
VISIBLE void *
Hash_nFind (hashtab_t *tab, const char *key, size_t sz)
{
uintptr_t h = Hash_nString (key, sz);
size_t ind = get_index (h, tab->tab_size, tab->size_bits);
hashlink_t *lnk = tab->tab[ind];
while (lnk) {
if (strncmp (key, tab->get_key (lnk->data, tab->user_data), sz) == 0)
return lnk->data;
lnk = lnk->next;
}
return 0;
}
VISIBLE void *
Hash_FindElement (hashtab_t *tab, const void *ele)
{