diff --git a/cache/lru_cache.cc b/cache/lru_cache.cc index b655b335f..11d18efdd 100644 --- a/cache/lru_cache.cc +++ b/cache/lru_cache.cc @@ -99,14 +99,20 @@ void LRUHandleTable::Resize() { length_ = new_length; } -LRUCacheShard::LRUCacheShard() - : capacity_(0), high_pri_pool_usage_(0), strict_capacity_limit_(false), - high_pri_pool_ratio_(0), high_pri_pool_capacity_(0), usage_(0), +LRUCacheShard::LRUCacheShard(size_t capacity, bool strict_capacity_limit, + double high_pri_pool_ratio) + : capacity_(0), + high_pri_pool_usage_(0), + strict_capacity_limit_(strict_capacity_limit), + high_pri_pool_ratio_(high_pri_pool_ratio), + high_pri_pool_capacity_(0), + usage_(0), lru_usage_(0) { // Make empty circular linked list lru_.next = &lru_; lru_.prev = &lru_; lru_low_pri_ = &lru_; + SetCapacity(capacity); } LRUCacheShard::~LRUCacheShard() {} @@ -244,17 +250,13 @@ void* LRUCacheShard::operator new(size_t size) { return port::cacheline_aligned_alloc(size); } -void* LRUCacheShard::operator new[](size_t size) { - return port::cacheline_aligned_alloc(size); -} +void* LRUCacheShard::operator new(size_t /*size*/, void* ptr) { return ptr; } void LRUCacheShard::operator delete(void *memblock) { port::cacheline_aligned_free(memblock); } -void LRUCacheShard::operator delete[](void* memblock) { - port::cacheline_aligned_free(memblock); -} +void LRUCacheShard::operator delete(void* /*memblock*/, void* /*ptr*/) {} void LRUCacheShard::SetCapacity(size_t capacity) { autovector last_reference_list; @@ -473,15 +475,21 @@ LRUCache::LRUCache(size_t capacity, int num_shard_bits, bool strict_capacity_limit, double high_pri_pool_ratio) : ShardedCache(capacity, num_shard_bits, strict_capacity_limit) { num_shards_ = 1 << num_shard_bits; - shards_ = new LRUCacheShard[num_shards_]; - SetCapacity(capacity); - SetStrictCapacityLimit(strict_capacity_limit); + shards_ = reinterpret_cast( + port::cacheline_aligned_alloc(sizeof(LRUCacheShard) * num_shards_)); + size_t per_shard = (capacity + (num_shards_ - 1)) / num_shards_; for (int i = 0; i < num_shards_; i++) { - shards_[i].SetHighPriorityPoolRatio(high_pri_pool_ratio); + new (&shards_[i]) + LRUCacheShard(per_shard, strict_capacity_limit, high_pri_pool_ratio); } } -LRUCache::~LRUCache() { delete[] shards_; } +LRUCache::~LRUCache() { + for (int i = 0; i < num_shards_; i++) { + shards_[i].~LRUCacheShard(); + } + port::cacheline_aligned_free(shards_); +} CacheShard* LRUCache::GetShard(int shard) { return reinterpret_cast(&shards_[shard]); diff --git a/cache/lru_cache.h b/cache/lru_cache.h index b325fb4cf..ac8cb9ee5 100644 --- a/cache/lru_cache.h +++ b/cache/lru_cache.h @@ -156,7 +156,8 @@ class LRUHandleTable { // A single shard of sharded cache. class ALIGN_AS(CACHE_LINE_SIZE) LRUCacheShard : public CacheShard { public: - LRUCacheShard(); + LRUCacheShard(size_t capacity, bool strict_capacity_limit, + double high_pri_pool_ratio); virtual ~LRUCacheShard(); // Separate from constructor so caller can easily make an array of LRUCache @@ -206,13 +207,16 @@ class ALIGN_AS(CACHE_LINE_SIZE) LRUCacheShard : public CacheShard { double GetHighPriPoolRatio(); // Overloading to aligned it to cache line size + // They are used by tests. void* operator new(size_t); - void* operator new[](size_t); + // placement new + void* operator new(size_t, void*); void operator delete(void *); - void operator delete[](void*); + // placement delete, does nothing. + void operator delete(void*, void*); private: void LRU_Remove(LRUHandle* e); diff --git a/cache/lru_cache_test.cc b/cache/lru_cache_test.cc index 1b83033c3..8d0f3ec1b 100644 --- a/cache/lru_cache_test.cc +++ b/cache/lru_cache_test.cc @@ -7,6 +7,7 @@ #include #include +#include "port/port.h" #include "util/testharness.h" namespace rocksdb { @@ -17,19 +18,8 @@ class LRUCacheTest : public testing::Test { ~LRUCacheTest() {} void NewCache(size_t capacity, double high_pri_pool_ratio = 0.0) { - cache_.reset( -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4316) // We've validated the alignment with the new operators -#endif - new LRUCacheShard() -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - ); - cache_->SetCapacity(capacity); - cache_->SetStrictCapacityLimit(false); - cache_->SetHighPriorityPoolRatio(high_pri_pool_ratio); + cache_.reset(new LRUCacheShard(capacity, false /*strict_capcity_limit*/, + high_pri_pool_ratio)); } void Insert(const std::string& key, @@ -114,7 +104,7 @@ TEST_F(LRUCacheTest, BasicLRU) { ValidateLRUList({"e", "z", "d", "u", "v"}); } -TEST_F(LRUCacheTest, MidPointInsertion) { +TEST_F(LRUCacheTest, EntriesWithPriority) { // Allocate 2 cache entries to high-pri pool. NewCache(5, 0.45);