diff --git a/db/db_bench.cc b/db/db_bench.cc index 346ff9d5b..8912fad1d 100644 --- a/db/db_bench.cc +++ b/db/db_bench.cc @@ -102,6 +102,11 @@ static bool FLAGS_use_existing_db = false; // Use the db with the following name. static const char* FLAGS_db = "/tmp/dbbench"; +// Number of shards for the block cache is 2 ** FLAGS_cache_numshardbits. +// Negative means use default settings. This is applied only +// if FLAGS_cache_size is non-negative. +static int FLAGS_cache_numshardbits = -1; + namespace leveldb { namespace { @@ -390,7 +395,10 @@ class Benchmark { public: Benchmark() - : cache_(FLAGS_cache_size >= 0 ? NewLRUCache(FLAGS_cache_size) : NULL), + : cache_(FLAGS_cache_size >= 0 ? + (FLAGS_cache_numshardbits >= 1 ? + NewLRUCache(FLAGS_cache_size, FLAGS_cache_numshardbits) : + NewLRUCache(FLAGS_cache_size)) : NULL), filter_policy_(FLAGS_bloom_bits >= 0 ? NewBloomFilterPolicy(FLAGS_bloom_bits) : NULL), @@ -955,6 +963,8 @@ int main(int argc, char** argv) { FLAGS_write_buffer_size = n; } else if (sscanf(argv[i], "--cache_size=%ld%c", &n, &junk) == 1) { FLAGS_cache_size = n; + } else if (sscanf(argv[i], "--cache_numshardbits=%d%c", &n, &junk) == 1) { + FLAGS_cache_numshardbits = n; } else if (sscanf(argv[i], "--bloom_bits=%d%c", &n, &junk) == 1) { FLAGS_bloom_bits = n; } else if (sscanf(argv[i], "--open_files=%d%c", &n, &junk) == 1) { diff --git a/include/leveldb/cache.h b/include/leveldb/cache.h index 5e3b47637..a7bd2afa7 100644 --- a/include/leveldb/cache.h +++ b/include/leveldb/cache.h @@ -28,6 +28,7 @@ class Cache; // Create a new cache with a fixed size capacity. This implementation // of Cache uses a least-recently-used eviction policy. extern Cache* NewLRUCache(size_t capacity); +extern Cache* NewLRUCache(size_t capacity, int numShardBits); class Cache { public: diff --git a/util/cache.cc b/util/cache.cc index 24f1f63f4..d76dc15c4 100644 --- a/util/cache.cc +++ b/util/cache.cc @@ -267,12 +267,12 @@ void LRUCache::Erase(const Slice& key, uint32_t hash) { } } -static const int kNumShardBits = 4; -static const int kNumShards = 1 << kNumShardBits; +static int kNumShardBits = 4; // default values, can be overridden +static int kNumShards = 1 << kNumShardBits; class ShardedLRUCache : public Cache { private: - LRUCache shard_[kNumShards]; + LRUCache* shard_; port::Mutex id_mutex_; uint64_t last_id_; @@ -284,14 +284,25 @@ class ShardedLRUCache : public Cache { return hash >> (32 - kNumShardBits); } - public: - explicit ShardedLRUCache(size_t capacity) - : last_id_(0) { + void init(size_t capacity, int numShardBits) { + kNumShardBits = numShardBits; + kNumShards = 1 << kNumShardBits; + shard_ = new LRUCache[kNumShards]; const size_t per_shard = (capacity + (kNumShards - 1)) / kNumShards; for (int s = 0; s < kNumShards; s++) { shard_[s].SetCapacity(per_shard); } } + + public: + explicit ShardedLRUCache(size_t capacity) + : last_id_(0) { + init(capacity, kNumShardBits); + } + ShardedLRUCache(size_t capacity, int numShardBits) + : last_id_(0) { + init(capacity, numShardBits); + } virtual ~ShardedLRUCache() { } virtual Handle* Insert(const Slice& key, void* value, size_t charge, void (*deleter)(const Slice& key, void* value)) { @@ -325,4 +336,8 @@ Cache* NewLRUCache(size_t capacity) { return new ShardedLRUCache(capacity); } +Cache* NewLRUCache(size_t capacity, int numShardBits) { + return new ShardedLRUCache(capacity, numShardBits); +} + } // namespace leveldb