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 | 399 +++++++++++++++++++++++++++++--------------------------- 1 files changed, 205 insertions(+), 194 deletions(-) diff --git a/src/shm/hashtable.cpp b/src/shm/hashtable.cpp index 243067b..ab07ad1 100755 --- a/src/shm/hashtable.cpp +++ b/src/shm/hashtable.cpp @@ -1,9 +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 { @@ -16,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 = {1, 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; + memset(hashtable, 0, sizeof(hashtable_t)); + 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); } @@ -47,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; } @@ -70,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; @@ -81,181 +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; - SemUtil::dec(hashtable->wlock); - tailq_header_t *my_tailq_head = hashtable->array[code] ; - if ( my_tailq_head == NULL) - { - SemUtil::inc(hashtable->wlock); - return NULL; + if( (rv = svsem_uni_wait(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_remove\n"); } - else + tailq_header_t *my_tailq_head = hashtable->array[code]; + if ((my_tailq_head == NULL) || (check_mm_valid(my_tailq_head) == false)) { - 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"); } - } - SemUtil::inc(hashtable->wlock); - return NULL; - -} - - - - - -void hashtable_removeall(hashtable_t *hashtable) -{ - tailq_entry_t *item; - SemUtil::dec(hashtable->wlock); - 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; - } - SemUtil::inc(hashtable->wlock); -} -/** - * 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"); - } -} -static size_t hashcode(int key) -{ - - return key % MAPSIZE; - /*printf("hashfun = %ld\n", code);*/ + return; + } } void *hashtable_get(hashtable_t *hashtable, int key) { - - if (SemUtil::dec_timeout(hashtable->mutex, &TIMEOUT) != 0) { - SemUtil::inc(hashtable->mutex); - SemUtil::dec(hashtable->mutex); - } + int rv; - hashtable->readcnt++; - if (hashtable->readcnt == 1) { - //鑾峰彇璇诲啓閿� - SemUtil::dec(hashtable->wlock); -// err_msg(0, "hashtable_get dec %d %d\n", --hashtable->tmp); - } - SemUtil::inc(hashtable->mutex); - // ================ + if((rv = svsem_uni_wait(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_get\n"); + } + void * res = _hashtable_get(hashtable, key); - void * res = _hashtable_get(hashtable, key); - - // ================== - - SemUtil::dec(hashtable->mutex); - hashtable->readcnt--; - if(hashtable->readcnt == 0) { - //閲婃斁璇诲啓閿� - SemUtil::inc(hashtable->wlock); -// err_msg(0, "hashtable_get inc %d\n", ++hashtable->tmp); - //閫氱煡鍐� - SemUtil::set(hashtable->cond, 1); - } - SemUtil::inc(hashtable->mutex); - return res; + 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) { - struct timespec timeout = {2, 0}; - if (SemUtil::dec_timeout(hashtable->mutex, &timeout) != 0) { - SemUtil::inc(hashtable->mutex); - SemUtil::dec(hashtable->mutex); - } - // 璁剧疆璇讳紭鍏堢骇楂� - while (hashtable->readcnt > 0) - { - SemUtil::set(hashtable->cond, 0); - SemUtil::inc(hashtable->mutex); - //绛夊緟鍐欓�氱煡 - if (SemUtil::dec_timeout(hashtable->cond, &timeout) != 0) { - hashtable->readcnt = 0; - SemUtil::inc(hashtable->cond); - SemUtil::dec(hashtable->cond); - } + int rv; - SemUtil::dec(hashtable->mutex); - + if((rv = svsem_uni_wait(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "hashtable_put\n"); } - SemUtil::inc(hashtable->mutex); + _hashtable_put(hashtable, key, value); + hashtable->queueCount++; - //鑾峰彇璇诲啓閿� - - SemUtil::dec(hashtable->wlock); - // err_msg(0, "hashtable_put dec %d\n", --hashtable->tmp); + if((rv = svsem_post(hashtable->mutex)) != 0) { + LoggerFactory::getLogger()->error(errno, "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); - //閲婃斁璇诲啓閿� - SemUtil::inc(hashtable->wlock); -// err_msg(0, "hashtable_put inc %d\n", ++hashtable->tmp); +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; @@ -274,29 +262,7 @@ void hashtable_foreach(hashtable_t *hashtable, std::function<void(int, void *)> cb) { - SemUtil::dec(hashtable->mutex); - hashtable->readcnt++; - if (hashtable->readcnt == 1) { - //鑾峰彇璇诲啓閿� - SemUtil::dec(hashtable->wlock); - } - SemUtil::inc(hashtable->mutex); - - // ================== - - _hashtable_foreach(hashtable, cb); - - // ================== - - SemUtil::dec(hashtable->mutex); - hashtable->readcnt--; - if(hashtable->readcnt == 0) { - //閲婃斁璇诲啓閿� - SemUtil::inc(hashtable->wlock); - //閫氱煡鍐� - SemUtil::set(hashtable->cond, 1); - } - SemUtil::inc(hashtable->mutex); + return _hashtable_foreach(hashtable, cb); } @@ -318,22 +284,67 @@ return keyset; } +void hashtable_removeall(hashtable_t *hashtable) +{ + tailq_entry_t *item; + int rv; + 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] ; -int hashtable_alloc_key(hashtable_t *hashtable) { - int key = START_KEY; + if (my_tailq_head == NULL ) + continue; - if (SemUtil::dec_timeout(hashtable->wlock, &TIMEOUT) != 0) { - SemUtil::inc(hashtable->wlock); - SemUtil::dec(hashtable->wlock); + 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); +} - SemUtil::inc(hashtable->wlock); -// err_msg(0, "hashtable_alloc_key inc %d\n", ++hashtable->tmp); - return key; + +static size_t hashcode(int key) +{ + int val; + + if (key < MAPSIZE) { + val = key; + } else { + val = key % MAPSIZE % (MAPSIZE - START_KEY) + START_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