add hash iterator
This commit is contained in:
parent
d1b298bca6
commit
af315a9cc7
|
@ -23,17 +23,18 @@ extern "C" {
|
||||||
#include "hashfunc.h"
|
#include "hashfunc.h"
|
||||||
|
|
||||||
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
|
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
|
||||||
#define HASH_VALUE_IN_TRASH (-1)
|
|
||||||
#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))
|
||||||
|
|
||||||
|
typedef void (*_hash_free_fn_t)(void *param);
|
||||||
|
|
||||||
typedef struct SHashNode {
|
typedef struct SHashNode {
|
||||||
char *key; // null-terminated string
|
char *key;
|
||||||
union {
|
union {
|
||||||
struct SHashNode * prev;
|
struct SHashNode * prev;
|
||||||
struct SHashEntry *prev1;
|
struct SHashEntry *prev1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHashNode *next;
|
struct SHashNode *next;
|
||||||
uint32_t hashVal; // the hash value of key, if hashVal == HASH_VALUE_IN_TRASH, this node is moved to trash
|
uint32_t hashVal; // the hash value of key, if hashVal == HASH_VALUE_IN_TRASH, this node is moved to trash
|
||||||
uint32_t keyLen; // length of the key
|
uint32_t keyLen; // length of the key
|
||||||
|
@ -46,18 +47,27 @@ typedef struct SHashEntry {
|
||||||
} SHashEntry;
|
} SHashEntry;
|
||||||
|
|
||||||
typedef struct SHashObj {
|
typedef struct SHashObj {
|
||||||
SHashEntry **hashList;
|
SHashEntry ** hashList;
|
||||||
size_t capacity; // number of slots
|
size_t capacity; // number of slots
|
||||||
size_t size; // number of elements in hash table
|
size_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
|
||||||
|
|
||||||
#if defined (LINUX)
|
#if defined(LINUX)
|
||||||
pthread_rwlock_t* lock;
|
pthread_rwlock_t *lock;
|
||||||
#else
|
#else
|
||||||
pthread_mutex_t* lock;
|
pthread_mutex_t *lock;
|
||||||
#endif
|
#endif
|
||||||
} SHashObj;
|
} SHashObj;
|
||||||
|
|
||||||
|
typedef struct SHashMutableIterator {
|
||||||
|
SHashObj * pHashObj;
|
||||||
|
int32_t entryIndex;
|
||||||
|
SHashNode *pCur;
|
||||||
|
SHashNode *pNext; // current node can be deleted for mutable iterator, so keep the next one before return current
|
||||||
|
int32_t num; // already check number of elements in hash table
|
||||||
|
} SHashMutableIterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init the hash table
|
* init the hash table
|
||||||
*
|
*
|
||||||
|
@ -102,7 +112,7 @@ void *taosHashGet(SHashObj *pHashObj, const char *key, size_t keyLen);
|
||||||
* @param key
|
* @param key
|
||||||
* @param keyLen
|
* @param keyLen
|
||||||
*/
|
*/
|
||||||
void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen);
|
void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clean up hash table
|
* clean up hash table
|
||||||
|
@ -110,6 +120,41 @@ void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen);
|
||||||
*/
|
*/
|
||||||
void taosHashCleanup(SHashObj *pHashObj);
|
void taosHashCleanup(SHashObj *pHashObj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the free callback function
|
||||||
|
* This function if set will be invoked right before freeing each hash node
|
||||||
|
* @param pHashObj
|
||||||
|
*/
|
||||||
|
void taosHashSetFreecb(SHashObj *pHashObj, _hash_free_fn_t freeFp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pHashObj
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SHashMutableIterator* taosHashCreateIter(SHashObj *pHashObj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param iter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool taosHashIterNext(SHashMutableIterator *iter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param iter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void *taosHashIterGet(SHashMutableIterator *iter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param iter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void* taosHashDestroyIter(SHashMutableIterator* iter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param pHashObj
|
* @param pHashObj
|
||||||
|
|
|
@ -24,8 +24,8 @@ static FORCE_INLINE void __wr_lock(void *lock) {
|
||||||
if (lock == NULL) {
|
if (lock == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (LINUX)
|
#if defined(LINUX)
|
||||||
pthread_rwlock_wrlock(lock);
|
pthread_rwlock_wrlock(lock);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(lock);
|
pthread_mutex_lock(lock);
|
||||||
|
@ -36,8 +36,8 @@ static FORCE_INLINE void __rd_lock(void *lock) {
|
||||||
if (lock == NULL) {
|
if (lock == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (LINUX)
|
#if defined(LINUX)
|
||||||
pthread_rwlock_rdlock(lock);
|
pthread_rwlock_rdlock(lock);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(lock);
|
pthread_mutex_lock(lock);
|
||||||
|
@ -48,8 +48,8 @@ static FORCE_INLINE void __unlock(void *lock) {
|
||||||
if (lock == NULL) {
|
if (lock == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (LINUX)
|
#if defined(LINUX)
|
||||||
pthread_rwlock_unlock(lock);
|
pthread_rwlock_unlock(lock);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_unlock(lock);
|
pthread_mutex_unlock(lock);
|
||||||
|
@ -60,8 +60,8 @@ static FORCE_INLINE int32_t __lock_init(void *lock) {
|
||||||
if (lock == NULL) {
|
if (lock == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (LINUX)
|
#if defined(LINUX)
|
||||||
return pthread_rwlock_init(lock, NULL);
|
return pthread_rwlock_init(lock, NULL);
|
||||||
#else
|
#else
|
||||||
return pthread_mutex_init(lock, NULL);
|
return pthread_mutex_init(lock, NULL);
|
||||||
|
@ -72,8 +72,8 @@ static FORCE_INLINE void __lock_destroy(void *lock) {
|
||||||
if (lock == NULL) {
|
if (lock == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (LINUX)
|
#if defined(LINUX)
|
||||||
pthread_rwlock_destroy(lock);
|
pthread_rwlock_destroy(lock);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_destroy(lock);
|
pthread_mutex_destroy(lock);
|
||||||
|
@ -107,7 +107,7 @@ static void doUpdateHashTable(SHashObj *pHashObj, SHashNode *pNode) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get SHashNode from hashlist, nodes from trash are not included.
|
* get SHashNode from hashlist, nodes from trash are not included.
|
||||||
* @param pHashObj Cache objection
|
* @param pHashObj Cache objection
|
||||||
* @param key key for hash
|
* @param key key for hash
|
||||||
* @param keyLen key length
|
* @param keyLen key length
|
||||||
* @return
|
* @return
|
||||||
|
@ -155,24 +155,24 @@ static void taosHashTableResize(SHashObj *pHashObj) {
|
||||||
|
|
||||||
int32_t newSize = pHashObj->capacity << 1U;
|
int32_t newSize = pHashObj->capacity << 1U;
|
||||||
if (newSize > HASH_MAX_CAPACITY) {
|
if (newSize > HASH_MAX_CAPACITY) {
|
||||||
pTrace("current capacity:%d, maximum capacity:%d, no resize applied due to limitation is reached", pHashObj->capacity,
|
pTrace("current capacity:%d, maximum capacity:%d, no resize applied due to limitation is reached",
|
||||||
HASH_MAX_CAPACITY);
|
pHashObj->capacity, HASH_MAX_CAPACITY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t st = taosGetTimestampUs();
|
int64_t st = taosGetTimestampUs();
|
||||||
|
|
||||||
SHashEntry **pNewEntry = realloc(pHashObj->hashList, sizeof(SHashEntry*) * newSize);
|
SHashEntry **pNewEntry = realloc(pHashObj->hashList, sizeof(SHashEntry *) * newSize);
|
||||||
if (pNewEntry == NULL) {
|
if (pNewEntry == NULL) {
|
||||||
pTrace("cache resize failed due to out of memory, capacity remain:%d", pHashObj->capacity);
|
pTrace("cache resize failed due to out of memory, capacity remain:%d", pHashObj->capacity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pHashObj->hashList = pNewEntry;
|
pHashObj->hashList = pNewEntry;
|
||||||
for(int32_t i = pHashObj->capacity; i < newSize; ++i) {
|
for (int32_t i = pHashObj->capacity; i < newSize; ++i) {
|
||||||
pHashObj->hashList[i] = calloc(1, sizeof(SHashEntry));
|
pHashObj->hashList[i] = calloc(1, sizeof(SHashEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
pHashObj->capacity = newSize;
|
pHashObj->capacity = newSize;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pHashObj->capacity; ++i) {
|
for (int32_t i = 0; i < pHashObj->capacity; ++i) {
|
||||||
|
@ -182,7 +182,7 @@ static void taosHashTableResize(SHashObj *pHashObj) {
|
||||||
if (pNode != NULL) {
|
if (pNode != NULL) {
|
||||||
assert(pNode->prev1 == pEntry && pEntry->num > 0);
|
assert(pNode->prev1 == pEntry && pEntry->num > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (pNode) {
|
while (pNode) {
|
||||||
int32_t j = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
|
int32_t j = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
|
||||||
if (j == i) { // this key resides in the same slot, no need to relocate it
|
if (j == i) { // this key resides in the same slot, no need to relocate it
|
||||||
|
@ -192,13 +192,13 @@ static void taosHashTableResize(SHashObj *pHashObj) {
|
||||||
|
|
||||||
// remove from current slot
|
// remove from current slot
|
||||||
assert(pNode->prev1 != NULL);
|
assert(pNode->prev1 != NULL);
|
||||||
|
|
||||||
if (pNode->prev1 == pEntry) { // first node of the overflow linked list
|
if (pNode->prev1 == pEntry) { // first node of the overflow linked list
|
||||||
pEntry->next = pNode->next;
|
pEntry->next = pNode->next;
|
||||||
} else {
|
} else {
|
||||||
pNode->prev->next = pNode->next;
|
pNode->prev->next = pNode->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
pEntry->num--;
|
pEntry->num--;
|
||||||
assert(pEntry->num >= 0);
|
assert(pEntry->num >= 0);
|
||||||
|
|
||||||
|
@ -214,13 +214,13 @@ static void taosHashTableResize(SHashObj *pHashObj) {
|
||||||
|
|
||||||
if (pNewIndexEntry->next != NULL) {
|
if (pNewIndexEntry->next != NULL) {
|
||||||
assert(pNewIndexEntry->next->prev1 == pNewIndexEntry);
|
assert(pNewIndexEntry->next->prev1 == pNewIndexEntry);
|
||||||
|
|
||||||
pNewIndexEntry->next->prev = pNode;
|
pNewIndexEntry->next->prev = pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
pNode->next = pNewIndexEntry->next;
|
pNode->next = pNewIndexEntry->next;
|
||||||
pNode->prev1 = pNewIndexEntry;
|
pNode->prev1 = pNewIndexEntry;
|
||||||
|
|
||||||
pNewIndexEntry->next = pNode;
|
pNewIndexEntry->next = pNode;
|
||||||
pNewIndexEntry->num++;
|
pNewIndexEntry->num++;
|
||||||
|
|
||||||
|
@ -258,14 +258,14 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool threadsafe) {
|
||||||
|
|
||||||
pHashObj->hashFp = fn;
|
pHashObj->hashFp = fn;
|
||||||
|
|
||||||
pHashObj->hashList = (SHashEntry **)calloc(pHashObj->capacity, sizeof(SHashEntry*));
|
pHashObj->hashList = (SHashEntry **)calloc(pHashObj->capacity, sizeof(SHashEntry *));
|
||||||
if (pHashObj->hashList == NULL) {
|
if (pHashObj->hashList == NULL) {
|
||||||
free(pHashObj);
|
free(pHashObj);
|
||||||
pError("failed to allocate memory, reason:%s", strerror(errno));
|
pError("failed to allocate memory, reason:%s", strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32_t i = 0; i < pHashObj->capacity; ++i) {
|
for (int32_t i = 0; i < pHashObj->capacity; ++i) {
|
||||||
pHashObj->hashList[i] = calloc(1, sizeof(SHashEntry));
|
pHashObj->hashList[i] = calloc(1, sizeof(SHashEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool threadsafe) {
|
||||||
pHashObj->lock = calloc(1, sizeof(pthread_mutex_t));
|
pHashObj->lock = calloc(1, sizeof(pthread_mutex_t));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__lock_init(pHashObj->lock) != 0) {
|
if (__lock_init(pHashObj->lock) != 0) {
|
||||||
free(pHashObj->hashList);
|
free(pHashObj->hashList);
|
||||||
free(pHashObj);
|
free(pHashObj);
|
||||||
|
@ -347,7 +347,7 @@ static void doAddToHashTable(SHashObj *pHashObj, SHashNode *pNode) {
|
||||||
|
|
||||||
int32_t index = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
|
int32_t index = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
|
||||||
SHashEntry *pEntry = pHashObj->hashList[index];
|
SHashEntry *pEntry = pHashObj->hashList[index];
|
||||||
|
|
||||||
pNode->next = pEntry->next;
|
pNode->next = pEntry->next;
|
||||||
|
|
||||||
if (pEntry->next) {
|
if (pEntry->next) {
|
||||||
|
@ -356,7 +356,7 @@ static void doAddToHashTable(SHashObj *pHashObj, SHashNode *pNode) {
|
||||||
|
|
||||||
pEntry->next = pNode;
|
pEntry->next = pNode;
|
||||||
pNode->prev1 = pEntry;
|
pNode->prev1 = pEntry;
|
||||||
|
|
||||||
pEntry->num++;
|
pEntry->num++;
|
||||||
pHashObj->size++;
|
pHashObj->size++;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ size_t taosHashGetSize(const SHashObj *pHashObj) {
|
||||||
if (pHashObj == NULL) {
|
if (pHashObj == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pHashObj->size;
|
return pHashObj->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ void *taosHashGet(SHashObj *pHashObj, const char *key, size_t keyLen) {
|
||||||
void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen) {
|
void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen) {
|
||||||
__wr_lock(pHashObj->lock);
|
__wr_lock(pHashObj->lock);
|
||||||
|
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
SHashNode *pNode = doGetNodeFromHashTable(pHashObj, key, keyLen, &val);
|
SHashNode *pNode = doGetNodeFromHashTable(pHashObj, key, keyLen, &val);
|
||||||
if (pNode == NULL) {
|
if (pNode == NULL) {
|
||||||
__unlock(pHashObj->lock);
|
__unlock(pHashObj->lock);
|
||||||
|
@ -446,13 +446,13 @@ void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen) {
|
||||||
pNode->prev->next = pNext;
|
pNode->prev->next = pNext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pNext != NULL) {
|
if (pNext != NULL) {
|
||||||
pNext->prev = pNode->prev;
|
pNext->prev = pNode->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t index = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
|
uint32_t index = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
|
||||||
|
|
||||||
SHashEntry *pEntry = pHashObj->hashList[index];
|
SHashEntry *pEntry = pHashObj->hashList[index];
|
||||||
pEntry->num--;
|
pEntry->num--;
|
||||||
|
|
||||||
|
@ -483,10 +483,14 @@ void taosHashCleanup(SHashObj *pHashObj) {
|
||||||
|
|
||||||
while (pNode) {
|
while (pNode) {
|
||||||
pNext = pNode->next;
|
pNext = pNode->next;
|
||||||
|
if (pHashObj->freeFp) {
|
||||||
|
pHashObj->freeFp(pNode->data);
|
||||||
|
}
|
||||||
|
|
||||||
free(pNode);
|
free(pNode);
|
||||||
pNode = pNext;
|
pNode = pNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
tfree(pEntry);
|
tfree(pEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,24 +500,122 @@ void taosHashCleanup(SHashObj *pHashObj) {
|
||||||
__unlock(pHashObj->lock);
|
__unlock(pHashObj->lock);
|
||||||
__lock_destroy(pHashObj->lock);
|
__lock_destroy(pHashObj->lock);
|
||||||
|
|
||||||
|
tfree(pHashObj->lock);
|
||||||
memset(pHashObj, 0, sizeof(SHashObj));
|
memset(pHashObj, 0, sizeof(SHashObj));
|
||||||
free(pHashObj);
|
free(pHashObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void taosHashSetFreecb(SHashObj *pHashObj, _hash_free_fn_t freeFp) {
|
||||||
|
if (pHashObj == NULL || freeFp == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pHashObj->freeFp = freeFp;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHashMutableIterator *taosHashCreateIter(SHashObj *pHashObj) {
|
||||||
|
SHashMutableIterator *pIter = calloc(1, sizeof(SHashMutableIterator));
|
||||||
|
if (pIter == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIter->pHashObj = pHashObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SHashNode *getNextHashNode(SHashMutableIterator *pIter) {
|
||||||
|
assert(pIter != NULL);
|
||||||
|
|
||||||
|
while (pIter->entryIndex < pIter->pHashObj->capacity) {
|
||||||
|
SHashEntry *pEntry = pIter->pHashObj->hashList[pIter->entryIndex];
|
||||||
|
if (pEntry->next == NULL) {
|
||||||
|
pIter->entryIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pEntry->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool taosHashIterNext(SHashMutableIterator *pIter) {
|
||||||
|
if (pIter == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = taosHashGetSize(pIter->pHashObj);
|
||||||
|
if (size == 0 || pIter->num >= size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the first one
|
||||||
|
if (pIter->num == 0) {
|
||||||
|
assert(pIter->pCur == NULL && pIter->pNext == NULL);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
SHashEntry *pEntry = pIter->pHashObj->hashList[pIter->entryIndex];
|
||||||
|
if (pEntry->next == NULL) {
|
||||||
|
pIter->entryIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIter->pCur = pEntry->next;
|
||||||
|
|
||||||
|
if (pIter->pCur->next) {
|
||||||
|
pIter->pNext = pIter->pCur->next;
|
||||||
|
} else {
|
||||||
|
pIter->pNext = getNextHashNode(pIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIter->num++;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
assert(pIter->pCur != NULL);
|
||||||
|
if (pIter->pNext) {
|
||||||
|
pIter->pCur = pIter->pNext;
|
||||||
|
} else { // no more data in the hash list
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIter->num++;
|
||||||
|
|
||||||
|
if (pIter->pCur->next) {
|
||||||
|
pIter->pNext = pIter->pCur->next;
|
||||||
|
} else {
|
||||||
|
pIter->pNext = getNextHashNode(pIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *taosHashIterGet(SHashMutableIterator *iter) { return (iter == NULL) ? NULL : iter->pCur->data; }
|
||||||
|
|
||||||
|
void *taosHashDestroyIter(SHashMutableIterator *iter) {
|
||||||
|
if (iter == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(iter);
|
||||||
|
}
|
||||||
|
|
||||||
// for profile only
|
// for profile only
|
||||||
int32_t taosHashGetMaxOverflowLinkLength(const SHashObj* pHashObj) {
|
int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj) {
|
||||||
if (pHashObj == NULL || pHashObj->size == 0) {
|
if (pHashObj == NULL || pHashObj->size == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t num = 0;
|
int32_t num = 0;
|
||||||
|
|
||||||
for(int32_t i = 0; i < pHashObj->size; ++i) {
|
for (int32_t i = 0; i < pHashObj->size; ++i) {
|
||||||
SHashEntry *pEntry = pHashObj->hashList[i];
|
SHashEntry *pEntry = pHashObj->hashList[i];
|
||||||
if (num < pEntry->num) {
|
if (num < pEntry->num) {
|
||||||
num = pEntry->num;
|
num = pEntry->num;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue