[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

@@ -5,6 +5,8 @@
#include "leveldb/cache.h"
#include <vector>
#include <string>
#include <iostream>
#include "util/coding.h"
#include "util/testharness.h"
@@ -178,6 +180,51 @@ TEST(CacheTest, NewId) {
ASSERT_NE(a, b);
}
class Value {
private:
int v_;
public:
Value(int v) : v_(v) { }
~Value() { std::cout << v_ << " is destructed\n"; }
};
void deleter(const Slice& key, void* value) {
delete (Value *)value;
}
TEST(CacheTest, BadEviction) {
int n = 10;
// a LRUCache with n entries and one shard only
std::shared_ptr<Cache> cache = NewLRUCache(n, 0);
std::vector<Cache::Handle*> handles(n+1);
// Insert n+1 entries, but not releasing.
for (int i = 0; i < n+1; i++) {
std::string key = std::to_string(i+1);
handles[i] = cache->Insert(key, new Value(i+1), 1, &deleter);
}
// Guess what's in the cache now?
for (int i = 0; i < n+1; i++) {
std::string key = std::to_string(i+1);
auto h = cache->Lookup(key);
std::cout << key << (h?" found\n":" not found\n");
// Only the first entry should be missing
ASSERT_TRUE(h || i == 0);
if (h) cache->Release(h);
}
for (int i = 0; i < n+1; i++) {
cache->Release(handles[i]);
}
std::cout << "Poor entries\n";
}
} // namespace leveldb
int main(int argc, char** argv) {