提交 8ed7d45a 编写于 作者: Y Yifan Hao

Hash table cleanup [7/n]

1. Add missing lock / unlock in profiling code. Without
   synchronization, the profiling code could access freed memory.
2. Remove unnecessary assert.
3. Remove unncessary if check in taosHashRemoveWithData.

* Testing
sample mysql:
taos> create database db;
Query OK, 0 of 0 row(s) in database (0.002291s)

taos> use db;
Query OK, 0 of 0 row(s) in database (0.000197s)

taos> create table t (ts timestamp, a int);
Query OK, 0 of 0 row(s) in database (0.003851s)

taos> insert into t values ('2019-07-15 00:00:00', 1);
Query OK, 1 of 1 row(s) in database (0.001128s)

taos> insert into t values ('2019-07-15 01:00:00', 2);
Query OK, 1 of 1 row(s) in database (0.000249s)

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.000772s)

taos> drop database db;
Query OK, 0 of 0 row(s) in database (0.002308s)
上级 699451e6
...@@ -173,7 +173,7 @@ void taosHashCleanup(SHashObj *pHashObj); ...@@ -173,7 +173,7 @@ void taosHashCleanup(SHashObj *pHashObj);
* @param pHashObj hash table object * @param pHashObj hash table object
* @return maximum number of collisions * @return maximum number of collisions
*/ */
int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj); int32_t taosHashGetMaxOverflowLinkLength(SHashObj *pHashObj);
/** /**
* return the consumed memory of the hash table * return the consumed memory of the hash table
......
...@@ -515,23 +515,16 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe ...@@ -515,23 +515,16 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
while (pNode) { while (pNode) {
if ((pNode->keyLen == keyLen) && if ((pNode->keyLen == keyLen) &&
((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && ((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) &&
pNode->removed == 0) pNode->removed == 0) {
break;
prevNode = pNode;
pNode = pNode->next;
}
if (pNode) {
code = 0; // it is found code = 0; // it is found
atomic_sub_fetch_32(&pNode->refCount, 1); atomic_sub_fetch_32(&pNode->refCount, 1);
pNode->removed = 1; pNode->removed = 1;
if (pNode->refCount <= 0) { if (pNode->refCount <= 0) {
if (prevNode) { if (prevNode == NULL) {
prevNode->next = pNode->next;
} else {
pe->next = pNode->next; pe->next = pNode->next;
} else {
prevNode->next = pNode->next;
} }
if (data) memcpy(data, GET_HASH_NODE_DATA(pNode), dsize); if (data) memcpy(data, GET_HASH_NODE_DATA(pNode), dsize);
...@@ -540,6 +533,10 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe ...@@ -540,6 +533,10 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
atomic_sub_fetch_64(&pHashObj->size, 1); atomic_sub_fetch_64(&pHashObj->size, 1);
FREE_HASH_NODE(pHashObj, pNode); FREE_HASH_NODE(pHashObj, pNode);
} }
} else {
prevNode = pNode;
pNode = pNode->next;
}
} }
if (pHashObj->type == HASH_ENTRY_LOCK) { if (pHashObj->type == HASH_ENTRY_LOCK) {
...@@ -649,24 +646,28 @@ void taosHashCleanup(SHashObj *pHashObj) { ...@@ -649,24 +646,28 @@ void taosHashCleanup(SHashObj *pHashObj) {
taosArrayDestroy(pHashObj->pMemBlock); taosArrayDestroy(pHashObj->pMemBlock);
memset(pHashObj, 0, sizeof(SHashObj));
free(pHashObj); free(pHashObj);
} }
// for profile only // for profile only
int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj) { int32_t taosHashGetMaxOverflowLinkLength(SHashObj *pHashObj) {
if (pHashObj == NULL || taosHashTableEmpty(pHashObj)) { if (pHashObj == NULL || taosHashTableEmpty(pHashObj)) {
return 0; return 0;
} }
int32_t num = 0; int32_t num = 0;
__rd_lock(&pHashObj->lock, pHashObj->type);
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];
// fine grain per entry lock is not held since this is used
// for profiling only and doesn't need an accurate count.
if (num < pEntry->num) { if (num < pEntry->num) {
num = pEntry->num; num = pEntry->num;
} }
} }
__rd_unlock(&pHashObj->lock, pHashObj->type);
return num; return num;
} }
...@@ -682,15 +683,15 @@ void taosHashTableResize(SHashObj *pHashObj) { ...@@ -682,15 +683,15 @@ void taosHashTableResize(SHashObj *pHashObj) {
int32_t newCapacity = (int32_t)(pHashObj->capacity << 1u); int32_t newCapacity = (int32_t)(pHashObj->capacity << 1u);
if (newCapacity > HASH_MAX_CAPACITY) { if (newCapacity > HASH_MAX_CAPACITY) {
// uDebug("current capacity:%d, maximum capacity:%d, no resize applied due to limitation is reached", uDebug("current capacity:%lu, maximum capacity:%d, no resize applied due to limitation is reached",
// pHashObj->capacity, HASH_MAX_CAPACITY); pHashObj->capacity, HASH_MAX_CAPACITY);
return; return;
} }
int64_t st = taosGetTimestampUs(); int64_t st = taosGetTimestampUs();
void *pNewEntryList = realloc(pHashObj->hashList, sizeof(void *) * newCapacity); void *pNewEntryList = realloc(pHashObj->hashList, sizeof(void *) * newCapacity);
if (pNewEntryList == NULL) { // todo handle error if (pNewEntryList == NULL) {
// 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:%lu", pHashObj->capacity);
return; return;
} }
...@@ -709,17 +710,13 @@ void taosHashTableResize(SHashObj *pHashObj) { ...@@ -709,17 +710,13 @@ void taosHashTableResize(SHashObj *pHashObj) {
for (int32_t i = 0; i < pHashObj->capacity; ++i) { for (int32_t i = 0; i < pHashObj->capacity; ++i) {
SHashEntry *pe = pHashObj->hashList[i]; SHashEntry *pe = pHashObj->hashList[i];
if (pe->num == 0) {
assert(pe->next == NULL);
} else {
assert(pe->next != NULL);
}
if (pe->num == 0) { if (pe->num == 0) {
assert(pe->next == NULL); assert(pe->next == NULL);
continue; continue;
} }
assert(pe->next != NULL);
while ((pNode = pe->next) != NULL) { while ((pNode = pe->next) != NULL) {
int32_t j = HASH_INDEX(pNode->hashVal, pHashObj->capacity); int32_t j = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
if (j != i) { if (j != i) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册