@nxtedition/rocksdb 7.0.4 → 7.0.7

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 (128) hide show
  1. package/binding.cc +320 -324
  2. package/chained-batch.js +6 -1
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +8 -3
  4. package/deps/rocksdb/rocksdb/Makefile +10 -4
  5. package/deps/rocksdb/rocksdb/TARGETS +6 -4
  6. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +9 -0
  7. package/deps/rocksdb/rocksdb/cache/cache_test.cc +14 -0
  8. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +8 -8
  9. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +272 -174
  10. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +201 -57
  11. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +19 -19
  12. package/deps/rocksdb/rocksdb/cache/lru_cache.h +2 -1
  13. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +170 -0
  14. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +95 -0
  15. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +298 -0
  16. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +172 -0
  17. package/deps/rocksdb/rocksdb/db/column_family.cc +8 -3
  18. package/deps/rocksdb/rocksdb/db/column_family.h +6 -3
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +10 -0
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +6 -6
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +22 -2
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +38 -0
  23. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +17 -5
  24. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +4 -7
  25. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +74 -71
  26. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +70 -1
  27. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +13 -12
  28. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +36 -0
  29. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +11 -4
  30. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +1 -1
  31. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +139 -91
  32. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +48 -14
  33. package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +90 -55
  34. package/deps/rocksdb/rocksdb/db/db_rate_limiter_test.cc +9 -4
  35. package/deps/rocksdb/rocksdb/db/db_test.cc +3 -1
  36. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +12 -7
  37. package/deps/rocksdb/rocksdb/db/db_write_test.cc +35 -0
  38. package/deps/rocksdb/rocksdb/db/dbformat.cc +3 -1
  39. package/deps/rocksdb/rocksdb/db/dbformat.h +5 -3
  40. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +1 -1
  41. package/deps/rocksdb/rocksdb/db/memtable.cc +1 -0
  42. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +4 -2
  43. package/deps/rocksdb/rocksdb/db/repair.cc +1 -1
  44. package/deps/rocksdb/rocksdb/db/version_builder.cc +43 -1
  45. package/deps/rocksdb/rocksdb/db/version_edit.cc +13 -5
  46. package/deps/rocksdb/rocksdb/db/version_edit.h +22 -1
  47. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +4 -5
  48. package/deps/rocksdb/rocksdb/db/version_set.cc +109 -41
  49. package/deps/rocksdb/rocksdb/db/version_set.h +36 -3
  50. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -4
  51. package/deps/rocksdb/rocksdb/db/version_set_test.cc +10 -10
  52. package/deps/rocksdb/rocksdb/db/version_util.h +1 -1
  53. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +1 -1
  54. package/deps/rocksdb/rocksdb/db/write_batch.cc +34 -10
  55. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +2 -0
  56. package/deps/rocksdb/rocksdb/db/write_callback_test.cc +4 -0
  57. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +2 -0
  58. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +4 -1
  59. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -1
  60. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +7 -5
  61. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +5 -10
  62. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +0 -7
  63. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +2 -0
  64. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +24 -3
  65. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +8 -0
  66. package/deps/rocksdb/rocksdb/file/writable_file_writer.h +10 -0
  67. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +5 -0
  68. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +4 -4
  69. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +9 -5
  70. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +5 -0
  71. package/deps/rocksdb/rocksdb/include/rocksdb/types.h +1 -0
  72. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +1 -1
  73. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +1 -1
  74. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +0 -3
  75. package/deps/rocksdb/rocksdb/microbench/ribbon_bench.cc +8 -6
  76. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +3 -1
  77. package/deps/rocksdb/rocksdb/options/options_helper.cc +4 -2
  78. package/deps/rocksdb/rocksdb/options/options_test.cc +1 -11
  79. package/deps/rocksdb/rocksdb/port/port_posix.h +7 -0
  80. package/deps/rocksdb/rocksdb/port/win/port_win.h +11 -3
  81. package/deps/rocksdb/rocksdb/src.mk +6 -2
  82. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +4 -33
  83. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +3 -3
  84. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +38 -118
  85. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +6 -8
  86. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +10 -13
  87. package/deps/rocksdb/rocksdb/table/block_based/block_like_traits.h +4 -9
  88. package/deps/rocksdb/rocksdb/table/block_based/block_type.h +0 -1
  89. package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +10 -28
  90. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +2 -3
  91. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +0 -91
  92. package/deps/rocksdb/rocksdb/table/block_based/filter_policy_internal.h +2 -30
  93. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +6 -27
  94. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +11 -13
  95. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +28 -40
  96. package/deps/rocksdb/rocksdb/table/block_based/mock_block_based_table.h +0 -1
  97. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +22 -43
  98. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +11 -22
  99. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +24 -25
  100. package/deps/rocksdb/rocksdb/table/block_fetcher.cc +0 -1
  101. package/deps/rocksdb/rocksdb/table/get_context.h +0 -1
  102. package/deps/rocksdb/rocksdb/table/table_test.cc +3 -18
  103. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +3 -16
  104. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +3 -3
  105. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +1 -1
  106. package/deps/rocksdb/rocksdb/util/bloom_test.cc +0 -201
  107. package/deps/rocksdb/rocksdb/util/distributed_mutex.h +48 -0
  108. package/deps/rocksdb/rocksdb/util/filter_bench.cc +5 -11
  109. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +3 -0
  110. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +7 -21
  111. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +1 -1
  112. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +45 -0
  113. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.h +21 -14
  114. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +10 -1
  115. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +3 -1
  116. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.cc +9 -0
  117. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn.cc +3 -2
  118. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn_db.cc +3 -1
  119. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +5 -4
  120. package/deps/rocksdb/rocksdb.gyp +1 -1
  121. package/index.js +36 -14
  122. package/package-lock.json +2 -2
  123. package/package.json +1 -1
  124. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  125. package/prebuilds/linux-x64/node.napi.node +0 -0
  126. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.cc +0 -358
  127. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.h +0 -127
  128. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block_test.cc +0 -219
@@ -37,8 +37,6 @@ std::shared_ptr<const FilterPolicy> Create(double bits_per_key,
37
37
  return BloomLikeFilterPolicy::Create(name, bits_per_key);
38
38
  }
39
39
  const std::string kLegacyBloom = test::LegacyBloomFilterPolicy::kClassName();
40
- const std::string kDeprecatedBlock =
41
- DeprecatedBlockBasedBloomFilterPolicy::kClassName();
42
40
  const std::string kFastLocalBloom =
43
41
  test::FastLocalBloomFilterPolicy::kClassName();
44
42
  const std::string kStandard128Ribbon =
@@ -189,7 +187,7 @@ TEST_F(DBBloomFilterTest, GetFilterByPrefixBloomCustomPrefixExtractor) {
189
187
  options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
190
188
  get_perf_context()->EnablePerLevelPerfContext();
191
189
  BlockBasedTableOptions bbto;
192
- bbto.filter_policy.reset(NewBloomFilterPolicy(10, false));
190
+ bbto.filter_policy.reset(NewBloomFilterPolicy(10));
193
191
  if (partition_filters) {
194
192
  bbto.partition_filters = true;
195
193
  bbto.index_type = BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
@@ -256,6 +254,15 @@ TEST_F(DBBloomFilterTest, GetFilterByPrefixBloomCustomPrefixExtractor) {
256
254
  (*(get_perf_context()->level_to_perf_context))[0].bloom_filter_useful);
257
255
  #endif // ROCKSDB_LITE
258
256
 
257
+ // No bloom on extractor changed, after re-open
258
+ options.prefix_extractor.reset(NewCappedPrefixTransform(10));
259
+ Reopen(options);
260
+ ASSERT_EQ("NOT_FOUND", Get("foobarbar"));
261
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_USEFUL), 3);
262
+ ASSERT_EQ(
263
+ 3,
264
+ (*(get_perf_context()->level_to_perf_context))[0].bloom_filter_useful);
265
+
259
266
  get_perf_context()->Reset();
260
267
  }
261
268
  }
@@ -267,7 +274,7 @@ TEST_F(DBBloomFilterTest, GetFilterByPrefixBloom) {
267
274
  options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
268
275
  get_perf_context()->EnablePerLevelPerfContext();
269
276
  BlockBasedTableOptions bbto;
270
- bbto.filter_policy.reset(NewBloomFilterPolicy(10, false));
277
+ bbto.filter_policy.reset(NewBloomFilterPolicy(10));
271
278
  if (partition_filters) {
272
279
  bbto.partition_filters = true;
273
280
  bbto.index_type = BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
@@ -331,7 +338,7 @@ TEST_F(DBBloomFilterTest, WholeKeyFilterProp) {
331
338
  get_perf_context()->EnablePerLevelPerfContext();
332
339
 
333
340
  BlockBasedTableOptions bbto;
334
- bbto.filter_policy.reset(NewBloomFilterPolicy(10, false));
341
+ bbto.filter_policy.reset(NewBloomFilterPolicy(10));
335
342
  bbto.whole_key_filtering = false;
336
343
  if (partition_filters) {
337
344
  bbto.partition_filters = true;
@@ -747,7 +754,6 @@ TEST_P(DBBloomFilterTestWithParam, SkipFilterOnEssentiallyZeroBpk) {
747
754
  INSTANTIATE_TEST_CASE_P(
748
755
  FormatDef, DBBloomFilterTestDefFormatVersion,
749
756
  ::testing::Values(
750
- std::make_tuple(kDeprecatedBlock, false, test::kDefaultFormatVersion),
751
757
  std::make_tuple(kAutoBloom, true, test::kDefaultFormatVersion),
752
758
  std::make_tuple(kAutoBloom, false, test::kDefaultFormatVersion),
753
759
  std::make_tuple(kAutoRibbon, false, test::kDefaultFormatVersion)));
@@ -755,7 +761,6 @@ INSTANTIATE_TEST_CASE_P(
755
761
  INSTANTIATE_TEST_CASE_P(
756
762
  FormatDef, DBBloomFilterTestWithParam,
757
763
  ::testing::Values(
758
- std::make_tuple(kDeprecatedBlock, false, test::kDefaultFormatVersion),
759
764
  std::make_tuple(kAutoBloom, true, test::kDefaultFormatVersion),
760
765
  std::make_tuple(kAutoBloom, false, test::kDefaultFormatVersion),
761
766
  std::make_tuple(kAutoRibbon, false, test::kDefaultFormatVersion)));
@@ -763,7 +768,6 @@ INSTANTIATE_TEST_CASE_P(
763
768
  INSTANTIATE_TEST_CASE_P(
764
769
  FormatLatest, DBBloomFilterTestWithParam,
765
770
  ::testing::Values(
766
- std::make_tuple(kDeprecatedBlock, false, kLatestFormatVersion),
767
771
  std::make_tuple(kAutoBloom, true, kLatestFormatVersion),
768
772
  std::make_tuple(kAutoBloom, false, kLatestFormatVersion),
769
773
  std::make_tuple(kAutoRibbon, false, kLatestFormatVersion)));
@@ -829,8 +833,6 @@ std::shared_ptr<const FilterPolicy> kCompatibilityRibbonPolicy{
829
833
  NewRibbonFilterPolicy(20, -1)};
830
834
 
831
835
  std::vector<CompatibilityConfig> kCompatibilityConfigs = {
832
- {Create(20, kDeprecatedBlock), false,
833
- BlockBasedTableOptions().format_version},
834
836
  {kCompatibilityBloomPolicy, false, BlockBasedTableOptions().format_version},
835
837
  {kCompatibilityBloomPolicy, true, BlockBasedTableOptions().format_version},
836
838
  {kCompatibilityBloomPolicy, false, /* legacy Bloom */ 4U},
@@ -878,9 +880,8 @@ TEST_F(DBBloomFilterTest, BloomFilterCompatibility) {
878
880
  ASSERT_EQ("val", Get(prefix + "Z")); // Filter positive
879
881
  // Filter negative, with high probability
880
882
  ASSERT_EQ("NOT_FOUND", Get(prefix + "Q"));
881
- // FULL_POSITIVE does not include block-based filter case (j == 0)
882
883
  EXPECT_EQ(TestGetAndResetTickerCount(options, BLOOM_FILTER_FULL_POSITIVE),
883
- j == 0 ? 0 : 2);
884
+ 2);
884
885
  EXPECT_EQ(TestGetAndResetTickerCount(options, BLOOM_FILTER_USEFUL), 1);
885
886
  }
886
887
  }
@@ -904,7 +905,7 @@ class ChargeFilterConstructionTestWithParam
904
905
  detect_filter_construct_corruption_(std::get<3>(GetParam())) {
905
906
  if (charge_filter_construction_ ==
906
907
  CacheEntryRoleOptions::Decision::kDisabled ||
907
- policy_ == kDeprecatedBlock || policy_ == kLegacyBloom) {
908
+ policy_ == kLegacyBloom) {
908
909
  // For these cases, we only interested in whether filter construction
909
910
  // cache charging happens instead of its accuracy. Therefore we don't
910
911
  // need many keys.
@@ -1031,8 +1032,6 @@ INSTANTIATE_TEST_CASE_P(
1031
1032
  std::make_tuple(CacheEntryRoleOptions::Decision::kEnabled,
1032
1033
  kStandard128Ribbon, true, true),
1033
1034
 
1034
- std::make_tuple(CacheEntryRoleOptions::Decision::kEnabled,
1035
- kDeprecatedBlock, false, false),
1036
1035
  std::make_tuple(CacheEntryRoleOptions::Decision::kEnabled, kLegacyBloom,
1037
1036
  false, false)));
1038
1037
 
@@ -1109,11 +1108,10 @@ TEST_P(ChargeFilterConstructionTestWithParam, Basic) {
1109
1108
  return;
1110
1109
  }
1111
1110
 
1112
- if (policy == kDeprecatedBlock || policy == kLegacyBloom) {
1111
+ if (policy == kLegacyBloom) {
1113
1112
  EXPECT_EQ(filter_construction_cache_res_peaks.size(), 0)
1114
1113
  << "There shouldn't be filter construction cache charging as this "
1115
- "feature does not support kDeprecatedBlock "
1116
- "nor kLegacyBloom";
1114
+ "feature does not support kLegacyBloom";
1117
1115
  return;
1118
1116
  }
1119
1117
 
@@ -1798,10 +1796,9 @@ class SliceTransformLimitedDomain : public SliceTransform {
1798
1796
  }
1799
1797
  };
1800
1798
 
1801
- TEST_F(DBBloomFilterTest, PrefixExtractorFullFilter) {
1799
+ TEST_F(DBBloomFilterTest, PrefixExtractorWithFilter1) {
1802
1800
  BlockBasedTableOptions bbto;
1803
- // Full Filter Block
1804
- bbto.filter_policy.reset(ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
1801
+ bbto.filter_policy.reset(ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10));
1805
1802
  bbto.whole_key_filtering = false;
1806
1803
 
1807
1804
  Options options = CurrentOptions();
@@ -1827,10 +1824,9 @@ TEST_F(DBBloomFilterTest, PrefixExtractorFullFilter) {
1827
1824
  ASSERT_EQ(Get("zzzzz_AAAA"), "val5");
1828
1825
  }
1829
1826
 
1830
- TEST_F(DBBloomFilterTest, PrefixExtractorBlockFilter) {
1827
+ TEST_F(DBBloomFilterTest, PrefixExtractorWithFilter2) {
1831
1828
  BlockBasedTableOptions bbto;
1832
- // Block Filter Block
1833
- bbto.filter_policy.reset(ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, true));
1829
+ bbto.filter_policy.reset(ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10));
1834
1830
 
1835
1831
  Options options = CurrentOptions();
1836
1832
  options.prefix_extractor = std::make_shared<SliceTransformLimitedDomain>();
@@ -2221,7 +2217,6 @@ class BloomStatsTestWithParam
2221
2217
  } else {
2222
2218
  BlockBasedTableOptions table_options;
2223
2219
  if (partition_filters_) {
2224
- assert(bfp_impl_ != kDeprecatedBlock);
2225
2220
  table_options.partition_filters = partition_filters_;
2226
2221
  table_options.index_type =
2227
2222
  BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
@@ -2346,9 +2341,7 @@ TEST_P(BloomStatsTestWithParam, BloomStatsTestWithIter) {
2346
2341
  ASSERT_OK(iter->status());
2347
2342
  ASSERT_TRUE(iter->Valid());
2348
2343
  ASSERT_EQ(value3, iter->value().ToString());
2349
- // The seek doesn't check block-based bloom filter because last index key
2350
- // starts with the same prefix we're seeking to.
2351
- uint64_t expected_hits = bfp_impl_ == kDeprecatedBlock ? 1 : 2;
2344
+ uint64_t expected_hits = 2;
2352
2345
  ASSERT_EQ(expected_hits, get_perf_context()->bloom_sst_hit_count);
2353
2346
 
2354
2347
  iter->Seek(key2);
@@ -2360,8 +2353,7 @@ TEST_P(BloomStatsTestWithParam, BloomStatsTestWithIter) {
2360
2353
 
2361
2354
  INSTANTIATE_TEST_CASE_P(
2362
2355
  BloomStatsTestWithParam, BloomStatsTestWithParam,
2363
- ::testing::Values(std::make_tuple(kDeprecatedBlock, false),
2364
- std::make_tuple(kLegacyBloom, false),
2356
+ ::testing::Values(std::make_tuple(kLegacyBloom, false),
2365
2357
  std::make_tuple(kLegacyBloom, true),
2366
2358
  std::make_tuple(kFastLocalBloom, false),
2367
2359
  std::make_tuple(kFastLocalBloom, true),
@@ -2486,7 +2478,7 @@ TEST_F(DBBloomFilterTest, OptimizeFiltersForHits) {
2486
2478
  options.level_compaction_dynamic_level_bytes = true;
2487
2479
  BlockBasedTableOptions bbto;
2488
2480
  bbto.cache_index_and_filter_blocks = true;
2489
- bbto.filter_policy.reset(NewBloomFilterPolicy(10, true));
2481
+ bbto.filter_policy.reset(NewBloomFilterPolicy(10));
2490
2482
  bbto.whole_key_filtering = true;
2491
2483
  options.table_factory.reset(NewBlockBasedTableFactory(bbto));
2492
2484
  options.optimize_filters_for_hits = true;
@@ -2674,7 +2666,6 @@ int CountIter(std::unique_ptr<Iterator>& iter, const Slice& key) {
2674
2666
  // as the upper bound and two keys are adjacent according to the comparator.
2675
2667
  TEST_F(DBBloomFilterTest, DynamicBloomFilterUpperBound) {
2676
2668
  for (const auto& bfp_impl : BloomLikeFilterPolicy::GetAllFixedImpls()) {
2677
- int using_full_builder = bfp_impl != kDeprecatedBlock;
2678
2669
  Options options;
2679
2670
  options.create_if_missing = true;
2680
2671
  options.env = CurrentOptions().env;
@@ -2726,8 +2717,7 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterUpperBound) {
2726
2717
  std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
2727
2718
  ASSERT_EQ(CountIter(iter, "abcdxx00"), 4);
2728
2719
  // should check bloom filter since upper bound meets requirement
2729
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2730
- 2 + using_full_builder);
2720
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 3);
2731
2721
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 0);
2732
2722
  }
2733
2723
  {
@@ -2740,8 +2730,7 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterUpperBound) {
2740
2730
  std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
2741
2731
  ASSERT_EQ(CountIter(iter, "abcdxx01"), 4);
2742
2732
  // should skip bloom filter since upper bound is too long
2743
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2744
- 2 + using_full_builder);
2733
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 3);
2745
2734
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 0);
2746
2735
  }
2747
2736
  {
@@ -2754,8 +2743,7 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterUpperBound) {
2754
2743
  ASSERT_EQ(CountIter(iter, "abcdxx02"), 4);
2755
2744
  // should check bloom filter since upper bound matches transformed seek
2756
2745
  // key
2757
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2758
- 2 + using_full_builder * 2);
2746
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 4);
2759
2747
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 0);
2760
2748
  }
2761
2749
  {
@@ -2768,8 +2756,7 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterUpperBound) {
2768
2756
  std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
2769
2757
  ASSERT_EQ(CountIter(iter, "aaaaaaaa"), 0);
2770
2758
  // should skip bloom filter since mismatch is found
2771
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2772
- 2 + using_full_builder * 2);
2759
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 4);
2773
2760
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 0);
2774
2761
  }
2775
2762
  ASSERT_OK(dbfull()->SetOptions({{"prefix_extractor", "fixed:3"}}));
@@ -2782,23 +2769,52 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterUpperBound) {
2782
2769
  read_options.iterate_upper_bound = &upper_bound;
2783
2770
  std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
2784
2771
  ASSERT_EQ(CountIter(iter, "abc"), 4);
2785
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2786
- 2 + using_full_builder * 2);
2772
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 4);
2773
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 0);
2774
+ }
2775
+ // Same with re-open
2776
+ options.prefix_extractor.reset(NewFixedPrefixTransform(3));
2777
+ Reopen(options);
2778
+ {
2779
+ Slice upper_bound("abd");
2780
+ ReadOptions read_options;
2781
+ read_options.prefix_same_as_start = true;
2782
+ read_options.iterate_upper_bound = &upper_bound;
2783
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
2784
+ ASSERT_EQ(CountIter(iter, "abc"), 4);
2785
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 4);
2787
2786
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 0);
2788
2787
  }
2789
- ASSERT_OK(dbfull()->SetOptions({{"prefix_extractor", "capped:4"}}));
2788
+ // Set back to capped:4 and verify BF is always read
2789
+ options.prefix_extractor.reset(NewCappedPrefixTransform(4));
2790
+ Reopen(options);
2790
2791
  {
2791
- // set back to capped:4 and verify BF is always read
2792
2792
  Slice upper_bound("abd");
2793
2793
  ReadOptions read_options;
2794
2794
  read_options.prefix_same_as_start = true;
2795
2795
  read_options.iterate_upper_bound = &upper_bound;
2796
2796
  std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
2797
2797
  ASSERT_EQ(CountIter(iter, "abc"), 0);
2798
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2799
- 3 + using_full_builder * 2);
2798
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 5);
2800
2799
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 1);
2801
2800
  }
2801
+ // Same if there's a problem initally loading prefix transform
2802
+ SyncPoint::GetInstance()->SetCallBack(
2803
+ "BlockBasedTable::Open::ForceNullTablePrefixExtractor",
2804
+ [&](void* arg) { *static_cast<bool*>(arg) = true; });
2805
+ SyncPoint::GetInstance()->EnableProcessing();
2806
+ Reopen(options);
2807
+ {
2808
+ Slice upper_bound("abd");
2809
+ ReadOptions read_options;
2810
+ read_options.prefix_same_as_start = true;
2811
+ read_options.iterate_upper_bound = &upper_bound;
2812
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
2813
+ ASSERT_EQ(CountIter(iter, "abc"), 0);
2814
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 6);
2815
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 2);
2816
+ }
2817
+ SyncPoint::GetInstance()->DisableProcessing();
2802
2818
  }
2803
2819
  }
2804
2820
 
@@ -2806,7 +2822,6 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterUpperBound) {
2806
2822
  // verify iterators can read all SST files using the latest config.
2807
2823
  TEST_F(DBBloomFilterTest, DynamicBloomFilterMultipleSST) {
2808
2824
  for (const auto& bfp_impl : BloomLikeFilterPolicy::GetAllFixedImpls()) {
2809
- int using_full_builder = bfp_impl != kDeprecatedBlock;
2810
2825
  Options options;
2811
2826
  options.env = CurrentOptions().env;
2812
2827
  options.create_if_missing = true;
@@ -2840,11 +2855,9 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterMultipleSST) {
2840
2855
  read_options.iterate_upper_bound = &upper_bound;
2841
2856
  std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
2842
2857
  ASSERT_EQ(CountIter(iter, "foo"), 2);
2843
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2844
- 1 + using_full_builder);
2858
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 2);
2845
2859
  ASSERT_EQ(CountIter(iter, "gpk"), 0);
2846
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2847
- 1 + using_full_builder);
2860
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 2);
2848
2861
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 0);
2849
2862
 
2850
2863
  // second SST with capped:3 BF
@@ -2857,14 +2870,12 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterMultipleSST) {
2857
2870
  // BF is cappped:3 now
2858
2871
  std::unique_ptr<Iterator> iter_tmp(db_->NewIterator(read_options));
2859
2872
  ASSERT_EQ(CountIter(iter_tmp, "foo"), 4);
2860
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2861
- 2 + using_full_builder * 2);
2873
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 4);
2862
2874
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 0);
2863
2875
  ASSERT_EQ(CountIter(iter_tmp, "gpk"), 0);
2864
2876
  // both counters are incremented because BF is "not changed" for 1 of the
2865
2877
  // 2 SST files, so filter is checked once and found no match.
2866
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2867
- 3 + using_full_builder * 2);
2878
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 5);
2868
2879
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 1);
2869
2880
  }
2870
2881
 
@@ -2882,25 +2893,21 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterMultipleSST) {
2882
2893
  std::unique_ptr<Iterator> iter_tmp(db_->NewIterator(read_options));
2883
2894
  ASSERT_EQ(CountIter(iter_tmp, "foo"), 9);
2884
2895
  // the first and last BF are checked
2885
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2886
- 4 + using_full_builder * 3);
2896
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 7);
2887
2897
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 1);
2888
2898
  ASSERT_EQ(CountIter(iter_tmp, "gpk"), 0);
2889
2899
  // only last BF is checked and not found
2890
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2891
- 5 + using_full_builder * 3);
2900
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 8);
2892
2901
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 2);
2893
2902
  }
2894
2903
 
2895
2904
  // iter_old can only see the first SST, so checked plus 1
2896
2905
  ASSERT_EQ(CountIter(iter_old, "foo"), 4);
2897
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2898
- 6 + using_full_builder * 3);
2906
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 9);
2899
2907
  // iter was created after the first setoptions call so only full filter
2900
2908
  // will check the filter
2901
2909
  ASSERT_EQ(CountIter(iter, "foo"), 2);
2902
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2903
- 6 + using_full_builder * 4);
2910
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 10);
2904
2911
 
2905
2912
  {
2906
2913
  // keys in all three SSTs are visible to iterator
@@ -2908,12 +2915,10 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterMultipleSST) {
2908
2915
  // so +2 for checked counter
2909
2916
  std::unique_ptr<Iterator> iter_all(db_->NewIterator(read_options));
2910
2917
  ASSERT_EQ(CountIter(iter_all, "foo"), 9);
2911
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2912
- 7 + using_full_builder * 5);
2918
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 12);
2913
2919
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 2);
2914
2920
  ASSERT_EQ(CountIter(iter_all, "gpk"), 0);
2915
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2916
- 8 + using_full_builder * 5);
2921
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 13);
2917
2922
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 3);
2918
2923
  }
2919
2924
  ASSERT_OK(dbfull()->SetOptions({{"prefix_extractor", "capped:3"}}));
@@ -2924,12 +2929,10 @@ TEST_F(DBBloomFilterTest, DynamicBloomFilterMultipleSST) {
2924
2929
  ASSERT_EQ(CountIter(iter_all, "foo"), 6);
2925
2930
  // all three SST are checked because the current options has the same as
2926
2931
  // the remaining SST (capped:3)
2927
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2928
- 9 + using_full_builder * 7);
2932
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 16);
2929
2933
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 3);
2930
2934
  ASSERT_EQ(CountIter(iter_all, "gpk"), 0);
2931
- ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED),
2932
- 10 + using_full_builder * 7);
2935
+ ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED), 17);
2933
2936
  ASSERT_EQ(TestGetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL), 4);
2934
2937
  }
2935
2938
  // TODO(Zhongyi): Maybe also need to add Get calls to test point look up?
@@ -5219,7 +5219,76 @@ INSTANTIATE_TEST_CASE_P(
5219
5219
  ::testing::Values(CompactionPri::kByCompensatedSize,
5220
5220
  CompactionPri::kOldestLargestSeqFirst,
5221
5221
  CompactionPri::kOldestSmallestSeqFirst,
5222
- CompactionPri::kMinOverlappingRatio));
5222
+ CompactionPri::kMinOverlappingRatio,
5223
+ CompactionPri::kRoundRobin));
5224
+
5225
+ TEST_F(DBCompactionTest, PersistRoundRobinCompactCursor) {
5226
+ Options options = CurrentOptions();
5227
+ options.write_buffer_size = 16 * 1024;
5228
+ options.max_bytes_for_level_base = 64 * 1024;
5229
+ options.level0_file_num_compaction_trigger = 4;
5230
+ options.compaction_pri = CompactionPri::kRoundRobin;
5231
+ options.max_bytes_for_level_multiplier = 4;
5232
+ options.num_levels = 3;
5233
+ options.compression = kNoCompression;
5234
+
5235
+ DestroyAndReopen(options);
5236
+
5237
+ Random rnd(301);
5238
+
5239
+ // 30 Files in L0 to trigger compactions between L1 and L2
5240
+ for (int i = 0; i < 30; i++) {
5241
+ for (int j = 0; j < 16; j++) {
5242
+ ASSERT_OK(Put(rnd.RandomString(24), rnd.RandomString(1000)));
5243
+ }
5244
+ }
5245
+
5246
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
5247
+
5248
+ VersionSet* const versions = dbfull()->GetVersionSet();
5249
+ assert(versions);
5250
+
5251
+ ColumnFamilyData* const cfd = versions->GetColumnFamilySet()->GetDefault();
5252
+ ASSERT_NE(cfd, nullptr);
5253
+
5254
+ Version* const current = cfd->current();
5255
+ ASSERT_NE(current, nullptr);
5256
+
5257
+ const VersionStorageInfo* const storage_info = current->storage_info();
5258
+ ASSERT_NE(storage_info, nullptr);
5259
+
5260
+ const std::vector<InternalKey> compact_cursors =
5261
+ storage_info->GetCompactCursors();
5262
+
5263
+ Reopen(options);
5264
+
5265
+ VersionSet* const reopened_versions = dbfull()->GetVersionSet();
5266
+ assert(reopened_versions);
5267
+
5268
+ ColumnFamilyData* const reopened_cfd =
5269
+ reopened_versions->GetColumnFamilySet()->GetDefault();
5270
+ ASSERT_NE(reopened_cfd, nullptr);
5271
+
5272
+ Version* const reopened_current = reopened_cfd->current();
5273
+ ASSERT_NE(reopened_current, nullptr);
5274
+
5275
+ const VersionStorageInfo* const reopened_storage_info =
5276
+ reopened_current->storage_info();
5277
+ ASSERT_NE(reopened_storage_info, nullptr);
5278
+
5279
+ const std::vector<InternalKey> reopened_compact_cursors =
5280
+ reopened_storage_info->GetCompactCursors();
5281
+ const auto icmp = reopened_storage_info->InternalComparator();
5282
+ ASSERT_EQ(compact_cursors.size(), reopened_compact_cursors.size());
5283
+ for (size_t i = 0; i < compact_cursors.size(); i++) {
5284
+ if (compact_cursors[i].Valid()) {
5285
+ ASSERT_EQ(0,
5286
+ icmp->Compare(compact_cursors[i], reopened_compact_cursors[i]));
5287
+ } else {
5288
+ ASSERT_TRUE(!reopened_compact_cursors[i].Valid());
5289
+ }
5290
+ }
5291
+ }
5223
5292
 
5224
5293
  class NoopMergeOperator : public MergeOperator {
5225
5294
  public:
@@ -101,6 +101,7 @@
101
101
  #include "util/compression.h"
102
102
  #include "util/crc32c.h"
103
103
  #include "util/defer.h"
104
+ #include "util/distributed_mutex.h"
104
105
  #include "util/hash_containers.h"
105
106
  #include "util/mutexlock.h"
106
107
  #include "util/stop_watch.h"
@@ -145,6 +146,8 @@ void DumpSupportInfo(Logger* logger) {
145
146
  }
146
147
  ROCKS_LOG_HEADER(logger, "Fast CRC32 supported: %s",
147
148
  crc32c::IsFastCrc32Supported().c_str());
149
+
150
+ ROCKS_LOG_HEADER(logger, "DMutex implementation: %s", DMutex::kName());
148
151
  }
149
152
  } // namespace
150
153
 
@@ -260,7 +263,7 @@ DBImpl::DBImpl(const DBOptions& options, const std::string& dbname,
260
263
  versions_.reset(new VersionSet(dbname_, &immutable_db_options_, file_options_,
261
264
  table_cache_.get(), write_buffer_manager_,
262
265
  &write_controller_, &block_cache_tracer_,
263
- io_tracer_, db_session_id_));
266
+ io_tracer_, db_id_, db_session_id_));
264
267
  column_family_memtables_.reset(
265
268
  new ColumnFamilyMemTablesImpl(versions_->GetColumnFamilySet()));
266
269
 
@@ -1364,6 +1367,7 @@ Status DBImpl::FlushWAL(bool sync) {
1364
1367
  }
1365
1368
 
1366
1369
  Status DBImpl::SyncWAL() {
1370
+ TEST_SYNC_POINT("DBImpl::SyncWAL:Begin");
1367
1371
  autovector<log::Writer*, 1> logs_to_sync;
1368
1372
  bool need_log_dir_sync;
1369
1373
  uint64_t current_log_number;
@@ -1376,7 +1380,7 @@ Status DBImpl::SyncWAL() {
1376
1380
  current_log_number = logfile_number_;
1377
1381
 
1378
1382
  while (logs_.front().number <= current_log_number &&
1379
- logs_.front().getting_synced) {
1383
+ logs_.front().IsSyncing()) {
1380
1384
  log_sync_cv_.Wait();
1381
1385
  }
1382
1386
  // First check that logs are safe to sync in background.
@@ -1393,8 +1397,7 @@ Status DBImpl::SyncWAL() {
1393
1397
  for (auto it = logs_.begin();
1394
1398
  it != logs_.end() && it->number <= current_log_number; ++it) {
1395
1399
  auto& log = *it;
1396
- assert(!log.getting_synced);
1397
- log.getting_synced = true;
1400
+ log.PrepareForSync();
1398
1401
  logs_to_sync.push_back(log.writer);
1399
1402
  }
1400
1403
 
@@ -1467,11 +1470,10 @@ Status DBImpl::MarkLogsSynced(uint64_t up_to, bool synced_dir) {
1467
1470
  VersionEdit synced_wals;
1468
1471
  for (auto it = logs_.begin(); it != logs_.end() && it->number <= up_to;) {
1469
1472
  auto& wal = *it;
1470
- assert(wal.getting_synced);
1473
+ assert(wal.IsSyncing());
1471
1474
  if (immutable_db_options_.track_and_verify_wals_in_manifest &&
1472
- wal.writer->file()->GetFileSize() > 0) {
1473
- synced_wals.AddWal(wal.number,
1474
- WalMetadata(wal.writer->file()->GetFileSize()));
1475
+ wal.GetPreSyncSize() > 0) {
1476
+ synced_wals.AddWal(wal.number, WalMetadata(wal.GetPreSyncSize()));
1475
1477
  }
1476
1478
 
1477
1479
  if (logs_.size() > 1) {
@@ -1480,12 +1482,12 @@ Status DBImpl::MarkLogsSynced(uint64_t up_to, bool synced_dir) {
1480
1482
  InstrumentedMutexLock l(&log_write_mutex_);
1481
1483
  it = logs_.erase(it);
1482
1484
  } else {
1483
- wal.getting_synced = false;
1485
+ wal.FinishSync();
1484
1486
  ++it;
1485
1487
  }
1486
1488
  }
1487
1489
  assert(logs_.empty() || logs_[0].number > up_to ||
1488
- (logs_.size() == 1 && !logs_[0].getting_synced));
1490
+ (logs_.size() == 1 && !logs_[0].IsSyncing()));
1489
1491
 
1490
1492
  Status s;
1491
1493
  if (synced_wals.IsWalAddition()) {
@@ -1505,8 +1507,7 @@ void DBImpl::MarkLogsNotSynced(uint64_t up_to) {
1505
1507
  for (auto it = logs_.begin(); it != logs_.end() && it->number <= up_to;
1506
1508
  ++it) {
1507
1509
  auto& wal = *it;
1508
- assert(wal.getting_synced);
1509
- wal.getting_synced = false;
1510
+ wal.FinishSync();
1510
1511
  }
1511
1512
  log_sync_cv_.SignalAll();
1512
1513
  }
@@ -1517,6 +1517,16 @@ class DBImpl : public DB {
1517
1517
  // recovery.
1518
1518
  Status LogAndApplyForRecovery(const RecoveryContext& recovery_ctx);
1519
1519
 
1520
+ void InvokeWalFilterIfNeededOnColumnFamilyToWalNumberMap();
1521
+
1522
+ // Return true to proceed with current WAL record whose content is stored in
1523
+ // `batch`. Return false to skip current WAL record.
1524
+ bool InvokeWalFilterIfNeededOnWalRecord(uint64_t wal_number,
1525
+ const std::string& wal_fname,
1526
+ log::Reader::Reporter& reporter,
1527
+ Status& status, bool& stop_replay,
1528
+ WriteBatch& batch);
1529
+
1520
1530
  private:
1521
1531
  friend class DB;
1522
1532
  friend class ErrorHandler;
@@ -1593,12 +1603,38 @@ class DBImpl : public DB {
1593
1603
  return s;
1594
1604
  }
1595
1605
 
1606
+ bool IsSyncing() { return getting_synced; }
1607
+
1608
+ uint64_t GetPreSyncSize() {
1609
+ assert(getting_synced);
1610
+ return pre_sync_size;
1611
+ }
1612
+
1613
+ void PrepareForSync() {
1614
+ assert(!getting_synced);
1615
+ // Size is expected to be monotonically increasing.
1616
+ assert(writer->file()->GetFlushedSize() >= pre_sync_size);
1617
+ getting_synced = true;
1618
+ pre_sync_size = writer->file()->GetFlushedSize();
1619
+ }
1620
+
1621
+ void FinishSync() {
1622
+ assert(getting_synced);
1623
+ getting_synced = false;
1624
+ }
1625
+
1596
1626
  uint64_t number;
1597
1627
  // Visual Studio doesn't support deque's member to be noncopyable because
1598
1628
  // of a std::unique_ptr as a member.
1599
1629
  log::Writer* writer; // own
1630
+
1631
+ private:
1600
1632
  // true for some prefix of logs_
1601
1633
  bool getting_synced = false;
1634
+ // The size of the file before the sync happens. This amount is guaranteed
1635
+ // to be persisted even if appends happen during sync so it can be used for
1636
+ // tracking the synced size in MANIFEST.
1637
+ uint64_t pre_sync_size = 0;
1602
1638
  };
1603
1639
 
1604
1640
  // PurgeFileInfo is a structure to hold information of files to be deleted in
@@ -88,14 +88,13 @@ IOStatus DBImpl::SyncClosedLogs(JobContext* job_context) {
88
88
  autovector<log::Writer*, 1> logs_to_sync;
89
89
  uint64_t current_log_number = logfile_number_;
90
90
  while (logs_.front().number < current_log_number &&
91
- logs_.front().getting_synced) {
91
+ logs_.front().IsSyncing()) {
92
92
  log_sync_cv_.Wait();
93
93
  }
94
94
  for (auto it = logs_.begin();
95
95
  it != logs_.end() && it->number < current_log_number; ++it) {
96
96
  auto& log = *it;
97
- assert(!log.getting_synced);
98
- log.getting_synced = true;
97
+ log.PrepareForSync();
99
98
  logs_to_sync.push_back(log.writer);
100
99
  }
101
100
 
@@ -3317,7 +3316,15 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
3317
3316
  moved_bytes += f->fd.GetFileSize();
3318
3317
  }
3319
3318
  }
3320
-
3319
+ if (c->compaction_reason() == CompactionReason::kLevelMaxLevelSize &&
3320
+ c->immutable_options()->compaction_pri == kRoundRobin) {
3321
+ int start_level = c->start_level();
3322
+ if (start_level > 0) {
3323
+ auto vstorage = c->input_version()->storage_info();
3324
+ c->edit()->AddCompactCursor(
3325
+ start_level, vstorage->GetNextCompactCursor(start_level));
3326
+ }
3327
+ }
3321
3328
  status = versions_->LogAndApply(c->column_family_data(),
3322
3329
  *c->mutable_cf_options(), c->edit(),
3323
3330
  &mutex_, directories_.GetDbDir());
@@ -288,7 +288,7 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
288
288
  }
289
289
  while (!logs_.empty() && logs_.front().number < min_log_number) {
290
290
  auto& log = logs_.front();
291
- if (log.getting_synced) {
291
+ if (log.IsSyncing()) {
292
292
  log_sync_cv_.Wait();
293
293
  // logs_ could have changed while we were waiting.
294
294
  continue;