add generic pointer hash table

This commit is contained in:
Stefan Frederik 2022-10-08 09:46:30 +02:00
parent 6be0fc392b
commit 5c2b14ebb8
2 changed files with 118 additions and 0 deletions

View File

@ -750,3 +750,103 @@ void int_hash_free(Int_hashtable *hashtable)
hashtable->size = 0;
}
}
/* GENERIC PURPOSE PTR HASH TABLE */
/* token value what ... what ...
* --------------------------------------------------------------------------
* "whatever" "whatever" XINSERT insert in hash table if not in.
* if already present update value if not NULL,
* return new entry address.
* "whatever" "whatever" XINSERT_NOREPLACE same as XINSERT but do not replace existing value
* return NULL if not found.
* "whatever" "whatever" XLOOKUP lookup in hash table,return entry addr.
* return NULL if not found
* "whatever" "whatever" XDELETE delete entry if found,return NULL
*/
Ptr_hashentry *ptr_hash_lookup(Ptr_hashtable *hashtable, const char *token, void *const value, int what)
{
unsigned int hashcode, idx;
Ptr_hashentry *entry, *saveptr, **preventry;
int s ;
int size = hashtable->size;
Ptr_hashentry **table = hashtable->table;
if(token==NULL || size == 0 || table == NULL) return NULL;
hashcode=str_hash(token);
idx=hashcode % size;
entry=table[idx];
preventry=&table[idx];
while(1)
{
if( !entry ) /* empty slot */
{
if(what==XINSERT || what == XINSERT_NOREPLACE) /* insert data */
{
s=sizeof( Ptr_hashentry );
entry=(Ptr_hashentry *)my_malloc(659, s);
entry->next=NULL;
entry->token=NULL;
my_strdup(658, &entry->token, token);
entry->value = value;
entry->hash=hashcode;
*preventry=entry;
}
return NULL; /* if element inserted return NULL since it was not in table */
}
if( entry -> hash==hashcode && strcmp(token,entry->token)==0 ) /* found a matching token */
{
if(what==XDELETE) /* remove token from the hash table ... */
{
saveptr=entry->next;
my_free(896, &entry->token);
my_free(897, &entry);
*preventry=saveptr;
}
else if(what == XINSERT ) {
entry->value = value;
}
return entry; /* found matching entry, return the address */
}
preventry=&entry->next; /* descend into the list. */
entry = entry->next;
}
}
void ptr_hash_init(Ptr_hashtable *hashtable, int size)
{
if(hashtable-,>size !=0 || hashtable->table != NULL) {
dbg(0, "ptr_hash_init(): Warning hash table not empty, possible data leak\n");
}
hashtable->size = size;
hashtable->table = my_calloc(1576, size, sizeof(Ptr_hashentry *));
}
static void ptr_hash_free_entry(Ptr_hashentry *entry)
{
Ptr_hashentry *tmp;
while( entry ) {
tmp = entry -> next;
my_free(1171, &(entry->token));
my_free(1172, &entry);
entry = tmp;
}
}
void ptr_hash_free(Ptr_hashtable *hashtable)
{
if(hashtable->table) {
int i;
Ptr_hashentry **table = hashtable->table;
for(i=0;i < hashtable->size;i++)
{
ptr_hash_free_entry( table[i] );
table[i] = NULL;
}
my_free(1575, &(hashtable->table));
hashtable->size = 0;
}
}

View File

@ -629,6 +629,20 @@ typedef struct {
int size;
} Int_hashtable;
/* generic pointer hash table */
typedef struct ptr_hashentry Ptr_hashentry;
struct ptr_hashentry
{
struct ptr_hashentry *next;
unsigned int hash;
char *token;
void *value;
};
typedef struct {
Ptr_hashentry **table;
int size;
} Ptr_hashtable;
typedef struct node_hashentry Node_hashentry;
struct node_hashentry
@ -1299,6 +1313,10 @@ extern void int_hash_init(Int_hashtable *hashtable, int size);
extern void int_hash_free(Int_hashtable *hashtable);
extern Int_hashentry *int_hash_lookup(Int_hashtable *hashtable,
const char *token, const int value, int what);
extern void ptr_hash_init(Ptr_hashtable *hashtable, int size);
extern void ptr_hash_free(Ptr_hashtable *hashtable);
extern Ptr_hashentry *ptr_hash_lookup(Ptr_hashtable *hashtable,
const char *token, void * const value, int what);
extern char *find_nth(const char *str, const char *sep, int n);
extern int isonlydigit(const char *s);