From 38c20e9b5992fff9239fb17ee8cd8cc262d2d439 Mon Sep 17 00:00:00 2001 From: Joseph Botosh Date: Mon, 13 Jun 2016 15:31:44 +0300 Subject: add hashtable functions htnew, htdelete, htput, htget, htclear, htsize htiterator, htinextkey, hticheck, htidelete --- src/emap/hashtable.c | 209 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 src/emap/hashtable.c (limited to 'src/emap/hashtable.c') diff --git a/src/emap/hashtable.c b/src/emap/hashtable.c new file mode 100644 index 0000000..9d2908d --- /dev/null +++ b/src/emap/hashtable.c @@ -0,0 +1,209 @@ +// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// Copyright (c) 2015 - 2016 Evol developers + +#include "common/hercules.h" + +#include "common/db.h" +#include "common/memmgr.h" +#include "emap/hashtable.h" + +struct htreg_interface htreg_s; +struct htreg_interface *htreg; + +int64 htreg_new_hashtable(void) +{ + int64 id = htreg->last_id++; + struct DBMap *ht = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, + HT_MAX_KEY_LEN); + i64db_put(htreg->htables, id, ht); + return id; +} + +bool htreg_destroy_hashtable(int64 id) +{ + struct DBMap *ht = i64db_get(htreg->htables, id); + if (ht) + { + db_destroy(ht); + i64db_remove(htreg->htables, id); + return true; + } + return false; +} + +bool htreg_hashtable_exists(int64 id) +{ + return i64db_exists(htreg->htables, id); +} + +int64 htreg_hashtable_size(int64 id) +{ + struct DBMap *ht = i64db_get(htreg->htables, id); + if (ht) + return db_size(ht); + return 0; +} + +bool htreg_clear_hashtable(int64 id) +{ + struct DBMap *ht = i64db_get(htreg->htables, id); + if (ht) + { + db_clear(ht); + return true; + } + return false; +} + +const struct DBData* htreg_hashtable_getvalue(int64 id, const char *key, + const struct DBData *defval) +{ + struct DBMap *ht = i64db_get(htreg->htables, id); + if (ht) + { + struct DBData *val = ht->get(ht, DB->str2key(key)); + return val ? val : defval; + } + return NULL; +} + +bool htreg_hashtable_setvalue(int64 id, const char *key, + struct DBData value) +{ + struct DBMap *ht = i64db_get(htreg->htables, id); + if (!ht) + return false; + + bool keep = true; + + switch(value.type) + { + case DB_DATA_INT: + case DB_DATA_UINT: + keep = value.u.i; + break; + case DB_DATA_PTR: + keep = value.u.ptr && *(char*)value.u.ptr; + break; + } + + if (keep) + ht->put(ht, DB->str2key(key), value, NULL); + else + strdb_remove(ht, key); + + return true; +} + +/** + * Iterators + */ +int64 htreg_create_iterator(int64 htId) +{ + struct DBMap *ht = i64db_get(htreg->htables, htId); + if (ht) + { + int64 id = htreg->last_iterator_id++; + struct DBIterator *it = db_iterator(ht); + i64db_put(htreg->iterators, id, it); + return id; + } + return 0; +} + +bool htreg_destroy_iterator(int64 id) +{ + struct DBIterator *it = i64db_get(htreg->iterators, id); + if (it) + { + dbi_destroy(it); + return true; + } + return false; +} + +bool htreg_iterator_check(int64 id) +{ + struct DBIterator *it = i64db_get(htreg->iterators, id); + return it ? dbi_exists(it) : false; +} + +bool htreg_iterator_exists(int64 id) +{ + return i64db_exists(htreg->iterators, id); +} + +const char* htreg_iterator_nextkey(int64 id) +{ + struct DBIterator *it = i64db_get(htreg->iterators, id); + if (it) + { + union DBKey key; + it->next(it, &key); + if (dbi_exists(it)) + return key.str; + } + return NULL; +} + +/** + * Initializer. + */ +void htreg_init(void) +{ + htreg->htables = i64db_alloc(DB_OPT_BASE); + htreg->iterators = i64db_alloc(DB_OPT_BASE); +} + +/** + * Finalizer. + */ +void htreg_final(void) +{ + struct DBIterator *iter = db_iterator(htreg->htables); + struct DBMap *ht; + + for(ht=dbi_first(iter); dbi_exists(iter); ht=dbi_next(iter)) + db_destroy(ht); + + dbi_destroy(iter); + db_destroy(htreg->htables); + + // NOTE: maybe I should destroy iteratos before hashtables + struct DBIterator *it; + iter = db_iterator(htreg->iterators); + + for (it=dbi_first(iter); dbi_exists(iter); it=dbi_next(iter)) + dbi_destroy(it); + + dbi_destroy(iter); + db_destroy(htreg->iterators); +} + +/** + * Interface defaults initializer. + */ +void htreg_defaults(void) +{ + htreg = &htreg_s; + + htreg->last_id = 1; + htreg->htables = NULL; + htreg->init = htreg_init; + htreg->final = htreg_final; + htreg->new_hashtable = htreg_new_hashtable; + htreg->destroy_hashtable = htreg_destroy_hashtable; + htreg->hashtable_exists = htreg_hashtable_exists; + htreg->hashtable_size = htreg_hashtable_size; + htreg->clear_hashtable = htreg_clear_hashtable; + htreg->hashtable_getvalue = htreg_hashtable_getvalue; + htreg->hashtable_setvalue = htreg_hashtable_setvalue; + + htreg->last_iterator_id = 1; + htreg->iterators = NULL; + htreg->create_iterator = htreg_create_iterator; + htreg->destroy_iterator = htreg_destroy_iterator; + htreg->iterator_check = htreg_iterator_check; + htreg->iterator_exists = htreg_iterator_exists; + htreg->iterator_nextkey = htreg_iterator_nextkey; +} -- cgit v1.2.3-60-g2f50