YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/db/db_block_cache_test.cc
Line
Count
Source
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.
5
//
6
// The following only applies to changes made to this file as part of YugaByte development.
7
//
8
// Portions Copyright (c) YugaByte, Inc.
9
//
10
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
11
// in compliance with the License.  You may obtain a copy of the License at
12
//
13
// http://www.apache.org/licenses/LICENSE-2.0
14
//
15
// Unless required by applicable law or agreed to in writing, software distributed under the License
16
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17
// or implied.  See the License for the specific language governing permissions and limitations
18
// under the License.
19
//
20
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
21
// Use of this source code is governed by a BSD-style license that can be
22
// found in the LICENSE file. See the AUTHORS file for names of contributors.
23
#include "yb/rocksdb/db/db_test_util.h"
24
#include "yb/rocksdb/port/stack_trace.h"
25
26
DECLARE_double(cache_single_touch_ratio);
27
DECLARE_bool(cache_overflow_single_touch);
28
29
namespace rocksdb {
30
31
class DBBlockCacheTest : public DBTestBase {
32
 private:
33
  size_t miss_count_ = 0;
34
  size_t hit_count_ = 0;
35
  size_t insert_count_ = 0;
36
  size_t failure_count_ = 0;
37
  size_t compressed_miss_count_ = 0;
38
  size_t compressed_hit_count_ = 0;
39
  size_t compressed_insert_count_ = 0;
40
  size_t compressed_failure_count_ = 0;
41
42
 public:
43
  const size_t kNumBlocks = 10;
44
  const size_t kValueSize = 100;
45
46
2
  DBBlockCacheTest() : DBTestBase("/db_block_cache_test") {}
47
48
2
  BlockBasedTableOptions GetTableOptions() {
49
2
    BlockBasedTableOptions table_options;
50
    // Set a small enough block size so that each key-value get its own block.
51
2
    table_options.block_size = 1;
52
2
    return table_options;
53
2
  }
54
55
2
  Options GetOptions(const BlockBasedTableOptions& table_options) {
56
2
    Options options = CurrentOptions();
57
2
    options.create_if_missing = true;
58
    // options.compression = kNoCompression;
59
2
    options.statistics = rocksdb::CreateDBStatisticsForTests();
60
2
    options.table_factory.reset(new BlockBasedTableFactory(table_options));
61
2
    return options;
62
2
  }
63
64
2
  void InitTable(const Options& options) {
65
2
    std::string value(kValueSize, 'a');
66
22
    for (size_t i = 0; i < kNumBlocks; i++) {
67
20
      ASSERT_OK(Put(ToString(i), value.c_str()));
68
20
    }
69
2
  }
70
71
2
  void RecordCacheCounters(const Options& options) {
72
2
    miss_count_ = TestGetTickerCount(options, BLOCK_CACHE_MISS);
73
2
    hit_count_ = TestGetTickerCount(options, BLOCK_CACHE_HIT);
74
2
    insert_count_ = TestGetTickerCount(options, BLOCK_CACHE_ADD);
75
2
    failure_count_ = TestGetTickerCount(options, BLOCK_CACHE_ADD_FAILURES);
76
2
    compressed_miss_count_ =
77
2
        TestGetTickerCount(options, BLOCK_CACHE_COMPRESSED_MISS);
78
2
    compressed_hit_count_ =
79
2
        TestGetTickerCount(options, BLOCK_CACHE_COMPRESSED_HIT);
80
2
    compressed_insert_count_ =
81
2
        TestGetTickerCount(options, BLOCK_CACHE_COMPRESSED_ADD);
82
2
    compressed_failure_count_ =
83
2
        TestGetTickerCount(options, BLOCK_CACHE_COMPRESSED_ADD_FAILURES);
84
2
  }
85
86
  void CheckCacheCounters(const Options& options, size_t expected_misses,
87
                          size_t expected_hits, size_t expected_inserts,
88
36
                          size_t expected_failures) {
89
36
    size_t new_miss_count = TestGetTickerCount(options, BLOCK_CACHE_MISS);
90
36
    size_t new_hit_count = TestGetTickerCount(options, BLOCK_CACHE_HIT);
91
36
    size_t new_st_hit_count = TestGetTickerCount(options, BLOCK_CACHE_SINGLE_TOUCH_HIT);
92
36
    size_t new_mt_hit_count = TestGetTickerCount(options, BLOCK_CACHE_MULTI_TOUCH_HIT);
93
36
    size_t new_insert_count = TestGetTickerCount(options, BLOCK_CACHE_ADD);
94
36
    size_t new_st_insert_count = TestGetTickerCount(options, BLOCK_CACHE_SINGLE_TOUCH_ADD);
95
36
    size_t new_mt_insert_count = TestGetTickerCount(options, BLOCK_CACHE_MULTI_TOUCH_ADD);
96
36
    size_t new_failure_count =
97
36
        TestGetTickerCount(options, BLOCK_CACHE_ADD_FAILURES);
98
36
    ASSERT_EQ(miss_count_ + expected_misses, new_miss_count);
99
36
    ASSERT_EQ(hit_count_ + expected_hits, new_hit_count);
100
36
    ASSERT_EQ(new_st_hit_count + new_mt_hit_count, new_hit_count);
101
36
    ASSERT_EQ(insert_count_ + expected_inserts, new_insert_count);
102
36
    ASSERT_EQ(new_st_insert_count + new_mt_insert_count, new_insert_count);
103
36
    ASSERT_EQ(failure_count_ + expected_failures, new_failure_count);
104
36
    miss_count_ = new_miss_count;
105
36
    hit_count_ = new_hit_count;
106
36
    insert_count_ = new_insert_count;
107
36
    failure_count_ = new_failure_count;
108
36
  }
109
110
  void CheckCompressedCacheCounters(const Options& options,
111
                                    size_t expected_misses,
112
                                    size_t expected_hits,
113
                                    size_t expected_inserts,
114
9
                                    size_t expected_failures) {
115
9
    size_t new_miss_count =
116
9
        TestGetTickerCount(options, BLOCK_CACHE_COMPRESSED_MISS);
117
9
    size_t new_hit_count =
118
9
        TestGetTickerCount(options, BLOCK_CACHE_COMPRESSED_HIT);
119
9
    size_t new_insert_count =
120
9
        TestGetTickerCount(options, BLOCK_CACHE_COMPRESSED_ADD);
121
9
    size_t new_failure_count =
122
9
        TestGetTickerCount(options, BLOCK_CACHE_COMPRESSED_ADD_FAILURES);
123
9
    ASSERT_EQ(compressed_miss_count_ + expected_misses, new_miss_count);
124
9
    ASSERT_EQ(compressed_hit_count_ + expected_hits, new_hit_count);
125
9
    ASSERT_EQ(compressed_insert_count_ + expected_inserts, new_insert_count);
126
9
    ASSERT_EQ(compressed_failure_count_ + expected_failures, new_failure_count);
127
9
    compressed_miss_count_ = new_miss_count;
128
9
    compressed_hit_count_ = new_hit_count;
129
9
    compressed_insert_count_ = new_insert_count;
130
9
    compressed_failure_count_ = new_failure_count;
131
9
  }
132
};
133
134
1
TEST_F(DBBlockCacheTest, TestWithoutCompressedBlockCache) {
135
1
  ReadOptions read_options;
136
1
  auto table_options = GetTableOptions();
137
1
  auto options = GetOptions(table_options);
138
1
  InitTable(options);
139
140
1
  FLAGS_cache_overflow_single_touch = false;
141
1
  std::shared_ptr<Cache> cache = NewLRUCache(0, 0, false);
142
1
  table_options.block_cache = cache;
143
1
  options.table_factory.reset(new BlockBasedTableFactory(table_options));
144
1
  Reopen(options);
145
1
  RecordCacheCounters(options);
146
147
1
  std::vector<std::unique_ptr<Iterator>> iterators(kNumBlocks - 1);
148
1
  Iterator* iter = nullptr;
149
150
  // Load blocks into cache.
151
10
  for (size_t i = 0; i < kNumBlocks - 1; i++) {
152
9
    iter = db_->NewIterator(read_options);
153
9
    iter->Seek(ToString(i));
154
9
    ASSERT_OK(iter->status());
155
9
    CheckCacheCounters(options, 1, 0, 1, 0);
156
9
    iterators[i].reset(iter);
157
9
  }
158
1
  size_t usage = cache->GetUsage();
159
1
  ASSERT_LT(0, usage);
160
  // Updating multi-touch capacity exactly equal to the usage to induce failures.
161
1
  cache->SetCapacity(usage / FLAGS_cache_single_touch_ratio);
162
1
  ASSERT_EQ(usage, cache->GetPinnedUsage());
163
164
  // Release iterators and access cache again.
165
10
  for (size_t i = 0; i < kNumBlocks - 1; i++) {
166
9
    iterators[i].reset();
167
9
    CheckCacheCounters(options, 0, 0, 0, 0);
168
9
  }
169
1
  ASSERT_EQ(0, cache->GetPinnedUsage());
170
10
  for (size_t i = 0; i < kNumBlocks - 1; i++) {
171
9
    iter = db_->NewIterator(read_options);
172
9
    iter->Seek(ToString(i));
173
9
    ASSERT_OK(iter->status());
174
9
    CheckCacheCounters(options, 0, 1, 0, 0);
175
9
    iterators[i].reset(iter);
176
9
  }
177
1
  FLAGS_cache_overflow_single_touch = true;
178
1
}
179
180
#ifdef SNAPPY
181
1
TEST_F(DBBlockCacheTest, TestWithCompressedBlockCache) {
182
1
  ReadOptions read_options;
183
1
  auto table_options = GetTableOptions();
184
1
  auto options = GetOptions(table_options);
185
1
  options.compression = CompressionType::kSnappyCompression;
186
1
  InitTable(options);
187
188
1
  FLAGS_cache_overflow_single_touch = false;
189
1
  std::shared_ptr<Cache> cache = NewLRUCache(0, 0, false);
190
1
  std::shared_ptr<Cache> compressed_cache = NewLRUCache(0, 0, false);
191
1
  table_options.block_cache = cache;
192
1
  table_options.block_cache_compressed = compressed_cache;
193
1
  options.table_factory.reset(new BlockBasedTableFactory(table_options));
194
1
  Reopen(options);
195
1
  RecordCacheCounters(options);
196
197
1
  std::vector<std::unique_ptr<Iterator>> iterators(kNumBlocks - 1);
198
1
  Iterator* iter = nullptr;
199
200
  // Load blocks into cache.
201
10
  for (size_t i = 0; i < kNumBlocks - 1; i++) {
202
9
    iter = db_->NewIterator(read_options);
203
9
    iter->Seek(ToString(i));
204
9
    ASSERT_OK(iter->status());
205
9
    CheckCacheCounters(options, 1, 0, 1, 0);
206
9
    CheckCompressedCacheCounters(options, 1, 0, 1, 0);
207
9
    iterators[i].reset(iter);
208
9
  }
209
1
  size_t usage = cache->GetUsage();
210
1
  ASSERT_LT(0, usage);
211
1
  ASSERT_EQ(usage, cache->GetPinnedUsage());
212
1
  size_t compressed_usage = compressed_cache->GetUsage();
213
1
  ASSERT_LT(0, compressed_usage);
214
  // Compressed block cache cannot be pinned.
215
1
  ASSERT_EQ(0, compressed_cache->GetPinnedUsage());
216
1
  FLAGS_cache_overflow_single_touch = true;
217
1
}
218
#endif
219
220
}  // namespace rocksdb
221
222
13.2k
int main(int argc, char** argv) {
223
13.2k
  rocksdb::port::InstallStackTraceHandler();
224
13.2k
  ::testing::InitGoogleTest(&argc, argv);
225
13.2k
  return RUN_ALL_TESTS();
226
13.2k
}