From 6a71b8ea7ae41e5c0a88bc2b44194dc3aba01f2d Mon Sep 17 00:00:00 2001 From: Yifan Hao Date: Wed, 24 Nov 2021 00:22:38 -0800 Subject: [PATCH] Hash table cleanup [5/n] 1. Simplify implementation of taosHashCondTraverse 2. Complete function header comments for a few more functions * Testing Run through the sample mysql: taos> create database db; Query OK, 0 of 0 row(s) in database (0.002475s) taos> use db; Query OK, 0 of 0 row(s) in database (0.000252s) taos> create table t (ts timestamp, a int); Query OK, 0 of 0 row(s) in database (0.003588s) taos> insert into t values ('2019-07-15 00:00:00', 1); Query OK, 1 of 1 row(s) in database (0.001268s) taos> insert into t values ('2019-07-15 01:00:00', 2); Query OK, 1 of 1 row(s) in database (0.000265s) taos> select * from t; ts | a | ======================================== 2019-07-15 00:00:00.000 | 1 | 2019-07-15 01:00:00.000 | 2 | Query OK, 2 row(s) in set (0.000822s) taos> drop database db; Query OK, 0 of 0 row(s) in database (0.001711s) --- src/util/inc/hash.h | 11 ++++++- src/util/src/hash.c | 72 +++++++++++++++------------------------------ 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/src/util/inc/hash.h b/src/util/inc/hash.h index 93cf90e17e..dea868f60e 100644 --- a/src/util/inc/hash.h +++ b/src/util/inc/hash.h @@ -142,7 +142,16 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen); */ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLen, void* data, size_t dsize); -int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), void *param); +/** + * traverse through all objects in the hash table and apply "fp" on each node. + * If "fp" returns false when applied on top of a node, the node will also be + * removed from table. + * + * @param pHashObj hash table object + * @param fp function pointer applied on each node + * @param param parameter fed into "fp" + */ +void taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), void *param); /** * clear the contents of the hash table diff --git a/src/util/src/hash.c b/src/util/src/hash.c index 0e9e3ad8e4..6e93db663e 100644 --- a/src/util/src/hash.c +++ b/src/util/src/hash.c @@ -131,7 +131,7 @@ static FORCE_INLINE SHashNode *doSearchInEntryList(SHashObj *pHashObj, SHashEntr } /** - * Resize the hash list if the threshold is reached + * resize the hash list if the threshold is reached * * @param pHashObj */ @@ -144,7 +144,7 @@ static void taosHashTableResize(SHashObj *pHashObj); * @param keyLen length of key * @param pData data to be stored in hash node * @param dsize size of data - * @return sHashNode + * @return SHashNode */ static SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal); @@ -178,7 +178,7 @@ static FORCE_INLINE void doUpdateHashNode(SHashObj *pHashObj, SHashEntry* pe, SH } /** - * Insert the hash node at the front of the linked list + * insert the hash node at the front of the linked list * * @param pHashObj hash table object * @param pNode the old node with requested key @@ -483,7 +483,7 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen) { } int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t dsize) { - if (pHashObj == NULL || taosHashTableEmpty(pHashObj)) { + if (pHashObj == NULL || taosHashTableEmpty(pHashObj) || key == NULL || keyLen == 0) { return -1; } @@ -513,7 +513,9 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe SHashNode *prevNode = NULL; while (pNode) { - if ((pNode->keyLen == keyLen) && ((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && pNode->removed == 0) + if ((pNode->keyLen == keyLen) && + ((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && + pNode->removed == 0) break; prevNode = pNode; @@ -549,9 +551,9 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe return code; } -int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), void *param) { - if (pHashObj == NULL || taosHashTableEmpty(pHashObj)) { - return 0; +void taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), void *param) { + if (pHashObj == NULL || taosHashTableEmpty(pHashObj) || fp == NULL) { + return; } // disable the resize process @@ -568,49 +570,22 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi taosWLockLatch(&pEntry->latch); } - // todo remove the first node - SHashNode *pNode = NULL; - while((pNode = pEntry->next) != NULL) { - if (fp && (!fp(param, GET_HASH_NODE_DATA(pNode)))) { - pEntry->num -= 1; - atomic_sub_fetch_64(&pHashObj->size, 1); - - pEntry->next = pNode->next; - - if (pEntry->num == 0) { - assert(pEntry->next == NULL); - } else { - assert(pEntry->next != NULL); - } - - FREE_HASH_NODE(pHashObj, pNode); + SHashNode *pPrevNode = NULL; + SHashNode *pNode = pEntry->next; + while (pNode != NULL) { + if (fp(param, GET_HASH_NODE_DATA(pNode))) { + pPrevNode = pNode; + pNode = pNode->next; } else { - break; - } - } - - // handle the following node - if (pNode != NULL) { - assert(pNode == pEntry->next); - SHashNode *pNext = NULL; - - while ((pNext = pNode->next) != NULL) { - // not qualified, remove it - if (fp && (!fp(param, GET_HASH_NODE_DATA(pNext)))) { - pNode->next = pNext->next; - pEntry->num -= 1; - atomic_sub_fetch_64(&pHashObj->size, 1); - - if (pEntry->num == 0) { - assert(pEntry->next == NULL); - } else { - assert(pEntry->next != NULL); - } - - FREE_HASH_NODE(pHashObj, pNext); + if (pPrevNode == NULL) { + pEntry->next = pNode->next; } else { - pNode = pNext; + pPrevNode->next = pNode->next; } + pEntry->num -= 1; + atomic_sub_fetch_64(&pHashObj->size, 1); + pNode = pNode->next; + FREE_HASH_NODE(pHashObj, pNode); } } @@ -620,7 +595,6 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi } __rd_unlock(&pHashObj->lock, pHashObj->type); - return 0; } void taosHashClear(SHashObj *pHashObj) { -- GitLab