@nxtedition/rocksdb 7.0.39 → 7.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/binding.cc +2 -12
  2. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +1 -1
  3. package/deps/rocksdb/rocksdb/db/column_family.cc +2 -2
  4. package/deps/rocksdb/rocksdb/db/column_family_test.cc +1 -1
  5. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +13 -3
  6. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +273 -134
  7. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +33 -2
  8. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +11 -3
  9. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +2 -1
  10. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +2 -2
  11. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +133 -5
  12. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +130 -1
  13. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +8 -4
  14. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +11 -9
  15. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +209 -12
  16. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +54 -39
  17. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +102 -19
  18. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +30 -11
  19. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +1 -1
  20. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +28 -25
  21. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +0 -14
  22. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +63 -54
  23. package/deps/rocksdb/rocksdb/db/db_test.cc +6 -6
  24. package/deps/rocksdb/rocksdb/db/error_handler.cc +7 -0
  25. package/deps/rocksdb/rocksdb/db/error_handler.h +10 -9
  26. package/deps/rocksdb/rocksdb/db/log_test.cc +13 -6
  27. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +1 -1
  28. package/deps/rocksdb/rocksdb/db/table_cache.cc +21 -0
  29. package/deps/rocksdb/rocksdb/db/table_cache.h +5 -0
  30. package/deps/rocksdb/rocksdb/db/version_set.cc +3 -2
  31. package/deps/rocksdb/rocksdb/db/version_set.h +6 -4
  32. package/deps/rocksdb/rocksdb/db/version_set_test.cc +8 -6
  33. package/deps/rocksdb/rocksdb/db/wal_edit.cc +22 -15
  34. package/deps/rocksdb/rocksdb/db/wal_edit.h +10 -0
  35. package/deps/rocksdb/rocksdb/db/wal_edit_test.cc +4 -5
  36. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +0 -36
  37. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +1 -12
  38. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +23 -29
  39. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +0 -5
  40. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +7 -0
  41. package/deps/rocksdb/rocksdb/env/env_test.cc +0 -5
  42. package/deps/rocksdb/rocksdb/env/io_posix.cc +1 -7
  43. package/deps/rocksdb/rocksdb/options/options_test.cc +16 -0
  44. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +51 -0
  45. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +3 -0
  46. package/deps/rocksdb/rocksdb/table/table_reader.h +14 -0
  47. package/deps/rocksdb/rocksdb/table/table_test.cc +52 -0
  48. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +8 -38
  49. package/deps/rocksdb/rocksdb/util/rate_limiter.cc +27 -21
  50. package/deps/rocksdb/rocksdb/util/rate_limiter.h +12 -10
  51. package/deps/rocksdb/rocksdb/util/rate_limiter_test.cc +11 -8
  52. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +2 -1
  53. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.cc +59 -0
  54. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.h +12 -0
  55. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +31 -0
  56. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +0 -3
  57. package/package.json +1 -1
  58. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  59. package/prebuilds/linux-x64/node.napi.node +0 -0
@@ -189,7 +189,8 @@ class CompactionPicker {
189
189
  VersionStorageInfo* vstorage,
190
190
  CompactionInputFiles* inputs,
191
191
  CompactionInputFiles* output_level_inputs,
192
- int* parent_index, int base_index);
192
+ int* parent_index, int base_index,
193
+ bool only_expand_towards_right = false);
193
194
 
194
195
  void GetGrandparents(VersionStorageInfo* vstorage,
195
196
  const CompactionInputFiles& inputs,
@@ -83,7 +83,7 @@ Compaction* FIFOCompactionPicker::PickTTLCompaction(
83
83
  break;
84
84
  }
85
85
  }
86
- total_size -= f->compensated_file_size;
86
+ total_size -= f->fd.file_size;
87
87
  inputs[0].files.push_back(f);
88
88
  }
89
89
  }
@@ -191,7 +191,7 @@ Compaction* FIFOCompactionPicker::PickSizeCompaction(
191
191
 
192
192
  for (auto ritr = level_files.rbegin(); ritr != level_files.rend(); ++ritr) {
193
193
  auto f = *ritr;
194
- total_size -= f->compensated_file_size;
194
+ total_size -= f->fd.file_size;
195
195
  inputs[0].files.push_back(f);
196
196
  char tmp_fsize[16];
197
197
  AppendHumanBytes(f->fd.GetFileSize(), tmp_fsize, sizeof(tmp_fsize));
@@ -76,6 +76,9 @@ class LevelCompactionBuilder {
76
76
  // files if needed.
77
77
  bool SetupOtherL0FilesIfNeeded();
78
78
 
79
+ // Compaction with round-robin compaction priority allows more files to be
80
+ // picked to form a large compaction
81
+ void SetupOtherFilesWithRoundRobinExpansion();
79
82
  // Based on initial files, setup other files need to be compacted
80
83
  // in this compaction, accordingly.
81
84
  bool SetupOtherInputsIfNeeded();
@@ -84,7 +87,9 @@ class LevelCompactionBuilder {
84
87
 
85
88
  // For the specfied level, pick a file that we want to compact.
86
89
  // Returns false if there is no file to compact.
87
- // If it returns true, inputs->files.size() will be exactly one.
90
+ // If it returns true, inputs->files.size() will be exactly one for
91
+ // all compaction priorities except round-robin. For round-robin,
92
+ // multiple consecutive files may be put into inputs->files.
88
93
  // If level is 0 and there is already a compaction on that level, this
89
94
  // function will return false.
90
95
  bool PickFileToCompact();
@@ -278,16 +283,141 @@ bool LevelCompactionBuilder::SetupOtherL0FilesIfNeeded() {
278
283
  return true;
279
284
  }
280
285
 
286
+ void LevelCompactionBuilder::SetupOtherFilesWithRoundRobinExpansion() {
287
+ // We only expand when the start level is not L0 under round robin
288
+ assert(start_level_ >= 1);
289
+
290
+ // For round-robin compaction priority, we have 3 constraints when picking
291
+ // multiple files.
292
+ // Constraint 1: We can only pick consecutive files
293
+ // -> Constraint 1a: When a file is being compacted (or some input files
294
+ // are being compacted after expanding, we cannot
295
+ // choose it and have to stop choosing more files
296
+ // -> Constraint 1b: When we reach the last file (with largest keys), we
297
+ // cannot choose more files (the next file will be the
298
+ // first one)
299
+ // Constraint 2: We should ensure the total compaction bytes (including the
300
+ // overlapped files from the next level) is no more than
301
+ // mutable_cf_options_.max_compaction_bytes
302
+ // Constraint 3: We try our best to pick as many files as possible so that
303
+ // the post-compaction level size is less than
304
+ // MaxBytesForLevel(start_level_)
305
+ // Constraint 4: We do not expand if it is possible to apply a trivial move
306
+ // Constraint 5 (TODO): Try to pick minimal files to split into the target
307
+ // number of subcompactions
308
+ TEST_SYNC_POINT("LevelCompactionPicker::RoundRobin");
309
+
310
+ // Only expand the inputs when we have selected a file in start_level_inputs_
311
+ if (start_level_inputs_.size() == 0) return;
312
+
313
+ uint64_t start_lvl_bytes_no_compacting = 0;
314
+ uint64_t curr_bytes_to_compact = 0;
315
+ uint64_t start_lvl_max_bytes_to_compact = 0;
316
+ const std::vector<FileMetaData*>& level_files =
317
+ vstorage_->LevelFiles(start_level_);
318
+ // Constraint 3 (pre-calculate the ideal max bytes to compact)
319
+ for (auto f : level_files) {
320
+ if (!f->being_compacted) {
321
+ start_lvl_bytes_no_compacting += f->compensated_file_size;
322
+ }
323
+ }
324
+ if (start_lvl_bytes_no_compacting >
325
+ vstorage_->MaxBytesForLevel(start_level_)) {
326
+ start_lvl_max_bytes_to_compact = start_lvl_bytes_no_compacting -
327
+ vstorage_->MaxBytesForLevel(start_level_);
328
+ }
329
+
330
+ size_t start_index = vstorage_->FilesByCompactionPri(start_level_)[0];
331
+ InternalKey smallest, largest;
332
+ // Constraint 4 (No need to check again later)
333
+ compaction_picker_->GetRange(start_level_inputs_, &smallest, &largest);
334
+ CompactionInputFiles output_level_inputs;
335
+ output_level_inputs.level = output_level_;
336
+ vstorage_->GetOverlappingInputs(output_level_, &smallest, &largest,
337
+ &output_level_inputs.files);
338
+ if (output_level_inputs.empty()) {
339
+ if (TryExtendNonL0TrivialMove((int)start_index)) {
340
+ return;
341
+ }
342
+ }
343
+ // Constraint 3
344
+ if (start_level_inputs_[0]->compensated_file_size >=
345
+ start_lvl_max_bytes_to_compact) {
346
+ return;
347
+ }
348
+ CompactionInputFiles tmp_start_level_inputs;
349
+ tmp_start_level_inputs = start_level_inputs_;
350
+ // TODO (zichen): Future parallel round-robin may also need to update this
351
+ // Constraint 1b (only expand till the end)
352
+ for (size_t i = start_index + 1; i < level_files.size(); i++) {
353
+ auto* f = level_files[i];
354
+ if (f->being_compacted) {
355
+ // Constraint 1a
356
+ return;
357
+ }
358
+
359
+ tmp_start_level_inputs.files.push_back(f);
360
+ if (!compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
361
+ &tmp_start_level_inputs) ||
362
+ compaction_picker_->FilesRangeOverlapWithCompaction(
363
+ {tmp_start_level_inputs}, output_level_)) {
364
+ // Constraint 1a
365
+ tmp_start_level_inputs.clear();
366
+ return;
367
+ }
368
+
369
+ curr_bytes_to_compact = 0;
370
+ for (auto start_lvl_f : tmp_start_level_inputs.files) {
371
+ curr_bytes_to_compact += start_lvl_f->compensated_file_size;
372
+ }
373
+
374
+ // Check whether any output level files are locked
375
+ compaction_picker_->GetRange(tmp_start_level_inputs, &smallest, &largest);
376
+ vstorage_->GetOverlappingInputs(output_level_, &smallest, &largest,
377
+ &output_level_inputs.files);
378
+ if (!output_level_inputs.empty() &&
379
+ !compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
380
+ &output_level_inputs)) {
381
+ // Constraint 1a
382
+ tmp_start_level_inputs.clear();
383
+ return;
384
+ }
385
+
386
+ uint64_t start_lvl_curr_bytes_to_compact = curr_bytes_to_compact;
387
+ for (auto output_lvl_f : output_level_inputs.files) {
388
+ curr_bytes_to_compact += output_lvl_f->compensated_file_size;
389
+ }
390
+ if (curr_bytes_to_compact > mutable_cf_options_.max_compaction_bytes) {
391
+ // Constraint 2
392
+ tmp_start_level_inputs.clear();
393
+ return;
394
+ }
395
+
396
+ start_level_inputs_.files = tmp_start_level_inputs.files;
397
+ // Constraint 3
398
+ if (start_lvl_curr_bytes_to_compact > start_lvl_max_bytes_to_compact) {
399
+ return;
400
+ }
401
+ }
402
+ }
403
+
281
404
  bool LevelCompactionBuilder::SetupOtherInputsIfNeeded() {
282
405
  // Setup input files from output level. For output to L0, we only compact
283
406
  // spans of files that do not interact with any pending compactions, so don't
284
407
  // need to consider other levels.
285
408
  if (output_level_ != 0) {
286
409
  output_level_inputs_.level = output_level_;
410
+ bool round_robin_expanding =
411
+ ioptions_.compaction_pri == kRoundRobin &&
412
+ compaction_reason_ == CompactionReason::kLevelMaxLevelSize;
413
+ if (round_robin_expanding) {
414
+ SetupOtherFilesWithRoundRobinExpansion();
415
+ }
287
416
  if (!is_l0_trivial_move_ &&
288
417
  !compaction_picker_->SetupOtherInputs(
289
418
  cf_name_, mutable_cf_options_, vstorage_, &start_level_inputs_,
290
- &output_level_inputs_, &parent_index_, base_index_)) {
419
+ &output_level_inputs_, &parent_index_, base_index_,
420
+ round_robin_expanding)) {
291
421
  return false;
292
422
  }
293
423
 
@@ -606,9 +736,6 @@ bool LevelCompactionBuilder::PickFileToCompact() {
606
736
  // user-key overlap.
607
737
  start_level_inputs_.clear();
608
738
 
609
- // To ensure every file is selcted in a round-robin manner, we cannot
610
- // skip the current file. So we return false and wait for the next time
611
- // we can pick this file to compact
612
739
  if (ioptions_.compaction_pri == kRoundRobin) {
613
740
  return false;
614
741
  }
@@ -641,6 +768,7 @@ bool LevelCompactionBuilder::PickFileToCompact() {
641
768
  continue;
642
769
  }
643
770
  }
771
+
644
772
  base_index_ = index;
645
773
  break;
646
774
  }
@@ -1318,7 +1318,7 @@ TEST_F(CompactionPickerTest, CompactionPriRoundRobin) {
1318
1318
  std::vector<uint32_t> selected_files = {8U, 6U, 6U};
1319
1319
 
1320
1320
  ioptions_.compaction_pri = kRoundRobin;
1321
- mutable_cf_options_.max_bytes_for_level_base = 10000000;
1321
+ mutable_cf_options_.max_bytes_for_level_base = 12000000;
1322
1322
  mutable_cf_options_.max_bytes_for_level_multiplier = 10;
1323
1323
  for (size_t i = 0; i < test_cursors.size(); i++) {
1324
1324
  // start a brand new version in each test.
@@ -1342,6 +1342,9 @@ TEST_F(CompactionPickerTest, CompactionPriRoundRobin) {
1342
1342
  cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
1343
1343
  &log_buffer_));
1344
1344
  ASSERT_TRUE(compaction.get() != nullptr);
1345
+ // Since the max bytes for level 2 is 120M, picking one file to compact
1346
+ // makes the post-compaction level size less than 120M, there is exactly one
1347
+ // file picked for round-robin compaction
1345
1348
  ASSERT_EQ(1U, compaction->num_input_files(0));
1346
1349
  ASSERT_EQ(selected_files[i], compaction->input(0, 0)->fd.GetNumber());
1347
1350
  // release the version storage
@@ -1349,6 +1352,132 @@ TEST_F(CompactionPickerTest, CompactionPriRoundRobin) {
1349
1352
  }
1350
1353
  }
1351
1354
 
1355
+ TEST_F(CompactionPickerTest, CompactionPriMultipleFilesRoundRobin1) {
1356
+ ioptions_.compaction_pri = kRoundRobin;
1357
+ mutable_cf_options_.max_compaction_bytes = 100000000u;
1358
+ mutable_cf_options_.max_bytes_for_level_base = 120;
1359
+ mutable_cf_options_.max_bytes_for_level_multiplier = 10;
1360
+ // start a brand new version in each test.
1361
+ NewVersionStorage(6, kCompactionStyleLevel);
1362
+ vstorage_->ResizeCompactCursors(6);
1363
+ // Set the cursor (file picking should start with 7U)
1364
+ vstorage_->AddCursorForOneLevel(2, InternalKey("199", 100, kTypeValue));
1365
+ Add(2, 6U, "150", "199", 500U);
1366
+ Add(2, 7U, "200", "249", 500U);
1367
+ Add(2, 8U, "300", "600", 500U);
1368
+ Add(2, 9U, "700", "800", 500U);
1369
+ Add(2, 10U, "850", "950", 500U);
1370
+
1371
+ Add(3, 26U, "130", "165", 600U);
1372
+ Add(3, 27U, "166", "170", 600U);
1373
+ Add(3, 28U, "270", "340", 600U);
1374
+ Add(3, 29U, "401", "500", 600U);
1375
+ Add(3, 30U, "601", "800", 600U);
1376
+ Add(3, 31U, "830", "890", 600U);
1377
+ UpdateVersionStorageInfo();
1378
+ LevelCompactionPicker local_level_compaction_picker =
1379
+ LevelCompactionPicker(ioptions_, &icmp_);
1380
+ std::unique_ptr<Compaction> compaction(
1381
+ local_level_compaction_picker.PickCompaction(
1382
+ cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
1383
+ &log_buffer_));
1384
+ ASSERT_TRUE(compaction.get() != nullptr);
1385
+
1386
+ // The maximum compaction bytes is very large in this case so we can igore its
1387
+ // constraint in this test case. The maximum bytes for level 2 is 1200
1388
+ // bytes, and thus at least 3 files should be picked so that the bytes in
1389
+ // level 2 is less than the maximum
1390
+ ASSERT_EQ(3U, compaction->num_input_files(0));
1391
+ ASSERT_EQ(7U, compaction->input(0, 0)->fd.GetNumber());
1392
+ ASSERT_EQ(8U, compaction->input(0, 1)->fd.GetNumber());
1393
+ ASSERT_EQ(9U, compaction->input(0, 2)->fd.GetNumber());
1394
+ // release the version storage
1395
+ DeleteVersionStorage();
1396
+ }
1397
+
1398
+ TEST_F(CompactionPickerTest, CompactionPriMultipleFilesRoundRobin2) {
1399
+ ioptions_.compaction_pri = kRoundRobin;
1400
+ mutable_cf_options_.max_compaction_bytes = 2500u;
1401
+ mutable_cf_options_.max_bytes_for_level_base = 120;
1402
+ mutable_cf_options_.max_bytes_for_level_multiplier = 10;
1403
+ // start a brand new version in each test.
1404
+ NewVersionStorage(6, kCompactionStyleLevel);
1405
+ vstorage_->ResizeCompactCursors(6);
1406
+ // Set the cursor (file picking should start with 6U)
1407
+ vstorage_->AddCursorForOneLevel(2, InternalKey("1000", 100, kTypeValue));
1408
+ Add(2, 6U, "150", "199", 500U); // Overlap with 26U, 27U
1409
+ Add(2, 7U, "200", "249", 500U); // Overlap with 27U
1410
+ Add(2, 8U, "300", "600", 500U); // Overlap with 28U, 29U
1411
+ Add(2, 9U, "700", "800", 500U);
1412
+ Add(2, 10U, "850", "950", 500U);
1413
+
1414
+ Add(3, 26U, "130", "165", 600U);
1415
+ Add(3, 27U, "166", "230", 600U);
1416
+ Add(3, 28U, "270", "340", 600U);
1417
+ Add(3, 29U, "401", "500", 600U);
1418
+ Add(3, 30U, "601", "800", 600U);
1419
+ Add(3, 31U, "830", "890", 600U);
1420
+ UpdateVersionStorageInfo();
1421
+ LevelCompactionPicker local_level_compaction_picker =
1422
+ LevelCompactionPicker(ioptions_, &icmp_);
1423
+ std::unique_ptr<Compaction> compaction(
1424
+ local_level_compaction_picker.PickCompaction(
1425
+ cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
1426
+ &log_buffer_));
1427
+ ASSERT_TRUE(compaction.get() != nullptr);
1428
+
1429
+ // The maximum compaction bytes is only 2500 bytes now. Even though we are
1430
+ // required to choose 3 files so that the post-compaction level size is less
1431
+ // than 1200 bytes. We cannot pick 3 files to compact since the maximum
1432
+ // compaction size is 2500. After picking files 6U and 7U, the number of
1433
+ // compaction bytes has reached 2200, and thus no more space to add another
1434
+ // input file with 50M bytes.
1435
+ ASSERT_EQ(2U, compaction->num_input_files(0));
1436
+ ASSERT_EQ(6U, compaction->input(0, 0)->fd.GetNumber());
1437
+ ASSERT_EQ(7U, compaction->input(0, 1)->fd.GetNumber());
1438
+ // release the version storage
1439
+ DeleteVersionStorage();
1440
+ }
1441
+
1442
+ TEST_F(CompactionPickerTest, CompactionPriMultipleFilesRoundRobin3) {
1443
+ ioptions_.compaction_pri = kRoundRobin;
1444
+ mutable_cf_options_.max_compaction_bytes = 1000000u;
1445
+ mutable_cf_options_.max_bytes_for_level_base = 120;
1446
+ mutable_cf_options_.max_bytes_for_level_multiplier = 10;
1447
+ // start a brand new version in each test.
1448
+ NewVersionStorage(6, kCompactionStyleLevel);
1449
+ vstorage_->ResizeCompactCursors(6);
1450
+ // Set the cursor (file picking should start with 9U)
1451
+ vstorage_->AddCursorForOneLevel(2, InternalKey("700", 100, kTypeValue));
1452
+ Add(2, 6U, "150", "199", 500U);
1453
+ Add(2, 7U, "200", "249", 500U);
1454
+ Add(2, 8U, "300", "600", 500U);
1455
+ Add(2, 9U, "700", "800", 500U);
1456
+ Add(2, 10U, "850", "950", 500U);
1457
+
1458
+ Add(3, 26U, "130", "165", 600U);
1459
+ Add(3, 27U, "166", "170", 600U);
1460
+ Add(3, 28U, "270", "340", 600U);
1461
+ Add(3, 29U, "401", "500", 600U);
1462
+ Add(3, 30U, "601", "800", 600U);
1463
+ Add(3, 31U, "830", "890", 600U);
1464
+ UpdateVersionStorageInfo();
1465
+ LevelCompactionPicker local_level_compaction_picker =
1466
+ LevelCompactionPicker(ioptions_, &icmp_);
1467
+ std::unique_ptr<Compaction> compaction(
1468
+ local_level_compaction_picker.PickCompaction(
1469
+ cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
1470
+ &log_buffer_));
1471
+ ASSERT_TRUE(compaction.get() != nullptr);
1472
+
1473
+ // Cannot pick more files since we reach the last file in level 2
1474
+ ASSERT_EQ(2U, compaction->num_input_files(0));
1475
+ ASSERT_EQ(9U, compaction->input(0, 0)->fd.GetNumber());
1476
+ ASSERT_EQ(10U, compaction->input(0, 1)->fd.GetNumber());
1477
+ // release the version storage
1478
+ DeleteVersionStorage();
1479
+ }
1480
+
1352
1481
  TEST_F(CompactionPickerTest, CompactionPriMinOverlappingManyFiles) {
1353
1482
  NewVersionStorage(6, kCompactionStyleLevel);
1354
1483
  ioptions_.compaction_pri = kMinOverlappingRatio;
@@ -47,10 +47,10 @@ CompactionJob::ProcessKeyValueCompactionWithCompactionService(
47
47
  compaction_input.db_options =
48
48
  BuildDBOptions(db_options_, mutable_db_options_copy_);
49
49
  compaction_input.snapshots = existing_snapshots_;
50
- compaction_input.has_begin = sub_compact->start;
50
+ compaction_input.has_begin = sub_compact->start.has_value();
51
51
  compaction_input.begin =
52
52
  compaction_input.has_begin ? sub_compact->start->ToString() : "";
53
- compaction_input.has_end = sub_compact->end;
53
+ compaction_input.has_end = sub_compact->end.has_value();
54
54
  compaction_input.end =
55
55
  compaction_input.has_end ? sub_compact->end->ToString() : "";
56
56
 
@@ -264,8 +264,12 @@ Status CompactionServiceCompactionJob::Run() {
264
264
  Slice begin = compaction_input_.begin;
265
265
  Slice end = compaction_input_.end;
266
266
  compact_->sub_compact_states.emplace_back(
267
- c, compaction_input_.has_begin ? &begin : nullptr,
268
- compaction_input_.has_end ? &end : nullptr, /*sub_job_id*/ 0);
267
+ c,
268
+ compaction_input_.has_begin ? std::optional<Slice>(begin)
269
+ : std::optional<Slice>(),
270
+ compaction_input_.has_end ? std::optional<Slice>(end)
271
+ : std::optional<Slice>(),
272
+ /*sub_job_id*/ 0);
269
273
 
270
274
  log_buffer_->FlushBufferToLog();
271
275
  LogCompaction();
@@ -10,6 +10,8 @@
10
10
 
11
11
  #pragma once
12
12
 
13
+ #include <optional>
14
+
13
15
  #include "db/blob/blob_file_addition.h"
14
16
  #include "db/blob/blob_garbage_meter.h"
15
17
  #include "db/compaction/compaction.h"
@@ -52,7 +54,7 @@ class SubcompactionState {
52
54
  // The boundaries of the key-range this compaction is interested in. No two
53
55
  // sub-compactions may have overlapping key-ranges.
54
56
  // 'start' is inclusive, 'end' is exclusive, and nullptr means unbounded
55
- const Slice *start, *end;
57
+ const std::optional<Slice> start, end;
56
58
 
57
59
  // The return status of this sub-compaction
58
60
  Status status;
@@ -117,8 +119,8 @@ class SubcompactionState {
117
119
  SubcompactionState(const SubcompactionState&) = delete;
118
120
  SubcompactionState& operator=(const SubcompactionState&) = delete;
119
121
 
120
- SubcompactionState(Compaction* c, Slice* _start, Slice* _end,
121
- uint32_t _sub_job_id)
122
+ SubcompactionState(Compaction* c, const std::optional<Slice> _start,
123
+ const std::optional<Slice> _end, uint32_t _sub_job_id)
122
124
  : compaction(c),
123
125
  start(_start),
124
126
  end(_end),
@@ -132,12 +134,12 @@ class SubcompactionState {
132
134
  // Invalid output_split_key indicates that we do not need to split
133
135
  if (output_split_key != nullptr) {
134
136
  // We may only split the output when the cursor is in the range. Split
135
- if ((end == nullptr || icmp->user_comparator()->Compare(
136
- ExtractUserKey(output_split_key->Encode()),
137
- ExtractUserKey(*end)) < 0) &&
138
- (start == nullptr || icmp->user_comparator()->Compare(
139
- ExtractUserKey(output_split_key->Encode()),
140
- ExtractUserKey(*start)) > 0)) {
137
+ if ((!end.has_value() ||
138
+ icmp->user_comparator()->Compare(
139
+ ExtractUserKey(output_split_key->Encode()), end.value()) < 0) &&
140
+ (!start.has_value() || icmp->user_comparator()->Compare(
141
+ ExtractUserKey(output_split_key->Encode()),
142
+ start.value()) > 0)) {
141
143
  local_output_split_key_ = output_split_key;
142
144
  }
143
145
  }