2001-02-19 21:15:25 +00:00
|
|
|
/*
|
2001-02-21 19:35:06 +00:00
|
|
|
hash.h
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-21 19:35:06 +00:00
|
|
|
hash tables
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-06-19 02:01:18 +00:00
|
|
|
Copyright (C) 2000 Bill Currie <bill@taniwha.org>
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2020-02-24 03:21:20 +00:00
|
|
|
#ifndef __QF_hash_h
|
|
|
|
#define __QF_hash_h
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2007-04-04 08:27:49 +00:00
|
|
|
#include <stdint.h>
|
2011-01-06 06:17:49 +00:00
|
|
|
#include <stdlib.h>
|
2007-04-04 08:27:49 +00:00
|
|
|
|
2004-11-08 23:27:00 +00:00
|
|
|
/** \defgroup hash Hash tables
|
2006-12-05 11:40:00 +00:00
|
|
|
\ingroup utils
|
2004-11-08 23:27:00 +00:00
|
|
|
*/
|
2020-02-11 06:20:49 +00:00
|
|
|
///@{
|
2004-11-08 23:27:00 +00:00
|
|
|
|
2001-06-11 19:17:40 +00:00
|
|
|
typedef struct hashtab_s hashtab_t;
|
2020-03-25 06:43:16 +00:00
|
|
|
typedef struct hashlink_s hashlink_t;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** create a new hash table.
|
|
|
|
\param tsize table size. larger values will give better distribution, but
|
2001-06-11 19:37:25 +00:00
|
|
|
use more memory.
|
2006-12-02 23:02:34 +00:00
|
|
|
\param gk a function that returns a string to be used as the key for
|
2001-06-11 19:37:25 +00:00
|
|
|
inserting or finding the element. First parameter is a pointer
|
|
|
|
to the element from which to extract the key, the second is
|
|
|
|
the user data pointer.
|
2006-12-02 23:02:34 +00:00
|
|
|
\param f a function to free the element. Only ever called from
|
2001-06-11 19:37:25 +00:00
|
|
|
Hash_FlushTable and Hash_DelTable. The first parameter is the
|
|
|
|
element to be freed and the second is the user data pointer.
|
2006-12-02 23:02:34 +00:00
|
|
|
\param ud user data pointer. set to whatever you want, it will be passed
|
2001-06-11 19:37:25 +00:00
|
|
|
to the get key and free functions as the second parameter.
|
2020-03-25 06:43:16 +00:00
|
|
|
\param hlfl Address of opaque pointer used for per-thread allocation of
|
|
|
|
internal memory. If null, a local static pointer will be used,
|
|
|
|
but the hash table will not be thread-safe unless all tables
|
|
|
|
created with a null \a hlfl (hashlink freelist) are used in
|
|
|
|
only the one thread. However, this applys only to updating a
|
|
|
|
hash table; hash tables that are not updated can be safely
|
|
|
|
shared between threads.
|
2006-12-02 23:02:34 +00:00
|
|
|
\return pointer to the hash table (to be passed to the other functions)
|
|
|
|
or 0 on error.
|
2001-06-11 19:37:25 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
Hash_Add(), Hash_Find(), Hash_FindList() and Hash_Del() use gk and strcmp.
|
2003-04-28 16:04:22 +00:00
|
|
|
|
2001-06-11 19:37:25 +00:00
|
|
|
multiple inserions of the same key are fine; later insertions override
|
|
|
|
previous ones until the later one is removed (Hash_Del).
|
|
|
|
*/
|
2012-07-18 13:34:37 +00:00
|
|
|
hashtab_t *Hash_NewTable (int tsize, const char *(*gk)(const void*,void*),
|
2020-03-25 06:43:16 +00:00
|
|
|
void (*f)(void*,void*), void *ud,
|
|
|
|
hashlink_t **hlfl);
|
2001-06-11 19:37:25 +00:00
|
|
|
|
2003-08-31 05:24:24 +00:00
|
|
|
/** change the hash and compare functions used by the Hash_*Element functions.
|
2001-08-16 02:51:53 +00:00
|
|
|
the default hash function just returns the address of the element, and the
|
|
|
|
default compare just compares the addresses. compare is to return 0 for not
|
|
|
|
equal and non-0 otherwise.
|
|
|
|
|
2003-04-28 16:04:22 +00:00
|
|
|
With suitably crafted gh and cmp functions, Hash_*Element functions can
|
|
|
|
be mixed with the non-element functions, but by default the results will
|
|
|
|
be undefined.
|
|
|
|
|
2006-12-05 11:40:00 +00:00
|
|
|
\param tab the table configure
|
2006-12-02 23:02:34 +00:00
|
|
|
\param gh takes the same parameters as gk in Hash_NewTable
|
|
|
|
\param cmp is element 1, element 2, userdata
|
2001-08-16 02:51:53 +00:00
|
|
|
*/
|
2012-07-18 13:34:37 +00:00
|
|
|
void Hash_SetHashCompare (hashtab_t *tab, uintptr_t (*gh)(const void*,void*),
|
|
|
|
int (*cmp)(const void*,const void*,void*));
|
2001-08-16 02:51:53 +00:00
|
|
|
|
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** delete a hash table.
|
|
|
|
\param tab the table to be deleted
|
2001-06-11 19:37:25 +00:00
|
|
|
*/
|
2001-02-21 19:35:06 +00:00
|
|
|
void Hash_DelTable (hashtab_t *tab);
|
2001-06-11 19:37:25 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** clean out all the entries from a hash table, starting over again.
|
|
|
|
\param tab the table to be cleared
|
2001-06-11 19:37:25 +00:00
|
|
|
*/
|
2001-03-05 05:11:26 +00:00
|
|
|
void Hash_FlushTable (hashtab_t *tab);
|
2001-06-11 19:37:25 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** add an entry to a hash table.
|
|
|
|
\param tab the table to be added to
|
|
|
|
\param ele the element to add to the table
|
|
|
|
\return 0 for success, -1 for error.
|
2001-06-11 19:37:25 +00:00
|
|
|
*/
|
2001-02-21 19:35:06 +00:00
|
|
|
int Hash_Add (hashtab_t *tab, void *ele);
|
2006-12-02 23:02:34 +00:00
|
|
|
|
|
|
|
/** add an entry to a hash table.
|
|
|
|
\param tab the table to be added to
|
|
|
|
\param ele the element to add to the table
|
|
|
|
\return 0 for success, -1 for error.
|
|
|
|
*/
|
2001-08-16 02:51:53 +00:00
|
|
|
int Hash_AddElement (hashtab_t *tab, void *ele);
|
2001-06-11 19:37:25 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** find an element within a hash table.
|
|
|
|
\param tab the table to search
|
|
|
|
\param key the key string identifying the element being searched for
|
|
|
|
\return pointer to the element if found, otherwise 0.
|
2001-06-11 19:37:25 +00:00
|
|
|
*/
|
2001-02-21 19:35:06 +00:00
|
|
|
void *Hash_Find (hashtab_t *tab, const char *key);
|
2006-12-02 23:02:34 +00:00
|
|
|
|
|
|
|
/** find an element within a hash table.
|
|
|
|
\param tab the table to search
|
|
|
|
\param ele element with info identifying the element being searched for
|
|
|
|
\return pointer to the element if found, otherwise 0.
|
|
|
|
*/
|
2012-07-18 13:34:37 +00:00
|
|
|
void *Hash_FindElement (hashtab_t *tab, const void *ele);
|
2001-06-11 19:37:25 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** find a list of elements within a hash table.
|
|
|
|
\param tab the table to search
|
|
|
|
\param key the key string identifying the elements being searched for
|
|
|
|
\return a null terminated list of element pointers if at least one
|
|
|
|
found, otherwise 0.
|
|
|
|
\note it is the caller's responsibilty to free() the list.
|
|
|
|
|
|
|
|
returned list is guaranteed to be in reverse order of insertion. ie,
|
|
|
|
deleting items from the list in list order will delete the correct items.
|
2002-05-30 21:56:57 +00:00
|
|
|
*/
|
|
|
|
void **Hash_FindList (hashtab_t *tab, const char *key);
|
2006-12-02 23:02:34 +00:00
|
|
|
|
|
|
|
/** find a list of elements within a hash table.
|
|
|
|
\param tab the table to search
|
|
|
|
\param ele element with info identifying the elements being searched for
|
|
|
|
\return a null terminated list of element pointers if at least one
|
|
|
|
found, otherwise 0.
|
|
|
|
\note it is the caller's responsibilty to free() the list.
|
|
|
|
|
|
|
|
returned list is guaranteed to be in reverse order of insertion. ie,
|
|
|
|
deleting items from the list in list order will delete the correct items.
|
|
|
|
*/
|
2002-05-30 21:56:57 +00:00
|
|
|
void **Hash_FindElementList (hashtab_t *tab, void *ele);
|
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** delete an element from a hash table.
|
|
|
|
\param tab the table to remove the element from
|
|
|
|
\param key the key string identifying the element to be deleted
|
|
|
|
\return a pointer to the element on success, 0 if the element could not
|
|
|
|
be found.
|
|
|
|
|
|
|
|
Does \em NOT call the free element function. That is the caller's
|
2001-06-11 19:37:25 +00:00
|
|
|
responsibility.
|
|
|
|
*/
|
2001-07-06 17:43:47 +00:00
|
|
|
void *Hash_Del (hashtab_t *tab, const char *key);
|
2006-12-02 23:02:34 +00:00
|
|
|
|
|
|
|
/** delete an element from a hash table.
|
|
|
|
\param tab the table to remove the element from
|
|
|
|
\param ele element with info identifying the element to be deleted
|
|
|
|
\return a pointer to the element on success, 0 if the element could not
|
|
|
|
be found.
|
|
|
|
|
|
|
|
Does \em NOT call the free element function. That is the caller's
|
|
|
|
responsibility.
|
|
|
|
*/
|
2001-08-16 02:51:53 +00:00
|
|
|
void *Hash_DelElement (hashtab_t *tab, void *ele);
|
|
|
|
|
2003-08-31 05:24:24 +00:00
|
|
|
/** calls the free element function for the supplied ele
|
2006-12-02 23:02:34 +00:00
|
|
|
\param tab the table associated with the element (for the free function)
|
|
|
|
\param ele the element to be freed
|
|
|
|
|
2006-12-04 13:08:52 +00:00
|
|
|
\par Example:
|
|
|
|
Hash_Free (tab, Hash_Del (tab, key));
|
2003-02-21 02:37:44 +00:00
|
|
|
*/
|
2003-01-27 18:16:15 +00:00
|
|
|
void Hash_Free (hashtab_t *tab, void *ele);
|
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** hash a string.
|
|
|
|
\param str the string to hash
|
|
|
|
\return the hash value of the string.
|
2012-05-21 23:23:22 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
this is the same function as used internally.
|
2001-08-16 02:51:53 +00:00
|
|
|
*/
|
2018-10-09 03:35:01 +00:00
|
|
|
unsigned long Hash_String (const char *str) __attribute__((pure));
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** hash a buffer.
|
|
|
|
\param buf the buffer to hash
|
|
|
|
\param len the size of the buffer
|
|
|
|
\return the hash value of the string.
|
2002-10-20 03:30:22 +00:00
|
|
|
*/
|
2018-10-09 03:35:01 +00:00
|
|
|
unsigned long Hash_Buffer (const void *buf, int len) __attribute__((pure));
|
2002-10-20 03:30:22 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** get the size of the table
|
|
|
|
\param tab the table in question
|
|
|
|
\return the number of elements in the table.
|
2004-02-07 07:47:23 +00:00
|
|
|
*/
|
2018-10-09 03:35:01 +00:00
|
|
|
size_t Hash_NumElements (hashtab_t *tab) __attribute__((pure));
|
2004-02-07 07:47:23 +00:00
|
|
|
|
2006-12-02 23:02:34 +00:00
|
|
|
/** list of all elements in the table.
|
|
|
|
\param tab the table to list
|
|
|
|
\return a null terminated list of element pointers for all elements
|
|
|
|
in the table
|
|
|
|
\note it is the caller's responsibilty to free() the list.
|
|
|
|
|
|
|
|
returned list is guaranteed to be in reverse order of insertion for
|
|
|
|
elements with the same key. ie, deleting items from the list in list order
|
|
|
|
will delete the correct items.
|
2001-10-02 23:17:25 +00:00
|
|
|
*/
|
|
|
|
void **Hash_GetList (hashtab_t *tab);
|
|
|
|
|
2003-08-31 05:24:24 +00:00
|
|
|
/** dump statistics about the hash table
|
2006-12-02 23:02:34 +00:00
|
|
|
\param tab the table to dump
|
2001-11-10 01:13:29 +00:00
|
|
|
*/
|
|
|
|
void Hash_Stats (hashtab_t *tab);
|
|
|
|
|
2020-02-11 06:20:49 +00:00
|
|
|
///@}
|
2004-11-08 23:27:00 +00:00
|
|
|
|
2020-02-24 03:21:20 +00:00
|
|
|
#endif//__QF_hash_h
|