]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/utilities/table_properties_collectors/compact_on_deletion_collector_test.cc
dowstream patches: fix-up series file
[ceph.git] / ceph / src / rocksdb / utilities / table_properties_collectors / compact_on_deletion_collector_test.cc
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
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).
7c673cae
FG
5//
6// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7// Use of this source code is governed by a BSD-style license that can be
8// found in the LICENSE file. See the AUTHORS file for names of contributors.
9
10#include <stdio.h>
11
12#ifndef ROCKSDB_LITE
13#include <algorithm>
14#include <cmath>
15#include <vector>
16
20effc67 17#include "port/stack_trace.h"
7c673cae
FG
18#include "rocksdb/table.h"
19#include "rocksdb/table_properties.h"
20#include "rocksdb/utilities/table_properties_collectors.h"
20effc67 21#include "test_util/testharness.h"
7c673cae
FG
22#include "util/random.h"
23#include "utilities/table_properties_collectors/compact_on_deletion_collector.h"
24
20effc67
TL
25namespace ROCKSDB_NAMESPACE {
26
27TEST(CompactOnDeletionCollector, DeletionRatio) {
28 TablePropertiesCollectorFactory::Context context;
29 context.column_family_id =
30 TablePropertiesCollectorFactory::Context::kUnknownColumnFamily;
31 const size_t kTotalEntries = 100;
32
33 {
34 // Disable deletion ratio.
35 for (double deletion_ratio : {-1.5, -1.0, 0.0, 1.5, 2.0}) {
36 auto factory = NewCompactOnDeletionCollectorFactory(0, 0, deletion_ratio);
37 std::unique_ptr<TablePropertiesCollector> collector(
38 factory->CreateTablePropertiesCollector(context));
39 for (size_t i = 0; i < kTotalEntries; i++) {
40 // All entries are deletion entries.
1e59de90
TL
41 ASSERT_OK(
42 collector->AddUserKey("hello", "rocksdb", kEntryDelete, 0, 0));
20effc67
TL
43 ASSERT_FALSE(collector->NeedCompact());
44 }
1e59de90 45 ASSERT_OK(collector->Finish(nullptr));
20effc67
TL
46 ASSERT_FALSE(collector->NeedCompact());
47 }
48 }
49
50 {
51 for (double deletion_ratio : {0.3, 0.5, 0.8, 1.0}) {
52 auto factory = NewCompactOnDeletionCollectorFactory(0, 0, deletion_ratio);
53 const size_t deletion_entries_trigger =
54 static_cast<size_t>(deletion_ratio * kTotalEntries);
55 for (int delta : {-1, 0, 1}) {
56 // Actual deletion entry ratio <, =, > deletion_ratio
57 size_t actual_deletion_entries = deletion_entries_trigger + delta;
58 std::unique_ptr<TablePropertiesCollector> collector(
59 factory->CreateTablePropertiesCollector(context));
60 for (size_t i = 0; i < kTotalEntries; i++) {
61 if (i < actual_deletion_entries) {
1e59de90
TL
62 ASSERT_OK(
63 collector->AddUserKey("hello", "rocksdb", kEntryDelete, 0, 0));
20effc67 64 } else {
1e59de90
TL
65 ASSERT_OK(
66 collector->AddUserKey("hello", "rocksdb", kEntryPut, 0, 0));
20effc67
TL
67 }
68 ASSERT_FALSE(collector->NeedCompact());
69 }
1e59de90 70 ASSERT_OK(collector->Finish(nullptr));
20effc67
TL
71 if (delta >= 0) {
72 // >= deletion_ratio
73 ASSERT_TRUE(collector->NeedCompact());
74 } else {
75 ASSERT_FALSE(collector->NeedCompact());
76 }
77 }
78 }
79 }
80}
81
82TEST(CompactOnDeletionCollector, SlidingWindow) {
1e59de90
TL
83 const int kWindowSizes[] = {1000, 10000, 10000, 127, 128, 129,
84 255, 256, 257, 2, 10000};
85 const int kDeletionTriggers[] = {500, 9500, 4323, 47, 61, 128,
86 250, 250, 250, 2, 2};
20effc67
TL
87 TablePropertiesCollectorFactory::Context context;
88 context.column_family_id =
f67539c2 89 TablePropertiesCollectorFactory::Context::kUnknownColumnFamily;
7c673cae
FG
90
91 std::vector<int> window_sizes;
92 std::vector<int> deletion_triggers;
93 // deterministic tests
94 for (int test = 0; test < 9; ++test) {
95 window_sizes.emplace_back(kWindowSizes[test]);
96 deletion_triggers.emplace_back(kDeletionTriggers[test]);
97 }
98
99 // randomize tests
20effc67 100 Random rnd(301);
7c673cae 101 const int kMaxTestSize = 100000l;
f67539c2 102 for (int random_test = 0; random_test < 10; random_test++) {
7c673cae
FG
103 int window_size = rnd.Uniform(kMaxTestSize) + 1;
104 int deletion_trigger = rnd.Uniform(window_size);
105 window_sizes.emplace_back(window_size);
106 deletion_triggers.emplace_back(deletion_trigger);
107 }
108
109 assert(window_sizes.size() == deletion_triggers.size());
110
111 for (size_t test = 0; test < window_sizes.size(); ++test) {
112 const int kBucketSize = 128;
113 const int kWindowSize = window_sizes[test];
114 const int kPaddedWindowSize =
115 kBucketSize * ((window_sizes[test] + kBucketSize - 1) / kBucketSize);
116 const int kNumDeletionTrigger = deletion_triggers[test];
117 const int kBias = (kNumDeletionTrigger + kBucketSize - 1) / kBucketSize;
118 // Simple test
119 {
20effc67
TL
120 auto factory = NewCompactOnDeletionCollectorFactory(kWindowSize,
121 kNumDeletionTrigger);
7c673cae
FG
122 const int kSample = 10;
123 for (int delete_rate = 0; delete_rate <= kSample; ++delete_rate) {
20effc67 124 std::unique_ptr<TablePropertiesCollector> collector(
11fdf7f2 125 factory->CreateTablePropertiesCollector(context));
7c673cae
FG
126 int deletions = 0;
127 for (int i = 0; i < kPaddedWindowSize; ++i) {
128 if (i % kSample < delete_rate) {
1e59de90
TL
129 ASSERT_OK(
130 collector->AddUserKey("hello", "rocksdb", kEntryDelete, 0, 0));
7c673cae
FG
131 deletions++;
132 } else {
1e59de90
TL
133 ASSERT_OK(
134 collector->AddUserKey("hello", "rocksdb", kEntryPut, 0, 0));
7c673cae
FG
135 }
136 }
1e59de90 137 if (collector->NeedCompact() != (deletions >= kNumDeletionTrigger) &&
7c673cae 138 std::abs(deletions - kNumDeletionTrigger) > kBias) {
1e59de90
TL
139 fprintf(stderr,
140 "[Error] collector->NeedCompact() != (%d >= %d)"
7c673cae 141 " with kWindowSize = %d and kNumDeletionTrigger = %d\n",
1e59de90
TL
142 deletions, kNumDeletionTrigger, kWindowSize,
143 kNumDeletionTrigger);
20effc67 144 ASSERT_TRUE(false);
7c673cae 145 }
1e59de90 146 ASSERT_OK(collector->Finish(nullptr));
7c673cae
FG
147 }
148 }
149
150 // Only one section of a file satisfies the compaction trigger
151 {
20effc67
TL
152 auto factory = NewCompactOnDeletionCollectorFactory(kWindowSize,
153 kNumDeletionTrigger);
7c673cae
FG
154 const int kSample = 10;
155 for (int delete_rate = 0; delete_rate <= kSample; ++delete_rate) {
20effc67 156 std::unique_ptr<TablePropertiesCollector> collector(
11fdf7f2 157 factory->CreateTablePropertiesCollector(context));
7c673cae
FG
158 int deletions = 0;
159 for (int section = 0; section < 5; ++section) {
160 int initial_entries = rnd.Uniform(kWindowSize) + kWindowSize;
161 for (int i = 0; i < initial_entries; ++i) {
1e59de90
TL
162 ASSERT_OK(
163 collector->AddUserKey("hello", "rocksdb", kEntryPut, 0, 0));
7c673cae
FG
164 }
165 }
166 for (int i = 0; i < kPaddedWindowSize; ++i) {
167 if (i % kSample < delete_rate) {
1e59de90
TL
168 ASSERT_OK(
169 collector->AddUserKey("hello", "rocksdb", kEntryDelete, 0, 0));
7c673cae
FG
170 deletions++;
171 } else {
1e59de90
TL
172 ASSERT_OK(
173 collector->AddUserKey("hello", "rocksdb", kEntryPut, 0, 0));
7c673cae
FG
174 }
175 }
176 for (int section = 0; section < 5; ++section) {
177 int ending_entries = rnd.Uniform(kWindowSize) + kWindowSize;
178 for (int i = 0; i < ending_entries; ++i) {
1e59de90
TL
179 ASSERT_OK(
180 collector->AddUserKey("hello", "rocksdb", kEntryPut, 0, 0));
7c673cae
FG
181 }
182 }
183 if (collector->NeedCompact() != (deletions >= kNumDeletionTrigger) &&
184 std::abs(deletions - kNumDeletionTrigger) > kBias) {
1e59de90
TL
185 fprintf(stderr,
186 "[Error] collector->NeedCompact() %d != (%d >= %d)"
7c673cae 187 " with kWindowSize = %d, kNumDeletionTrigger = %d\n",
1e59de90
TL
188 collector->NeedCompact(), deletions, kNumDeletionTrigger,
189 kWindowSize, kNumDeletionTrigger);
20effc67 190 ASSERT_TRUE(false);
7c673cae 191 }
1e59de90 192 ASSERT_OK(collector->Finish(nullptr));
7c673cae
FG
193 }
194 }
195
196 // TEST 3: Issues a lots of deletes, but their density is not
197 // high enough to trigger compaction.
198 {
20effc67
TL
199 std::unique_ptr<TablePropertiesCollector> collector;
200 auto factory = NewCompactOnDeletionCollectorFactory(kWindowSize,
201 kNumDeletionTrigger);
7c673cae
FG
202 collector.reset(factory->CreateTablePropertiesCollector(context));
203 assert(collector->NeedCompact() == false);
204 // Insert "kNumDeletionTrigger * 0.95" deletions for every
205 // "kWindowSize" and verify compaction is not needed.
206 const int kDeletionsPerSection = kNumDeletionTrigger * 95 / 100;
207 if (kDeletionsPerSection >= 0) {
208 for (int section = 0; section < 200; ++section) {
209 for (int i = 0; i < kPaddedWindowSize; ++i) {
210 if (i < kDeletionsPerSection) {
1e59de90
TL
211 ASSERT_OK(collector->AddUserKey("hello", "rocksdb", kEntryDelete,
212 0, 0));
7c673cae 213 } else {
1e59de90
TL
214 ASSERT_OK(
215 collector->AddUserKey("hello", "rocksdb", kEntryPut, 0, 0));
7c673cae
FG
216 }
217 }
218 }
219 if (collector->NeedCompact() &&
220 std::abs(kDeletionsPerSection - kNumDeletionTrigger) > kBias) {
1e59de90
TL
221 fprintf(stderr,
222 "[Error] collector->NeedCompact() != false"
7c673cae
FG
223 " with kWindowSize = %d and kNumDeletionTrigger = %d\n",
224 kWindowSize, kNumDeletionTrigger);
20effc67 225 ASSERT_TRUE(false);
7c673cae 226 }
1e59de90 227 ASSERT_OK(collector->Finish(nullptr));
7c673cae
FG
228 }
229 }
230 }
20effc67
TL
231}
232
233} // namespace ROCKSDB_NAMESPACE
234
235int main(int argc, char** argv) {
236 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
237 ::testing::InitGoogleTest(&argc, argv);
238 return RUN_ALL_TESTS();
7c673cae
FG
239}
240#else
11fdf7f2 241int main(int /*argc*/, char** /*argv*/) {
7c673cae
FG
242 fprintf(stderr, "SKIPPED as RocksDBLite does not include utilities.\n");
243 return 0;
244}
245#endif // !ROCKSDB_LITE