From 2561a007b8d8999a4750046d0cfb3b1ad5af50ac Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期二, 09 四月 2024 15:29:32 +0800 Subject: [PATCH] test for perf --- src/shm/hashtable.cpp | 446 ++++++++++++++++++++++++------------------------------- 1 files changed, 193 insertions(+), 253 deletions(-) diff --git a/src/shm/hashtable.cpp b/src/shm/hashtable.cpp index e421630..ab07ad1 100755 --- a/src/shm/hashtable.cpp +++ b/src/shm/hashtable.cpp @@ -1,10 +1,14 @@ #include "usg_common.h" #include "hashtable.h" #include "mm.h" -#include "sem_util.h" +#include "svsem.h" +#include "bh_api.h" #include "logger_factory.h" #include <set> #include <functional> +#include <limits.h> + + typedef struct tailq_entry_t { @@ -17,30 +21,22 @@ TAILQ_ENTRY(tailq_entry_t) joint; } tailq_entry_t; -#define START_KEY 1000 - typedef TAILQ_HEAD(tailq_header_t, tailq_entry_t) tailq_header_t; static size_t hashcode(int key); -static struct timespec TIMEOUT = {2, 0}; - void hashtable_init(hashtable_t *hashtable ) { memset(hashtable, 0, sizeof(hashtable_t)); - hashtable->mutex = SemUtil::get(IPC_PRIVATE, 1); - hashtable->wlock = SemUtil::get(IPC_PRIVATE, 1); - hashtable->cond = SemUtil::get(IPC_PRIVATE, 1); - hashtable->readcnt = 0; -printf("hashtable->mutex=%d\n", hashtable->mutex); + hashtable->mutex = svsem_get(IPC_PRIVATE, 1); + hashtable->queueCount = 0; + hashtable->currentKey = START_KEY; } void hashtable_destroy(hashtable_t *hashtable) { - SemUtil::remove( hashtable->mutex); - SemUtil::remove( hashtable->wlock); - SemUtil::remove( hashtable->cond); + svsem_remove( hashtable->mutex); } @@ -48,20 +44,25 @@ { size_t code = hashcode(key); tailq_entry_t *item; - tailq_header_t *my_tailq_head = hashtable->array[code] ; - if ( my_tailq_head == NULL) + tailq_header_t *my_tailq_head = hashtable->array[code]; + if ((my_tailq_head == NULL) || (check_mm_valid(my_tailq_head) == false)) { + hashtable->array[code] = NULL; return NULL; } - else - { - TAILQ_FOREACH(item, my_tailq_head, joint) - { - if (key == item->key) - return item->value; - } + TAILQ_FOREACH(item, my_tailq_head, joint) + { + if ((check_mm_valid(item) == true) && ((key == item->key) || (code == item->key))) + return item->value; + + break; } + + hashtable->array[code] = NULL; + hashtable->queueCount--; + mm_free(my_tailq_head); + return NULL; } @@ -71,10 +72,15 @@ size_t code = hashcode(key); void *oldvalue; tailq_entry_t *item; - tailq_header_t *my_tailq_head = hashtable->array[code] ; - if ( my_tailq_head == NULL) + tailq_header_t *my_tailq_head = hashtable->array[code]; + if ((my_tailq_head == NULL) || (check_mm_valid(my_tailq_head) == false)) { + if (inter_key_get() == 0) { + inter_key_set(key); + } + my_tailq_head = (tailq_header_t*) mm_malloc(sizeof(tailq_header_t )); + TAILQ_INIT(my_tailq_head); hashtable->array[code] = my_tailq_head; goto putnew; @@ -82,227 +88,162 @@ TAILQ_FOREACH(item, my_tailq_head, joint) { - if (key ==item->key) + if ((check_mm_valid(item) == true) && (key ==item->key)) { - oldvalue = item -> value; + oldvalue = item->value; item->key= key; - item -> value = value; + item->value = value; return oldvalue; } + + goto putnew; } putnew: + + if (inter_key_get() == 0) { + inter_key_set(key); + } item = (tailq_entry_t *) mm_malloc(sizeof(tailq_entry_t)); item->key = key; - item -> value = value; - TAILQ_INSERT_TAIL(my_tailq_head, item, joint); + item->value = value; + TAILQ_INSERT_HEAD(my_tailq_head, item, joint); return NULL; } -void *hashtable_remove(hashtable_t *hashtable, int key) +void hashtable_remove(hashtable_t *hashtable, int key) { size_t code = hashcode(key); tailq_entry_t *item; - void *oldvalue; int rv; - if( (rv = SemUtil::dec(hashtable->wlock)) != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_remove\n"); + if( (rv = svsem_uni_wait(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_remove\n"); } - tailq_header_t *my_tailq_head = hashtable->array[code] ; - if ( my_tailq_head == NULL) + tailq_header_t *my_tailq_head = hashtable->array[code]; + if ((my_tailq_head == NULL) || (check_mm_valid(my_tailq_head) == false)) { - SemUtil::inc(hashtable->wlock); - return NULL; - } - else - { - for (item = TAILQ_FIRST(my_tailq_head); item != NULL; item = TAILQ_NEXT(item, joint)) - { - if (key == item->key) - { - oldvalue = item->value; - /* Remove the item from the tail queue. */ - TAILQ_REMOVE(my_tailq_head, item, joint); - - /* mm_free the item as we don't need it anymore. */ - mm_free(item); - SemUtil::inc(hashtable->wlock); - return oldvalue; - } + hashtable->array[code] = NULL; + if((rv = svsem_post(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_remove\n"); } - } - if((rv = SemUtil::inc(hashtable->wlock)) != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_remove\n"); - } - - return NULL; - -} - - - - - -void hashtable_removeall(hashtable_t *hashtable) -{ - tailq_entry_t *item; - int rv; - rv = SemUtil::dec(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_removeall\n"); - } - for (int i = 0; i < MAPSIZE; i++) - { - tailq_header_t *my_tailq_head = hashtable->array[i] ; - - if (my_tailq_head == NULL ) - continue; - - while ((item = TAILQ_FIRST(my_tailq_head)) ) + return; + } else { + for (item = TAILQ_FIRST(my_tailq_head); item != NULL;) { + /* Remove the item from the tail queue. */ TAILQ_REMOVE(my_tailq_head, item, joint); - mm_free(item); + + /* mm_free the item as we don't need it anymore. */ + if (check_mm_valid(item) == true) + mm_free(item); + + hashtable->array[code] = NULL; + hashtable->queueCount--; + mm_free(my_tailq_head); + svsem_post(hashtable->mutex); + + return; } - mm_free(my_tailq_head); - hashtable->array[i] = NULL; - } - rv = SemUtil::inc(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_removeall\n"); - } -} -/** - * for debug - */ -void hashtable_printall(hashtable_t *hashtable) -{ - tailq_entry_t *item; - for (int i = 0; i < MAPSIZE; i++) - { - tailq_header_t *my_tailq_head = hashtable->array[i] ; - - if (my_tailq_head == NULL ) - continue; - - printf("code=%d\n", i); - TAILQ_FOREACH(item, my_tailq_head, joint) - { - printf("%d:%s\n", item->key, (char *)item->value); + if((rv = svsem_post(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_remove\n"); } - printf("\n"); + + return; } -} - -static size_t hashcode(int key) -{ - - return key % MAPSIZE; - /*printf("hashfun = %ld\n", code);*/ } void *hashtable_get(hashtable_t *hashtable, int key) { - int rv; - rv = SemUtil::dec(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_get 1"); - } - hashtable->readcnt++; - if (hashtable->readcnt == 1) { - //鑾峰彇璇诲啓閿� - rv = SemUtil::dec(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_get 2"); - } - } - rv = SemUtil::inc(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_get 3"); - } - // ================ + if((rv = svsem_uni_wait(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_get\n"); + } void * res = _hashtable_get(hashtable, key); - // ================== - - rv = SemUtil::dec(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_get 4"); - } - hashtable->readcnt--; - if(hashtable->readcnt == 0) { - //閲婃斁璇诲啓閿� - rv = SemUtil::inc(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_get 5"); - } - //閫氱煡鍐� - rv = SemUtil::set(hashtable->cond, 1); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_get 6"); - } - } - - rv = SemUtil::inc(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_get 7"); + if((rv = svsem_post(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_get\n"); } return res; } void hashtable_put(hashtable_t *hashtable, int key, void *value) { - int rv; - rv = SemUtil::dec(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); + if((rv = svsem_uni_wait(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_put\n"); } - // 璁剧疆璇讳紭鍏堢骇楂� - while (hashtable->readcnt > 0) - { - rv = SemUtil::set(hashtable->cond, 0); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); - } - rv = SemUtil::inc(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); - } - //绛夊緟鍐欓�氱煡 - rv = SemUtil::dec(hashtable->cond); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); - } + _hashtable_put(hashtable, key, value); + hashtable->queueCount++; - - rv = SemUtil::dec(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); - } - } - rv = SemUtil::inc(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); + if((rv = svsem_post(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_put\n"); } - //鑾峰彇璇诲啓閿� - rv = SemUtil::dec(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); +} + +bool hashtable_check_put(hashtable_t *hashtable, int key, void *value, bool overwrite) { + + int rv; + void * val; + if(( rv = svsem_uni_wait(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_put\n"); } + if(overwrite) { + _hashtable_put(hashtable, key, value); + goto suc; + } + val = _hashtable_get(hashtable, key); + if(val != NULL && val != (void *)1) + goto fail; _hashtable_put(hashtable, key, value); - //閲婃斁璇诲啓閿� - rv = SemUtil::inc(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); +suc: + if(( rv = svsem_post(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_put\n"); } + return true; + +fail: + if(( rv = svsem_post(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_put\n"); + } + return false; } +int hashtable_get_queue_count(hashtable_t *hashtable) { + return hashtable->queueCount; +} +int hashtable_alloc_key(hashtable_t *hashtable) { + int rv; + int key = hashtable->currentKey; + + if( key == INT_MAX || key < START_KEY) { + key = START_KEY; + } + + rv = svsem_uni_wait(hashtable->mutex); + if(rv != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_alloc_key\n"); + } + + while(_hashtable_get(hashtable, key) != NULL) { + key++; + } + // 鍗犵敤key + + _hashtable_put(hashtable, key, (void *)1); + + hashtable->currentKey = key; + rv = svsem_post(hashtable->mutex); + if(rv != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_alloc_key\n"); + } + + return key; +} static inline void _hashtable_foreach(hashtable_t *hashtable, std::function<void(int, void *)> cb) { tailq_entry_t *item; @@ -321,51 +262,7 @@ void hashtable_foreach(hashtable_t *hashtable, std::function<void(int, void *)> cb) { - int rv; - rv = SemUtil::dec(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); - } - hashtable->readcnt++; - if (hashtable->readcnt == 1) { - //鑾峰彇璇诲啓閿� - rv = SemUtil::dec(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); - } - } - rv = SemUtil::inc(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); - } - - // ================== - - _hashtable_foreach(hashtable, cb); - - // ================== - - rv = SemUtil::dec(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); - } - hashtable->readcnt--; - if(hashtable->readcnt == 0) { - //閲婃斁璇诲啓閿� - rv = SemUtil::inc(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); - } - //閫氱煡鍐� - rv = SemUtil::set(hashtable->cond, 1); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); - } - } - rv = SemUtil::inc(hashtable->mutex); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); - } + return _hashtable_foreach(hashtable, cb); } @@ -387,24 +284,67 @@ return keyset; } - -int hashtable_alloc_key(hashtable_t *hashtable) { +void hashtable_removeall(hashtable_t *hashtable) +{ + tailq_entry_t *item; int rv; - int key = START_KEY; - rv = SemUtil::dec(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_alloc_key\n"); + if( (rv = svsem_uni_wait(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_removeall\n"); + } + for (int i = 0; i < MAPSIZE; i++) + { + tailq_header_t *my_tailq_head = hashtable->array[i] ; + + if (my_tailq_head == NULL ) + continue; + + while ((item = TAILQ_FIRST(my_tailq_head)) ) + { + TAILQ_REMOVE(my_tailq_head, item, joint); + mm_free(item); + } + mm_free(my_tailq_head); + hashtable->array[i] = NULL; } - while(_hashtable_get(hashtable, key) != NULL) { - key++; + hashtable->queueCount = 0; + if((rv = svsem_post(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_removeall\n"); } - // 鍗犵敤key - _hashtable_put(hashtable, key, (void *)1); +} - rv = SemUtil::inc(hashtable->wlock); - if(rv != 0) { - LoggerFactory::getLogger()->error(rv, "hashtable_alloc_key\n"); + +static size_t hashcode(int key) +{ + int val; + + if (key < MAPSIZE) { + val = key; + } else { + val = key % MAPSIZE % (MAPSIZE - START_KEY) + START_KEY; } - return key; + + return val; +} + +/** + * for debug + */ +static void hashtable_printall(hashtable_t *hashtable) +{ + tailq_entry_t *item; + for (int i = 0; i < MAPSIZE; i++) + { + tailq_header_t *my_tailq_head = hashtable->array[i] ; + + if (my_tailq_head == NULL ) + continue; + + printf("code=%d\n", i); + TAILQ_FOREACH(item, my_tailq_head, joint) + { + printf("%d:%s\n", item->key, (char *)item->value); + } + printf("\n"); + } } -- Gitblit v1.8.0