hash
This commit is contained in:
parent
1f25cac308
commit
e7852552a1
|
@ -13,22 +13,22 @@
|
||||||
* 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 *);
|
||||||
typedef void (*_hash_free_fn_t)(void *);
|
typedef void (*_hash_free_fn_t)(void *);
|
||||||
|
|
||||||
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
|
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
|
||||||
#define HASH_DEFAULT_LOAD_FACTOR (0.75)
|
#define HASH_DEFAULT_LOAD_FACTOR (0.75)
|
||||||
|
|
||||||
#define HASH_INDEX(v, c) ((v) & ((c)-1))
|
#define HASH_INDEX(v, c) ((v) & ((c)-1))
|
||||||
|
@ -59,43 +59,43 @@ _equal_fn_t taosGetDefaultEqualFunction(int32_t type);
|
||||||
|
|
||||||
typedef struct SHashNode {
|
typedef struct SHashNode {
|
||||||
struct SHashNode *next;
|
struct SHashNode *next;
|
||||||
uint32_t hashVal; // the hash value of key
|
uint32_t hashVal; // the hash value of key
|
||||||
uint32_t dataLen; // length of data
|
uint32_t dataLen; // length of data
|
||||||
uint32_t keyLen; // length of the key
|
uint32_t keyLen; // length of the key
|
||||||
uint16_t count; // reference count
|
uint16_t count; // reference count
|
||||||
int8_t removed; // flag to indicate removed
|
int8_t removed; // flag to indicate removed
|
||||||
char data[];
|
char data[];
|
||||||
} SHashNode;
|
} SHashNode;
|
||||||
|
|
||||||
#define GET_HASH_NODE_KEY(_n) ((char*)(_n) + sizeof(SHashNode) + (_n)->dataLen)
|
#define GET_HASH_NODE_KEY(_n) ((char *)(_n) + sizeof(SHashNode) + (_n)->dataLen)
|
||||||
#define GET_HASH_NODE_DATA(_n) ((char*)(_n) + sizeof(SHashNode))
|
#define GET_HASH_NODE_DATA(_n) ((char *)(_n) + sizeof(SHashNode))
|
||||||
#define GET_HASH_PNODE(_n) ((SHashNode *)((char*)(_n) - sizeof(SHashNode)))
|
#define GET_HASH_PNODE(_n) ((SHashNode *)((char *)(_n) - sizeof(SHashNode)))
|
||||||
|
|
||||||
typedef enum SHashLockTypeE {
|
typedef enum SHashLockTypeE {
|
||||||
HASH_NO_LOCK = 0,
|
HASH_NO_LOCK = 0,
|
||||||
HASH_ENTRY_LOCK = 1,
|
HASH_ENTRY_LOCK = 1,
|
||||||
} SHashLockTypeE;
|
} SHashLockTypeE;
|
||||||
|
|
||||||
typedef struct SHashEntry {
|
typedef struct SHashEntry {
|
||||||
int32_t num; // number of elements in current entry
|
int32_t num; // number of elements in current entry
|
||||||
SRWLatch latch; // entry latch
|
SRWLatch latch; // entry latch
|
||||||
SHashNode *next;
|
SHashNode *next;
|
||||||
} SHashEntry;
|
} SHashEntry;
|
||||||
|
|
||||||
typedef struct SHashObj {
|
typedef struct SHashObj {
|
||||||
SHashEntry **hashList;
|
SHashEntry **hashList;
|
||||||
uint32_t capacity; // number of slots
|
uint32_t capacity; // number of slots
|
||||||
uint32_t size; // number of elements in hash table
|
uint32_t size; // number of elements in hash table
|
||||||
|
|
||||||
_hash_fn_t hashFp; // hash function
|
_hash_fn_t hashFp; // hash function
|
||||||
_hash_free_fn_t freeFp; // hash node free callback function
|
_hash_free_fn_t freeFp; // hash node free callback function
|
||||||
_equal_fn_t equalFp; // equal function
|
_equal_fn_t equalFp; // equal function
|
||||||
_hash_before_fn_t callbackFp; // function invoked before return the value to caller
|
_hash_before_fn_t callbackFp; // function invoked before return the value to caller
|
||||||
|
|
||||||
SRWLatch lock; // read-write spin lock
|
SRWLatch lock; // read-write spin lock
|
||||||
SHashLockTypeE type; // lock type
|
SHashLockTypeE type; // lock type
|
||||||
bool enableUpdate; // enable update
|
bool enableUpdate; // enable update
|
||||||
SArray *pMemBlock; // memory block allocated for SHashEntry
|
SArray *pMemBlock; // memory block allocated for SHashEntry
|
||||||
} SHashObj;
|
} SHashObj;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -147,7 +146,7 @@ void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen);
|
||||||
* @param destBuf
|
* @param destBuf
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
void *taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void* destBuf);
|
void *taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void *destBuf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone the result to interval allocated buffer
|
* Clone the result to interval allocated buffer
|
||||||
|
@ -157,7 +156,7 @@ void *taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void*
|
||||||
* @param destBuf
|
* @param destBuf
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove item with the specified key
|
* remove item with the specified key
|
||||||
|
@ -206,15 +205,14 @@ void *taosHashIterate(SHashObj *pHashObj, void *p);
|
||||||
* @param pHashObj
|
* @param pHashObj
|
||||||
* @param p
|
* @param p
|
||||||
*/
|
*/
|
||||||
void taosHashCancelIterate(SHashObj *pHashObj, void *p);
|
void taosHashCancelIterate(SHashObj *pHashObj, void *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the corresponding key information for a given data in hash table
|
* Get the corresponding key information for a given data in hash table
|
||||||
* @param data
|
* @param data
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
@ -222,13 +220,13 @@ int32_t taosHashGetKey(void *data, void** key, size_t* keyLen);
|
||||||
* @param dst
|
* @param dst
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static FORCE_INLINE int32_t taosHashCopyKey(void *data, void* dst) {
|
static FORCE_INLINE int32_t taosHashCopyKey(void *data, void *dst) {
|
||||||
if (NULL == data || NULL == dst) {
|
if (NULL == data || NULL == dst) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHashNode * node = GET_HASH_PNODE(data);
|
SHashNode *node = GET_HASH_PNODE(data);
|
||||||
void* key = GET_HASH_NODE_KEY(node);
|
void *key = GET_HASH_NODE_KEY(node);
|
||||||
memcpy(dst, key, node->keyLen);
|
memcpy(dst, key, node->keyLen);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -249,7 +247,7 @@ int32_t taosHashGetDataLen(void *data);
|
||||||
* @param keyLen
|
* @param keyLen
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
void* taosHashAcquire(SHashObj *pHashObj, const void *key, size_t keyLen);
|
void *taosHashAcquire(SHashObj *pHashObj, const void *key, size_t keyLen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* release the prevous acquired obj
|
* release the prevous acquired obj
|
||||||
|
@ -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,16 +13,15 @@
|
||||||
* 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
|
||||||
#define EXT_SIZE 1024
|
#define EXT_SIZE 1024
|
||||||
#define HASH_NEED_RESIZE(_h) ((_h)->size >= (_h)->capacity * HASH_DEFAULT_LOAD_FACTOR)
|
#define HASH_NEED_RESIZE(_h) ((_h)->size >= (_h)->capacity * HASH_DEFAULT_LOAD_FACTOR)
|
||||||
|
|
||||||
#define DO_FREE_HASH_NODE(_n) \
|
#define DO_FREE_HASH_NODE(_n) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -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--;
|
||||||
|
@ -129,11 +131,11 @@ static FORCE_INLINE SHashNode *doUpdateHashNode(SHashObj *pHashObj, SHashEntry*
|
||||||
pNewNode->next = pNode->next;
|
pNewNode->next = pNode->next;
|
||||||
DO_FREE_HASH_NODE(pNode);
|
DO_FREE_HASH_NODE(pNode);
|
||||||
} else {
|
} else {
|
||||||
pNewNode->next = pNode;
|
pNewNode->next = pNode;
|
||||||
pe->num++;
|
pe->num++;
|
||||||
atomic_add_fetch_32(&pHashObj->size, 1);
|
atomic_add_fetch_32(&pHashObj->size, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pNewNode;
|
return pNewNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +177,7 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTyp
|
||||||
pHashObj->capacity = taosHashCapacity((int32_t)capacity);
|
pHashObj->capacity = taosHashCapacity((int32_t)capacity);
|
||||||
assert((pHashObj->capacity & (pHashObj->capacity - 1)) == 0);
|
assert((pHashObj->capacity & (pHashObj->capacity - 1)) == 0);
|
||||||
pHashObj->equalFp = memcmp;
|
pHashObj->equalFp = memcmp;
|
||||||
pHashObj->hashFp = fn;
|
pHashObj->hashFp = fn;
|
||||||
pHashObj->type = type;
|
pHashObj->type = type;
|
||||||
pHashObj->enableUpdate = update;
|
pHashObj->enableUpdate = update;
|
||||||
|
|
||||||
|
@ -201,8 +203,8 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTyp
|
||||||
void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp) {
|
void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp) {
|
||||||
if (pHashObj != NULL && fp != NULL) {
|
if (pHashObj != NULL && fp != NULL) {
|
||||||
pHashObj->equalFp = fp;
|
pHashObj->equalFp = fp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t taosHashGetSize(const SHashObj *pHashObj) {
|
int32_t taosHashGetSize(const SHashObj *pHashObj) {
|
||||||
if (!pHashObj) {
|
if (!pHashObj) {
|
||||||
|
@ -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);
|
||||||
|
@ -224,12 +224,12 @@ int32_t taosHashPutImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void
|
||||||
|
|
||||||
// need the resize process, write lock applied
|
// need the resize process, write lock applied
|
||||||
if (HASH_NEED_RESIZE(pHashObj)) {
|
if (HASH_NEED_RESIZE(pHashObj)) {
|
||||||
__wr_lock((void*) &pHashObj->lock, pHashObj->type);
|
__wr_lock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
taosHashTableResize(pHashObj);
|
taosHashTableResize(pHashObj);
|
||||||
__wr_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__wr_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
__rd_lock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_lock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
|
|
||||||
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
|
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
|
||||||
SHashEntry *pe = pHashObj->hashList[slot];
|
SHashEntry *pe = pHashObj->hashList[slot];
|
||||||
|
@ -245,9 +245,10 @@ int32_t taosHashPutImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void
|
||||||
assert(pNode == NULL);
|
assert(pNode == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -271,13 +272,13 @@ int32_t taosHashPutImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable resize
|
// enable resize
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
atomic_add_fetch_32(&pHashObj->size, 1);
|
atomic_add_fetch_32(&pHashObj->size, 1);
|
||||||
|
|
||||||
if (newAdded) {
|
if (newAdded) {
|
||||||
*newAdded = true;
|
*newAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// not support the update operation, return error
|
// not support the update operation, return error
|
||||||
|
@ -292,7 +293,7 @@ int32_t taosHashPutImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable resize
|
// enable resize
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
|
|
||||||
if (newAdded) {
|
if (newAdded) {
|
||||||
*newAdded = false;
|
*newAdded = false;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -324,14 +325,14 @@ void* taosHashGetCloneExt(SHashObj *pHashObj, const void *key, size_t keyLen, vo
|
||||||
uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
|
uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
|
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
|
||||||
SHashEntry *pe = pHashObj->hashList[slot];
|
SHashEntry *pe = pHashObj->hashList[slot];
|
||||||
|
|
||||||
// no data, return directly
|
// no data, return directly
|
||||||
if (atomic_load_32(&pe->num) == 0) {
|
if (atomic_load_32(&pe->num) == 0) {
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,19 +354,19 @@ void* taosHashGetCloneExt(SHashObj *pHashObj, const void *key, size_t keyLen, vo
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
fp(GET_HASH_NODE_DATA(pNode));
|
fp(GET_HASH_NODE_DATA(pNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*d == NULL) {
|
if (*d == NULL) {
|
||||||
*sz = pNode->dataLen + EXT_SIZE;
|
|
||||||
*d = calloc(1, *sz);
|
|
||||||
} else if (*sz < pNode->dataLen){
|
|
||||||
*sz = pNode->dataLen + EXT_SIZE;
|
*sz = pNode->dataLen + EXT_SIZE;
|
||||||
*d = realloc(*d, *sz);
|
*d = calloc(1, *sz);
|
||||||
|
} else if (*sz < pNode->dataLen) {
|
||||||
|
*sz = pNode->dataLen + EXT_SIZE;
|
||||||
|
*d = realloc(*d, *sz);
|
||||||
}
|
}
|
||||||
memcpy((char *)(*d), GET_HASH_NODE_DATA(pNode), pNode->dataLen);
|
memcpy((char *)(*d), GET_HASH_NODE_DATA(pNode), pNode->dataLen);
|
||||||
// just make runtime happy
|
// just make runtime happy
|
||||||
if ((*sz) - pNode->dataLen > 0) {
|
if ((*sz) - pNode->dataLen > 0) {
|
||||||
memset((char *)(*d) + pNode->dataLen, 0, (*sz) - pNode->dataLen);
|
memset((char *)(*d) + pNode->dataLen, 0, (*sz) - pNode->dataLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
data = GET_HASH_NODE_DATA(pNode);
|
data = GET_HASH_NODE_DATA(pNode);
|
||||||
}
|
}
|
||||||
|
@ -374,11 +375,11 @@ void* taosHashGetCloneExt(SHashObj *pHashObj, const void *key, size_t keyLen, vo
|
||||||
taosRUnLockLatch(&pe->latch);
|
taosRUnLockLatch(&pe->latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* taosHashGetCloneImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void* d, bool acquire) {
|
void *taosHashGetCloneImpl(SHashObj *pHashObj, const void *key, size_t keyLen, void *d, bool acquire) {
|
||||||
if (taosHashTableEmpty(pHashObj) || keyLen == 0 || key == NULL) {
|
if (taosHashTableEmpty(pHashObj) || keyLen == 0 || key == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -386,14 +387,14 @@ void* taosHashGetCloneImpl(SHashObj *pHashObj, const void *key, size_t keyLen, v
|
||||||
uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
|
uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
|
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
|
||||||
SHashEntry *pe = pHashObj->hashList[slot];
|
SHashEntry *pe = pHashObj->hashList[slot];
|
||||||
|
|
||||||
// no data, return directly
|
// no data, return directly
|
||||||
if (atomic_load_32(&pe->num) == 0) {
|
if (atomic_load_32(&pe->num) == 0) {
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,20 +432,19 @@ void* taosHashGetCloneImpl(SHashObj *pHashObj, const void *key, size_t keyLen, v
|
||||||
taosRUnLockLatch(&pe->latch);
|
taosRUnLockLatch(&pe->latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void* d) {
|
void *taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void *d) {
|
||||||
return taosHashGetCloneImpl(pHashObj, key, keyLen, d, false);
|
return taosHashGetCloneImpl(pHashObj, key, keyLen, d, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* taosHashAcquire(SHashObj *pHashObj, const void *key, size_t keyLen) {
|
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;
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen/*, voi
|
||||||
uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
|
uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)keyLen);
|
||||||
|
|
||||||
// disable the resize process
|
// disable the resize process
|
||||||
__rd_lock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_lock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
|
|
||||||
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
|
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
|
||||||
SHashEntry *pe = pHashObj->hashList[slot];
|
SHashEntry *pe = pHashObj->hashList[slot];
|
||||||
|
@ -466,23 +466,23 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen/*, voi
|
||||||
assert(pe->next == NULL);
|
assert(pe->next == NULL);
|
||||||
taosWUnLockLatch(&pe->latch);
|
taosWUnLockLatch(&pe->latch);
|
||||||
|
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
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
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen/*, voi
|
||||||
pe->next = pNode->next;
|
pe->next = pNode->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (data) memcpy(data, GET_HASH_NODE_DATA(pNode), dsize);
|
// if (data) memcpy(data, GET_HASH_NODE_DATA(pNode), dsize);
|
||||||
|
|
||||||
pe->num--;
|
pe->num--;
|
||||||
atomic_sub_fetch_32(&pHashObj->size, 1);
|
atomic_sub_fetch_32(&pHashObj->size, 1);
|
||||||
|
@ -507,7 +507,7 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen/*, voi
|
||||||
taosWUnLockLatch(&pe->latch);
|
taosWUnLockLatch(&pe->latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -518,7 +518,7 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable the resize process
|
// disable the resize process
|
||||||
__rd_lock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_lock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
|
|
||||||
int32_t numOfEntries = (int32_t)pHashObj->capacity;
|
int32_t numOfEntries = (int32_t)pHashObj->capacity;
|
||||||
for (int32_t i = 0; i < numOfEntries; ++i) {
|
for (int32_t i = 0; i < numOfEntries; ++i) {
|
||||||
|
@ -533,7 +533,7 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi
|
||||||
|
|
||||||
// todo remove the first node
|
// todo remove the first node
|
||||||
SHashNode *pNode = NULL;
|
SHashNode *pNode = NULL;
|
||||||
while((pNode = pEntry->next) != NULL) {
|
while ((pNode = pEntry->next) != NULL) {
|
||||||
if (fp && (!fp(param, GET_HASH_NODE_DATA(pNode)))) {
|
if (fp && (!fp(param, GET_HASH_NODE_DATA(pNode)))) {
|
||||||
pEntry->num -= 1;
|
pEntry->num -= 1;
|
||||||
atomic_sub_fetch_32(&pHashObj->size, 1);
|
atomic_sub_fetch_32(&pHashObj->size, 1);
|
||||||
|
@ -582,7 +582,7 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ void taosHashClear(SHashObj *pHashObj) {
|
||||||
|
|
||||||
SHashNode *pNode, *pNext;
|
SHashNode *pNode, *pNext;
|
||||||
|
|
||||||
__wr_lock((void*) &pHashObj->lock, pHashObj->type);
|
__wr_lock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
|
|
||||||
for (int32_t i = 0; i < pHashObj->capacity; ++i) {
|
for (int32_t i = 0; i < pHashObj->capacity; ++i) {
|
||||||
SHashEntry *pEntry = pHashObj->hashList[i];
|
SHashEntry *pEntry = pHashObj->hashList[i];
|
||||||
|
@ -617,7 +617,7 @@ void taosHashClear(SHashObj *pHashObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_store_32(&pHashObj->size, 0);
|
atomic_store_32(&pHashObj->size, 0);
|
||||||
__wr_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__wr_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosHashCleanup(SHashObj *pHashObj) {
|
void taosHashCleanup(SHashObj *pHashObj) {
|
||||||
|
@ -676,7 +676,7 @@ void taosHashTableResize(SHashObj *pHashObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t st = taosGetTimestampUs();
|
int64_t st = taosGetTimestampUs();
|
||||||
void *pNewEntryList = realloc(pHashObj->hashList, sizeof(void *) * newSize);
|
void *pNewEntryList = realloc(pHashObj->hashList, sizeof(void *) * newSize);
|
||||||
if (pNewEntryList == NULL) { // todo handle error
|
if (pNewEntryList == NULL) { // todo handle error
|
||||||
// uDebug("cache resize failed due to out of memory, capacity remain:%d", pHashObj->capacity);
|
// uDebug("cache resize failed due to out of memory, capacity remain:%d", pHashObj->capacity);
|
||||||
return;
|
return;
|
||||||
|
@ -685,7 +685,7 @@ void taosHashTableResize(SHashObj *pHashObj) {
|
||||||
pHashObj->hashList = pNewEntryList;
|
pHashObj->hashList = pNewEntryList;
|
||||||
|
|
||||||
size_t inc = newSize - pHashObj->capacity;
|
size_t inc = newSize - pHashObj->capacity;
|
||||||
void * p = calloc(inc, sizeof(SHashEntry));
|
void *p = calloc(inc, sizeof(SHashEntry));
|
||||||
|
|
||||||
for (int32_t i = 0; i < inc; ++i) {
|
for (int32_t i = 0; i < inc; ++i) {
|
||||||
pHashObj->hashList[i + pHashObj->capacity] = (void *)((char *)p + i * sizeof(SHashEntry));
|
pHashObj->hashList[i + pHashObj->capacity] = (void *)((char *)p + i * sizeof(SHashEntry));
|
||||||
|
@ -756,15 +756,13 @@ void taosHashTableResize(SHashObj *pHashObj) {
|
||||||
} else {
|
} else {
|
||||||
assert(pe->next != NULL);
|
assert(pe->next != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t et = taosGetTimestampUs();
|
int64_t et = taosGetTimestampUs();
|
||||||
|
|
||||||
uDebug("hash table resize completed, new capacity:%d, load factor:%f, elapsed time:%fms", (int32_t)pHashObj->capacity,
|
uDebug("hash table resize completed, new capacity:%d, load factor:%f, elapsed time:%fms", (int32_t)pHashObj->capacity,
|
||||||
((double)pHashObj->size) / pHashObj->capacity, (et - st) / 1000.0);
|
((double)pHashObj->size) / pHashObj->capacity, (et - st) / 1000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal) {
|
SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal) {
|
||||||
|
@ -775,12 +773,12 @@ SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, s
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pNewNode->keyLen = (uint32_t)keyLen;
|
pNewNode->keyLen = (uint32_t)keyLen;
|
||||||
pNewNode->hashVal = hashVal;
|
pNewNode->hashVal = hashVal;
|
||||||
pNewNode->dataLen = (uint32_t) dsize;
|
pNewNode->dataLen = (uint32_t)dsize;
|
||||||
pNewNode->count = 1;
|
pNewNode->count = 1;
|
||||||
pNewNode->removed = 0;
|
pNewNode->removed = 0;
|
||||||
pNewNode->next = NULL;
|
pNewNode->next = NULL;
|
||||||
|
|
||||||
memcpy(GET_HASH_NODE_DATA(pNewNode), pData, dsize);
|
memcpy(GET_HASH_NODE_DATA(pNewNode), pData, dsize);
|
||||||
memcpy(GET_HASH_NODE_KEY(pNewNode), key, keyLen);
|
memcpy(GET_HASH_NODE_KEY(pNewNode), key, keyLen);
|
||||||
|
@ -802,15 +800,16 @@ 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) {
|
||||||
if (NULL == data || NULL == key) {
|
if (NULL == data || NULL == key) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHashNode * node = GET_HASH_PNODE(data);
|
SHashNode *node = GET_HASH_PNODE(data);
|
||||||
*key = GET_HASH_NODE_KEY(node);
|
*key = GET_HASH_NODE_KEY(node);
|
||||||
if (keyLen) {
|
if (keyLen) {
|
||||||
*keyLen = node->keyLen;
|
*keyLen = node->keyLen;
|
||||||
|
@ -820,19 +819,17 @@ FORCE_INLINE int32_t taosHashGetKey(void *data, void** key, size_t* keyLen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE int32_t taosHashGetDataLen(void *data) {
|
FORCE_INLINE int32_t taosHashGetDataLen(void *data) {
|
||||||
SHashNode * node = GET_HASH_PNODE(data);
|
SHashNode *node = GET_HASH_PNODE(data);
|
||||||
return node->keyLen;
|
return node->keyLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE uint32_t taosHashGetDataKeyLen(SHashObj *pHashObj, void *data) {
|
FORCE_INLINE uint32_t taosHashGetDataKeyLen(SHashObj *pHashObj, void *data) {
|
||||||
SHashNode * node = GET_HASH_PNODE(data);
|
SHashNode *node = GET_HASH_PNODE(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,14 +844,13 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pNode) {
|
if (pNode) {
|
||||||
pNode = pNode->next;
|
pNode = pNode->next;
|
||||||
while (pNode) {
|
while (pNode) {
|
||||||
if (pNode->removed == 0) break;
|
if (pNode->removed == 0) break;
|
||||||
|
@ -862,17 +858,17 @@ static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int *slot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pOld->count--;
|
pOld->count--;
|
||||||
if (pOld->count <=0) {
|
if (pOld->count <= 0) {
|
||||||
if (prevNode) {
|
if (prevNode) {
|
||||||
prevNode->next = pOld->next;
|
prevNode->next = pOld->next;
|
||||||
} else {
|
} else {
|
||||||
pe->next = pOld->next;
|
pe->next = pOld->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
pe->num--;
|
pe->num--;
|
||||||
atomic_sub_fetch_32(&pHashObj->size, 1);
|
atomic_sub_fetch_32(&pHashObj->size, 1);
|
||||||
FREE_HASH_NODE(pHashObj, pOld);
|
FREE_HASH_NODE(pHashObj, pOld);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uError("pNode:%p data:%p is not there!!!", pNode, p);
|
uError("pNode:%p data:%p is not there!!!", pNode, p);
|
||||||
}
|
}
|
||||||
|
@ -881,13 +877,13 @@ 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
|
||||||
__rd_lock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_lock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
|
|
||||||
SHashNode *pNode = NULL;
|
SHashNode *pNode = NULL;
|
||||||
if (p) {
|
if (p) {
|
||||||
|
@ -896,7 +892,7 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) {
|
||||||
SHashEntry *pe = pHashObj->hashList[slot];
|
SHashEntry *pe = pHashObj->hashList[slot];
|
||||||
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
||||||
taosWUnLockLatch(&pe->latch);
|
taosWUnLockLatch(&pe->latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
slot = slot + 1;
|
slot = slot + 1;
|
||||||
}
|
}
|
||||||
|
@ -921,7 +917,7 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) {
|
||||||
|
|
||||||
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
||||||
taosWUnLockLatch(&pe->latch);
|
taosWUnLockLatch(&pe->latch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,10 +943,10 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) {
|
||||||
|
|
||||||
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
||||||
taosWUnLockLatch(&pe->latch);
|
taosWUnLockLatch(&pe->latch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__rd_unlock((void*) &pHashObj->lock, pHashObj->type);
|
__rd_unlock((void *)&pHashObj->lock, pHashObj->type);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -958,21 +954,17 @@ void taosHashCancelIterate(SHashObj *pHashObj, void *p) {
|
||||||
if (pHashObj == NULL || p == NULL) return;
|
if (pHashObj == NULL || p == NULL) return;
|
||||||
|
|
||||||
// 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];
|
||||||
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
||||||
taosWUnLockLatch(&pe->latch);
|
taosWUnLockLatch(&pe->latch);
|
||||||
}
|
}
|
||||||
|
|
||||||
__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