From e5fe80e4e3ae7908e65a42ed5ae01d29e5d37183 Mon Sep 17 00:00:00 2001 From: Dhruba Borthakur Date: Wed, 29 Aug 2012 09:47:53 -0700 Subject: [PATCH] The sharding of the block cache is limited to 2*20 pieces. Summary: The numbers of shards that the block cache is divided into is configurable. However, if the user specifies that he/she wants the block cache to be divided into more than 2**20 pieces, then the system will rey to allocate a huge array of that size) that could fail. It is better to limit the sharding of the block cache to an upper bound. The default sharding is 16 shards (i.e. 2**4) and the maximum is now 2 million shards (i.e. 2**20). Also, fixed a bug with the LRUCache where the numShardBits should be a private member of the LRUCache object rather than a static variable. Test Plan: run db_bench with --cache_numshardbits=64. Task ID: # Blame Rev: Reviewers: heyongqiang Reviewed By: heyongqiang Differential Revision: https://reviews.facebook.net/D5013 --- db/db_bench.cc | 7 ++++++- util/cache.cc | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/db/db_bench.cc b/db/db_bench.cc index 4644ed87b..7d3157ba7 100644 --- a/db/db_bench.cc +++ b/db/db_bench.cc @@ -1048,7 +1048,12 @@ int main(int argc, char** argv) { } 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; + if (n < 20) { + FLAGS_cache_numshardbits = n; + } else { + fprintf(stderr, "The cache cannot be sharded into 2**%d pieces\n", n); + exit(1); + } } 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/util/cache.cc b/util/cache.cc index d76dc15c4..dedb370b3 100644 --- a/util/cache.cc +++ b/util/cache.cc @@ -275,21 +275,22 @@ class ShardedLRUCache : public Cache { LRUCache* shard_; port::Mutex id_mutex_; uint64_t last_id_; + int numShardBits; static inline uint32_t HashSlice(const Slice& s) { return Hash(s.data(), s.size(), 0); } - static uint32_t Shard(uint32_t hash) { - return hash >> (32 - kNumShardBits); + uint32_t Shard(uint32_t hash) { + return hash >> (32 - numShardBits); } - 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++) { + void init(size_t capacity, int numbits) { + numShardBits = numbits; + int numShards = 1 << numShardBits; + shard_ = new LRUCache[numShards]; + const size_t per_shard = (capacity + (numShards - 1)) / numShards; + for (int s = 0; s < numShards; s++) { shard_[s].SetCapacity(per_shard); } } @@ -337,6 +338,9 @@ Cache* NewLRUCache(size_t capacity) { } Cache* NewLRUCache(size_t capacity, int numShardBits) { + if (numShardBits >= 20) { + return NULL; // the cache cannot be sharded into too many fine pieces + } return new ShardedLRUCache(capacity, numShardBits); }