@nxtedition/rocksdb 8.0.0 → 8.0.2

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 (144) hide show
  1. package/BUILDING.md +2 -2
  2. package/binding.cc +2 -7
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +10 -9
  4. package/deps/rocksdb/rocksdb/Makefile +2 -2
  5. package/deps/rocksdb/rocksdb/TARGETS +4 -2
  6. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +0 -5
  7. package/deps/rocksdb/rocksdb/cache/cache_test.cc +8 -29
  8. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +146 -0
  9. package/deps/rocksdb/rocksdb/cache/clock_cache.h +13 -1
  10. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +57 -146
  11. package/deps/rocksdb/rocksdb/cache/secondary_cache.cc +32 -0
  12. package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator.h +11 -0
  13. package/deps/rocksdb/rocksdb/db/column_family.cc +11 -9
  14. package/deps/rocksdb/rocksdb/db/column_family.h +20 -0
  15. package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator.h +5 -0
  16. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +13 -33
  17. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +5 -0
  18. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +27 -8
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +17 -1
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +2 -1
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +4 -2
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +8 -6
  23. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +65 -7
  24. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +5 -0
  25. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +10 -32
  26. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +28 -47
  27. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +28 -22
  28. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +8 -14
  29. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +8 -8
  30. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +5 -4
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +170 -140
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +5 -1
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +5 -4
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +8 -2
  35. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +8 -0
  36. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +266 -138
  37. package/deps/rocksdb/rocksdb/db/corruption_test.cc +86 -1
  38. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +72 -5
  39. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +119 -10
  40. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +585 -264
  41. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +46 -18
  42. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +5 -1
  43. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +6 -15
  44. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +1 -1
  45. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +1 -1
  46. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +3 -0
  47. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +8 -8
  48. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +10 -0
  49. package/deps/rocksdb/rocksdb/db/db_iter.cc +57 -36
  50. package/deps/rocksdb/rocksdb/db/db_iter.h +2 -1
  51. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +250 -2
  52. package/deps/rocksdb/rocksdb/db/db_test.cc +3 -0
  53. package/deps/rocksdb/rocksdb/db/db_test2.cc +307 -8
  54. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +129 -0
  55. package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +21 -0
  56. package/deps/rocksdb/rocksdb/db/dbformat.cc +25 -0
  57. package/deps/rocksdb/rocksdb/db/dbformat.h +2 -0
  58. package/deps/rocksdb/rocksdb/db/experimental.cc +1 -1
  59. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +5 -2
  60. package/deps/rocksdb/rocksdb/db/flush_job.cc +5 -2
  61. package/deps/rocksdb/rocksdb/db/history_trimming_iterator.h +4 -0
  62. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +56 -53
  63. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +3 -4
  64. package/deps/rocksdb/rocksdb/db/memtable.cc +55 -9
  65. package/deps/rocksdb/rocksdb/db/merge_helper.cc +76 -102
  66. package/deps/rocksdb/rocksdb/db/merge_helper.h +2 -11
  67. package/deps/rocksdb/rocksdb/db/periodic_task_scheduler_test.cc +10 -10
  68. package/deps/rocksdb/rocksdb/db/repair.cc +64 -22
  69. package/deps/rocksdb/rocksdb/db/repair_test.cc +54 -0
  70. package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +26 -26
  71. package/deps/rocksdb/rocksdb/db/table_cache.cc +2 -0
  72. package/deps/rocksdb/rocksdb/db/table_properties_collector.h +3 -1
  73. package/deps/rocksdb/rocksdb/db/version_builder.cc +90 -43
  74. package/deps/rocksdb/rocksdb/db/version_builder.h +20 -0
  75. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +190 -67
  76. package/deps/rocksdb/rocksdb/db/version_edit.cc +15 -1
  77. package/deps/rocksdb/rocksdb/db/version_edit.h +16 -4
  78. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +41 -11
  79. package/deps/rocksdb/rocksdb/db/version_edit_handler.h +27 -12
  80. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +18 -16
  81. package/deps/rocksdb/rocksdb/db/version_set.cc +219 -38
  82. package/deps/rocksdb/rocksdb/db/version_set.h +34 -4
  83. package/deps/rocksdb/rocksdb/db/version_set_test.cc +45 -25
  84. package/deps/rocksdb/rocksdb/db/wide/db_wide_basic_test.cc +122 -61
  85. package/deps/rocksdb/rocksdb/db/write_thread.cc +5 -2
  86. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +0 -1
  87. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +0 -4
  88. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +12 -17
  89. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +6 -4
  90. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +1 -1
  91. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +1 -0
  92. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +0 -48
  93. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +8 -0
  94. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +196 -171
  95. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +6 -0
  96. package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +9 -3
  97. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +25 -18
  98. package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +27 -5
  99. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +5 -0
  100. package/deps/rocksdb/rocksdb/include/rocksdb/status.h +3 -0
  101. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +3 -0
  102. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +1 -1
  103. package/deps/rocksdb/rocksdb/logging/logging.h +13 -19
  104. package/deps/rocksdb/rocksdb/memory/arena.cc +4 -3
  105. package/deps/rocksdb/rocksdb/memory/arena_test.cc +30 -0
  106. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +3 -1
  107. package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +26 -26
  108. package/deps/rocksdb/rocksdb/src.mk +2 -1
  109. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.cc +3 -2
  110. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +2 -10
  111. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +12 -29
  112. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +1 -1
  113. package/deps/rocksdb/rocksdb/table/block_based/block_like_traits.h +0 -39
  114. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +0 -1
  115. package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +3 -3
  116. package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.cc +142 -0
  117. package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.h +241 -0
  118. package/deps/rocksdb/rocksdb/table/format.cc +24 -20
  119. package/deps/rocksdb/rocksdb/table/format.h +5 -2
  120. package/deps/rocksdb/rocksdb/table/get_context.cc +52 -11
  121. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +97 -115
  122. package/deps/rocksdb/rocksdb/table/merging_iterator.h +82 -1
  123. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +2 -2
  124. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +1 -1
  125. package/deps/rocksdb/rocksdb/table/table_test.cc +7 -6
  126. package/deps/rocksdb/rocksdb/test_util/testutil.h +10 -0
  127. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +0 -6
  128. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.h +2 -2
  129. package/deps/rocksdb/rocksdb/util/bloom_test.cc +1 -1
  130. package/deps/rocksdb/rocksdb/util/crc32c.cc +1 -1
  131. package/deps/rocksdb/rocksdb/util/status.cc +7 -0
  132. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +5 -0
  133. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +4 -0
  134. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +7 -67
  135. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +1 -3
  136. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +1 -0
  137. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +59 -0
  138. package/deps/rocksdb/rocksdb.gyp +2 -1
  139. package/package.json +1 -1
  140. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  141. package/prebuilds/linux-x64/node.napi.node +0 -0
  142. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +0 -580
  143. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +0 -476
  144. package/max_rev_operator.h +0 -100
@@ -223,7 +223,8 @@ class CorruptionTest : public testing::Test {
223
223
  }
224
224
  ASSERT_TRUE(!fname.empty()) << filetype;
225
225
 
226
- ASSERT_OK(test::CorruptFile(env_, fname, offset, bytes_to_corrupt));
226
+ ASSERT_OK(test::CorruptFile(env_, fname, offset, bytes_to_corrupt,
227
+ /*verify_checksum*/ filetype == kTableFile));
227
228
  }
228
229
 
229
230
  // corrupts exactly one file at level `level`. if no file found at level,
@@ -518,6 +519,90 @@ TEST_F(CorruptionTest, TableFileIndexData) {
518
519
  ASSERT_TRUE(TryReopen().IsCorruption());
519
520
  }
520
521
 
522
+ TEST_F(CorruptionTest, TableFileFooterMagic) {
523
+ Build(100);
524
+ DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
525
+ ASSERT_OK(dbi->TEST_FlushMemTable());
526
+ Check(100, 100);
527
+ // Corrupt the whole footer
528
+ Corrupt(kTableFile, -100, 100);
529
+ Status s = TryReopen();
530
+ ASSERT_TRUE(s.IsCorruption());
531
+ // Contains useful message, and magic number should be the first thing
532
+ // reported as corrupt.
533
+ ASSERT_TRUE(s.ToString().find("magic number") != std::string::npos);
534
+ // with file name
535
+ ASSERT_TRUE(s.ToString().find(".sst") != std::string::npos);
536
+ }
537
+
538
+ TEST_F(CorruptionTest, TableFileFooterNotMagic) {
539
+ Build(100);
540
+ DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
541
+ ASSERT_OK(dbi->TEST_FlushMemTable());
542
+ Check(100, 100);
543
+ // Corrupt footer except magic number
544
+ Corrupt(kTableFile, -100, 92);
545
+ Status s = TryReopen();
546
+ ASSERT_TRUE(s.IsCorruption());
547
+ // The next thing checked after magic number is format_version
548
+ ASSERT_TRUE(s.ToString().find("format_version") != std::string::npos);
549
+ // with file name
550
+ ASSERT_TRUE(s.ToString().find(".sst") != std::string::npos);
551
+ }
552
+
553
+ TEST_F(CorruptionTest, TableFileWrongSize) {
554
+ Build(100);
555
+ DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
556
+ ASSERT_OK(dbi->TEST_FlushMemTable());
557
+ Check(100, 100);
558
+
559
+ // ********************************************
560
+ // Make the file bigger by appending to it
561
+ std::vector<LiveFileMetaData> metadata;
562
+ db_->GetLiveFilesMetaData(&metadata);
563
+ ASSERT_EQ(1U, metadata.size());
564
+ std::string filename = dbname_ + metadata[0].name;
565
+ const auto& fs = options_.env->GetFileSystem();
566
+ {
567
+ std::unique_ptr<FSWritableFile> f;
568
+ ASSERT_OK(fs->ReopenWritableFile(filename, FileOptions(), &f, nullptr));
569
+ ASSERT_OK(f->Append("blahblah", IOOptions(), nullptr));
570
+ ASSERT_OK(f->Close(IOOptions(), nullptr));
571
+ }
572
+
573
+ // DB actually accepts this without paranoid checks, relying on size
574
+ // recorded in manifest to locate the SST footer.
575
+ options_.paranoid_checks = false;
576
+ options_.skip_checking_sst_file_sizes_on_db_open = false;
577
+ Reopen();
578
+ Check(100, 100);
579
+
580
+ // But reports the issue with paranoid checks
581
+ options_.paranoid_checks = true;
582
+ Status s = TryReopen();
583
+ ASSERT_TRUE(s.IsCorruption());
584
+ ASSERT_TRUE(s.ToString().find("file size mismatch") != std::string::npos);
585
+
586
+ // ********************************************
587
+ // Make the file smaller with truncation.
588
+ // First leaving a partial footer, and then completely removing footer.
589
+ for (size_t bytes_lost : {8, 100}) {
590
+ ASSERT_OK(
591
+ test::TruncateFile(env_, filename, metadata[0].size - bytes_lost));
592
+
593
+ // Reported well with paranoid checks
594
+ options_.paranoid_checks = true;
595
+ s = TryReopen();
596
+ ASSERT_TRUE(s.IsCorruption());
597
+ ASSERT_TRUE(s.ToString().find("file size mismatch") != std::string::npos);
598
+
599
+ // Without paranoid checks, not reported until read
600
+ options_.paranoid_checks = false;
601
+ Reopen();
602
+ Check(0, 0); // Missing data
603
+ }
604
+ }
605
+
521
606
  TEST_F(CorruptionTest, MissingDescriptor) {
522
607
  Build(1000);
523
608
  RepairDB();
@@ -2158,11 +2158,11 @@ class DBMultiGetAsyncIOTest : public DBBasicTest,
2158
2158
  : DBBasicTest(), statistics_(ROCKSDB_NAMESPACE::CreateDBStatistics()) {
2159
2159
  BlockBasedTableOptions bbto;
2160
2160
  bbto.filter_policy.reset(NewBloomFilterPolicy(10));
2161
- Options options = CurrentOptions();
2162
- options.disable_auto_compactions = true;
2163
- options.statistics = statistics_;
2164
- options.table_factory.reset(NewBlockBasedTableFactory(bbto));
2165
- Reopen(options);
2161
+ options_ = CurrentOptions();
2162
+ options_.disable_auto_compactions = true;
2163
+ options_.statistics = statistics_;
2164
+ options_.table_factory.reset(NewBlockBasedTableFactory(bbto));
2165
+ Reopen(options_);
2166
2166
  int num_keys = 0;
2167
2167
 
2168
2168
  // Put all keys in the bottommost level, and overwrite some keys
@@ -2227,8 +2227,12 @@ class DBMultiGetAsyncIOTest : public DBBasicTest,
2227
2227
 
2228
2228
  const std::shared_ptr<Statistics>& statistics() { return statistics_; }
2229
2229
 
2230
+ protected:
2231
+ void ReopenDB() { Reopen(options_); }
2232
+
2230
2233
  private:
2231
2234
  std::shared_ptr<Statistics> statistics_;
2235
+ Options options_;
2232
2236
  };
2233
2237
 
2234
2238
  TEST_P(DBMultiGetAsyncIOTest, GetFromL0) {
@@ -2305,6 +2309,69 @@ TEST_P(DBMultiGetAsyncIOTest, GetFromL1) {
2305
2309
  ASSERT_EQ(statistics()->getTickerCount(MULTIGET_COROUTINE_COUNT), 3);
2306
2310
  }
2307
2311
 
2312
+ TEST_P(DBMultiGetAsyncIOTest, GetFromL1Error) {
2313
+ std::vector<std::string> key_strs;
2314
+ std::vector<Slice> keys;
2315
+ std::vector<PinnableSlice> values;
2316
+ std::vector<Status> statuses;
2317
+
2318
+ key_strs.push_back(Key(33));
2319
+ key_strs.push_back(Key(54));
2320
+ key_strs.push_back(Key(102));
2321
+ keys.push_back(key_strs[0]);
2322
+ keys.push_back(key_strs[1]);
2323
+ keys.push_back(key_strs[2]);
2324
+ values.resize(keys.size());
2325
+ statuses.resize(keys.size());
2326
+
2327
+ SyncPoint::GetInstance()->SetCallBack(
2328
+ "TableCache::GetTableReader:BeforeOpenFile", [&](void* status) {
2329
+ static int count = 0;
2330
+ count++;
2331
+ // Fail the last table reader open, which is the 6th SST file
2332
+ // since 3 overlapping L0 files + 3 L1 files containing the keys
2333
+ if (count == 6) {
2334
+ Status* s = static_cast<Status*>(status);
2335
+ *s = Status::IOError();
2336
+ }
2337
+ });
2338
+ // DB open will create table readers unless we reduce the table cache
2339
+ // capacity.
2340
+ // SanitizeOptions will set max_open_files to minimum of 20. Table cache
2341
+ // is allocated with max_open_files - 10 as capacity. So override
2342
+ // max_open_files to 11 so table cache capacity will become 1. This will
2343
+ // prevent file open during DB open and force the file to be opened
2344
+ // during MultiGet
2345
+ SyncPoint::GetInstance()->SetCallBack(
2346
+ "SanitizeOptions::AfterChangeMaxOpenFiles", [&](void* arg) {
2347
+ int* max_open_files = (int*)arg;
2348
+ *max_open_files = 11;
2349
+ });
2350
+ SyncPoint::GetInstance()->EnableProcessing();
2351
+
2352
+ ReopenDB();
2353
+
2354
+ ReadOptions ro;
2355
+ ro.async_io = true;
2356
+ ro.optimize_multiget_for_io = GetParam();
2357
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2358
+ keys.data(), values.data(), statuses.data());
2359
+ SyncPoint::GetInstance()->DisableProcessing();
2360
+ ASSERT_EQ(values.size(), 3);
2361
+ ASSERT_EQ(statuses[0], Status::OK());
2362
+ ASSERT_EQ(statuses[1], Status::OK());
2363
+ ASSERT_EQ(statuses[2], Status::IOError());
2364
+
2365
+ HistogramData multiget_io_batch_size;
2366
+
2367
+ statistics()->histogramData(MULTIGET_IO_BATCH_SIZE, &multiget_io_batch_size);
2368
+
2369
+ // A batch of 3 async IOs is expected, one for each overlapping file in L1
2370
+ ASSERT_EQ(multiget_io_batch_size.count, 1);
2371
+ ASSERT_EQ(multiget_io_batch_size.max, 2);
2372
+ ASSERT_EQ(statistics()->getTickerCount(MULTIGET_COROUTINE_COUNT), 2);
2373
+ }
2374
+
2308
2375
  TEST_P(DBMultiGetAsyncIOTest, LastKeyInFile) {
2309
2376
  std::vector<std::string> key_strs;
2310
2377
  std::vector<Slice> keys;
@@ -13,7 +13,6 @@
13
13
 
14
14
  #include "cache/cache_entry_roles.h"
15
15
  #include "cache/cache_key.h"
16
- #include "cache/fast_lru_cache.h"
17
16
  #include "cache/lru_cache.h"
18
17
  #include "db/column_family.h"
19
18
  #include "db/db_impl/db_impl.h"
@@ -944,10 +943,7 @@ TEST_F(DBBlockCacheTest, AddRedundantStats) {
944
943
  capacity,
945
944
  BlockBasedTableOptions().block_size /*estimated_value_size*/,
946
945
  num_shard_bits)
947
- .MakeSharedCache(),
948
- NewFastLRUCache(capacity, 1 /*estimated_value_size*/, num_shard_bits,
949
- false /*strict_capacity_limit*/,
950
- kDefaultCacheMetadataChargePolicy)}) {
946
+ .MakeSharedCache()}) {
951
947
  if (!base_cache) {
952
948
  // Skip clock cache when not supported
953
949
  continue;
@@ -1306,11 +1302,6 @@ TEST_F(DBBlockCacheTest, CacheEntryRoleStats) {
1306
1302
  capacity,
1307
1303
  BlockBasedTableOptions().block_size /*estimated_value_size*/)
1308
1304
  .MakeSharedCache()}) {
1309
- if (!cache) {
1310
- // Skip clock cache when not supported
1311
- continue;
1312
- }
1313
-
1314
1305
  ++iterations_tested;
1315
1306
 
1316
1307
  Options options = CurrentOptions();
@@ -1543,6 +1534,124 @@ TEST_F(DBBlockCacheTest, CacheEntryRoleStats) {
1543
1534
  }
1544
1535
  }
1545
1536
 
1537
+ namespace {
1538
+
1539
+ void DummyFillCache(Cache& cache, size_t entry_size,
1540
+ std::vector<CacheHandleGuard<void>>& handles) {
1541
+ // fprintf(stderr, "Entry size: %zu\n", entry_size);
1542
+ handles.clear();
1543
+ cache.EraseUnRefEntries();
1544
+ void* fake_value = &cache;
1545
+ size_t capacity = cache.GetCapacity();
1546
+ OffsetableCacheKey ck{"abc", "abc", 42};
1547
+ for (size_t my_usage = 0; my_usage < capacity;) {
1548
+ size_t charge = std::min(entry_size, capacity - my_usage);
1549
+ Cache::Handle* handle;
1550
+ Status st = cache.Insert(ck.WithOffset(my_usage).AsSlice(), fake_value,
1551
+ charge, /*deleter*/ nullptr, &handle);
1552
+ ASSERT_OK(st);
1553
+ handles.emplace_back(&cache, handle);
1554
+ my_usage += charge;
1555
+ }
1556
+ }
1557
+
1558
+ class CountingLogger : public Logger {
1559
+ public:
1560
+ ~CountingLogger() override {}
1561
+ using Logger::Logv;
1562
+ void Logv(const InfoLogLevel log_level, const char* format,
1563
+ va_list /*ap*/) override {
1564
+ if (std::strstr(format, "HyperClockCache") == nullptr) {
1565
+ // Not a match
1566
+ return;
1567
+ }
1568
+ // static StderrLogger debug;
1569
+ // debug.Logv(log_level, format, ap);
1570
+ if (log_level == InfoLogLevel::INFO_LEVEL) {
1571
+ ++info_count_;
1572
+ } else if (log_level == InfoLogLevel::WARN_LEVEL) {
1573
+ ++warn_count_;
1574
+ } else if (log_level == InfoLogLevel::ERROR_LEVEL) {
1575
+ ++error_count_;
1576
+ }
1577
+ }
1578
+
1579
+ std::array<int, 3> PopCounts() {
1580
+ std::array<int, 3> rv{{info_count_, warn_count_, error_count_}};
1581
+ info_count_ = warn_count_ = error_count_ = 0;
1582
+ return rv;
1583
+ }
1584
+
1585
+ private:
1586
+ int info_count_{};
1587
+ int warn_count_{};
1588
+ int error_count_{};
1589
+ };
1590
+
1591
+ } // namespace
1592
+
1593
+ TEST_F(DBBlockCacheTest, HyperClockCacheReportProblems) {
1594
+ size_t capacity = 1024 * 1024;
1595
+ size_t value_size_est = 8 * 1024;
1596
+ HyperClockCacheOptions hcc_opts{capacity, value_size_est};
1597
+ hcc_opts.num_shard_bits = 2; // 4 shards
1598
+ hcc_opts.metadata_charge_policy = kDontChargeCacheMetadata;
1599
+ std::shared_ptr<Cache> cache = hcc_opts.MakeSharedCache();
1600
+ std::shared_ptr<CountingLogger> logger = std::make_shared<CountingLogger>();
1601
+
1602
+ auto table_options = GetTableOptions();
1603
+ auto options = GetOptions(table_options);
1604
+ table_options.block_cache = cache;
1605
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
1606
+ options.info_log = logger;
1607
+ // Going to sample more directly
1608
+ options.stats_dump_period_sec = 0;
1609
+ Reopen(options);
1610
+
1611
+ std::vector<CacheHandleGuard<void>> handles;
1612
+
1613
+ // Clear anything from DB startup
1614
+ logger->PopCounts();
1615
+
1616
+ // Fill cache based on expected size and check that when we
1617
+ // don't report anything relevant in periodic stats dump
1618
+ DummyFillCache(*cache, value_size_est, handles);
1619
+ dbfull()->DumpStats();
1620
+ EXPECT_EQ(logger->PopCounts(), (std::array<int, 3>{{0, 0, 0}}));
1621
+
1622
+ // Same, within reasonable bounds
1623
+ DummyFillCache(*cache, value_size_est - value_size_est / 4, handles);
1624
+ dbfull()->DumpStats();
1625
+ EXPECT_EQ(logger->PopCounts(), (std::array<int, 3>{{0, 0, 0}}));
1626
+
1627
+ DummyFillCache(*cache, value_size_est + value_size_est / 3, handles);
1628
+ dbfull()->DumpStats();
1629
+ EXPECT_EQ(logger->PopCounts(), (std::array<int, 3>{{0, 0, 0}}));
1630
+
1631
+ // Estimate too high (value size too low) eventually reports ERROR
1632
+ DummyFillCache(*cache, value_size_est / 2, handles);
1633
+ dbfull()->DumpStats();
1634
+ EXPECT_EQ(logger->PopCounts(), (std::array<int, 3>{{0, 1, 0}}));
1635
+
1636
+ DummyFillCache(*cache, value_size_est / 3, handles);
1637
+ dbfull()->DumpStats();
1638
+ EXPECT_EQ(logger->PopCounts(), (std::array<int, 3>{{0, 0, 1}}));
1639
+
1640
+ // Estimate too low (value size too high) starts with INFO
1641
+ // and is only WARNING in the worst case
1642
+ DummyFillCache(*cache, value_size_est * 2, handles);
1643
+ dbfull()->DumpStats();
1644
+ EXPECT_EQ(logger->PopCounts(), (std::array<int, 3>{{1, 0, 0}}));
1645
+
1646
+ DummyFillCache(*cache, value_size_est * 3, handles);
1647
+ dbfull()->DumpStats();
1648
+ EXPECT_EQ(logger->PopCounts(), (std::array<int, 3>{{0, 1, 0}}));
1649
+
1650
+ DummyFillCache(*cache, value_size_est * 20, handles);
1651
+ dbfull()->DumpStats();
1652
+ EXPECT_EQ(logger->PopCounts(), (std::array<int, 3>{{0, 1, 0}}));
1653
+ }
1654
+
1546
1655
  #endif // ROCKSDB_LITE
1547
1656
 
1548
1657
  class DBBlockCacheKeyTest