This commit is contained in:
Shengliang Guan 2022-02-28 13:53:11 +08:00
parent 1f25cac308
commit e7852552a1
2 changed files with 128 additions and 139 deletions

View File

@ -13,16 +13,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef TDENGINE_HASH_H #ifndef _TD_UTIL_HASH_H_
#define TDENGINE_HASH_H #define _TD_UTIL_HASH_H_
#include "tarray.h"
#include "tlockfree.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "tarray.h"
#include "tlockfree.h"
typedef uint32_t (*_hash_fn_t)(const char *, uint32_t); typedef uint32_t (*_hash_fn_t)(const char *, uint32_t);
typedef int32_t (*_equal_fn_t)(const void *, const void *, size_t len); typedef int32_t (*_equal_fn_t)(const void *, const void *, size_t len);
typedef void (*_hash_before_fn_t)(void *); typedef void (*_hash_before_fn_t)(void *);
@ -128,7 +128,6 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
int32_t taosHashPutExt(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size, bool *newAdded); int32_t taosHashPutExt(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size, bool *newAdded);
/** /**
* return the payload data with the specified key * return the payload data with the specified key
* *
@ -215,7 +214,6 @@ void taosHashCancelIterate(SHashObj *pHashObj, void *p);
*/ */
int32_t taosHashGetKey(void *data, void **key, size_t *keyLen); int32_t taosHashGetKey(void *data, void **key, size_t *keyLen);
/** /**
* Get the corresponding key information for a given data in hash table, using memcpy * Get the corresponding key information for a given data in hash table, using memcpy
* @param data * @param data
@ -262,9 +260,8 @@ void taosHashRelease(SHashObj *pHashObj, void *p);
void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp); void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif // TDENGINE_HASH_H #endif // _TD_UTIL_HASH_H_

View File

@ -13,11 +13,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "os.h" #define _DEFAULT_SOURCE
#include "thash.h" #include "thash.h"
#include "tlog.h"
#include "taos.h"
#include "tdef.h" #include "tdef.h"
#include "tlog.h"
// the add ref count operation may trigger the warning if the reference count is greater than the MAX_WARNING_REF_COUNT // the add ref count operation may trigger the warning if the reference count is greater than the MAX_WARNING_REF_COUNT
#define MAX_WARNING_REF_COUNT 10000 #define MAX_WARNING_REF_COUNT 10000
@ -74,10 +73,12 @@ static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
return i; return i;
} }
static FORCE_INLINE SHashNode *doSearchInEntryList(SHashObj *pHashObj, SHashEntry *pe, const void *key, size_t keyLen, uint32_t hashVal) { static FORCE_INLINE SHashNode *doSearchInEntryList(SHashObj *pHashObj, SHashEntry *pe, const void *key, size_t keyLen,
uint32_t hashVal) {
SHashNode *pNode = pe->next; SHashNode *pNode = pe->next;
while (pNode) { 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) {
assert(pNode->hashVal == hashVal); assert(pNode->hashVal == hashVal);
break; break;
} }
@ -115,7 +116,8 @@ static SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *p
* @param dsize size of actual data * @param dsize size of actual data
* @return hash node * @return hash node
*/ */
static FORCE_INLINE SHashNode *doUpdateHashNode(SHashObj *pHashObj, SHashEntry* pe, SHashNode* prev, SHashNode *pNode, SHashNode *pNewNode) { static FORCE_INLINE SHashNode *doUpdateHashNode(SHashObj *pHashObj, SHashEntry *pe, SHashNode *prev, SHashNode *pNode,
SHashNode *pNewNode) {
assert(pNode->keyLen == pNewNode->keyLen); assert(pNode->keyLen == pNewNode->keyLen);
pNode->count--; pNode->count--;
@ -211,9 +213,7 @@ int32_t taosHashGetSize(const SHashObj *pHashObj) {
return (int32_t)atomic_load_32(&pHashObj->size); return (int32_t)atomic_load_32(&pHashObj->size);
} }
static FORCE_INLINE bool taosHashTableEmpty(const SHashObj *pHashObj) { static FORCE_INLINE bool taosHashTableEmpty(const SHashObj *pHashObj) { return taosHashGetSize(pHashObj) == 0; }
return taosHashGetSize(pHashObj) == 0;
}
int32_t taosHashPutImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size, bool *newAdded) { int32_t taosHashPutImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size, bool *newAdded) {
uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen); uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
@ -247,7 +247,8 @@ int32_t taosHashPutImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void
SHashNode *prev = NULL; SHashNode *prev = NULL;
while (pNode) { 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) {
assert(pNode->hashVal == hashVal); assert(pNode->hashVal == hashVal);
break; break;
} }
@ -310,13 +311,13 @@ int32_t taosHashPutExt(SHashObj *pHashObj, const void *key, size_t keyLen, void
return taosHashPutImpl(pHashObj, key, keyLen, data, size, newAdded); return taosHashPutImpl(pHashObj, key, keyLen, data, size, newAdded);
} }
void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen) { void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen) {
return taosHashGetClone(pHashObj, key, keyLen, NULL); return taosHashGetClone(pHashObj, key, keyLen, NULL);
} }
// TODO(yihaoDeng), merge with taosHashGetClone // TODO(yihaoDeng), merge with taosHashGetClone
void* taosHashGetCloneExt(SHashObj *pHashObj, const void *key, size_t keyLen, void (*fp)(void *), void** d, size_t *sz) { void *taosHashGetCloneExt(SHashObj *pHashObj, const void *key, size_t keyLen, void (*fp)(void *), void **d,
size_t *sz) {
if (taosHashTableEmpty(pHashObj) || keyLen == 0 || key == NULL) { if (taosHashTableEmpty(pHashObj) || keyLen == 0 || key == NULL) {
return NULL; return NULL;
} }
@ -443,7 +444,6 @@ void* taosHashAcquire(SHashObj *pHashObj, const void *key, size_t keyLen) {
return taosHashGetCloneImpl(pHashObj, key, keyLen, NULL, true); return taosHashGetCloneImpl(pHashObj, key, keyLen, NULL, true);
} }
int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen /*, void *data, size_t dsize*/) { int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen /*, void *data, size_t dsize*/) {
if (pHashObj == NULL || taosHashTableEmpty(pHashObj)) { if (pHashObj == NULL || taosHashTableEmpty(pHashObj)) {
return -1; return -1;
@ -470,19 +470,19 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen/*, voi
return -1; return -1;
} }
int code = -1; int32_t code = -1;
SHashNode *pNode = pe->next; SHashNode *pNode = pe->next;
SHashNode *prevNode = NULL; SHashNode *prevNode = NULL;
while (pNode) { 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; break;
prevNode = pNode; prevNode = pNode;
pNode = pNode->next; pNode = pNode->next;
} }
if (pNode) { if (pNode) {
code = 0; // it is found code = 0; // it is found
@ -756,9 +756,7 @@ void taosHashTableResize(SHashObj *pHashObj) {
} else { } else {
assert(pe->next != NULL); assert(pe->next != NULL);
} }
} }
} }
int64_t et = taosGetTimestampUs(); int64_t et = taosGetTimestampUs();
@ -802,7 +800,8 @@ size_t taosHashGetMemSize(const SHashObj *pHashObj) {
return 0; return 0;
} }
return (pHashObj->capacity * (sizeof(SHashEntry) + POINTER_BYTES)) + sizeof(SHashNode) * taosHashGetSize(pHashObj) + sizeof(SHashObj); return (pHashObj->capacity * (sizeof(SHashEntry) + POINTER_BYTES)) + sizeof(SHashNode) * taosHashGetSize(pHashObj) +
sizeof(SHashObj);
} }
FORCE_INLINE int32_t taosHashGetKey(void *data, void **key, size_t *keyLen) { FORCE_INLINE int32_t taosHashGetKey(void *data, void **key, size_t *keyLen) {
@ -829,10 +828,8 @@ FORCE_INLINE uint32_t taosHashGetDataKeyLen(SHashObj *pHashObj, void *data) {
return node->keyLen; return node->keyLen;
} }
// release the pNode, return next pNode, and lock the current entry // release the pNode, return next pNode, and lock the current entry
static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int *slot) { static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int32_t *slot) {
SHashNode *pOld = (SHashNode *)GET_HASH_PNODE(p); SHashNode *pOld = (SHashNode *)GET_HASH_PNODE(p);
SHashNode *prevNode = NULL; SHashNode *prevNode = NULL;
@ -847,8 +844,7 @@ static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int *slot) {
SHashNode *pNode = pe->next; SHashNode *pNode = pe->next;
while (pNode) { while (pNode) {
if (pNode == pOld) if (pNode == pOld) break;
break;
prevNode = pNode; prevNode = pNode;
pNode = pNode->next; pNode = pNode->next;
@ -883,7 +879,7 @@ static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int *slot) {
void *taosHashIterate(SHashObj *pHashObj, void *p) { void *taosHashIterate(SHashObj *pHashObj, void *p) {
if (pHashObj == NULL) return NULL; if (pHashObj == NULL) return NULL;
int slot = 0; int32_t slot = 0;
char *data = NULL; char *data = NULL;
// only add the read lock to disable the resize process // only add the read lock to disable the resize process
@ -960,7 +956,7 @@ void taosHashCancelIterate(SHashObj *pHashObj, void *p) {
// only add the read lock to disable the resize process // only add the read lock to disable the resize process
__rd_lock((void *)&pHashObj->lock, pHashObj->type); __rd_lock((void *)&pHashObj->lock, pHashObj->type);
int slot; int32_t slot;
taosHashReleaseNode(pHashObj, p, &slot); taosHashReleaseNode(pHashObj, p, &slot);
SHashEntry *pe = pHashObj->hashList[slot]; SHashEntry *pe = pHashObj->hashList[slot];
@ -971,8 +967,4 @@ void taosHashCancelIterate(SHashObj *pHashObj, void *p) {
__rd_unlock((void *)&pHashObj->lock, pHashObj->type); __rd_unlock((void *)&pHashObj->lock, pHashObj->type);
} }
void taosHashRelease(SHashObj *pHashObj, void *p) { void taosHashRelease(SHashObj *pHashObj, void *p) { taosHashCancelIterate(pHashObj, p); }
taosHashCancelIterate(pHashObj, p);
}