hash
This commit is contained in:
parent
1f25cac308
commit
e7852552a1
|
@ -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_
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue