]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/simulator_cache/cache_simulator_test.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rocksdb / utilities / simulator_cache / cache_simulator_test.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
5
6 #include "utilities/simulator_cache/cache_simulator.h"
7
8 #include <cstdlib>
9 #include "rocksdb/env.h"
10 #include "test_util/testharness.h"
11 #include "test_util/testutil.h"
12
13 namespace ROCKSDB_NAMESPACE {
14 namespace {
15 const std::string kBlockKeyPrefix = "test-block-";
16 const std::string kRefKeyPrefix = "test-get-";
17 const std::string kRefKeySequenceNumber = std::string(8, 'c');
18 const uint64_t kGetId = 1;
19 const uint64_t kGetBlockId = 100;
20 const uint64_t kCompactionBlockId = 1000;
21 const uint64_t kCacheSize = 1024 * 1024 * 1024;
22 const uint64_t kGhostCacheSize = 1024 * 1024;
23 } // namespace
24
25 class CacheSimulatorTest : public testing::Test {
26 public:
27 const size_t kNumBlocks = 5;
28 const size_t kValueSize = 1000;
29
30 CacheSimulatorTest() { env_ = ROCKSDB_NAMESPACE::Env::Default(); }
31
32 BlockCacheTraceRecord GenerateGetRecord(uint64_t getid) {
33 BlockCacheTraceRecord record;
34 record.block_type = TraceType::kBlockTraceDataBlock;
35 record.block_size = 4096;
36 record.block_key = kBlockKeyPrefix + std::to_string(kGetBlockId);
37 record.access_timestamp = env_->NowMicros();
38 record.cf_id = 0;
39 record.cf_name = "test";
40 record.caller = TableReaderCaller::kUserGet;
41 record.level = 6;
42 record.sst_fd_number = 0;
43 record.get_id = getid;
44 record.is_cache_hit = Boolean::kFalse;
45 record.no_insert = Boolean::kFalse;
46 record.referenced_key =
47 kRefKeyPrefix + std::to_string(kGetId) + kRefKeySequenceNumber;
48 record.referenced_key_exist_in_block = Boolean::kTrue;
49 record.referenced_data_size = 100;
50 record.num_keys_in_block = 300;
51 return record;
52 }
53
54 BlockCacheTraceRecord GenerateCompactionRecord() {
55 BlockCacheTraceRecord record;
56 record.block_type = TraceType::kBlockTraceDataBlock;
57 record.block_size = 4096;
58 record.block_key = kBlockKeyPrefix + std::to_string(kCompactionBlockId);
59 record.access_timestamp = env_->NowMicros();
60 record.cf_id = 0;
61 record.cf_name = "test";
62 record.caller = TableReaderCaller::kCompaction;
63 record.level = 6;
64 record.sst_fd_number = kCompactionBlockId;
65 record.is_cache_hit = Boolean::kFalse;
66 record.no_insert = Boolean::kTrue;
67 return record;
68 }
69
70 void AssertCache(std::shared_ptr<Cache> sim_cache,
71 const MissRatioStats& miss_ratio_stats,
72 uint64_t expected_usage, uint64_t expected_num_accesses,
73 uint64_t expected_num_misses,
74 std::vector<std::string> blocks,
75 std::vector<std::string> keys) {
76 EXPECT_EQ(expected_usage, sim_cache->GetUsage());
77 EXPECT_EQ(expected_num_accesses, miss_ratio_stats.total_accesses());
78 EXPECT_EQ(expected_num_misses, miss_ratio_stats.total_misses());
79 for (auto const& block : blocks) {
80 auto handle = sim_cache->Lookup(block);
81 EXPECT_NE(nullptr, handle);
82 sim_cache->Release(handle);
83 }
84 for (auto const& key : keys) {
85 std::string row_key = kRefKeyPrefix + key + kRefKeySequenceNumber;
86 auto handle =
87 sim_cache->Lookup("0_" + ExtractUserKey(row_key).ToString());
88 EXPECT_NE(nullptr, handle);
89 sim_cache->Release(handle);
90 }
91 }
92
93 Env* env_;
94 };
95
96 TEST_F(CacheSimulatorTest, GhostCache) {
97 const std::string key1 = "test1";
98 const std::string key2 = "test2";
99 std::unique_ptr<GhostCache> ghost_cache(new GhostCache(
100 NewLRUCache(/*capacity=*/kGhostCacheSize, /*num_shard_bits=*/1,
101 /*strict_capacity_limit=*/false,
102 /*high_pri_pool_ratio=*/0)));
103 EXPECT_FALSE(ghost_cache->Admit(key1));
104 EXPECT_TRUE(ghost_cache->Admit(key1));
105 EXPECT_TRUE(ghost_cache->Admit(key1));
106 EXPECT_FALSE(ghost_cache->Admit(key2));
107 EXPECT_TRUE(ghost_cache->Admit(key2));
108 }
109
110 TEST_F(CacheSimulatorTest, CacheSimulator) {
111 const BlockCacheTraceRecord& access = GenerateGetRecord(kGetId);
112 const BlockCacheTraceRecord& compaction_access = GenerateCompactionRecord();
113 std::shared_ptr<Cache> sim_cache =
114 NewLRUCache(/*capacity=*/kCacheSize, /*num_shard_bits=*/1,
115 /*strict_capacity_limit=*/false,
116 /*high_pri_pool_ratio=*/0);
117 std::unique_ptr<CacheSimulator> cache_simulator(
118 new CacheSimulator(nullptr, sim_cache));
119 cache_simulator->Access(access);
120 cache_simulator->Access(access);
121 ASSERT_EQ(2, cache_simulator->miss_ratio_stats().total_accesses());
122 ASSERT_EQ(50, cache_simulator->miss_ratio_stats().miss_ratio());
123 ASSERT_EQ(2, cache_simulator->miss_ratio_stats().user_accesses());
124 ASSERT_EQ(50, cache_simulator->miss_ratio_stats().user_miss_ratio());
125
126 cache_simulator->Access(compaction_access);
127 cache_simulator->Access(compaction_access);
128 ASSERT_EQ(4, cache_simulator->miss_ratio_stats().total_accesses());
129 ASSERT_EQ(75, cache_simulator->miss_ratio_stats().miss_ratio());
130 ASSERT_EQ(2, cache_simulator->miss_ratio_stats().user_accesses());
131 ASSERT_EQ(50, cache_simulator->miss_ratio_stats().user_miss_ratio());
132
133 cache_simulator->reset_counter();
134 ASSERT_EQ(0, cache_simulator->miss_ratio_stats().total_accesses());
135 ASSERT_EQ(-1, cache_simulator->miss_ratio_stats().miss_ratio());
136 auto handle = sim_cache->Lookup(access.block_key);
137 ASSERT_NE(nullptr, handle);
138 sim_cache->Release(handle);
139 handle = sim_cache->Lookup(compaction_access.block_key);
140 ASSERT_EQ(nullptr, handle);
141 }
142
143 TEST_F(CacheSimulatorTest, GhostCacheSimulator) {
144 const BlockCacheTraceRecord& access = GenerateGetRecord(kGetId);
145 std::unique_ptr<GhostCache> ghost_cache(new GhostCache(
146 NewLRUCache(/*capacity=*/kGhostCacheSize, /*num_shard_bits=*/1,
147 /*strict_capacity_limit=*/false,
148 /*high_pri_pool_ratio=*/0)));
149 std::unique_ptr<CacheSimulator> cache_simulator(new CacheSimulator(
150 std::move(ghost_cache),
151 NewLRUCache(/*capacity=*/kCacheSize, /*num_shard_bits=*/1,
152 /*strict_capacity_limit=*/false,
153 /*high_pri_pool_ratio=*/0)));
154 cache_simulator->Access(access);
155 cache_simulator->Access(access);
156 ASSERT_EQ(2, cache_simulator->miss_ratio_stats().total_accesses());
157 // Both of them will be miss since we have a ghost cache.
158 ASSERT_EQ(100, cache_simulator->miss_ratio_stats().miss_ratio());
159 }
160
161 TEST_F(CacheSimulatorTest, PrioritizedCacheSimulator) {
162 const BlockCacheTraceRecord& access = GenerateGetRecord(kGetId);
163 std::shared_ptr<Cache> sim_cache =
164 NewLRUCache(/*capacity=*/kCacheSize, /*num_shard_bits=*/1,
165 /*strict_capacity_limit=*/false,
166 /*high_pri_pool_ratio=*/0);
167 std::unique_ptr<PrioritizedCacheSimulator> cache_simulator(
168 new PrioritizedCacheSimulator(nullptr, sim_cache));
169 cache_simulator->Access(access);
170 cache_simulator->Access(access);
171 ASSERT_EQ(2, cache_simulator->miss_ratio_stats().total_accesses());
172 ASSERT_EQ(50, cache_simulator->miss_ratio_stats().miss_ratio());
173
174 auto handle = sim_cache->Lookup(access.block_key);
175 ASSERT_NE(nullptr, handle);
176 sim_cache->Release(handle);
177 }
178
179 TEST_F(CacheSimulatorTest, GhostPrioritizedCacheSimulator) {
180 const BlockCacheTraceRecord& access = GenerateGetRecord(kGetId);
181 std::unique_ptr<GhostCache> ghost_cache(new GhostCache(
182 NewLRUCache(/*capacity=*/kGhostCacheSize, /*num_shard_bits=*/1,
183 /*strict_capacity_limit=*/false,
184 /*high_pri_pool_ratio=*/0)));
185 std::unique_ptr<PrioritizedCacheSimulator> cache_simulator(
186 new PrioritizedCacheSimulator(
187 std::move(ghost_cache),
188 NewLRUCache(/*capacity=*/kCacheSize, /*num_shard_bits=*/1,
189 /*strict_capacity_limit=*/false,
190 /*high_pri_pool_ratio=*/0)));
191 cache_simulator->Access(access);
192 cache_simulator->Access(access);
193 ASSERT_EQ(2, cache_simulator->miss_ratio_stats().total_accesses());
194 // Both of them will be miss since we have a ghost cache.
195 ASSERT_EQ(100, cache_simulator->miss_ratio_stats().miss_ratio());
196 }
197
198 TEST_F(CacheSimulatorTest, HybridRowBlockCacheSimulator) {
199 uint64_t block_id = 100;
200 BlockCacheTraceRecord first_get = GenerateGetRecord(kGetId);
201 first_get.get_from_user_specified_snapshot = Boolean::kTrue;
202 BlockCacheTraceRecord second_get = GenerateGetRecord(kGetId + 1);
203 second_get.referenced_data_size = 0;
204 second_get.referenced_key_exist_in_block = Boolean::kFalse;
205 second_get.get_from_user_specified_snapshot = Boolean::kTrue;
206 BlockCacheTraceRecord third_get = GenerateGetRecord(kGetId + 2);
207 third_get.referenced_data_size = 0;
208 third_get.referenced_key_exist_in_block = Boolean::kFalse;
209 third_get.referenced_key = kRefKeyPrefix + "third_get";
210 // We didn't find the referenced key in the third get.
211 third_get.referenced_key_exist_in_block = Boolean::kFalse;
212 third_get.referenced_data_size = 0;
213 std::shared_ptr<Cache> sim_cache =
214 NewLRUCache(/*capacity=*/kCacheSize, /*num_shard_bits=*/1,
215 /*strict_capacity_limit=*/false,
216 /*high_pri_pool_ratio=*/0);
217 std::unique_ptr<HybridRowBlockCacheSimulator> cache_simulator(
218 new HybridRowBlockCacheSimulator(
219 nullptr, sim_cache, /*insert_blocks_row_kvpair_misses=*/true));
220 // The first get request accesses 10 blocks. We should only report 10 accesses
221 // and 100% miss.
222 for (uint32_t i = 0; i < 10; i++) {
223 first_get.block_key = kBlockKeyPrefix + std::to_string(block_id);
224 cache_simulator->Access(first_get);
225 block_id++;
226 }
227
228 ASSERT_EQ(10, cache_simulator->miss_ratio_stats().total_accesses());
229 ASSERT_EQ(100, cache_simulator->miss_ratio_stats().miss_ratio());
230 ASSERT_EQ(10, cache_simulator->miss_ratio_stats().user_accesses());
231 ASSERT_EQ(100, cache_simulator->miss_ratio_stats().user_miss_ratio());
232 auto handle =
233 sim_cache->Lookup(std::to_string(first_get.sst_fd_number) + "_" +
234 ExtractUserKey(first_get.referenced_key).ToString());
235 ASSERT_NE(nullptr, handle);
236 sim_cache->Release(handle);
237 for (uint32_t i = 100; i < block_id; i++) {
238 handle = sim_cache->Lookup(kBlockKeyPrefix + std::to_string(i));
239 ASSERT_NE(nullptr, handle);
240 sim_cache->Release(handle);
241 }
242
243 // The second get request accesses the same key. We should report 15
244 // access and 66% miss, 10 misses with 15 accesses.
245 // We do not consider these 5 block lookups as misses since the row hits the
246 // cache.
247 for (uint32_t i = 0; i < 5; i++) {
248 second_get.block_key = kBlockKeyPrefix + std::to_string(block_id);
249 cache_simulator->Access(second_get);
250 block_id++;
251 }
252 ASSERT_EQ(15, cache_simulator->miss_ratio_stats().total_accesses());
253 ASSERT_EQ(66, static_cast<uint64_t>(
254 cache_simulator->miss_ratio_stats().miss_ratio()));
255 ASSERT_EQ(15, cache_simulator->miss_ratio_stats().user_accesses());
256 ASSERT_EQ(66, static_cast<uint64_t>(
257 cache_simulator->miss_ratio_stats().user_miss_ratio()));
258 handle =
259 sim_cache->Lookup(std::to_string(second_get.sst_fd_number) + "_" +
260 ExtractUserKey(second_get.referenced_key).ToString());
261 ASSERT_NE(nullptr, handle);
262 sim_cache->Release(handle);
263 for (uint32_t i = 100; i < block_id; i++) {
264 handle = sim_cache->Lookup(kBlockKeyPrefix + std::to_string(i));
265 if (i < 110) {
266 ASSERT_NE(nullptr, handle) << i;
267 sim_cache->Release(handle);
268 } else {
269 ASSERT_EQ(nullptr, handle) << i;
270 }
271 }
272
273 // The third get on a different key and does not have a size.
274 // This key should not be inserted into the cache.
275 for (uint32_t i = 0; i < 5; i++) {
276 third_get.block_key = kBlockKeyPrefix + std::to_string(block_id);
277 cache_simulator->Access(third_get);
278 block_id++;
279 }
280 ASSERT_EQ(20, cache_simulator->miss_ratio_stats().total_accesses());
281 ASSERT_EQ(75, static_cast<uint64_t>(
282 cache_simulator->miss_ratio_stats().miss_ratio()));
283 ASSERT_EQ(20, cache_simulator->miss_ratio_stats().user_accesses());
284 ASSERT_EQ(75, static_cast<uint64_t>(
285 cache_simulator->miss_ratio_stats().user_miss_ratio()));
286 // Assert that the third key is not inserted into the cache.
287 handle = sim_cache->Lookup(std::to_string(third_get.sst_fd_number) + "_" +
288 third_get.referenced_key);
289 ASSERT_EQ(nullptr, handle);
290 for (uint32_t i = 100; i < block_id; i++) {
291 if (i < 110 || i >= 115) {
292 handle = sim_cache->Lookup(kBlockKeyPrefix + std::to_string(i));
293 ASSERT_NE(nullptr, handle) << i;
294 sim_cache->Release(handle);
295 } else {
296 handle = sim_cache->Lookup(kBlockKeyPrefix + std::to_string(i));
297 ASSERT_EQ(nullptr, handle) << i;
298 }
299 }
300 }
301
302 TEST_F(CacheSimulatorTest, HybridRowBlockCacheSimulatorGetTest) {
303 BlockCacheTraceRecord get = GenerateGetRecord(kGetId);
304 get.block_size = 1;
305 get.referenced_data_size = 0;
306 get.access_timestamp = 0;
307 get.block_key = "1";
308 get.get_id = 1;
309 get.get_from_user_specified_snapshot = Boolean::kFalse;
310 get.referenced_key =
311 kRefKeyPrefix + std::to_string(1) + kRefKeySequenceNumber;
312 get.no_insert = Boolean::kFalse;
313 get.sst_fd_number = 0;
314 get.get_from_user_specified_snapshot = Boolean::kFalse;
315
316 LRUCacheOptions co;
317 co.capacity = 16;
318 co.num_shard_bits = 1;
319 co.strict_capacity_limit = false;
320 co.high_pri_pool_ratio = 0;
321 co.metadata_charge_policy = kDontChargeCacheMetadata;
322 std::shared_ptr<Cache> sim_cache = NewLRUCache(co);
323 std::unique_ptr<HybridRowBlockCacheSimulator> cache_simulator(
324 new HybridRowBlockCacheSimulator(
325 nullptr, sim_cache, /*insert_blocks_row_kvpair_misses=*/true));
326 // Expect a miss and does not insert the row key-value pair since it does not
327 // have size.
328 cache_simulator->Access(get);
329 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 1, 1, 1, {"1"},
330 {});
331 get.access_timestamp += 1;
332 get.referenced_data_size = 1;
333 get.block_key = "2";
334 cache_simulator->Access(get);
335 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 3, 2, 2,
336 {"1", "2"}, {"1"});
337 get.access_timestamp += 1;
338 get.block_key = "3";
339 // K1 should not inserted again.
340 cache_simulator->Access(get);
341 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 4, 3, 3,
342 {"1", "2", "3"}, {"1"});
343
344 // A second get request referencing the same key.
345 get.access_timestamp += 1;
346 get.get_id = 2;
347 get.block_key = "4";
348 get.referenced_data_size = 0;
349 cache_simulator->Access(get);
350 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 4, 4, 3,
351 {"1", "2", "3"}, {"1"});
352
353 // A third get request searches three files, three different keys.
354 // And the second key observes a hit.
355 get.access_timestamp += 1;
356 get.referenced_data_size = 1;
357 get.get_id = 3;
358 get.block_key = "3";
359 get.referenced_key = kRefKeyPrefix + "2" + kRefKeySequenceNumber;
360 // K2 should observe a miss. Block 3 observes a hit.
361 cache_simulator->Access(get);
362 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 5, 5, 3,
363 {"1", "2", "3"}, {"1", "2"});
364
365 get.access_timestamp += 1;
366 get.referenced_data_size = 1;
367 get.get_id = 3;
368 get.block_key = "4";
369 get.referenced_data_size = 1;
370 get.referenced_key = kRefKeyPrefix + "1" + kRefKeySequenceNumber;
371 // K1 should observe a hit.
372 cache_simulator->Access(get);
373 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 5, 6, 3,
374 {"1", "2", "3"}, {"1", "2"});
375
376 get.access_timestamp += 1;
377 get.referenced_data_size = 1;
378 get.get_id = 3;
379 get.block_key = "4";
380 get.referenced_data_size = 1;
381 get.referenced_key = kRefKeyPrefix + "3" + kRefKeySequenceNumber;
382 // K3 should observe a miss.
383 // However, as the get already complete, we should not access k3 any more.
384 cache_simulator->Access(get);
385 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 5, 7, 3,
386 {"1", "2", "3"}, {"1", "2"});
387
388 // A fourth get request searches one file and two blocks. One row key.
389 get.access_timestamp += 1;
390 get.get_id = 4;
391 get.block_key = "5";
392 get.referenced_key = kRefKeyPrefix + "4" + kRefKeySequenceNumber;
393 get.referenced_data_size = 1;
394 cache_simulator->Access(get);
395 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 7, 8, 4,
396 {"1", "2", "3", "5"}, {"1", "2", "4"});
397 for (auto const& key : {"1", "2", "4"}) {
398 auto handle = sim_cache->Lookup("0_" + kRefKeyPrefix + key);
399 ASSERT_NE(nullptr, handle);
400 sim_cache->Release(handle);
401 }
402
403 // A bunch of insertions which evict cached row keys.
404 for (uint32_t i = 6; i < 100; i++) {
405 get.access_timestamp += 1;
406 get.get_id = 0;
407 get.block_key = std::to_string(i);
408 cache_simulator->Access(get);
409 }
410
411 get.get_id = 4;
412 // A different block.
413 get.block_key = "100";
414 // Same row key and should not be inserted again.
415 get.referenced_key = kRefKeyPrefix + "4" + kRefKeySequenceNumber;
416 get.referenced_data_size = 1;
417 cache_simulator->Access(get);
418 AssertCache(sim_cache, cache_simulator->miss_ratio_stats(), 16, 103, 99, {},
419 {});
420 for (auto const& key : {"1", "2", "4"}) {
421 auto handle = sim_cache->Lookup("0_" + kRefKeyPrefix + key);
422 ASSERT_EQ(nullptr, handle);
423 }
424 }
425
426 TEST_F(CacheSimulatorTest, HybridRowBlockNoInsertCacheSimulator) {
427 uint64_t block_id = 100;
428 BlockCacheTraceRecord first_get = GenerateGetRecord(kGetId);
429 std::shared_ptr<Cache> sim_cache =
430 NewLRUCache(/*capacity=*/kCacheSize, /*num_shard_bits=*/1,
431 /*strict_capacity_limit=*/false,
432 /*high_pri_pool_ratio=*/0);
433 std::unique_ptr<HybridRowBlockCacheSimulator> cache_simulator(
434 new HybridRowBlockCacheSimulator(
435 nullptr, sim_cache, /*insert_blocks_row_kvpair_misses=*/false));
436 for (uint32_t i = 0; i < 9; i++) {
437 first_get.block_key = kBlockKeyPrefix + std::to_string(block_id);
438 cache_simulator->Access(first_get);
439 block_id++;
440 }
441 auto handle =
442 sim_cache->Lookup(std::to_string(first_get.sst_fd_number) + "_" +
443 ExtractUserKey(first_get.referenced_key).ToString());
444 ASSERT_NE(nullptr, handle);
445 sim_cache->Release(handle);
446 // All blocks are missing from the cache since insert_blocks_row_kvpair_misses
447 // is set to false.
448 for (uint32_t i = 100; i < block_id; i++) {
449 handle = sim_cache->Lookup(kBlockKeyPrefix + std::to_string(i));
450 ASSERT_EQ(nullptr, handle);
451 }
452 }
453
454 TEST_F(CacheSimulatorTest, GhostHybridRowBlockCacheSimulator) {
455 std::unique_ptr<GhostCache> ghost_cache(new GhostCache(
456 NewLRUCache(/*capacity=*/kGhostCacheSize, /*num_shard_bits=*/1,
457 /*strict_capacity_limit=*/false,
458 /*high_pri_pool_ratio=*/0)));
459 const BlockCacheTraceRecord& first_get = GenerateGetRecord(kGetId);
460 const BlockCacheTraceRecord& second_get = GenerateGetRecord(kGetId + 1);
461 const BlockCacheTraceRecord& third_get = GenerateGetRecord(kGetId + 2);
462 std::unique_ptr<HybridRowBlockCacheSimulator> cache_simulator(
463 new HybridRowBlockCacheSimulator(
464 std::move(ghost_cache),
465 NewLRUCache(/*capacity=*/kCacheSize, /*num_shard_bits=*/1,
466 /*strict_capacity_limit=*/false,
467 /*high_pri_pool_ratio=*/0),
468 /*insert_blocks_row_kvpair_misses=*/false));
469 // Two get requests access the same key.
470 cache_simulator->Access(first_get);
471 cache_simulator->Access(second_get);
472 ASSERT_EQ(2, cache_simulator->miss_ratio_stats().total_accesses());
473 ASSERT_EQ(100, cache_simulator->miss_ratio_stats().miss_ratio());
474 ASSERT_EQ(2, cache_simulator->miss_ratio_stats().user_accesses());
475 ASSERT_EQ(100, cache_simulator->miss_ratio_stats().user_miss_ratio());
476 // We insert the key-value pair upon the second get request. A third get
477 // request should observe a hit.
478 for (uint32_t i = 0; i < 10; i++) {
479 cache_simulator->Access(third_get);
480 }
481 ASSERT_EQ(12, cache_simulator->miss_ratio_stats().total_accesses());
482 ASSERT_EQ(16, static_cast<uint64_t>(
483 cache_simulator->miss_ratio_stats().miss_ratio()));
484 ASSERT_EQ(12, cache_simulator->miss_ratio_stats().user_accesses());
485 ASSERT_EQ(16, static_cast<uint64_t>(
486 cache_simulator->miss_ratio_stats().user_miss_ratio()));
487 }
488
489 } // namespace ROCKSDB_NAMESPACE
490
491 int main(int argc, char** argv) {
492 ::testing::InitGoogleTest(&argc, argv);
493 return RUN_ALL_TESTS();
494 }