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).
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.
11 #include <unordered_map>
13 #include "db/column_family.h"
14 #include "db/db_impl/db_impl.h"
15 #include "db/db_test_util.h"
16 #include "options/options_helper.h"
17 #include "port/stack_trace.h"
18 #include "rocksdb/cache.h"
19 #include "rocksdb/convenience.h"
20 #include "rocksdb/rate_limiter.h"
21 #include "rocksdb/stats_history.h"
22 #include "test_util/sync_point.h"
23 #include "test_util/testutil.h"
24 #include "util/random.h"
26 namespace ROCKSDB_NAMESPACE
{
28 class DBOptionsTest
: public DBTestBase
{
30 DBOptionsTest() : DBTestBase("db_options_test", /*env_do_fsync=*/true) {}
33 std::unordered_map
<std::string
, std::string
> GetMutableDBOptionsMap(
34 const DBOptions
& options
) {
35 std::string options_str
;
36 std::unordered_map
<std::string
, std::string
> mutable_map
;
37 ConfigOptions
config_options(options
);
38 config_options
.delimiter
= "; ";
40 EXPECT_OK(GetStringFromMutableDBOptions(
41 config_options
, MutableDBOptions(options
), &options_str
));
42 EXPECT_OK(StringToMap(options_str
, &mutable_map
));
47 std::unordered_map
<std::string
, std::string
> GetMutableCFOptionsMap(
48 const ColumnFamilyOptions
& options
) {
49 std::string options_str
;
50 ConfigOptions config_options
;
51 config_options
.delimiter
= "; ";
53 std::unordered_map
<std::string
, std::string
> mutable_map
;
54 EXPECT_OK(GetStringFromMutableCFOptions(
55 config_options
, MutableCFOptions(options
), &options_str
));
56 EXPECT_OK(StringToMap(options_str
, &mutable_map
));
60 std::unordered_map
<std::string
, std::string
> GetRandomizedMutableCFOptionsMap(
62 Options options
= CurrentOptions();
64 ImmutableDBOptions
db_options(options
);
65 test::RandomInitCFOptions(&options
, options
, rnd
);
66 auto sanitized_options
= SanitizeOptions(db_options
, options
);
67 auto opt_map
= GetMutableCFOptionsMap(sanitized_options
);
68 delete options
.compaction_filter
;
72 std::unordered_map
<std::string
, std::string
> GetRandomizedMutableDBOptionsMap(
75 test::RandomInitDBOptions(&db_options
, rnd
);
76 auto sanitized_options
= SanitizeOptions(dbname_
, db_options
);
77 return GetMutableDBOptionsMap(sanitized_options
);
79 #endif // ROCKSDB_LITE
82 TEST_F(DBOptionsTest
, ImmutableTrackAndVerifyWalsInManifest
) {
85 options
.track_and_verify_wals_in_manifest
= true;
87 ImmutableDBOptions
db_options(options
);
88 ASSERT_TRUE(db_options
.track_and_verify_wals_in_manifest
);
91 ASSERT_TRUE(dbfull()->GetDBOptions().track_and_verify_wals_in_manifest
);
94 dbfull()->SetDBOptions({{"track_and_verify_wals_in_manifest", "false"}});
98 TEST_F(DBOptionsTest
, ImmutableVerifySstUniqueIdInManifest
) {
101 options
.verify_sst_unique_id_in_manifest
= true;
103 ImmutableDBOptions
db_options(options
);
104 ASSERT_TRUE(db_options
.verify_sst_unique_id_in_manifest
);
107 ASSERT_TRUE(dbfull()->GetDBOptions().verify_sst_unique_id_in_manifest
);
110 dbfull()->SetDBOptions({{"verify_sst_unique_id_in_manifest", "false"}});
111 ASSERT_FALSE(s
.ok());
114 // RocksDB lite don't support dynamic options.
117 TEST_F(DBOptionsTest
, AvoidUpdatingOptions
) {
120 options
.max_background_jobs
= 4;
121 options
.delayed_write_rate
= 1024;
125 SyncPoint::GetInstance()->DisableProcessing();
126 SyncPoint::GetInstance()->ClearAllCallBacks();
127 bool is_changed_stats
= false;
128 SyncPoint::GetInstance()->SetCallBack(
129 "DBImpl::WriteOptionsFile:PersistOptions", [&](void* /*arg*/) {
130 ASSERT_FALSE(is_changed_stats
); // should only save options file once
131 is_changed_stats
= true;
133 SyncPoint::GetInstance()->EnableProcessing();
135 // helper function to check the status and reset after each check
136 auto is_changed
= [&] {
137 bool ret
= is_changed_stats
;
138 is_changed_stats
= false;
142 // without changing the value, but it's sanitized to a different value
143 ASSERT_OK(dbfull()->SetDBOptions({{"bytes_per_sync", "0"}}));
144 ASSERT_TRUE(is_changed());
146 // without changing the value
147 ASSERT_OK(dbfull()->SetDBOptions({{"max_background_jobs", "4"}}));
148 ASSERT_FALSE(is_changed());
150 // changing the value
151 ASSERT_OK(dbfull()->SetDBOptions({{"bytes_per_sync", "123"}}));
152 ASSERT_TRUE(is_changed());
155 ASSERT_OK(dbfull()->SetDBOptions({{"bytes_per_sync", "123"}}));
156 ASSERT_FALSE(is_changed());
158 // without changing a default value
159 ASSERT_OK(dbfull()->SetDBOptions({{"strict_bytes_per_sync", "false"}}));
160 ASSERT_FALSE(is_changed());
163 ASSERT_OK(dbfull()->SetDBOptions({{"strict_bytes_per_sync", "true"}}));
164 ASSERT_TRUE(is_changed());
166 // multiple values without change
167 ASSERT_OK(dbfull()->SetDBOptions(
168 {{"max_total_wal_size", "0"}, {"stats_dump_period_sec", "600"}}));
169 ASSERT_FALSE(is_changed());
171 // multiple values with change
172 ASSERT_OK(dbfull()->SetDBOptions(
173 {{"max_open_files", "100"}, {"stats_dump_period_sec", "600"}}));
174 ASSERT_TRUE(is_changed());
177 TEST_F(DBOptionsTest
, GetLatestDBOptions
) {
178 // GetOptions should be able to get latest option changed by SetOptions.
180 options
.create_if_missing
= true;
184 auto new_options
= GetRandomizedMutableDBOptionsMap(&rnd
);
185 ASSERT_OK(dbfull()->SetDBOptions(new_options
));
186 ASSERT_EQ(new_options
, GetMutableDBOptionsMap(dbfull()->GetDBOptions()));
189 TEST_F(DBOptionsTest
, GetLatestCFOptions
) {
190 // GetOptions should be able to get latest option changed by SetOptions.
192 options
.create_if_missing
= true;
196 CreateColumnFamilies({"foo"}, options
);
197 ReopenWithColumnFamilies({"default", "foo"}, options
);
198 auto options_default
= GetRandomizedMutableCFOptionsMap(&rnd
);
199 auto options_foo
= GetRandomizedMutableCFOptionsMap(&rnd
);
200 ASSERT_OK(dbfull()->SetOptions(handles_
[0], options_default
));
201 ASSERT_OK(dbfull()->SetOptions(handles_
[1], options_foo
));
202 ASSERT_EQ(options_default
,
203 GetMutableCFOptionsMap(dbfull()->GetOptions(handles_
[0])));
204 ASSERT_EQ(options_foo
,
205 GetMutableCFOptionsMap(dbfull()->GetOptions(handles_
[1])));
208 TEST_F(DBOptionsTest
, SetMutableTableOptions
) {
210 options
.create_if_missing
= true;
212 options
.blob_file_size
= 16384;
213 BlockBasedTableOptions bbto
;
214 bbto
.no_block_cache
= true;
215 bbto
.block_size
= 8192;
216 bbto
.block_restart_interval
= 7;
218 options
.table_factory
.reset(NewBlockBasedTableFactory(bbto
));
221 ColumnFamilyHandle
* cfh
= dbfull()->DefaultColumnFamily();
222 Options c_opts
= dbfull()->GetOptions(cfh
);
225 c_opts
.table_factory
->GetOptions
<BlockBasedTableOptions
>();
226 ASSERT_NE(c_bbto
, nullptr);
227 ASSERT_EQ(c_opts
.blob_file_size
, 16384);
228 ASSERT_EQ(c_bbto
->no_block_cache
, true);
229 ASSERT_EQ(c_bbto
->block_size
, 8192);
230 ASSERT_EQ(c_bbto
->block_restart_interval
, 7);
231 ASSERT_OK(dbfull()->SetOptions(
232 cfh
, {{"table_factory.block_size", "16384"},
233 {"table_factory.block_restart_interval", "11"}}));
234 ASSERT_EQ(c_bbto
->block_size
, 16384);
235 ASSERT_EQ(c_bbto
->block_restart_interval
, 11);
237 // Now set an option that is not mutable - options should not change
239 dbfull()->SetOptions(cfh
, {{"table_factory.no_block_cache", "false"}}));
240 ASSERT_EQ(c_bbto
->no_block_cache
, true);
241 ASSERT_EQ(c_bbto
->block_size
, 16384);
242 ASSERT_EQ(c_bbto
->block_restart_interval
, 11);
244 // Set some that are mutable and some that are not - options should not change
245 ASSERT_NOK(dbfull()->SetOptions(
246 cfh
, {{"table_factory.no_block_cache", "false"},
247 {"table_factory.block_size", "8192"},
248 {"table_factory.block_restart_interval", "7"}}));
249 ASSERT_EQ(c_bbto
->no_block_cache
, true);
250 ASSERT_EQ(c_bbto
->block_size
, 16384);
251 ASSERT_EQ(c_bbto
->block_restart_interval
, 11);
253 // Set some that are mutable and some that do not exist - options should not
255 ASSERT_NOK(dbfull()->SetOptions(
256 cfh
, {{"table_factory.block_size", "8192"},
257 {"table_factory.does_not_exist", "true"},
258 {"table_factory.block_restart_interval", "7"}}));
259 ASSERT_EQ(c_bbto
->no_block_cache
, true);
260 ASSERT_EQ(c_bbto
->block_size
, 16384);
261 ASSERT_EQ(c_bbto
->block_restart_interval
, 11);
263 // Trying to change the table factory fails
264 ASSERT_NOK(dbfull()->SetOptions(
265 cfh
, {{"table_factory", TableFactory::kPlainTableName()}}));
267 // Set some on the table and some on the Column Family
268 ASSERT_OK(dbfull()->SetOptions(
269 cfh
, {{"table_factory.block_size", "16384"},
270 {"blob_file_size", "32768"},
271 {"table_factory.block_restart_interval", "13"}}));
272 c_opts
= dbfull()->GetOptions(cfh
);
273 ASSERT_EQ(c_opts
.blob_file_size
, 32768);
274 ASSERT_EQ(c_bbto
->block_size
, 16384);
275 ASSERT_EQ(c_bbto
->block_restart_interval
, 13);
276 // Set some on the table and a bad one on the ColumnFamily - options should
278 ASSERT_NOK(dbfull()->SetOptions(
279 cfh
, {{"table_factory.block_size", "1024"},
280 {"no_such_option", "32768"},
281 {"table_factory.block_restart_interval", "7"}}));
282 ASSERT_EQ(c_bbto
->block_size
, 16384);
283 ASSERT_EQ(c_bbto
->block_restart_interval
, 13);
286 TEST_F(DBOptionsTest
, SetWithCustomMemTableFactory
) {
287 class DummySkipListFactory
: public SkipListFactory
{
289 static const char* kClassName() { return "DummySkipListFactory"; }
290 const char* Name() const override
{ return kClassName(); }
291 explicit DummySkipListFactory() : SkipListFactory(2) {}
294 // Verify the DummySkipList cannot be created
295 ConfigOptions config_options
;
296 config_options
.ignore_unsupported_options
= false;
297 std::unique_ptr
<MemTableRepFactory
> factory
;
298 ASSERT_NOK(MemTableRepFactory::CreateFromString(
299 config_options
, DummySkipListFactory::kClassName(), &factory
));
302 options
.create_if_missing
= true;
303 // Try with fail_if_options_file_error=false/true to update the options
304 for (bool on_error
: {false, true}) {
305 options
.fail_if_options_file_error
= on_error
;
307 options
.disable_auto_compactions
= false;
309 options
.memtable_factory
.reset(new DummySkipListFactory());
312 ColumnFamilyHandle
* cfh
= dbfull()->DefaultColumnFamily();
314 dbfull()->SetOptions(cfh
, {{"disable_auto_compactions", "true"}}));
315 ColumnFamilyDescriptor cfd
;
316 ASSERT_OK(cfh
->GetDescriptor(&cfd
));
317 ASSERT_STREQ(cfd
.options
.memtable_factory
->Name(),
318 DummySkipListFactory::kClassName());
319 ColumnFamilyHandle
* test
= nullptr;
320 ASSERT_OK(dbfull()->CreateColumnFamily(options
, "test", &test
));
321 ASSERT_OK(test
->GetDescriptor(&cfd
));
322 ASSERT_STREQ(cfd
.options
.memtable_factory
->Name(),
323 DummySkipListFactory::kClassName());
325 ASSERT_OK(dbfull()->DropColumnFamily(test
));
330 TEST_F(DBOptionsTest
, SetBytesPerSync
) {
331 const size_t kValueSize
= 1024 * 1024; // 1MB
333 options
.create_if_missing
= true;
334 options
.bytes_per_sync
= 1024 * 1024;
335 options
.use_direct_reads
= false;
336 options
.write_buffer_size
= 400 * kValueSize
;
337 options
.disable_auto_compactions
= true;
338 options
.compression
= kNoCompression
;
342 int low_bytes_per_sync
= 0;
344 const std::string
kValue(kValueSize
, 'v');
345 ASSERT_EQ(options
.bytes_per_sync
, dbfull()->GetDBOptions().bytes_per_sync
);
346 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
347 "WritableFileWriter::RangeSync:0", [&](void* /*arg*/) { counter
++; });
349 WriteOptions write_opts
;
350 // should sync approximately 40MB/1MB ~= 40 times.
351 for (i
= 0; i
< 40; i
++) {
352 ASSERT_OK(Put(Key(i
), kValue
, write_opts
));
354 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
355 ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr));
356 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
357 low_bytes_per_sync
= counter
;
358 ASSERT_GT(low_bytes_per_sync
, 35);
359 ASSERT_LT(low_bytes_per_sync
, 45);
362 // 8388608 = 8 * 1024 * 1024
363 ASSERT_OK(dbfull()->SetDBOptions({{"bytes_per_sync", "8388608"}}));
364 ASSERT_EQ(8388608, dbfull()->GetDBOptions().bytes_per_sync
);
365 // should sync approximately 40MB*2/8MB ~= 10 times.
366 // data will be 40*2MB because of previous Puts too.
367 for (i
= 0; i
< 40; i
++) {
368 ASSERT_OK(Put(Key(i
), kValue
, write_opts
));
370 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
371 ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr));
372 ASSERT_GT(counter
, 5);
373 ASSERT_LT(counter
, 15);
375 // Redundant assert. But leaving it here just to get the point across that
376 // low_bytes_per_sync > counter.
377 ASSERT_GT(low_bytes_per_sync
, counter
);
380 TEST_F(DBOptionsTest
, SetWalBytesPerSync
) {
381 const size_t kValueSize
= 1024 * 1024 * 3;
383 options
.create_if_missing
= true;
384 options
.wal_bytes_per_sync
= 512;
385 options
.write_buffer_size
= 100 * kValueSize
;
386 options
.disable_auto_compactions
= true;
387 options
.compression
= kNoCompression
;
390 ASSERT_EQ(512, dbfull()->GetDBOptions().wal_bytes_per_sync
);
391 std::atomic_int counter
{0};
392 int low_bytes_per_sync
= 0;
393 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
394 "WritableFileWriter::RangeSync:0",
395 [&](void* /*arg*/) { counter
.fetch_add(1); });
396 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
397 const std::string
kValue(kValueSize
, 'v');
399 for (; i
< 10; i
++) {
400 ASSERT_OK(Put(Key(i
), kValue
));
402 // Do not flush. If we flush here, SwitchWAL will reuse old WAL file since its
403 // empty and will not get the new wal_bytes_per_sync value.
404 low_bytes_per_sync
= counter
;
405 // 5242880 = 1024 * 1024 * 5
406 ASSERT_OK(dbfull()->SetDBOptions({{"wal_bytes_per_sync", "5242880"}}));
407 ASSERT_EQ(5242880, dbfull()->GetDBOptions().wal_bytes_per_sync
);
410 for (; i
< 10; i
++) {
411 ASSERT_OK(Put(Key(i
), kValue
));
413 ASSERT_GT(counter
, 0);
414 ASSERT_GT(low_bytes_per_sync
, 0);
415 ASSERT_GT(low_bytes_per_sync
, counter
);
418 TEST_F(DBOptionsTest
, WritableFileMaxBufferSize
) {
420 options
.create_if_missing
= true;
421 options
.writable_file_max_buffer_size
= 1024 * 1024;
422 options
.level0_file_num_compaction_trigger
= 3;
423 options
.max_manifest_file_size
= 1;
425 int buffer_size
= 1024 * 1024;
427 ASSERT_EQ(buffer_size
,
428 dbfull()->GetDBOptions().writable_file_max_buffer_size
);
430 std::atomic
<int> match_cnt(0);
431 std::atomic
<int> unmatch_cnt(0);
432 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
433 "WritableFileWriter::WritableFileWriter:0", [&](void* arg
) {
434 int value
= static_cast<int>(reinterpret_cast<uintptr_t>(arg
));
435 if (value
== buffer_size
) {
441 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
444 ASSERT_OK(Put("foo", std::to_string(i
)));
445 ASSERT_OK(Put("bar", std::to_string(i
)));
448 ASSERT_OK(dbfull()->TEST_WaitForCompact());
449 ASSERT_EQ(unmatch_cnt
, 0);
450 ASSERT_GE(match_cnt
, 11);
453 dbfull()->SetDBOptions({{"writable_file_max_buffer_size", "524288"}}));
454 buffer_size
= 512 * 1024;
456 unmatch_cnt
= 0; // SetDBOptions() will create a WritableFileWriter
458 ASSERT_EQ(buffer_size
,
459 dbfull()->GetDBOptions().writable_file_max_buffer_size
);
462 ASSERT_OK(Put("foo", std::to_string(i
)));
463 ASSERT_OK(Put("bar", std::to_string(i
)));
466 ASSERT_OK(dbfull()->TEST_WaitForCompact());
467 ASSERT_EQ(unmatch_cnt
, 0);
468 ASSERT_GE(match_cnt
, 11);
471 TEST_F(DBOptionsTest
, SetOptionsAndReopen
) {
473 auto rand_opts
= GetRandomizedMutableCFOptionsMap(&rnd
);
474 ASSERT_OK(dbfull()->SetOptions(rand_opts
));
475 // Verify if DB can be reopen after setting options.
478 ASSERT_OK(TryReopen(options
));
481 TEST_F(DBOptionsTest
, EnableAutoCompactionAndTriggerStall
) {
482 const std::string
kValue(1024, 'v');
483 for (int method_type
= 0; method_type
< 2; method_type
++) {
484 for (int option_type
= 0; option_type
< 4; option_type
++) {
486 options
.create_if_missing
= true;
487 options
.disable_auto_compactions
= true;
488 options
.write_buffer_size
= 1024 * 1024 * 10;
489 options
.compression
= CompressionType::kNoCompression
;
490 options
.level0_file_num_compaction_trigger
= 1;
491 options
.level0_stop_writes_trigger
= std::numeric_limits
<int>::max();
492 options
.level0_slowdown_writes_trigger
= std::numeric_limits
<int>::max();
493 options
.hard_pending_compaction_bytes_limit
=
494 std::numeric_limits
<uint64_t>::max();
495 options
.soft_pending_compaction_bytes_limit
=
496 std::numeric_limits
<uint64_t>::max();
499 DestroyAndReopen(options
);
501 for (; i
< 1024; i
++) {
502 ASSERT_OK(Put(Key(i
), kValue
));
505 for (; i
< 1024 * 2; i
++) {
506 ASSERT_OK(Put(Key(i
), kValue
));
509 ASSERT_OK(dbfull()->TEST_WaitForFlushMemTable());
510 ASSERT_EQ(2, NumTableFilesAtLevel(0));
511 uint64_t l0_size
= SizeAtLevel(0);
513 switch (option_type
) {
515 // test with level0_stop_writes_trigger
516 options
.level0_stop_writes_trigger
= 2;
517 options
.level0_slowdown_writes_trigger
= 2;
520 options
.level0_slowdown_writes_trigger
= 2;
523 options
.hard_pending_compaction_bytes_limit
= l0_size
;
524 options
.soft_pending_compaction_bytes_limit
= l0_size
;
527 options
.soft_pending_compaction_bytes_limit
= l0_size
;
531 ASSERT_OK(dbfull()->TEST_WaitForCompact());
532 ASSERT_FALSE(dbfull()->TEST_write_controler().IsStopped());
533 ASSERT_FALSE(dbfull()->TEST_write_controler().NeedsDelay());
535 SyncPoint::GetInstance()->LoadDependency(
536 {{"DBOptionsTest::EnableAutoCompactionAndTriggerStall:1",
537 "BackgroundCallCompaction:0"},
538 {"DBImpl::BackgroundCompaction():BeforePickCompaction",
539 "DBOptionsTest::EnableAutoCompactionAndTriggerStall:2"},
540 {"DBOptionsTest::EnableAutoCompactionAndTriggerStall:3",
541 "DBImpl::BackgroundCompaction():AfterPickCompaction"}});
542 // Block background compaction.
543 SyncPoint::GetInstance()->EnableProcessing();
545 switch (method_type
) {
548 dbfull()->SetOptions({{"disable_auto_compactions", "false"}}));
551 ASSERT_OK(dbfull()->EnableAutoCompaction(
552 {dbfull()->DefaultColumnFamily()}));
555 TEST_SYNC_POINT("DBOptionsTest::EnableAutoCompactionAndTriggerStall:1");
556 // Wait for stall condition recalculate.
557 TEST_SYNC_POINT("DBOptionsTest::EnableAutoCompactionAndTriggerStall:2");
559 switch (option_type
) {
561 ASSERT_TRUE(dbfull()->TEST_write_controler().IsStopped());
564 ASSERT_FALSE(dbfull()->TEST_write_controler().IsStopped());
565 ASSERT_TRUE(dbfull()->TEST_write_controler().NeedsDelay());
568 ASSERT_TRUE(dbfull()->TEST_write_controler().IsStopped());
571 ASSERT_FALSE(dbfull()->TEST_write_controler().IsStopped());
572 ASSERT_TRUE(dbfull()->TEST_write_controler().NeedsDelay());
575 TEST_SYNC_POINT("DBOptionsTest::EnableAutoCompactionAndTriggerStall:3");
577 // Background compaction executed.
578 ASSERT_OK(dbfull()->TEST_WaitForCompact());
579 ASSERT_FALSE(dbfull()->TEST_write_controler().IsStopped());
580 ASSERT_FALSE(dbfull()->TEST_write_controler().NeedsDelay());
585 TEST_F(DBOptionsTest
, SetOptionsMayTriggerCompaction
) {
587 options
.create_if_missing
= true;
588 options
.level0_file_num_compaction_trigger
= 1000;
591 for (int i
= 0; i
< 3; i
++) {
592 // Need to insert two keys to avoid trivial move.
593 ASSERT_OK(Put("foo", std::to_string(i
)));
594 ASSERT_OK(Put("bar", std::to_string(i
)));
597 ASSERT_EQ("3", FilesPerLevel());
599 dbfull()->SetOptions({{"level0_file_num_compaction_trigger", "3"}}));
600 ASSERT_OK(dbfull()->TEST_WaitForCompact());
601 ASSERT_EQ("0,1", FilesPerLevel());
604 TEST_F(DBOptionsTest
, SetBackgroundCompactionThreads
) {
606 options
.create_if_missing
= true;
607 options
.max_background_compactions
= 1; // default value
610 ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
611 ASSERT_OK(dbfull()->SetDBOptions({{"max_background_compactions", "3"}}));
612 ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
613 auto stop_token
= dbfull()->TEST_write_controler().GetStopToken();
614 ASSERT_EQ(3, dbfull()->TEST_BGCompactionsAllowed());
617 TEST_F(DBOptionsTest
, SetBackgroundFlushThreads
) {
619 options
.create_if_missing
= true;
620 options
.max_background_flushes
= 1;
623 ASSERT_EQ(1, dbfull()->TEST_BGFlushesAllowed());
624 ASSERT_EQ(1, env_
->GetBackgroundThreads(Env::Priority::HIGH
));
625 ASSERT_OK(dbfull()->SetDBOptions({{"max_background_flushes", "3"}}));
626 ASSERT_EQ(3, env_
->GetBackgroundThreads(Env::Priority::HIGH
));
627 ASSERT_EQ(3, dbfull()->TEST_BGFlushesAllowed());
630 TEST_F(DBOptionsTest
, SetBackgroundJobs
) {
632 options
.create_if_missing
= true;
633 options
.max_background_jobs
= 8;
637 for (int i
= 0; i
< 2; ++i
) {
639 options
.max_background_jobs
= 12;
640 ASSERT_OK(dbfull()->SetDBOptions(
641 {{"max_background_jobs",
642 std::to_string(options
.max_background_jobs
)}}));
645 const int expected_max_flushes
= options
.max_background_jobs
/ 4;
647 ASSERT_EQ(expected_max_flushes
, dbfull()->TEST_BGFlushesAllowed());
648 ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
650 auto stop_token
= dbfull()->TEST_write_controler().GetStopToken();
652 const int expected_max_compactions
= 3 * expected_max_flushes
;
654 ASSERT_EQ(expected_max_flushes
, dbfull()->TEST_BGFlushesAllowed());
655 ASSERT_EQ(expected_max_compactions
, dbfull()->TEST_BGCompactionsAllowed());
657 ASSERT_EQ(expected_max_flushes
,
658 env_
->GetBackgroundThreads(Env::Priority::HIGH
));
659 ASSERT_EQ(expected_max_compactions
,
660 env_
->GetBackgroundThreads(Env::Priority::LOW
));
664 TEST_F(DBOptionsTest
, AvoidFlushDuringShutdown
) {
666 options
.create_if_missing
= true;
667 options
.disable_auto_compactions
= true;
669 WriteOptions write_without_wal
;
670 write_without_wal
.disableWAL
= true;
672 ASSERT_FALSE(options
.avoid_flush_during_shutdown
);
673 DestroyAndReopen(options
);
674 ASSERT_OK(Put("foo", "v1", write_without_wal
));
676 ASSERT_EQ("v1", Get("foo"));
677 ASSERT_EQ("1", FilesPerLevel());
679 DestroyAndReopen(options
);
680 ASSERT_OK(Put("foo", "v2", write_without_wal
));
681 ASSERT_OK(dbfull()->SetDBOptions({{"avoid_flush_during_shutdown", "true"}}));
683 ASSERT_EQ("NOT_FOUND", Get("foo"));
684 ASSERT_EQ("", FilesPerLevel());
687 TEST_F(DBOptionsTest
, SetDelayedWriteRateOption
) {
689 options
.create_if_missing
= true;
690 options
.delayed_write_rate
= 2 * 1024U * 1024U;
693 ASSERT_EQ(2 * 1024U * 1024U,
694 dbfull()->TEST_write_controler().max_delayed_write_rate());
696 ASSERT_OK(dbfull()->SetDBOptions({{"delayed_write_rate", "20000"}}));
697 ASSERT_EQ(20000, dbfull()->TEST_write_controler().max_delayed_write_rate());
700 TEST_F(DBOptionsTest
, MaxTotalWalSizeChange
) {
702 const auto value_size
= size_t(1024);
703 std::string value
= rnd
.RandomString(value_size
);
706 options
.create_if_missing
= true;
708 CreateColumnFamilies({"1", "2", "3"}, options
);
709 ReopenWithColumnFamilies({"default", "1", "2", "3"}, options
);
711 WriteOptions write_options
;
713 const int key_count
= 100;
714 for (int i
= 0; i
< key_count
; ++i
) {
715 for (size_t cf
= 0; cf
< handles_
.size(); ++cf
) {
716 ASSERT_OK(Put(static_cast<int>(cf
), Key(i
), value
));
719 ASSERT_OK(dbfull()->SetDBOptions({{"max_total_wal_size", "10"}}));
721 for (size_t cf
= 0; cf
< handles_
.size(); ++cf
) {
722 ASSERT_OK(dbfull()->TEST_WaitForFlushMemTable(handles_
[cf
]));
723 ASSERT_EQ("1", FilesPerLevel(static_cast<int>(cf
)));
727 TEST_F(DBOptionsTest
, SetStatsDumpPeriodSec
) {
729 options
.create_if_missing
= true;
730 options
.stats_dump_period_sec
= 5;
733 ASSERT_EQ(5u, dbfull()->GetDBOptions().stats_dump_period_sec
);
735 for (int i
= 0; i
< 20; i
++) {
736 unsigned int num
= rand() % 5000 + 1;
737 ASSERT_OK(dbfull()->SetDBOptions(
738 {{"stats_dump_period_sec", std::to_string(num
)}}));
739 ASSERT_EQ(num
, dbfull()->GetDBOptions().stats_dump_period_sec
);
744 TEST_F(DBOptionsTest
, SetOptionsStatsPersistPeriodSec
) {
746 options
.create_if_missing
= true;
747 options
.stats_persist_period_sec
= 5;
750 ASSERT_EQ(5u, dbfull()->GetDBOptions().stats_persist_period_sec
);
752 ASSERT_OK(dbfull()->SetDBOptions({{"stats_persist_period_sec", "12345"}}));
753 ASSERT_EQ(12345u, dbfull()->GetDBOptions().stats_persist_period_sec
);
754 ASSERT_NOK(dbfull()->SetDBOptions({{"stats_persist_period_sec", "abcde"}}));
755 ASSERT_EQ(12345u, dbfull()->GetDBOptions().stats_persist_period_sec
);
758 static void assert_candidate_files_empty(DBImpl
* dbfull
, const bool empty
) {
759 dbfull
->TEST_LockMutex();
760 JobContext
job_context(0);
761 dbfull
->FindObsoleteFiles(&job_context
, false);
762 ASSERT_EQ(empty
, job_context
.full_scan_candidate_files
.empty());
763 dbfull
->TEST_UnlockMutex();
764 if (job_context
.HaveSomethingToDelete()) {
765 // fulfill the contract of FindObsoleteFiles by calling PurgeObsoleteFiles
766 // afterwards; otherwise the test may hang on shutdown
767 dbfull
->PurgeObsoleteFiles(job_context
);
772 TEST_F(DBOptionsTest
, DeleteObsoleteFilesPeriodChange
) {
775 SetTimeElapseOnlySleepOnReopen(&options
);
776 options
.create_if_missing
= true;
777 ASSERT_OK(TryReopen(options
));
779 // Verify that candidate files set is empty when no full scan requested.
780 assert_candidate_files_empty(dbfull(), true);
783 dbfull()->SetDBOptions({{"delete_obsolete_files_period_micros", "0"}}));
785 // After delete_obsolete_files_period_micros updated to 0, the next call
786 // to FindObsoleteFiles should make a full scan
787 assert_candidate_files_empty(dbfull(), false);
790 dbfull()->SetDBOptions({{"delete_obsolete_files_period_micros", "20"}}));
792 assert_candidate_files_empty(dbfull(), true);
794 env_
->MockSleepForMicroseconds(20);
795 assert_candidate_files_empty(dbfull(), true);
797 env_
->MockSleepForMicroseconds(1);
798 assert_candidate_files_empty(dbfull(), false);
803 TEST_F(DBOptionsTest
, MaxOpenFilesChange
) {
804 SpecialEnv
env(env_
);
806 options
.env
= CurrentOptions().env
;
807 options
.max_open_files
= -1;
811 Cache
* tc
= dbfull()->TEST_table_cache();
813 ASSERT_EQ(-1, dbfull()->GetDBOptions().max_open_files
);
814 ASSERT_LT(2000, tc
->GetCapacity());
815 ASSERT_OK(dbfull()->SetDBOptions({{"max_open_files", "1024"}}));
816 ASSERT_EQ(1024, dbfull()->GetDBOptions().max_open_files
);
817 // examine the table cache (actual size should be 1014)
818 ASSERT_GT(1500, tc
->GetCapacity());
822 TEST_F(DBOptionsTest
, SanitizeDelayedWriteRate
) {
824 options
.env
= CurrentOptions().env
;
825 options
.delayed_write_rate
= 0;
827 ASSERT_EQ(16 * 1024 * 1024, dbfull()->GetDBOptions().delayed_write_rate
);
829 options
.rate_limiter
.reset(NewGenericRateLimiter(31 * 1024 * 1024));
831 ASSERT_EQ(31 * 1024 * 1024, dbfull()->GetDBOptions().delayed_write_rate
);
834 TEST_F(DBOptionsTest
, SanitizeUniversalTTLCompaction
) {
836 options
.env
= CurrentOptions().env
;
837 options
.compaction_style
= kCompactionStyleUniversal
;
840 options
.periodic_compaction_seconds
= 0;
842 ASSERT_EQ(0, dbfull()->GetOptions().ttl
);
843 ASSERT_EQ(0, dbfull()->GetOptions().periodic_compaction_seconds
);
846 options
.periodic_compaction_seconds
= 100;
848 ASSERT_EQ(0, dbfull()->GetOptions().ttl
);
849 ASSERT_EQ(100, dbfull()->GetOptions().periodic_compaction_seconds
);
852 options
.periodic_compaction_seconds
= 0;
854 ASSERT_EQ(100, dbfull()->GetOptions().ttl
);
855 ASSERT_EQ(100, dbfull()->GetOptions().periodic_compaction_seconds
);
858 options
.periodic_compaction_seconds
= 500;
860 ASSERT_EQ(100, dbfull()->GetOptions().ttl
);
861 ASSERT_EQ(100, dbfull()->GetOptions().periodic_compaction_seconds
);
864 TEST_F(DBOptionsTest
, SanitizeTtlDefault
) {
866 options
.env
= CurrentOptions().env
;
868 ASSERT_EQ(30 * 24 * 60 * 60, dbfull()->GetOptions().ttl
);
870 options
.compaction_style
= kCompactionStyleLevel
;
873 ASSERT_EQ(0, dbfull()->GetOptions().ttl
);
877 ASSERT_EQ(100, dbfull()->GetOptions().ttl
);
880 TEST_F(DBOptionsTest
, SanitizeFIFOPeriodicCompaction
) {
882 options
.compaction_style
= kCompactionStyleFIFO
;
883 options
.env
= CurrentOptions().env
;
886 ASSERT_EQ(30 * 24 * 60 * 60, dbfull()->GetOptions().ttl
);
890 ASSERT_EQ(100, dbfull()->GetOptions().ttl
);
892 options
.ttl
= 100 * 24 * 60 * 60;
894 ASSERT_EQ(100 * 24 * 60 * 60, dbfull()->GetOptions().ttl
);
897 options
.periodic_compaction_seconds
= 300;
899 ASSERT_EQ(200, dbfull()->GetOptions().ttl
);
902 options
.periodic_compaction_seconds
= 300;
904 ASSERT_EQ(300, dbfull()->GetOptions().ttl
);
907 TEST_F(DBOptionsTest
, SetFIFOCompactionOptions
) {
909 options
.env
= CurrentOptions().env
;
910 options
.compaction_style
= kCompactionStyleFIFO
;
911 options
.write_buffer_size
= 10 << 10; // 10KB
912 options
.arena_block_size
= 4096;
913 options
.compression
= kNoCompression
;
914 options
.create_if_missing
= true;
915 options
.compaction_options_fifo
.allow_compaction
= false;
916 env_
->SetMockSleep();
919 // NOTE: Presumed unnecessary and removed: resetting mock time in env
921 // Test dynamically changing ttl.
922 options
.ttl
= 1 * 60 * 60; // 1 hour
923 ASSERT_OK(TryReopen(options
));
926 for (int i
= 0; i
< 10; i
++) {
927 // Generate and flush a file about 10KB.
928 for (int j
= 0; j
< 10; j
++) {
929 ASSERT_OK(Put(std::to_string(i
* 20 + j
), rnd
.RandomString(980)));
933 ASSERT_OK(dbfull()->TEST_WaitForCompact());
934 ASSERT_EQ(NumTableFilesAtLevel(0), 10);
936 env_
->MockSleepForSeconds(61);
938 // No files should be compacted as ttl is set to 1 hour.
939 ASSERT_EQ(dbfull()->GetOptions().ttl
, 3600);
940 ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr));
941 ASSERT_EQ(NumTableFilesAtLevel(0), 10);
943 // Set ttl to 1 minute. So all files should get deleted.
944 ASSERT_OK(dbfull()->SetOptions({{"ttl", "60"}}));
945 ASSERT_EQ(dbfull()->GetOptions().ttl
, 60);
946 ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr));
947 ASSERT_OK(dbfull()->TEST_WaitForCompact());
948 ASSERT_EQ(NumTableFilesAtLevel(0), 0);
950 // NOTE: Presumed unnecessary and removed: resetting mock time in env
952 // Test dynamically changing compaction_options_fifo.max_table_files_size
953 options
.compaction_options_fifo
.max_table_files_size
= 500 << 10; // 00KB
955 DestroyAndReopen(options
);
957 for (int i
= 0; i
< 10; i
++) {
958 // Generate and flush a file about 10KB.
959 for (int j
= 0; j
< 10; j
++) {
960 ASSERT_OK(Put(std::to_string(i
* 20 + j
), rnd
.RandomString(980)));
964 ASSERT_OK(dbfull()->TEST_WaitForCompact());
965 ASSERT_EQ(NumTableFilesAtLevel(0), 10);
967 // No files should be compacted as max_table_files_size is set to 500 KB.
968 ASSERT_EQ(dbfull()->GetOptions().compaction_options_fifo
.max_table_files_size
,
970 ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr));
971 ASSERT_EQ(NumTableFilesAtLevel(0), 10);
973 // Set max_table_files_size to 12 KB. So only 1 file should remain now.
974 ASSERT_OK(dbfull()->SetOptions(
975 {{"compaction_options_fifo", "{max_table_files_size=12288;}"}}));
976 ASSERT_EQ(dbfull()->GetOptions().compaction_options_fifo
.max_table_files_size
,
978 ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr));
979 ASSERT_OK(dbfull()->TEST_WaitForCompact());
980 ASSERT_EQ(NumTableFilesAtLevel(0), 1);
982 // Test dynamically changing compaction_options_fifo.allow_compaction
983 options
.compaction_options_fifo
.max_table_files_size
= 500 << 10; // 500KB
985 options
.compaction_options_fifo
.allow_compaction
= false;
986 options
.level0_file_num_compaction_trigger
= 6;
987 DestroyAndReopen(options
);
989 for (int i
= 0; i
< 10; i
++) {
990 // Generate and flush a file about 10KB.
991 for (int j
= 0; j
< 10; j
++) {
992 ASSERT_OK(Put(std::to_string(i
* 20 + j
), rnd
.RandomString(980)));
996 ASSERT_OK(dbfull()->TEST_WaitForCompact());
997 ASSERT_EQ(NumTableFilesAtLevel(0), 10);
999 // No files should be compacted as max_table_files_size is set to 500 KB and
1000 // allow_compaction is false
1001 ASSERT_EQ(dbfull()->GetOptions().compaction_options_fifo
.allow_compaction
,
1003 ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1004 ASSERT_EQ(NumTableFilesAtLevel(0), 10);
1006 // Set allow_compaction to true. So number of files should be between 1 and 5.
1007 ASSERT_OK(dbfull()->SetOptions(
1008 {{"compaction_options_fifo", "{allow_compaction=true;}"}}));
1009 ASSERT_EQ(dbfull()->GetOptions().compaction_options_fifo
.allow_compaction
,
1011 ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1012 ASSERT_OK(dbfull()->TEST_WaitForCompact());
1013 ASSERT_GE(NumTableFilesAtLevel(0), 1);
1014 ASSERT_LE(NumTableFilesAtLevel(0), 5);
1017 TEST_F(DBOptionsTest
, CompactionReadaheadSizeChange
) {
1018 SpecialEnv
env(env_
);
1022 options
.compaction_readahead_size
= 0;
1023 options
.level0_file_num_compaction_trigger
= 2;
1024 const std::string
kValue(1024, 'v');
1027 ASSERT_EQ(0, dbfull()->GetDBOptions().compaction_readahead_size
);
1028 ASSERT_OK(dbfull()->SetDBOptions({{"compaction_readahead_size", "256"}}));
1029 ASSERT_EQ(256, dbfull()->GetDBOptions().compaction_readahead_size
);
1030 for (int i
= 0; i
< 1024; i
++) {
1031 ASSERT_OK(Put(Key(i
), kValue
));
1034 for (int i
= 0; i
< 1024 * 2; i
++) {
1035 ASSERT_OK(Put(Key(i
), kValue
));
1038 ASSERT_OK(dbfull()->TEST_WaitForCompact());
1039 ASSERT_EQ(256, env_
->compaction_readahead_size_
);
1043 TEST_F(DBOptionsTest
, FIFOTtlBackwardCompatible
) {
1045 options
.compaction_style
= kCompactionStyleFIFO
;
1046 options
.write_buffer_size
= 10 << 10; // 10KB
1047 options
.create_if_missing
= true;
1048 options
.env
= CurrentOptions().env
;
1050 ASSERT_OK(TryReopen(options
));
1053 for (int i
= 0; i
< 10; i
++) {
1054 // Generate and flush a file about 10KB.
1055 for (int j
= 0; j
< 10; j
++) {
1056 ASSERT_OK(Put(std::to_string(i
* 20 + j
), rnd
.RandomString(980)));
1060 ASSERT_OK(dbfull()->TEST_WaitForCompact());
1061 ASSERT_EQ(NumTableFilesAtLevel(0), 10);
1063 // In release 6.0, ttl was promoted from a secondary level option under
1064 // compaction_options_fifo to a top level option under ColumnFamilyOptions.
1065 // We still need to handle old SetOptions calls but should ignore
1066 // ttl under compaction_options_fifo.
1067 ASSERT_OK(dbfull()->SetOptions(
1068 {{"compaction_options_fifo",
1069 "{allow_compaction=true;max_table_files_size=1024;ttl=731;}"},
1071 ASSERT_EQ(dbfull()->GetOptions().compaction_options_fifo
.allow_compaction
,
1073 ASSERT_EQ(dbfull()->GetOptions().compaction_options_fifo
.max_table_files_size
,
1075 ASSERT_EQ(dbfull()->GetOptions().ttl
, 60);
1077 // Put ttl as the first option inside compaction_options_fifo. That works as
1078 // it doesn't overwrite any other option.
1079 ASSERT_OK(dbfull()->SetOptions(
1080 {{"compaction_options_fifo",
1081 "{ttl=985;allow_compaction=true;max_table_files_size=1024;}"},
1083 ASSERT_EQ(dbfull()->GetOptions().compaction_options_fifo
.allow_compaction
,
1085 ASSERT_EQ(dbfull()->GetOptions().compaction_options_fifo
.max_table_files_size
,
1087 ASSERT_EQ(dbfull()->GetOptions().ttl
, 191);
1090 TEST_F(DBOptionsTest
, ChangeCompression
) {
1091 if (!Snappy_Supported() || !LZ4_Supported()) {
1095 options
.write_buffer_size
= 10 << 10; // 10KB
1096 options
.level0_file_num_compaction_trigger
= 2;
1097 options
.create_if_missing
= true;
1098 options
.compression
= CompressionType::kLZ4Compression
;
1099 options
.bottommost_compression
= CompressionType::kNoCompression
;
1100 options
.bottommost_compression_opts
.level
= 2;
1101 options
.bottommost_compression_opts
.parallel_threads
= 1;
1102 options
.env
= CurrentOptions().env
;
1104 ASSERT_OK(TryReopen(options
));
1106 CompressionType compression_used
= CompressionType::kLZ4Compression
;
1107 CompressionOptions compression_opt_used
;
1108 bool compacted
= false;
1109 SyncPoint::GetInstance()->SetCallBack(
1110 "LevelCompactionPicker::PickCompaction:Return", [&](void* arg
) {
1111 Compaction
* c
= reinterpret_cast<Compaction
*>(arg
);
1112 compression_used
= c
->output_compression();
1113 compression_opt_used
= c
->output_compression_opts();
1116 SyncPoint::GetInstance()->EnableProcessing();
1118 ASSERT_OK(Put("foo", "foofoofoo"));
1119 ASSERT_OK(Put("bar", "foofoofoo"));
1121 ASSERT_OK(Put("foo", "foofoofoo"));
1122 ASSERT_OK(Put("bar", "foofoofoo"));
1124 ASSERT_OK(dbfull()->TEST_WaitForCompact());
1125 ASSERT_TRUE(compacted
);
1126 ASSERT_EQ(CompressionType::kNoCompression
, compression_used
);
1127 ASSERT_EQ(options
.compression_opts
.level
, compression_opt_used
.level
);
1128 ASSERT_EQ(options
.compression_opts
.parallel_threads
,
1129 compression_opt_used
.parallel_threads
);
1131 compression_used
= CompressionType::kLZ4Compression
;
1133 ASSERT_OK(dbfull()->SetOptions(
1134 {{"bottommost_compression", "kSnappyCompression"},
1135 {"bottommost_compression_opts", "0:6:0:0:4:true"}}));
1136 ASSERT_OK(Put("foo", "foofoofoo"));
1137 ASSERT_OK(Put("bar", "foofoofoo"));
1139 ASSERT_OK(Put("foo", "foofoofoo"));
1140 ASSERT_OK(Put("bar", "foofoofoo"));
1142 ASSERT_OK(dbfull()->TEST_WaitForCompact());
1143 ASSERT_TRUE(compacted
);
1144 ASSERT_EQ(CompressionType::kSnappyCompression
, compression_used
);
1145 ASSERT_EQ(6, compression_opt_used
.level
);
1146 // Right now parallel_level is not yet allowed to be changed.
1148 SyncPoint::GetInstance()->DisableProcessing();
1151 #endif // ROCKSDB_LITE
1153 TEST_F(DBOptionsTest
, BottommostCompressionOptsWithFallbackType
) {
1154 // Verify the bottommost compression options still take effect even when the
1155 // bottommost compression type is left at its default value. Verify for both
1156 // automatic and manual compaction.
1157 if (!Snappy_Supported() || !LZ4_Supported()) {
1161 constexpr int kUpperCompressionLevel
= 1;
1162 constexpr int kBottommostCompressionLevel
= 2;
1163 constexpr int kNumL0Files
= 2;
1165 Options options
= CurrentOptions();
1166 options
.level0_file_num_compaction_trigger
= kNumL0Files
;
1167 options
.compression
= CompressionType::kLZ4Compression
;
1168 options
.compression_opts
.level
= kUpperCompressionLevel
;
1169 options
.bottommost_compression_opts
.level
= kBottommostCompressionLevel
;
1170 options
.bottommost_compression_opts
.enabled
= true;
1173 CompressionType compression_used
= CompressionType::kDisableCompressionOption
;
1174 CompressionOptions compression_opt_used
;
1175 bool compacted
= false;
1176 SyncPoint::GetInstance()->SetCallBack(
1177 "CompactionPicker::RegisterCompaction:Registered", [&](void* arg
) {
1178 Compaction
* c
= static_cast<Compaction
*>(arg
);
1179 compression_used
= c
->output_compression();
1180 compression_opt_used
= c
->output_compression_opts();
1183 SyncPoint::GetInstance()->EnableProcessing();
1185 // First, verify for automatic compaction.
1186 for (int i
= 0; i
< kNumL0Files
; ++i
) {
1187 ASSERT_OK(Put("foo", "foofoofoo"));
1188 ASSERT_OK(Put("bar", "foofoofoo"));
1191 ASSERT_OK(dbfull()->TEST_WaitForCompact());
1193 ASSERT_TRUE(compacted
);
1194 ASSERT_EQ(CompressionType::kLZ4Compression
, compression_used
);
1195 ASSERT_EQ(kBottommostCompressionLevel
, compression_opt_used
.level
);
1197 // Second, verify for manual compaction.
1199 compression_used
= CompressionType::kDisableCompressionOption
;
1200 compression_opt_used
= CompressionOptions();
1201 CompactRangeOptions cro
;
1202 cro
.bottommost_level_compaction
= BottommostLevelCompaction::kForceOptimized
;
1203 ASSERT_OK(dbfull()->CompactRange(cro
, nullptr, nullptr));
1205 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
1206 ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->ClearAllCallBacks();
1208 ASSERT_TRUE(compacted
);
1209 ASSERT_EQ(CompressionType::kLZ4Compression
, compression_used
);
1210 ASSERT_EQ(kBottommostCompressionLevel
, compression_opt_used
.level
);
1213 } // namespace ROCKSDB_NAMESPACE
1215 int main(int argc
, char** argv
) {
1216 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
1217 ::testing::InitGoogleTest(&argc
, argv
);
1218 return RUN_ALL_TESTS();