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() {}
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<LRUHandle*> last_reference_list;
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<LRUCacheShard*>(
+ 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<CacheShard*>(&shards_[shard]);
// 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
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);
#include <string>
#include <vector>
+#include "port/port.h"
#include "util/testharness.h"
namespace rocksdb {
~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,
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);