]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/cache/lru_cache_test.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
6 #include "cache/lru_cache.h"
10 #include "util/testharness.h"
14 class LRUCacheTest
: public testing::Test
{
19 void NewCache(size_t capacity
, double high_pri_pool_ratio
= 0.0) {
20 cache_
.reset(new LRUCacheShard());
21 cache_
->SetCapacity(capacity
);
22 cache_
->SetStrictCapacityLimit(false);
23 cache_
->SetHighPriorityPoolRatio(high_pri_pool_ratio
);
26 void Insert(const std::string
& key
,
27 Cache::Priority priority
= Cache::Priority::LOW
) {
28 cache_
->Insert(key
, 0 /*hash*/, nullptr /*value*/, 1 /*charge*/,
29 nullptr /*deleter*/, nullptr /*handle*/, priority
);
32 void Insert(char key
, Cache::Priority priority
= Cache::Priority::LOW
) {
33 Insert(std::string(1, key
), priority
);
36 bool Lookup(const std::string
& key
) {
37 auto handle
= cache_
->Lookup(key
, 0 /*hash*/);
39 cache_
->Release(handle
);
45 bool Lookup(char key
) { return Lookup(std::string(1, key
)); }
47 void Erase(const std::string
& key
) { cache_
->Erase(key
, 0 /*hash*/); }
49 void ValidateLRUList(std::vector
<std::string
> keys
,
50 size_t num_high_pri_pool_keys
= 0) {
52 LRUHandle
* lru_low_pri
;
53 cache_
->TEST_GetLRUList(&lru
, &lru_low_pri
);
54 LRUHandle
* iter
= lru
;
55 bool in_high_pri_pool
= false;
56 size_t high_pri_pool_keys
= 0;
57 if (iter
== lru_low_pri
) {
58 in_high_pri_pool
= true;
60 for (const auto& key
: keys
) {
63 ASSERT_EQ(key
, iter
->key().ToString());
64 ASSERT_EQ(in_high_pri_pool
, iter
->InHighPriPool());
65 if (in_high_pri_pool
) {
68 if (iter
== lru_low_pri
) {
69 ASSERT_FALSE(in_high_pri_pool
);
70 in_high_pri_pool
= true;
73 ASSERT_EQ(lru
, iter
->next
);
74 ASSERT_TRUE(in_high_pri_pool
);
75 ASSERT_EQ(num_high_pri_pool_keys
, high_pri_pool_keys
);
79 std::unique_ptr
<LRUCacheShard
> cache_
;
82 TEST_F(LRUCacheTest
, BasicLRU
) {
84 for (char ch
= 'a'; ch
<= 'e'; ch
++) {
87 ValidateLRUList({"a", "b", "c", "d", "e"});
88 for (char ch
= 'x'; ch
<= 'z'; ch
++) {
91 ValidateLRUList({"d", "e", "x", "y", "z"});
92 ASSERT_FALSE(Lookup("b"));
93 ValidateLRUList({"d", "e", "x", "y", "z"});
94 ASSERT_TRUE(Lookup("e"));
95 ValidateLRUList({"d", "x", "y", "z", "e"});
96 ASSERT_TRUE(Lookup("z"));
97 ValidateLRUList({"d", "x", "y", "e", "z"});
99 ValidateLRUList({"d", "y", "e", "z"});
100 ASSERT_TRUE(Lookup("d"));
101 ValidateLRUList({"y", "e", "z", "d"});
103 ValidateLRUList({"y", "e", "z", "d", "u"});
105 ValidateLRUList({"e", "z", "d", "u", "v"});
108 TEST_F(LRUCacheTest
, MidPointInsertion
) {
109 // Allocate 2 cache entries to high-pri pool.
112 Insert("a", Cache::Priority::LOW
);
113 Insert("b", Cache::Priority::LOW
);
114 Insert("c", Cache::Priority::LOW
);
115 ValidateLRUList({"a", "b", "c"}, 0);
117 // Low-pri entries can take high-pri pool capacity if available
118 Insert("u", Cache::Priority::LOW
);
119 Insert("v", Cache::Priority::LOW
);
120 ValidateLRUList({"a", "b", "c", "u", "v"}, 0);
122 Insert("X", Cache::Priority::HIGH
);
123 Insert("Y", Cache::Priority::HIGH
);
124 ValidateLRUList({"c", "u", "v", "X", "Y"}, 2);
126 // High-pri entries can overflow to low-pri pool.
127 Insert("Z", Cache::Priority::HIGH
);
128 ValidateLRUList({"u", "v", "X", "Y", "Z"}, 2);
130 // Low-pri entries will be inserted to head of low-pri pool.
131 Insert("a", Cache::Priority::LOW
);
132 ValidateLRUList({"v", "X", "a", "Y", "Z"}, 2);
134 // Low-pri entries will be inserted to head of low-pri pool after lookup.
135 ASSERT_TRUE(Lookup("v"));
136 ValidateLRUList({"X", "a", "v", "Y", "Z"}, 2);
138 // High-pri entries will be inserted to the head of the list after lookup.
139 ASSERT_TRUE(Lookup("X"));
140 ValidateLRUList({"a", "v", "Y", "Z", "X"}, 2);
141 ASSERT_TRUE(Lookup("Z"));
142 ValidateLRUList({"a", "v", "Y", "X", "Z"}, 2);
145 ValidateLRUList({"a", "v", "X", "Z"}, 2);
147 ValidateLRUList({"a", "v", "Z"}, 1);
148 Insert("d", Cache::Priority::LOW
);
149 Insert("e", Cache::Priority::LOW
);
150 ValidateLRUList({"a", "v", "d", "e", "Z"}, 1);
151 Insert("f", Cache::Priority::LOW
);
152 Insert("g", Cache::Priority::LOW
);
153 ValidateLRUList({"d", "e", "f", "g", "Z"}, 1);
154 ASSERT_TRUE(Lookup("d"));
155 ValidateLRUList({"e", "f", "g", "d", "Z"}, 1);
158 } // namespace rocksdb
160 int main(int argc
, char** argv
) {
161 ::testing::InitGoogleTest(&argc
, argv
);
162 return RUN_ALL_TESTS();