diff options
Diffstat (limited to 'src/htsinthash.c')
-rw-r--r-- | src/htsinthash.c | 174 |
1 files changed, 151 insertions, 23 deletions
diff --git a/src/htsinthash.c b/src/htsinthash.c index eb155cb..e81a74f 100644 --- a/src/htsinthash.c +++ b/src/htsinthash.c @@ -42,11 +42,16 @@ Please visit our Website: http://www.httrack.com /* specific definitions */ #include "htsbase.h" -#include "htsglobal.h" #include "htsmd5.h" /* END specific definitions */ /* Specific macros */ +#ifdef NO_MALLOCT +#undef malloct +#undef freet +#undef calloct +#undef strcpybuff +#endif #ifndef malloct #define malloct malloc #define freet free @@ -54,21 +59,55 @@ Please visit our Website: http://www.httrack.com #define strcpybuff strcpy #endif +// static functions + +static void inthash_delchain(inthash_chain* hash,t_inthash_freehandler free_handler); +static void inthash_default_free_handler(void* value); +static unsigned long int inthash_key(const char* value); +static void inthash_init(inthash hashtable); + + // inthash -- simple hash table, using a key (char[]) and a value (ulong int) -unsigned long int inthash_key(char* value) { +static unsigned long int inthash_key(const char* value) { return md5sum32(value); } +int inthash_read_pvoid(inthash hashtable,const char* name, void** pvalue) { + inthash_value value = INTHASH_VALUE_NULL; + int ret = inthash_read_value(hashtable, name, (pvalue != NULL) ? &value : NULL); + if (pvalue != NULL) + *pvalue = value.ptr; + return ret; +} + +int inthash_write_pvoid(inthash hashtable,const char* name, void* pvalue) { + inthash_value value = INTHASH_VALUE_NULL; + value.ptr = pvalue; + return inthash_write_value(hashtable, name, value); +} + +void inthash_add_pvoid(inthash hashtable, const char* name, void* pvalue) { + inthash_value value = INTHASH_VALUE_NULL; + value.ptr = pvalue; + inthash_add_value(hashtable, name, value); +} + // Check for duplicate entry (==1 : added) -int inthash_write(inthash hashtable,char* name,long int value) { +int inthash_write(inthash hashtable,const char* name,long int intvalue) { + inthash_value value = INTHASH_VALUE_NULL; + value.intg = intvalue; + return inthash_write_value(hashtable, name, value); +} + +int inthash_write_value(inthash hashtable,const char* name,inthash_value value) { int pos = (inthash_key(name) % hashtable->hash_size); inthash_chain* h=hashtable->hash[pos]; while (h) { if (strcmp(h->name,name)==0) { /* Delete element */ if (hashtable->flag_valueismalloc) { - void* ptr = (void*)h->value.intg; + void* ptr = h->value.ptr; if (ptr != NULL) { if (hashtable->free_handler) hashtable->free_handler(ptr); @@ -77,19 +116,19 @@ int inthash_write(inthash hashtable,char* name,long int value) { } } /* Insert */ - h->value.intg=value; + h->value=value; return 0; } h=h->next; } // Not found, add it! - inthash_add(hashtable,name,value); + inthash_add_value(hashtable,name,value); return 1; } // Increment pos value, create one if necessary (=0) // (==1 : created) -int inthash_inc(inthash hashtable,char* name) { +int inthash_inc(inthash hashtable,const char* name) { long int value=0; int r=0; if (inthash_read(hashtable,name,&value)) { @@ -105,7 +144,14 @@ int inthash_inc(inthash hashtable,char* name) { // Does not check for duplicate entry -void inthash_add(inthash hashtable,char* name,long int value) { +void inthash_add(inthash hashtable, const char* name, long int intvalue) { + inthash_value value = INTHASH_VALUE_NULL; + memset(&value, 0, sizeof(value)); + value.intg = intvalue; + inthash_add_value(hashtable, name, value); +} + +void inthash_add_value(inthash hashtable, const char* name, inthash_value value) { int pos = (inthash_key(name) % hashtable->hash_size); inthash_chain** h=&hashtable->hash[pos]; @@ -120,11 +166,12 @@ void inthash_add(inthash hashtable,char* name,long int value) { (*h)->name=((char*)(*h)) + sizeof(inthash_chain); (*h)->next=NULL; strcpybuff((*h)->name,name); - (*h)->value.intg=value; + (*h)->value=value; + hashtable->nitems++; } } -void* inthash_addblk(inthash hashtable,char* name,int blksize) { +void* inthash_addblk(inthash hashtable,const char* name,int blksize) { int pos = (inthash_key(name) % hashtable->hash_size); inthash_chain** h=&hashtable->hash[pos]; @@ -141,19 +188,28 @@ void* inthash_addblk(inthash hashtable,char* name,int blksize) { (*h)->name = ((char*)(*h)) + sizeof(inthash_chain); (*h)->next=NULL; strcpybuff((*h)->name,name); - (*h)->value.intg = (unsigned long) (char*) ((char*)(*h)) + sizeof(inthash_chain) + strlen(name) + 2; - return (void*)(*h)->value.intg; + (*h)->value.ptr = (void*) ( ((char*)(*h)) + sizeof(inthash_chain) + strlen(name) + 2 ); + hashtable->nitems++; + return (*h)->value.ptr; } return NULL; } -int inthash_read(inthash hashtable,char* name,long int* value) { +int inthash_read(inthash hashtable,const char* name,long int* intvalue) { + inthash_value value = INTHASH_VALUE_NULL; + int ret = inthash_read_value(hashtable, name, (intvalue != NULL) ? &value : NULL); + if (intvalue != NULL) + *intvalue = value.intg; + return ret; +} + +int inthash_read_value(inthash hashtable,const char* name,inthash_value* value) { int pos = (inthash_key(name) % hashtable->hash_size); inthash_chain* h=hashtable->hash[pos]; while (h) { if (strcmp(h->name,name)==0) { if (value != NULL) - *value=h->value.intg; + *value=h->value; return 1; } h=h->next; @@ -161,7 +217,45 @@ int inthash_read(inthash hashtable,char* name,long int* value) { return 0; } -int inthash_readptr(inthash hashtable,char* name,long int* value) { +int inthash_exists(inthash hashtable, const char* name) { + return inthash_read_value(hashtable, name, NULL); +} + +int inthash_remove(inthash hashtable,const char* name) { + int pos = (inthash_key(name) % hashtable->hash_size); + inthash_chain** h=&hashtable->hash[pos]; + t_inthash_freehandler free_handler=NULL; + if ( hashtable->flag_valueismalloc ) { + if ( hashtable->free_handler ) + free_handler=hashtable->free_handler; + else + free_handler=inthash_default_free_handler; + } + while (*h) { + if (strcmp((*h)->name,name)==0) { + inthash_chain* next; + if (free_handler) { + if ((*h)->value.ptr) { + void* ptr = (*h)->value.ptr; + if (free_handler) + free_handler(ptr); + else + freet(ptr); + (*h)->value.ptr=0; + } + } + next=(*h)->next; + freet(*h); + *h=next; + hashtable->nitems--; + return 1; + } + h=&((*h)->next); + } + return 0; +} + +int inthash_readptr(inthash hashtable,const char* name,long int* value) { int ret; *value = 0; ret = inthash_read(hashtable, name, value); @@ -170,31 +264,32 @@ int inthash_readptr(inthash hashtable,char* name,long int* value) { return ret; } -void inthash_init(inthash hashtable) { +static void inthash_init(inthash hashtable) { unsigned int i; for(i=0;i<hashtable->hash_size;i++) { hashtable->hash[i]=NULL; } } -void inthash_delchain(inthash_chain* hash,t_inthash_freehandler free_handler) { - if (hash) { - inthash_delchain(hash->next,free_handler); +static void inthash_delchain(inthash_chain* hash,t_inthash_freehandler free_handler) { + while(hash != NULL) { + inthash_chain* next=hash->next; if (free_handler) { // pos is a malloc() block, delete it! - if (hash->value.intg) { - void* ptr = (void*)hash->value.intg; + if (hash->value.ptr) { + void* ptr = hash->value.ptr; if (free_handler) free_handler(ptr); else freet(ptr); - hash->value.intg=0; + hash->value.ptr=0; } } freet(hash); + hash=next; } } -void inthash_default_free_handler(void* value) { +static void inthash_default_free_handler(void* value) { if (value) freet(value); } @@ -210,6 +305,7 @@ inthash inthash_new(int size) { hashtable->hash_size=size; inthash_init(hashtable); } + hashtable->nitems = 0; } return hashtable; } @@ -229,6 +325,12 @@ void inthash_value_set_free_handler(inthash hashtable, t_inthash_freehandler fre hashtable->free_handler = free_handler; } +unsigned int inthash_nitems(inthash hashtable) { + if (hashtable!= NULL) + return hashtable->nitems; + return 0; +} + void inthash_delete(inthash* hashtable) { if (hashtable) { if (*hashtable) { @@ -253,3 +355,29 @@ void inthash_delete(inthash* hashtable) { } } } + +// Enumerators + +struct_inthash_enum inthash_enum_new(inthash hashtable) { + struct_inthash_enum e; + memset(&e, 0, sizeof(e)); + e.index = 0; + e.item = NULL; + e.table = hashtable; + return e; +} + +inthash_chain* inthash_enum_next(struct_inthash_enum* e) { + inthash_chain* item = NULL; + if (e != NULL) { + while(e->item == NULL && e->index < (int) e->table->hash_size) { + e->item = e->table->hash[e->index]; + e->index++; + } + if (e->item != NULL) { + item = e->item; + e->item = e->item->next; + } + } + return item; +} |