From 5c2b14ebb8a19a6e2d9e3c804649cc4eccf3d0ec Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Sat, 8 Oct 2022 09:46:30 +0200 Subject: [PATCH] add generic pointer hash table --- src/spice_netlist.c | 100 ++++++++++++++++++++++++++++++++++++++++++++ src/xschem.h | 18 ++++++++ 2 files changed, 118 insertions(+) diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 9255e550..f509bf2f 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -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; + } +} diff --git a/src/xschem.h b/src/xschem.h index 24facbe1..dd749ddc 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -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);