fix(util/lru): free cache if shards init failed

This commit is contained in:
Minglei Jin 2024-08-22 10:57:38 +08:00
parent dcf682939e
commit ccd95c8bc0
1 changed files with 30 additions and 26 deletions

View File

@ -87,13 +87,13 @@ struct SLRUEntry {
#define TAOS_LRU_ENTRY_REF(h) (++(h)->refs) #define TAOS_LRU_ENTRY_REF(h) (++(h)->refs)
static bool taosLRUEntryUnref(SLRUEntry *entry) { static bool taosLRUEntryUnref(SLRUEntry *entry) {
ASSERT(entry->refs > 0); // ASSERT(entry->refs > 0);
--entry->refs; --entry->refs;
return entry->refs == 0; return entry->refs == 0;
} }
static void taosLRUEntryFree(SLRUEntry *entry) { static void taosLRUEntryFree(SLRUEntry *entry) {
ASSERT(entry->refs == 0); // ASSERT(entry->refs == 0);
if (entry->deleter) { if (entry->deleter) {
(*entry->deleter)(entry->keyData, entry->keyLength, entry->value, entry->ud); (*entry->deleter)(entry->keyData, entry->keyLength, entry->value, entry->ud);
@ -129,7 +129,7 @@ static void taosLRUEntryTableApply(SLRUEntryTable *table, _taos_lru_table_func_t
SLRUEntry *h = table->list[i]; SLRUEntry *h = table->list[i];
while (h) { while (h) {
SLRUEntry *n = h->nextHash; SLRUEntry *n = h->nextHash;
ASSERT(TAOS_LRU_ENTRY_IN_CACHE(h)); // ASSERT(TAOS_LRU_ENTRY_IN_CACHE(h));
func(h); func(h);
h = n; h = n;
} }
@ -155,7 +155,7 @@ static int taosLRUEntryTableApplyF(SLRUEntryTable *table, _taos_lru_functor_t fu
SLRUEntry *h = table->list[i]; SLRUEntry *h = table->list[i];
while (h) { while (h) {
SLRUEntry *n = h->nextHash; SLRUEntry *n = h->nextHash;
ASSERT(TAOS_LRU_ENTRY_IN_CACHE(h)); // ASSERT(TAOS_LRU_ENTRY_IN_CACHE(h));
ret = functor(h->keyData, h->keyLength, h->value, ud); ret = functor(h->keyData, h->keyLength, h->value, ud);
if (ret) { if (ret) {
return ret; return ret;
@ -205,7 +205,7 @@ static void taosLRUEntryTableResize(SLRUEntryTable *table) {
++count; ++count;
} }
} }
ASSERT(table->elems == count); // ASSERT(table->elems == count);
taosMemoryFree(table->list); taosMemoryFree(table->list);
table->list = newList; table->list = newList;
@ -261,16 +261,16 @@ struct SLRUCacheShard {
static void taosLRUCacheShardMaintainPoolSize(SLRUCacheShard *shard) { static void taosLRUCacheShardMaintainPoolSize(SLRUCacheShard *shard) {
while (shard->highPriPoolUsage > shard->highPriPoolCapacity) { while (shard->highPriPoolUsage > shard->highPriPoolCapacity) {
shard->lruLowPri = shard->lruLowPri->next; shard->lruLowPri = shard->lruLowPri->next;
ASSERT(shard->lruLowPri != &shard->lru); // ASSERT(shard->lruLowPri != &shard->lru);
TAOS_LRU_ENTRY_SET_IN_HIGH_POOL(shard->lruLowPri, false); TAOS_LRU_ENTRY_SET_IN_HIGH_POOL(shard->lruLowPri, false);
ASSERT(shard->highPriPoolUsage >= shard->lruLowPri->totalCharge); // ASSERT(shard->highPriPoolUsage >= shard->lruLowPri->totalCharge);
shard->highPriPoolUsage -= shard->lruLowPri->totalCharge; shard->highPriPoolUsage -= shard->lruLowPri->totalCharge;
} }
} }
static void taosLRUCacheShardLRUInsert(SLRUCacheShard *shard, SLRUEntry *e) { static void taosLRUCacheShardLRUInsert(SLRUCacheShard *shard, SLRUEntry *e) {
ASSERT(e->next == NULL && e->prev == NULL); // ASSERT(e->next == NULL && e->prev == NULL);
if (shard->highPriPoolRatio > 0 && (TAOS_LRU_ENTRY_IS_HIGH_PRI(e) || TAOS_LRU_ENTRY_HAS_HIT(e))) { if (shard->highPriPoolRatio > 0 && (TAOS_LRU_ENTRY_IS_HIGH_PRI(e) || TAOS_LRU_ENTRY_HAS_HIT(e))) {
e->next = &shard->lru; e->next = &shard->lru;
@ -297,7 +297,7 @@ static void taosLRUCacheShardLRUInsert(SLRUCacheShard *shard, SLRUEntry *e) {
} }
static void taosLRUCacheShardLRURemove(SLRUCacheShard *shard, SLRUEntry *e) { static void taosLRUCacheShardLRURemove(SLRUCacheShard *shard, SLRUEntry *e) {
ASSERT(e->next && e->prev); // ASSERT(e->next && e->prev);
if (shard->lruLowPri == e) { if (shard->lruLowPri == e) {
shard->lruLowPri = e->prev; shard->lruLowPri = e->prev;
@ -306,10 +306,10 @@ static void taosLRUCacheShardLRURemove(SLRUCacheShard *shard, SLRUEntry *e) {
e->prev->next = e->next; e->prev->next = e->next;
e->prev = e->next = NULL; e->prev = e->next = NULL;
ASSERT(shard->lruUsage >= e->totalCharge); // ASSERT(shard->lruUsage >= e->totalCharge);
shard->lruUsage -= e->totalCharge; shard->lruUsage -= e->totalCharge;
if (TAOS_LRU_ENTRY_IN_HIGH_POOL(e)) { if (TAOS_LRU_ENTRY_IN_HIGH_POOL(e)) {
ASSERT(shard->highPriPoolUsage >= e->totalCharge); // ASSERT(shard->highPriPoolUsage >= e->totalCharge);
shard->highPriPoolUsage -= e->totalCharge; shard->highPriPoolUsage -= e->totalCharge;
} }
} }
@ -317,13 +317,13 @@ static void taosLRUCacheShardLRURemove(SLRUCacheShard *shard, SLRUEntry *e) {
static void taosLRUCacheShardEvictLRU(SLRUCacheShard *shard, size_t charge, SArray *deleted) { static void taosLRUCacheShardEvictLRU(SLRUCacheShard *shard, size_t charge, SArray *deleted) {
while (shard->usage + charge > shard->capacity && shard->lru.next != &shard->lru) { while (shard->usage + charge > shard->capacity && shard->lru.next != &shard->lru) {
SLRUEntry *old = shard->lru.next; SLRUEntry *old = shard->lru.next;
ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old) && !TAOS_LRU_ENTRY_HAS_REFS(old)); // ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old) && !TAOS_LRU_ENTRY_HAS_REFS(old));
taosLRUCacheShardLRURemove(shard, old); taosLRUCacheShardLRURemove(shard, old);
(void)taosLRUEntryTableRemove(&shard->table, old->keyData, old->keyLength, old->hash); (void)taosLRUEntryTableRemove(&shard->table, old->keyData, old->keyLength, old->hash);
TAOS_LRU_ENTRY_SET_IN_CACHE(old, false); TAOS_LRU_ENTRY_SET_IN_CACHE(old, false);
ASSERT(shard->usage >= old->totalCharge); // ASSERT(shard->usage >= old->totalCharge);
shard->usage -= old->totalCharge; shard->usage -= old->totalCharge;
(void)taosArrayPush(deleted, &old); (void)taosArrayPush(deleted, &old);
@ -332,6 +332,9 @@ static void taosLRUCacheShardEvictLRU(SLRUCacheShard *shard, size_t charge, SArr
static void taosLRUCacheShardSetCapacity(SLRUCacheShard *shard, size_t capacity) { static void taosLRUCacheShardSetCapacity(SLRUCacheShard *shard, size_t capacity) {
SArray *lastReferenceList = taosArrayInit(16, POINTER_BYTES); SArray *lastReferenceList = taosArrayInit(16, POINTER_BYTES);
if (!lastReferenceList) {
return;
}
(void)taosThreadMutexLock(&shard->mutex); (void)taosThreadMutexLock(&shard->mutex);
@ -411,11 +414,11 @@ static LRUStatus taosLRUCacheShardInsertEntry(SLRUCacheShard *shard, SLRUEntry *
if (old != NULL) { if (old != NULL) {
status = TAOS_LRU_STATUS_OK_OVERWRITTEN; status = TAOS_LRU_STATUS_OK_OVERWRITTEN;
ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old)); // ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old));
TAOS_LRU_ENTRY_SET_IN_CACHE(old, false); TAOS_LRU_ENTRY_SET_IN_CACHE(old, false);
if (!TAOS_LRU_ENTRY_HAS_REFS(old)) { if (!TAOS_LRU_ENTRY_HAS_REFS(old)) {
taosLRUCacheShardLRURemove(shard, old); taosLRUCacheShardLRURemove(shard, old);
ASSERT(shard->usage >= old->totalCharge); // ASSERT(shard->usage >= old->totalCharge);
shard->usage -= old->totalCharge; shard->usage -= old->totalCharge;
(void)taosArrayPush(lastReferenceList, &old); (void)taosArrayPush(lastReferenceList, &old);
@ -476,7 +479,7 @@ static LRUHandle *taosLRUCacheShardLookup(SLRUCacheShard *shard, const void *key
(void)taosThreadMutexLock(&shard->mutex); (void)taosThreadMutexLock(&shard->mutex);
e = taosLRUEntryTableLookup(&shard->table, key, keyLen, hash); e = taosLRUEntryTableLookup(&shard->table, key, keyLen, hash);
if (e != NULL) { if (e != NULL) {
ASSERT(TAOS_LRU_ENTRY_IN_CACHE(e)); // ASSERT(TAOS_LRU_ENTRY_IN_CACHE(e));
if (!TAOS_LRU_ENTRY_HAS_REFS(e)) { if (!TAOS_LRU_ENTRY_HAS_REFS(e)) {
taosLRUCacheShardLRURemove(shard, e); taosLRUCacheShardLRURemove(shard, e);
} }
@ -495,12 +498,12 @@ static void taosLRUCacheShardErase(SLRUCacheShard *shard, const void *key, size_
SLRUEntry *e = taosLRUEntryTableRemove(&shard->table, key, keyLen, hash); SLRUEntry *e = taosLRUEntryTableRemove(&shard->table, key, keyLen, hash);
if (e != NULL) { if (e != NULL) {
ASSERT(TAOS_LRU_ENTRY_IN_CACHE(e)); // ASSERT(TAOS_LRU_ENTRY_IN_CACHE(e));
TAOS_LRU_ENTRY_SET_IN_CACHE(e, false); TAOS_LRU_ENTRY_SET_IN_CACHE(e, false);
if (!TAOS_LRU_ENTRY_HAS_REFS(e)) { if (!TAOS_LRU_ENTRY_HAS_REFS(e)) {
taosLRUCacheShardLRURemove(shard, e); taosLRUCacheShardLRURemove(shard, e);
ASSERT(shard->usage >= e->totalCharge); // ASSERT(shard->usage >= e->totalCharge);
shard->usage -= e->totalCharge; shard->usage -= e->totalCharge;
lastReference = true; lastReference = true;
} }
@ -532,11 +535,11 @@ static void taosLRUCacheShardEraseUnrefEntries(SLRUCacheShard *shard) {
while (shard->lru.next != &shard->lru) { while (shard->lru.next != &shard->lru) {
SLRUEntry *old = shard->lru.next; SLRUEntry *old = shard->lru.next;
ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old) && !TAOS_LRU_ENTRY_HAS_REFS(old)); // ASSERT(TAOS_LRU_ENTRY_IN_CACHE(old) && !TAOS_LRU_ENTRY_HAS_REFS(old));
taosLRUCacheShardLRURemove(shard, old); taosLRUCacheShardLRURemove(shard, old);
(void)taosLRUEntryTableRemove(&shard->table, old->keyData, old->keyLength, old->hash); (void)taosLRUEntryTableRemove(&shard->table, old->keyData, old->keyLength, old->hash);
TAOS_LRU_ENTRY_SET_IN_CACHE(old, false); TAOS_LRU_ENTRY_SET_IN_CACHE(old, false);
ASSERT(shard->usage >= old->totalCharge); // ASSERT(shard->usage >= old->totalCharge);
shard->usage -= old->totalCharge; shard->usage -= old->totalCharge;
(void)taosArrayPush(lastReferenceList, &old); (void)taosArrayPush(lastReferenceList, &old);
@ -557,7 +560,7 @@ static bool taosLRUCacheShardRef(SLRUCacheShard *shard, LRUHandle *handle) {
SLRUEntry *e = (SLRUEntry *)handle; SLRUEntry *e = (SLRUEntry *)handle;
(void)taosThreadMutexLock(&shard->mutex); (void)taosThreadMutexLock(&shard->mutex);
ASSERT(TAOS_LRU_ENTRY_HAS_REFS(e)); // ASSERT(TAOS_LRU_ENTRY_HAS_REFS(e));
TAOS_LRU_ENTRY_REF(e); TAOS_LRU_ENTRY_REF(e);
(void)taosThreadMutexUnlock(&shard->mutex); (void)taosThreadMutexUnlock(&shard->mutex);
@ -578,7 +581,7 @@ static bool taosLRUCacheShardRelease(SLRUCacheShard *shard, LRUHandle *handle, b
lastReference = taosLRUEntryUnref(e); lastReference = taosLRUEntryUnref(e);
if (lastReference && TAOS_LRU_ENTRY_IN_CACHE(e)) { if (lastReference && TAOS_LRU_ENTRY_IN_CACHE(e)) {
if (shard->usage > shard->capacity || eraseIfLastRef) { if (shard->usage > shard->capacity || eraseIfLastRef) {
ASSERT(shard->lru.next == &shard->lru || eraseIfLastRef); // ASSERT(shard->lru.next == &shard->lru || eraseIfLastRef);
(void)taosLRUEntryTableRemove(&shard->table, e->keyData, e->keyLength, e->hash); (void)taosLRUEntryTableRemove(&shard->table, e->keyData, e->keyLength, e->hash);
TAOS_LRU_ENTRY_SET_IN_CACHE(e, false); TAOS_LRU_ENTRY_SET_IN_CACHE(e, false);
@ -590,7 +593,7 @@ static bool taosLRUCacheShardRelease(SLRUCacheShard *shard, LRUHandle *handle, b
} }
if (lastReference && e->value) { if (lastReference && e->value) {
ASSERT(shard->usage >= e->totalCharge); // ASSERT(shard->usage >= e->totalCharge);
shard->usage -= e->totalCharge; shard->usage -= e->totalCharge;
} }
@ -628,7 +631,7 @@ static size_t taosLRUCacheShardGetPinnedUsage(SLRUCacheShard *shard) {
(void)taosThreadMutexLock(&shard->mutex); (void)taosThreadMutexLock(&shard->mutex);
ASSERT(shard->usage >= shard->lruUsage); // ASSERT(shard->usage >= shard->lruUsage);
usage = shard->usage - shard->lruUsage; usage = shard->usage - shard->lruUsage;
(void)taosThreadMutexUnlock(&shard->mutex); (void)taosThreadMutexUnlock(&shard->mutex);
@ -699,7 +702,8 @@ SLRUCache *taosLRUCacheInit(size_t capacity, int numShardBits, double highPriPoo
for (int i = 0; i < numShards; ++i) { for (int i = 0; i < numShards; ++i) {
if (TSDB_CODE_SUCCESS != if (TSDB_CODE_SUCCESS !=
taosLRUCacheShardInit(&cache->shards[i], perShard, strictCapacity, highPriPoolRatio, 32 - numShardBits)) taosLRUCacheShardInit(&cache->shards[i], perShard, strictCapacity, highPriPoolRatio, 32 - numShardBits))
return NULL; taosMemoryFree(cache);
return NULL;
} }
cache->numShards = numShards; cache->numShards = numShards;
@ -718,7 +722,7 @@ void taosLRUCacheCleanup(SLRUCache *cache) {
if (cache) { if (cache) {
if (cache->shards) { if (cache->shards) {
int numShards = cache->numShards; int numShards = cache->numShards;
ASSERT(numShards > 0); // ASSERT(numShards > 0);
for (int i = 0; i < numShards; ++i) { for (int i = 0; i < numShards; ++i) {
taosLRUCacheShardCleanup(&cache->shards[i]); taosLRUCacheShardCleanup(&cache->shards[i]);
} }