[RocksDB] Fix LRUCache Eviction problem

Summary:
1. The stock LRUCache nukes itself whenever the working set (the total number of entries not released by client at a certain time) is bigger than the cache capacity.
See https://our.dev.facebook.com/intern/tasks/?t=2252281
2. There's a bug in shard calculation leading to segmentation fault when only one shard is needed.

Test Plan: make check

Reviewers: dhruba, heyongqiang

Reviewed By: heyongqiang

CC: leveldb, zshao, sheki

Differential Revision: https://reviews.facebook.net/D9927
This commit is contained in:
Haobo Xu
2013-04-03 18:53:42 -07:00
parent 2b9a360c8b
commit a77bc3d14c
2 changed files with 52 additions and 3 deletions

View File

@@ -189,7 +189,7 @@ void LRUCache::Unref(LRUHandle* e) {
assert(e->refs > 0);
e->refs--;
if (e->refs <= 0) {
usage_ -= e->charge;
(*e->deleter)(e->key(), e->value);
free(e);
}
@@ -198,6 +198,7 @@ void LRUCache::Unref(LRUHandle* e) {
void LRUCache::LRU_Remove(LRUHandle* e) {
e->next->prev = e->prev;
e->prev->next = e->next;
usage_ -= e->charge;
}
void LRUCache::LRU_Append(LRUHandle* e) {
@@ -206,6 +207,7 @@ void LRUCache::LRU_Append(LRUHandle* e) {
e->prev = lru_.prev;
e->prev->next = e;
e->next->prev = e;
usage_ += e->charge;
}
Cache::Handle* LRUCache::Lookup(const Slice& key, uint32_t hash) {
@@ -239,7 +241,6 @@ Cache::Handle* LRUCache::Insert(
e->refs = 2; // One from LRUCache, one for the returned handle
memcpy(e->key_data, key.data(), key.size());
LRU_Append(e);
usage_ += charge;
LRUHandle* old = table_.Insert(e);
if (old != nullptr) {
@@ -281,7 +282,8 @@ class ShardedLRUCache : public Cache {
}
uint32_t Shard(uint32_t hash) {
return hash >> (32 - numShardBits);
// Note, hash >> 32 yields hash in gcc, not the zero we expect!
return (numShardBits > 0) ? (hash >> (32 - numShardBits)) : 0;
}
void init(size_t capacity, int numbits) {