]>
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).
6 #include "utilities/persistent_cache/hash_table.h"
14 #include "db/db_test_util.h"
15 #include "memory/arena.h"
16 #include "test_util/testharness.h"
17 #include "util/random.h"
18 #include "utilities/persistent_cache/hash_table_evictable.h"
22 namespace ROCKSDB_NAMESPACE
{
24 struct HashTableTest
: public testing::Test
{
25 ~HashTableTest() override
{ map_
.Clear(&HashTableTest::ClearNode
); }
29 explicit Node(const uint64_t key
, const std::string
& val
= std::string())
30 : key_(key
), val_(val
) {}
37 bool operator()(const Node
& lhs
, const Node
& rhs
) {
38 return lhs
.key_
== rhs
.key_
;
43 uint64_t operator()(const Node
& node
) {
44 return std::hash
<uint64_t>()(node
.key_
);
48 static void ClearNode(Node
/*node*/) {}
50 HashTable
<Node
, Hash
, Equal
> map_
;
53 struct EvictableHashTableTest
: public testing::Test
{
54 ~EvictableHashTableTest() override
{
55 map_
.Clear(&EvictableHashTableTest::ClearNode
);
58 struct Node
: LRUElement
<Node
> {
60 explicit Node(const uint64_t key
, const std::string
& val
= std::string())
61 : key_(key
), val_(val
) {}
65 std::atomic
<uint32_t> refs_
{0};
69 bool operator()(const Node
* lhs
, const Node
* rhs
) {
70 return lhs
->key_
== rhs
->key_
;
75 uint64_t operator()(const Node
* node
) {
76 return std::hash
<uint64_t>()(node
->key_
);
80 static void ClearNode(Node
* /*node*/) {}
82 EvictableHashTable
<Node
, Hash
, Equal
> map_
;
85 TEST_F(HashTableTest
, TestInsert
) {
86 const uint64_t max_keys
= 1024 * 1024;
89 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
90 map_
.Insert(Node(k
, std::string(1000, k
% 255)));
94 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
96 port::RWMutex
* rlock
= nullptr;
97 assert(map_
.Find(Node(k
), &val
, &rlock
));
99 assert(val
.val_
== std::string(1000, k
% 255));
103 TEST_F(HashTableTest
, TestErase
) {
104 const uint64_t max_keys
= 1024 * 1024;
106 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
107 map_
.Insert(Node(k
, std::string(1000, k
% 255)));
110 auto rand
= Random64(time(nullptr));
111 // erase a few keys randomly
112 std::set
<uint64_t> erased
;
113 for (int i
= 0; i
< 1024; ++i
) {
114 uint64_t k
= rand
.Next() % max_keys
;
115 if (erased
.find(k
) != erased
.end()) {
118 assert(map_
.Erase(Node(k
), /*ret=*/nullptr));
123 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
125 port::RWMutex
* rlock
= nullptr;
126 bool status
= map_
.Find(Node(k
), &val
, &rlock
);
127 if (erased
.find(k
) == erased
.end()) {
130 assert(val
.val_
== std::string(1000, k
% 255));
137 TEST_F(EvictableHashTableTest
, TestEvict
) {
138 const uint64_t max_keys
= 1024 * 1024;
141 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
142 map_
.Insert(new Node(k
, std::string(1000, k
% 255)));
146 for (uint64_t k
= 0; k
< max_keys
; ++k
) {
147 Node
* val
= map_
.Evict();
148 // unfortunately we can't predict eviction value since it is from any one of
151 assert(val
->val_
== std::string(1000, val
->key_
% 255));
156 } // namespace ROCKSDB_NAMESPACE
159 int main(int argc
, char** argv
) {
160 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
161 ::testing::InitGoogleTest(&argc
, argv
);
162 return RUN_ALL_TESTS();