From: Mike D. Lowis Date: Wed, 30 Sep 2015 19:38:02 +0000 (-0400) Subject: Added incomplete hashtable implementation X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=b025e04f05f749e8bab7183d732538990d494f0b;p=archive%2Fcarl.git Added incomplete hashtable implementation --- diff --git a/build.ninja b/build.ninja index 9556fd5..4f68f6a 100644 --- a/build.ninja +++ b/build.ninja @@ -47,8 +47,9 @@ build source/data/vec.o: cc source/data/vec.c build source/data/list.o: cc source/data/list.c build source/data/bstree.o: cc source/data/bstree.c build source/data/slist.o: cc source/data/slist.c +build source/data/hash.o: cc source/data/hash.c build source/main.o: cc source/main.c -build libcarl.a: ar source/refcount.o source/utf/runetype/toupper.o source/utf/runetype/tolower.o source/utf/runetype/uppers.o source/utf/runetype/numbers.o source/utf/runetype/symbols.o source/utf/runetype/totitle.o source/utf/runetype/titles.o source/utf/runetype/lowers.o source/utf/runetype/spaces.o source/utf/runetype/punctuation.o source/utf/runetype/alphas.o source/utf/runetype/digits.o source/utf/runetype/controls.o source/utf/runetype/marks.o source/utf/runetype/otherletters.o source/utf/runetype/other.o source/utf/runecmp.o source/utf/runeinrange.o source/utf/chartorune.o source/utf/runetype.o source/utf/runelen.o source/utf/fullrune.o source/utf/runenlen.o source/utf/runetochar.o source/data/vec.o source/data/list.o source/data/bstree.o source/data/slist.o source/main.o +build libcarl.a: ar source/refcount.o source/utf/runetype/toupper.o source/utf/runetype/tolower.o source/utf/runetype/uppers.o source/utf/runetype/numbers.o source/utf/runetype/symbols.o source/utf/runetype/totitle.o source/utf/runetype/titles.o source/utf/runetype/lowers.o source/utf/runetype/spaces.o source/utf/runetype/punctuation.o source/utf/runetype/alphas.o source/utf/runetype/digits.o source/utf/runetype/controls.o source/utf/runetype/marks.o source/utf/runetype/otherletters.o source/utf/runetype/other.o source/utf/runecmp.o source/utf/runeinrange.o source/utf/chartorune.o source/utf/runetype.o source/utf/runelen.o source/utf/fullrune.o source/utf/runenlen.o source/utf/runetochar.o source/data/vec.o source/data/list.o source/data/bstree.o source/data/slist.o source/data/hash.o source/main.o build tests/refcount.o: cc tests/refcount.c build tests/utf/test_unicodedata.o: cc tests/utf/test_unicodedata.c build tests/data/bstree.o: cc tests/data/bstree.c diff --git a/source/data/hash.c b/source/data/hash.c new file mode 100644 index 0000000..d42475f --- /dev/null +++ b/source/data/hash.c @@ -0,0 +1,94 @@ +/** + @file hash.c + @brief See header for details + $Revision$ + $HeadURL$ + */ +#include +#include + +#define NUM_PRIMES (sizeof(primes)/sizeof(unsigned int)) + +static unsigned int Primes[] = { + 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, + 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, + 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, + 805306457, 1610612741 +}; + +static inline unsigned int num_buckets(hash_t* hash) { + return Primes[hash->bkt_count]; +} + +void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn) +{ + hash->size = 0; + hash->bkt_count = 0; + hash->hashfn = hashfn; + hash->cmpfn = cmpfn; + hash->delfn = delfn; + hash->buckets = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash)); +} + +void hash_deinit(hash_t* hash) +{ + (void)hash; +} + +bool hash_set(hash_t* hash, hash_entry_t* entry) +{ + //if (hash->size >= num_buckets(hash)) + // rehash(hash); + unsigned int hashval = hash->hashfn(entry); + unsigned int index = (hashval % num_buckets(hash)); + hash_entry_t* parent = NULL; + hash_entry_t* node = hash->buckets[index]; + //find_entry(&parent, &node, hash); + + if (node != NULL) { + if (parent == NULL) { + hash_entry_t* deadite = node; + node = node->next; + hash->delfn(deadite); + } + + } else { + + } + return true; +} + +hash_entry_t* hash_get(hash_t* hash, hash_entry_t* entry) +{ + unsigned int hashval = hash->hashfn(entry); + unsigned int index = (hashval % num_buckets(hash)); + //hash_entry_t* parent = NULL; + hash_entry_t* node = hash->buckets[index]; + //find_entry(&parent, &node, hashval, entry); + return node; +} + +bool hash_del(hash_t* hash, hash_entry_t* entry) +{ + (void)hash; + (void)entry; + return false; +} + +void hash_clr(hash_t* hash) +{ + /* Delete all the entries in the hash */ + for (unsigned int i = 0; i < num_buckets(hash); i++) { + hash_entry_t* node = hash->buckets[0]; + while (node != NULL) { + hash_entry_t* deadite = node; + node = node->next; + hash->delfn(deadite); + } + } + /* Shrink the buckets array */ + free(hash->buckets); + hash->bkt_count = 0; + hash->buckets = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash)); +} + diff --git a/source/data/hash.h b/source/data/hash.h new file mode 100644 index 0000000..e743769 --- /dev/null +++ b/source/data/hash.h @@ -0,0 +1,42 @@ +/** + @file hash.h + @brief Generic hashtable implementation. +*/ +#ifndef HASH_H +#define HASH_H + +#include +#include + +typedef struct hash_entry_t { + struct hash_entry_t* next; +} hash_entry_t; + +typedef unsigned int (*hash_hashfn_t)(const hash_entry_t* entry); + +typedef int (*hash_cmpfn_t)(const hash_entry_t* entry1, const hash_entry_t* entry2); + +typedef void (*hash_freefn_t)(hash_entry_t* key); + +typedef struct { + size_t size; + size_t bkt_count; + hash_entry_t** buckets; + hash_hashfn_t hashfn; + hash_cmpfn_t cmpfn; + hash_freefn_t delfn; +} hash_t; + +void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn); + +void hash_deinit(hash_t* hash); + +bool hash_set(hash_t* hash, hash_entry_t* entry); + +hash_entry_t* hash_get(hash_t* hash, hash_entry_t* entry); + +bool hash_del(hash_t* hash, hash_entry_t* entry); + +void hash_clr(hash_t* hash); + +#endif /* HASH_H */