]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/persistent_cache/hash_table_test.cc
1 // Copyright (c) 2013, 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).
11 #include "db/db_test_util.h"
12 #include "util/arena.h"
13 #include "util/random.h"
14 #include "util/testharness.h"
15 #include "utilities/persistent_cache/hash_table.h"
16 #include "utilities/persistent_cache/hash_table_evictable.h"
22 struct HashTableTest
: public testing::Test
{
23 ~HashTableTest() override
{ map_
.Clear(&HashTableTest::ClearNode
); }
27 explicit Node(const uint64_t key
, const std::string
& val
= std::string())
28 : key_(key
), val_(val
) {}
35 bool operator()(const Node
& lhs
, const Node
& rhs
) {
36 return lhs
.key_
== rhs
.key_
;
41 uint64_t operator()(const Node
& node
) {
42 return std::hash
<uint64_t>()(node
.key_
);
46 static void ClearNode(Node
/*node*/) {}
48 HashTable
<Node
, Hash
, Equal
> map_
;
51 struct EvictableHashTableTest
: public testing::Test
{
52 ~EvictableHashTableTest() override
{
53 map_
.Clear(&EvictableHashTableTest::ClearNode
);
56 struct Node
: LRUElement
<Node
> {
58 explicit Node(const uint64_t key
, const std::string
& val
= std::string())
59 : key_(key
), val_(val
) {}
63 std::atomic
<uint32_t> refs_
{0};
67 bool operator()(const Node
* lhs
, const Node
* rhs
) {
68 return lhs
->key_
== rhs
->key_
;
73 uint64_t operator()(const Node
* node
) {
74 return std::hash
<uint64_t>()(node
->key_
);
78 static void ClearNode(Node
* /*node*/) {}
80 EvictableHashTable
<Node
, Hash
, Equal
> map_
;
83 TEST_F(HashTableTest
, TestInsert
) {
84 const uint64_t max_keys
= 1024 * 1024;
87 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
88 map_
.Insert(Node(k
, std::string(1000, k
% 255)));
92 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
94 port::RWMutex
* rlock
= nullptr;
95 assert(map_
.Find(Node(k
), &val
, &rlock
));
97 assert(val
.val_
== std::string(1000, k
% 255));
101 TEST_F(HashTableTest
, TestErase
) {
102 const uint64_t max_keys
= 1024 * 1024;
104 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
105 map_
.Insert(Node(k
, std::string(1000, k
% 255)));
108 auto rand
= Random64(time(nullptr));
109 // erase a few keys randomly
110 std::set
<uint64_t> erased
;
111 for (int i
= 0; i
< 1024; ++i
) {
112 uint64_t k
= rand
.Next() % max_keys
;
113 if (erased
.find(k
) != erased
.end()) {
116 assert(map_
.Erase(Node(k
), /*ret=*/nullptr));
121 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
123 port::RWMutex
* rlock
= nullptr;
124 bool status
= map_
.Find(Node(k
), &val
, &rlock
);
125 if (erased
.find(k
) == erased
.end()) {
128 assert(val
.val_
== std::string(1000, k
% 255));
135 TEST_F(EvictableHashTableTest
, TestEvict
) {
136 const uint64_t max_keys
= 1024 * 1024;
139 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
140 map_
.Insert(new Node(k
, std::string(1000, k
% 255)));
144 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
145 Node
* val
= map_
.Evict();
146 // unfortunately we can't predict eviction value since it is from any one of
149 assert(val
->val_
== std::string(1000, val
->key_
% 255));
154 } // namespace rocksdb
157 int main(int argc
, char** argv
) {
158 ::testing::InitGoogleTest(&argc
, argv
);
159 return RUN_ALL_TESTS();