@nxtedition/rocksdb 13.1.4 → 13.2.0

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 (237) hide show
  1. package/binding.cc +43 -16
  2. package/deps/rocksdb/rocksdb/{TARGETS → BUCK} +27 -0
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +3 -1
  4. package/deps/rocksdb/rocksdb/Makefile +2 -2
  5. package/deps/rocksdb/rocksdb/cache/cache.cc +3 -1
  6. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.h +2 -0
  7. package/deps/rocksdb/rocksdb/db/attribute_group_iterator_impl.h +34 -9
  8. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +7 -6
  9. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +5 -1
  10. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +22 -14
  11. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +149 -0
  12. package/deps/rocksdb/rocksdb/db/builder.cc +13 -24
  13. package/deps/rocksdb/rocksdb/db/coalescing_iterator.h +35 -10
  14. package/deps/rocksdb/rocksdb/db/column_family.cc +21 -10
  15. package/deps/rocksdb/rocksdb/db/column_family.h +15 -8
  16. package/deps/rocksdb/rocksdb/db/column_family_test.cc +98 -7
  17. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +126 -16
  18. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +51 -5
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +2 -2
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +2 -8
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +24 -0
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +52 -22
  23. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +9 -7
  24. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +36 -9
  25. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +6 -0
  26. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +30 -17
  27. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +26 -23
  28. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +43 -33
  29. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +6 -5
  30. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +19 -9
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +6 -5
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +632 -411
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +171 -51
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +7 -5
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +37 -10
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +51 -11
  37. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +10 -3
  38. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +350 -154
  39. package/deps/rocksdb/rocksdb/db/convenience.cc +1 -1
  40. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +62 -27
  41. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +68 -1
  42. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +91 -0
  43. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +134 -70
  44. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +71 -23
  45. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +43 -16
  46. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +47 -33
  47. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +27 -19
  48. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +38 -25
  49. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +3 -3
  50. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +7 -4
  51. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +258 -42
  52. package/deps/rocksdb/rocksdb/db/db_io_failure_test.cc +161 -9
  53. package/deps/rocksdb/rocksdb/db/db_iter.cc +118 -86
  54. package/deps/rocksdb/rocksdb/db/db_iter.h +44 -17
  55. package/deps/rocksdb/rocksdb/db/db_options_test.cc +27 -6
  56. package/deps/rocksdb/rocksdb/db/db_test.cc +48 -16
  57. package/deps/rocksdb/rocksdb/db/db_test2.cc +60 -15
  58. package/deps/rocksdb/rocksdb/db/db_test_util.cc +97 -44
  59. package/deps/rocksdb/rocksdb/db/db_test_util.h +7 -1
  60. package/deps/rocksdb/rocksdb/db/dbformat.cc +15 -5
  61. package/deps/rocksdb/rocksdb/db/dbformat.h +137 -55
  62. package/deps/rocksdb/rocksdb/db/event_helpers.cc +1 -0
  63. package/deps/rocksdb/rocksdb/db/experimental.cc +54 -0
  64. package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +663 -8
  65. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +152 -91
  66. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +134 -11
  67. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +55 -9
  68. package/deps/rocksdb/rocksdb/db/flush_job.cc +52 -29
  69. package/deps/rocksdb/rocksdb/db/flush_job.h +5 -3
  70. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +18 -12
  71. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +23 -29
  72. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +3 -2
  73. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +2 -0
  74. package/deps/rocksdb/rocksdb/db/internal_stats.cc +9 -6
  75. package/deps/rocksdb/rocksdb/db/internal_stats.h +54 -0
  76. package/deps/rocksdb/rocksdb/db/job_context.h +1 -1
  77. package/deps/rocksdb/rocksdb/db/log_reader.cc +6 -7
  78. package/deps/rocksdb/rocksdb/db/manifest_ops.cc +47 -0
  79. package/deps/rocksdb/rocksdb/db/manifest_ops.h +20 -0
  80. package/deps/rocksdb/rocksdb/db/memtable.cc +165 -64
  81. package/deps/rocksdb/rocksdb/db/memtable.h +422 -243
  82. package/deps/rocksdb/rocksdb/db/memtable_list.cc +99 -68
  83. package/deps/rocksdb/rocksdb/db/memtable_list.h +63 -38
  84. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +28 -25
  85. package/deps/rocksdb/rocksdb/db/multi_cf_iterator_impl.h +118 -60
  86. package/deps/rocksdb/rocksdb/db/multi_cf_iterator_test.cc +344 -89
  87. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +2 -3
  88. package/deps/rocksdb/rocksdb/db/repair.cc +15 -14
  89. package/deps/rocksdb/rocksdb/db/repair_test.cc +0 -13
  90. package/deps/rocksdb/rocksdb/db/snapshot_checker.h +7 -0
  91. package/deps/rocksdb/rocksdb/db/table_cache.cc +62 -65
  92. package/deps/rocksdb/rocksdb/db/table_cache.h +70 -76
  93. package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +5 -6
  94. package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +1 -1
  95. package/deps/rocksdb/rocksdb/db/transaction_log_impl.cc +8 -7
  96. package/deps/rocksdb/rocksdb/db/version_builder.cc +17 -19
  97. package/deps/rocksdb/rocksdb/db/version_builder.h +13 -12
  98. package/deps/rocksdb/rocksdb/db/version_edit.h +30 -0
  99. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +3 -5
  100. package/deps/rocksdb/rocksdb/db/version_set.cc +89 -129
  101. package/deps/rocksdb/rocksdb/db/version_set.h +12 -4
  102. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -2
  103. package/deps/rocksdb/rocksdb/db/version_set_test.cc +12 -8
  104. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +0 -15
  105. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +0 -2
  106. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +9 -7
  107. package/deps/rocksdb/rocksdb/db/wide/wide_columns_helper.cc +0 -8
  108. package/deps/rocksdb/rocksdb/db/wide/wide_columns_helper.h +28 -2
  109. package/deps/rocksdb/rocksdb/db/write_batch.cc +32 -10
  110. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +9 -0
  111. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +2 -1
  112. package/deps/rocksdb/rocksdb/db/write_thread.cc +3 -1
  113. package/deps/rocksdb/rocksdb/db/write_thread.h +6 -2
  114. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +15 -0
  115. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +7 -0
  116. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +4 -0
  117. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +18 -2
  118. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +100 -22
  119. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +15 -4
  120. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +34 -8
  121. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +223 -78
  122. package/deps/rocksdb/rocksdb/env/file_system.cc +6 -1
  123. package/deps/rocksdb/rocksdb/env/fs_posix.cc +53 -0
  124. package/deps/rocksdb/rocksdb/env/io_posix.cc +63 -17
  125. package/deps/rocksdb/rocksdb/env/io_posix.h +30 -1
  126. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +132 -48
  127. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +92 -24
  128. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +727 -109
  129. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +3 -4
  130. package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +1 -1
  131. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +8 -0
  132. package/deps/rocksdb/rocksdb/include/rocksdb/attribute_groups.h +20 -1
  133. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +9 -0
  134. package/deps/rocksdb/rocksdb/include/rocksdb/configurable.h +9 -5
  135. package/deps/rocksdb/rocksdb/include/rocksdb/convenience.h +2 -0
  136. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +10 -2
  137. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +1 -0
  138. package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +7 -0
  139. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +34 -37
  140. package/deps/rocksdb/rocksdb/include/rocksdb/iterator_base.h +21 -0
  141. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +56 -28
  142. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +3 -0
  143. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +36 -28
  144. package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +11 -0
  145. package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +1 -0
  146. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_type.h +84 -60
  147. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/secondary_index.h +102 -0
  148. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/table_properties_collectors.h +89 -2
  149. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction.h +32 -0
  150. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db.h +30 -1
  151. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +23 -2
  152. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  153. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +2 -0
  154. package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +79 -21
  155. package/deps/rocksdb/rocksdb/memtable/skiplist.h +41 -18
  156. package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +1 -5
  157. package/deps/rocksdb/rocksdb/memtable/wbwi_memtable.cc +169 -0
  158. package/deps/rocksdb/rocksdb/memtable/wbwi_memtable.h +400 -0
  159. package/deps/rocksdb/rocksdb/monitoring/thread_status_util_debug.cc +2 -0
  160. package/deps/rocksdb/rocksdb/options/cf_options.cc +137 -82
  161. package/deps/rocksdb/rocksdb/options/cf_options.h +18 -6
  162. package/deps/rocksdb/rocksdb/options/configurable.cc +31 -17
  163. package/deps/rocksdb/rocksdb/options/configurable_helper.h +7 -6
  164. package/deps/rocksdb/rocksdb/options/options_helper.cc +10 -8
  165. package/deps/rocksdb/rocksdb/options/options_parser.cc +74 -54
  166. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +89 -0
  167. package/deps/rocksdb/rocksdb/options/options_test.cc +112 -26
  168. package/deps/rocksdb/rocksdb/port/port.h +5 -9
  169. package/deps/rocksdb/rocksdb/src.mk +8 -0
  170. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.h +4 -0
  171. package/deps/rocksdb/rocksdb/table/block_based/block.h +1 -7
  172. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +2 -0
  173. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +62 -80
  174. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +13 -3
  175. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +16 -5
  176. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +38 -7
  177. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +12 -4
  178. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +4 -1
  179. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +4 -1
  180. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +204 -1
  181. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +3 -3
  182. package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +2 -1
  183. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_factory.h +4 -0
  184. package/deps/rocksdb/rocksdb/table/format.cc +3 -3
  185. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +4 -1
  186. package/deps/rocksdb/rocksdb/table/mock_table.cc +0 -50
  187. package/deps/rocksdb/rocksdb/table/mock_table.h +53 -0
  188. package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.h +4 -0
  189. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +1 -1
  190. package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +10 -5
  191. package/deps/rocksdb/rocksdb/table/table_builder.h +3 -1
  192. package/deps/rocksdb/rocksdb/table/table_properties.cc +181 -0
  193. package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +5 -5
  194. package/deps/rocksdb/rocksdb/table/table_test.cc +71 -64
  195. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim.py +45 -45
  196. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim_test.py +35 -35
  197. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py +43 -43
  198. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +41 -4
  199. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +1 -0
  200. package/deps/rocksdb/rocksdb/tools/sst_dump_test.cc +1 -1
  201. package/deps/rocksdb/rocksdb/unreleased_history/add.sh +13 -0
  202. package/deps/rocksdb/rocksdb/util/aligned_buffer.h +24 -5
  203. package/deps/rocksdb/rocksdb/util/compaction_job_stats_impl.cc +7 -0
  204. package/deps/rocksdb/rocksdb/util/file_checksum_helper.cc +0 -52
  205. package/deps/rocksdb/rocksdb/util/file_checksum_helper.h +1 -10
  206. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +92 -0
  207. package/deps/rocksdb/rocksdb/util/thread_operation.h +1 -0
  208. package/deps/rocksdb/rocksdb/util/udt_util.cc +50 -4
  209. package/deps/rocksdb/rocksdb/util/udt_util.h +24 -11
  210. package/deps/rocksdb/rocksdb/util/udt_util_test.cc +26 -13
  211. package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +1 -16
  212. package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +2 -0
  213. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index.cc +214 -0
  214. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index.h +60 -0
  215. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index_test.cc +124 -0
  216. package/deps/rocksdb/rocksdb/utilities/secondary_index/secondary_index_mixin.h +441 -0
  217. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_for_tiering_collector.cc +34 -3
  218. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_for_tiering_collector.h +7 -2
  219. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +437 -0
  220. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +34 -11
  221. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.h +14 -7
  222. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.cc +7 -1
  223. package/deps/rocksdb/rocksdb/utilities/transactions/snapshot_checker.cc +17 -0
  224. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +69 -0
  225. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.h +20 -0
  226. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +1290 -0
  227. package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +324 -0
  228. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +18 -1
  229. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.h +8 -1
  230. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +57 -12
  231. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +32 -3
  232. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +33 -2
  233. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +721 -9
  234. package/deps/rocksdb/rocksdb.gyp +2 -0
  235. package/package.json +1 -1
  236. package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
  237. package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
@@ -218,7 +218,34 @@ class DBIter final : public Iterator {
218
218
  }
219
219
  void set_valid(bool v) { valid_ = v; }
220
220
 
221
+ bool PrepareValue() override;
222
+
221
223
  private:
224
+ class BlobReader {
225
+ public:
226
+ BlobReader(const Version* version, ReadTier read_tier,
227
+ bool verify_checksums, bool fill_cache,
228
+ Env::IOActivity io_activity)
229
+ : version_(version),
230
+ read_tier_(read_tier),
231
+ verify_checksums_(verify_checksums),
232
+ fill_cache_(fill_cache),
233
+ io_activity_(io_activity) {}
234
+
235
+ const Slice& GetBlobValue() const { return blob_value_; }
236
+ Status RetrieveAndSetBlobValue(const Slice& user_key,
237
+ const Slice& blob_index);
238
+ void ResetBlobValue() { blob_value_.Reset(); }
239
+
240
+ private:
241
+ PinnableSlice blob_value_;
242
+ const Version* version_;
243
+ ReadTier read_tier_;
244
+ bool verify_checksums_;
245
+ bool fill_cache_;
246
+ Env::IOActivity io_activity_;
247
+ };
248
+
222
249
  // For all methods in this block:
223
250
  // PRE: iter_->Valid() && status_.ok()
224
251
  // Return false if there was an error, and status() is non-ok, valid_ = false;
@@ -299,15 +326,6 @@ class DBIter final : public Iterator {
299
326
  : user_comparator_.CompareWithoutTimestamp(a, b);
300
327
  }
301
328
 
302
- // Retrieves the blob value for the specified user key using the given blob
303
- // index when using the integrated BlobDB implementation.
304
- bool SetBlobValueIfNeeded(const Slice& user_key, const Slice& blob_index);
305
-
306
- void ResetBlobValue() {
307
- is_blob_ = false;
308
- blob_value_.Reset();
309
- }
310
-
311
329
  void SetValueAndColumnsFromPlain(const Slice& slice) {
312
330
  assert(value_.empty());
313
331
  assert(wide_columns_.empty());
@@ -316,6 +334,11 @@ class DBIter final : public Iterator {
316
334
  wide_columns_.emplace_back(kDefaultWideColumnName, slice);
317
335
  }
318
336
 
337
+ bool SetValueAndColumnsFromBlobImpl(const Slice& user_key,
338
+ const Slice& blob_index);
339
+ bool SetValueAndColumnsFromBlob(const Slice& user_key,
340
+ const Slice& blob_index);
341
+
319
342
  bool SetValueAndColumnsFromEntity(Slice slice);
320
343
 
321
344
  bool SetValueAndColumnsFromMergeResult(const Status& merge_status,
@@ -326,14 +349,21 @@ class DBIter final : public Iterator {
326
349
  wide_columns_.clear();
327
350
  }
328
351
 
352
+ void ResetBlobData() {
353
+ blob_reader_.ResetBlobValue();
354
+ lazy_blob_index_.clear();
355
+ is_blob_ = false;
356
+ }
357
+
329
358
  // The following methods perform the actual merge operation for the
330
- // no base value/plain base value/wide-column base value cases.
359
+ // no/plain/blob/wide-column base value cases.
331
360
  // If user-defined timestamp is enabled, `user_key` includes timestamp.
332
361
  bool MergeWithNoBaseValue(const Slice& user_key);
333
362
  bool MergeWithPlainBaseValue(const Slice& value, const Slice& user_key);
363
+ bool MergeWithBlobBaseValue(const Slice& blob_index, const Slice& user_key);
334
364
  bool MergeWithWideColumnBaseValue(const Slice& entity, const Slice& user_key);
335
365
 
336
- bool PrepareValue() {
366
+ bool PrepareValueInternal() {
337
367
  if (!iter_.PrepareValue()) {
338
368
  assert(!iter_.status().ok());
339
369
  valid_ = false;
@@ -356,7 +386,7 @@ class DBIter final : public Iterator {
356
386
  UserComparatorWrapper user_comparator_;
357
387
  const MergeOperator* const merge_operator_;
358
388
  IteratorWrapper iter_;
359
- const Version* version_;
389
+ BlobReader blob_reader_;
360
390
  ReadCallback* read_callback_;
361
391
  // Max visible sequence number. It is normally the snapshot seq unless we have
362
392
  // uncommitted data in db as in WriteUnCommitted.
@@ -376,7 +406,6 @@ class DBIter final : public Iterator {
376
406
  std::string saved_value_;
377
407
  Slice pinned_value_;
378
408
  // for prefix seek mode to support prev()
379
- PinnableSlice blob_value_;
380
409
  // Value of the default column
381
410
  Slice value_;
382
411
  // All columns (i.e. name-value pairs)
@@ -410,15 +439,13 @@ class DBIter final : public Iterator {
410
439
  // Expect the inner iterator to maintain a total order.
411
440
  // prefix_extractor_ must be non-NULL if the value is false.
412
441
  const bool expect_total_order_inner_iter_;
413
- ReadTier read_tier_;
414
- bool fill_cache_;
415
- bool verify_checksums_;
416
442
  // Whether the iterator is allowed to expose blob references. Set to true when
417
443
  // the stacked BlobDB implementation is used, false otherwise.
418
444
  bool expose_blob_index_;
445
+ bool allow_unprepared_value_;
446
+ Slice lazy_blob_index_;
419
447
  bool is_blob_;
420
448
  bool arena_mode_;
421
- const Env::IOActivity io_activity_;
422
449
  // List of operands for merge operator.
423
450
  MergeContext merge_context_;
424
451
  LocalStatistics local_stats_;
@@ -56,6 +56,11 @@ class DBOptionsTest : public DBTestBase {
56
56
  EXPECT_OK(GetStringFromMutableCFOptions(
57
57
  config_options, MutableCFOptions(options), &options_str));
58
58
  EXPECT_OK(StringToMap(options_str, &mutable_map));
59
+ for (auto& opt : TEST_GetImmutableInMutableCFOptions()) {
60
+ // Not yet mutable but migrated to MutableCFOptions in preparation for
61
+ // being mutable
62
+ mutable_map.erase(opt);
63
+ }
59
64
  return mutable_map;
60
65
  }
61
66
 
@@ -231,21 +236,33 @@ TEST_F(DBOptionsTest, SetMutableTableOptions) {
231
236
  ASSERT_OK(dbfull()->SetOptions(
232
237
  cfh, {{"table_factory.block_size", "16384"},
233
238
  {"table_factory.block_restart_interval", "11"}}));
239
+ // Old c_bbto
240
+ ASSERT_EQ(c_bbto->block_size, 8192);
241
+ ASSERT_EQ(c_bbto->block_restart_interval, 7);
242
+ // New c_bbto
243
+ c_opts = dbfull()->GetOptions(cfh);
244
+ c_bbto = c_opts.table_factory->GetOptions<BlockBasedTableOptions>();
234
245
  ASSERT_EQ(c_bbto->block_size, 16384);
235
246
  ASSERT_EQ(c_bbto->block_restart_interval, 11);
236
247
 
237
248
  // Now set an option that is not mutable - options should not change
238
- ASSERT_NOK(
239
- dbfull()->SetOptions(cfh, {{"table_factory.no_block_cache", "false"}}));
249
+ // FIXME: find a way to make this fail again
250
+ // ASSERT_NOK(
251
+ // dbfull()->SetOptions(cfh, {{"table_factory.no_block_cache", "false"}}));
252
+ c_opts = dbfull()->GetOptions(cfh);
253
+ ASSERT_EQ(c_bbto, c_opts.table_factory->GetOptions<BlockBasedTableOptions>());
240
254
  ASSERT_EQ(c_bbto->no_block_cache, true);
241
255
  ASSERT_EQ(c_bbto->block_size, 16384);
242
256
  ASSERT_EQ(c_bbto->block_restart_interval, 11);
243
257
 
244
258
  // 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"}}));
259
+ // FIXME: find a way to make this fail again
260
+ // ASSERT_NOK(dbfull()->SetOptions(
261
+ // cfh, {{"table_factory.no_block_cache", "false"},
262
+ // {"table_factory.block_size", "8192"},
263
+ // {"table_factory.block_restart_interval", "7"}}));
264
+ c_opts = dbfull()->GetOptions(cfh);
265
+ ASSERT_EQ(c_bbto, c_opts.table_factory->GetOptions<BlockBasedTableOptions>());
249
266
  ASSERT_EQ(c_bbto->no_block_cache, true);
250
267
  ASSERT_EQ(c_bbto->block_size, 16384);
251
268
  ASSERT_EQ(c_bbto->block_restart_interval, 11);
@@ -256,6 +273,8 @@ TEST_F(DBOptionsTest, SetMutableTableOptions) {
256
273
  cfh, {{"table_factory.block_size", "8192"},
257
274
  {"table_factory.does_not_exist", "true"},
258
275
  {"table_factory.block_restart_interval", "7"}}));
276
+ c_opts = dbfull()->GetOptions(cfh);
277
+ ASSERT_EQ(c_bbto, c_opts.table_factory->GetOptions<BlockBasedTableOptions>());
259
278
  ASSERT_EQ(c_bbto->no_block_cache, true);
260
279
  ASSERT_EQ(c_bbto->block_size, 16384);
261
280
  ASSERT_EQ(c_bbto->block_restart_interval, 11);
@@ -271,6 +290,7 @@ TEST_F(DBOptionsTest, SetMutableTableOptions) {
271
290
  {"table_factory.block_restart_interval", "13"}}));
272
291
  c_opts = dbfull()->GetOptions(cfh);
273
292
  ASSERT_EQ(c_opts.blob_file_size, 32768);
293
+ c_bbto = c_opts.table_factory->GetOptions<BlockBasedTableOptions>();
274
294
  ASSERT_EQ(c_bbto->block_size, 16384);
275
295
  ASSERT_EQ(c_bbto->block_restart_interval, 13);
276
296
  // Set some on the table and a bad one on the ColumnFamily - options should
@@ -279,6 +299,7 @@ TEST_F(DBOptionsTest, SetMutableTableOptions) {
279
299
  cfh, {{"table_factory.block_size", "1024"},
280
300
  {"no_such_option", "32768"},
281
301
  {"table_factory.block_restart_interval", "7"}}));
302
+ ASSERT_EQ(c_bbto, c_opts.table_factory->GetOptions<BlockBasedTableOptions>());
282
303
  ASSERT_EQ(c_bbto->block_size, 16384);
283
304
  ASSERT_EQ(c_bbto->block_restart_interval, 13);
284
305
  }
@@ -1826,21 +1826,30 @@ TEST_F(DBTest, GetApproximateMemTableStats) {
1826
1826
  uint64_t count;
1827
1827
  uint64_t size;
1828
1828
 
1829
+ // Because Random::GetTLSInstance() seed is reset in DBTestBase,
1830
+ // this test is deterministic.
1831
+
1829
1832
  std::string start = Key(50);
1830
1833
  std::string end = Key(60);
1831
1834
  Range r(start, end);
1832
1835
  db_->GetApproximateMemTableStats(r, &count, &size);
1833
- ASSERT_GT(count, 0);
1834
- ASSERT_LE(count, N);
1835
- ASSERT_GT(size, 6000);
1836
- ASSERT_LT(size, 204800);
1836
+ // When actual count is <= 10, it returns that as the minimum
1837
+ EXPECT_EQ(count, 10);
1838
+ EXPECT_EQ(size, 10440);
1839
+
1840
+ start = Key(20);
1841
+ end = Key(100);
1842
+ r = Range(start, end);
1843
+ db_->GetApproximateMemTableStats(r, &count, &size);
1844
+ EXPECT_EQ(count, 72);
1845
+ EXPECT_EQ(size, 75168);
1837
1846
 
1838
1847
  start = Key(500);
1839
1848
  end = Key(600);
1840
1849
  r = Range(start, end);
1841
1850
  db_->GetApproximateMemTableStats(r, &count, &size);
1842
- ASSERT_EQ(count, 0);
1843
- ASSERT_EQ(size, 0);
1851
+ EXPECT_EQ(count, 0);
1852
+ EXPECT_EQ(size, 0);
1844
1853
 
1845
1854
  ASSERT_OK(Flush());
1846
1855
 
@@ -1848,8 +1857,8 @@ TEST_F(DBTest, GetApproximateMemTableStats) {
1848
1857
  end = Key(60);
1849
1858
  r = Range(start, end);
1850
1859
  db_->GetApproximateMemTableStats(r, &count, &size);
1851
- ASSERT_EQ(count, 0);
1852
- ASSERT_EQ(size, 0);
1860
+ EXPECT_EQ(count, 0);
1861
+ EXPECT_EQ(size, 0);
1853
1862
 
1854
1863
  for (int i = 0; i < N; i++) {
1855
1864
  ASSERT_OK(Put(Key(1000 + i), rnd.RandomString(1024)));
@@ -1857,10 +1866,11 @@ TEST_F(DBTest, GetApproximateMemTableStats) {
1857
1866
 
1858
1867
  start = Key(100);
1859
1868
  end = Key(1020);
1869
+ // Actually 20 keys in the range ^^
1860
1870
  r = Range(start, end);
1861
1871
  db_->GetApproximateMemTableStats(r, &count, &size);
1862
- ASSERT_GT(count, 20);
1863
- ASSERT_GT(size, 6000);
1872
+ EXPECT_EQ(count, 20);
1873
+ EXPECT_EQ(size, 20880);
1864
1874
  }
1865
1875
 
1866
1876
  TEST_F(DBTest, ApproximateSizes) {
@@ -5169,10 +5179,14 @@ TEST_F(DBTest, DynamicLevelCompressionPerLevel) {
5169
5179
  options.max_bytes_for_level_multiplier = 4;
5170
5180
  options.max_background_compactions = 1;
5171
5181
  options.num_levels = 5;
5182
+ options.statistics = CreateDBStatistics();
5172
5183
 
5173
5184
  options.compression_per_level.resize(3);
5185
+ // No compression for L0
5174
5186
  options.compression_per_level[0] = kNoCompression;
5187
+ // No compression for the Ln whre L0 is compacted to
5175
5188
  options.compression_per_level[1] = kNoCompression;
5189
+ // Snpapy compression for Ln+1
5176
5190
  options.compression_per_level[2] = kSnappyCompression;
5177
5191
 
5178
5192
  OnFileDeletionListener* listener = new OnFileDeletionListener();
@@ -5181,7 +5195,7 @@ TEST_F(DBTest, DynamicLevelCompressionPerLevel) {
5181
5195
  DestroyAndReopen(options);
5182
5196
 
5183
5197
  // Insert more than 80K. L4 should be base level. Neither L0 nor L4 should
5184
- // be compressed, so total data size should be more than 80K.
5198
+ // be compressed, so there shouldn't be any compression.
5185
5199
  for (int i = 0; i < 20; i++) {
5186
5200
  ASSERT_OK(Put(Key(keys[i]), CompressibleString(&rnd, 4000)));
5187
5201
  }
@@ -5191,10 +5205,17 @@ TEST_F(DBTest, DynamicLevelCompressionPerLevel) {
5191
5205
  ASSERT_EQ(NumTableFilesAtLevel(1), 0);
5192
5206
  ASSERT_EQ(NumTableFilesAtLevel(2), 0);
5193
5207
  ASSERT_EQ(NumTableFilesAtLevel(3), 0);
5194
- // Assuming each files' metadata is at least 50 bytes/
5195
- ASSERT_GT(SizeAtLevel(0) + SizeAtLevel(4), 20U * 4000U + 50U * 4);
5208
+ ASSERT_TRUE(NumTableFilesAtLevel(0) > 0 || NumTableFilesAtLevel(4) > 0);
5209
+
5210
+ // Verify there was no compression
5211
+ auto num_block_compressed =
5212
+ options.statistics->getTickerCount(NUMBER_BLOCK_COMPRESSED);
5213
+ ASSERT_EQ(num_block_compressed, 0);
5196
5214
 
5197
- // Insert 400KB. Some data will be compressed
5215
+ // Insert 400KB and there will be some files end up in L3. According to the
5216
+ // above compression settings for each level, there will be some compression.
5217
+ ASSERT_OK(options.statistics->Reset());
5218
+ ASSERT_EQ(num_block_compressed, 0);
5198
5219
  for (int i = 21; i < 120; i++) {
5199
5220
  ASSERT_OK(Put(Key(keys[i]), CompressibleString(&rnd, 4000)));
5200
5221
  }
@@ -5202,9 +5223,14 @@ TEST_F(DBTest, DynamicLevelCompressionPerLevel) {
5202
5223
  ASSERT_OK(dbfull()->TEST_WaitForCompact());
5203
5224
  ASSERT_EQ(NumTableFilesAtLevel(1), 0);
5204
5225
  ASSERT_EQ(NumTableFilesAtLevel(2), 0);
5226
+ ASSERT_GE(NumTableFilesAtLevel(3), 1);
5227
+ ASSERT_GE(NumTableFilesAtLevel(4), 1);
5228
+
5229
+ // Verify there was compression
5230
+ num_block_compressed =
5231
+ options.statistics->getTickerCount(NUMBER_BLOCK_COMPRESSED);
5232
+ ASSERT_GT(num_block_compressed, 0);
5205
5233
 
5206
- ASSERT_LT(SizeAtLevel(0) + SizeAtLevel(3) + SizeAtLevel(4),
5207
- 120U * 4000U + 50U * 24);
5208
5234
  // Make sure data in files in L3 is not compacted by removing all files
5209
5235
  // in L4 and calculate number of rows
5210
5236
  ASSERT_OK(dbfull()->SetOptions({
@@ -5224,6 +5250,12 @@ TEST_F(DBTest, DynamicLevelCompressionPerLevel) {
5224
5250
  num_keys++;
5225
5251
  }
5226
5252
  ASSERT_OK(iter->status());
5253
+
5254
+ ASSERT_EQ(NumTableFilesAtLevel(1), 0);
5255
+ ASSERT_EQ(NumTableFilesAtLevel(2), 0);
5256
+ ASSERT_GE(NumTableFilesAtLevel(3), 1);
5257
+ ASSERT_EQ(NumTableFilesAtLevel(4), 0);
5258
+
5227
5259
  ASSERT_GT(SizeAtLevel(0) + SizeAtLevel(3), num_keys * 4000U + num_keys * 10U);
5228
5260
  }
5229
5261
 
@@ -16,6 +16,7 @@
16
16
  #include "db/db_test_util.h"
17
17
  #include "db/read_callback.h"
18
18
  #include "db/version_edit.h"
19
+ #include "env/fs_readonly.h"
19
20
  #include "options/options_helper.h"
20
21
  #include "port/port.h"
21
22
  #include "port/stack_trace.h"
@@ -36,18 +37,6 @@ namespace ROCKSDB_NAMESPACE {
36
37
  class DBTest2 : public DBTestBase {
37
38
  public:
38
39
  DBTest2() : DBTestBase("db_test2", /*env_do_fsync=*/true) {}
39
- std::vector<FileMetaData*> GetLevelFileMetadatas(int level, int cf = 0) {
40
- VersionSet* const versions = dbfull()->GetVersionSet();
41
- assert(versions);
42
- ColumnFamilyData* const cfd =
43
- versions->GetColumnFamilySet()->GetColumnFamily(cf);
44
- assert(cfd);
45
- Version* const current = cfd->current();
46
- assert(current);
47
- VersionStorageInfo* const storage_info = current->storage_info();
48
- assert(storage_info);
49
- return storage_info->LevelFiles(level);
50
- }
51
40
  };
52
41
 
53
42
  TEST_F(DBTest2, OpenForReadOnly) {
@@ -2115,16 +2104,15 @@ TEST_P(PinL0IndexAndFilterBlocksTest,
2115
2104
  ASSERT_EQ(2, TestGetTickerCount(options, BLOCK_CACHE_ADD));
2116
2105
  ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_DATA_MISS));
2117
2106
 
2118
- std::string value;
2119
2107
  // Miss and hit count should remain the same, they're all pinned.
2120
- ASSERT_TRUE(db_->KeyMayExist(ReadOptions(), handles_[1], "key", &value));
2108
+ ASSERT_TRUE(db_->KeyMayExist(ReadOptions(), handles_[1], "key", nullptr));
2121
2109
  ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_FILTER_MISS));
2122
2110
  ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_FILTER_HIT));
2123
2111
  ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_INDEX_MISS));
2124
2112
  ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_INDEX_HIT));
2125
2113
 
2126
2114
  // Miss and hit count should remain the same, they're all pinned.
2127
- value = Get(1, "key");
2115
+ std::string value = Get(1, "key");
2128
2116
  ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_FILTER_MISS));
2129
2117
  ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_FILTER_HIT));
2130
2118
  ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_INDEX_MISS));
@@ -8074,6 +8062,63 @@ TEST_F(DBTest2, TableCacheMissDuringReadFromBlockCacheTier) {
8074
8062
  ASSERT_EQ(orig_num_file_opens, TestGetTickerCount(options, NO_FILE_OPENS));
8075
8063
  }
8076
8064
 
8065
+ TEST_F(DBTest2, GetFileChecksumsFromCurrentManifest_CRC32) {
8066
+ Options opts = CurrentOptions();
8067
+ opts.create_if_missing = true;
8068
+ opts.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory();
8069
+ opts.level0_file_num_compaction_trigger = 10;
8070
+
8071
+ // Bootstrap the test database.
8072
+ DB* db = nullptr;
8073
+ std::string dbname = test::PerThreadDBPath("file_chksum");
8074
+ ASSERT_OK(DB::Open(opts, dbname, &db));
8075
+
8076
+ WriteOptions wopts;
8077
+ FlushOptions fopts;
8078
+ fopts.wait = true;
8079
+ Random rnd(test::RandomSeed());
8080
+ for (int i = 0; i < 4; i++) {
8081
+ ASSERT_OK(db->Put(wopts, Key(i), rnd.RandomString(100)));
8082
+ ASSERT_OK(db->Flush(fopts));
8083
+ }
8084
+
8085
+ // Obtain rich files metadata for source of truth.
8086
+ std::vector<LiveFileMetaData> live_files;
8087
+ db->GetLiveFilesMetaData(&live_files);
8088
+
8089
+ ASSERT_OK(db->Close());
8090
+ delete db;
8091
+ db = nullptr;
8092
+
8093
+ // Process current MANIFEST file and build internal file checksum mappings.
8094
+ std::unique_ptr<FileChecksumList> checksum_list(NewFileChecksumList());
8095
+ auto read_only_fs =
8096
+ std::make_shared<ReadOnlyFileSystem>(env_->GetFileSystem());
8097
+ ASSERT_OK(experimental::GetFileChecksumsFromCurrentManifest(
8098
+ read_only_fs.get(), dbname, checksum_list.get()));
8099
+
8100
+ ASSERT_TRUE(checksum_list != nullptr);
8101
+
8102
+ // Retrieve files, related checksums and checksum functions.
8103
+ std::vector<uint64_t> file_numbers;
8104
+ std::vector<std::string> checksums;
8105
+ std::vector<std::string> checksum_func_names;
8106
+ ASSERT_OK(checksum_list->GetAllFileChecksums(&file_numbers, &checksums,
8107
+ &checksum_func_names));
8108
+
8109
+ // Compare results.
8110
+ ASSERT_EQ(live_files.size(), checksum_list->size());
8111
+ for (size_t i = 0; i < live_files.size(); i++) {
8112
+ std::string stored_checksum;
8113
+ std::string stored_func_name;
8114
+ ASSERT_OK(checksum_list->SearchOneFileChecksum(
8115
+ live_files[i].file_number, &stored_checksum, &stored_func_name));
8116
+
8117
+ ASSERT_EQ(live_files[i].file_checksum, stored_checksum);
8118
+ ASSERT_EQ(live_files[i].file_checksum_func_name, stored_func_name);
8119
+ }
8120
+ }
8121
+
8077
8122
  } // namespace ROCKSDB_NAMESPACE
8078
8123
 
8079
8124
  int main(int argc, char** argv) {
@@ -934,6 +934,13 @@ Status DBTestBase::Get(const std::string& k, PinnableSlice* v) {
934
934
  return s;
935
935
  }
936
936
 
937
+ Status DBTestBase::CompactRange(const CompactRangeOptions& options,
938
+ std::optional<Slice> begin,
939
+ std::optional<Slice> end) {
940
+ return db_->CompactRange(options, begin ? &begin.value() : nullptr,
941
+ end ? &end.value() : nullptr);
942
+ }
943
+
937
944
  uint64_t DBTestBase::GetNumSnapshots() {
938
945
  uint64_t int_num;
939
946
  EXPECT_TRUE(dbfull()->GetIntProperty("rocksdb.num-snapshots", &int_num));
@@ -1263,6 +1270,20 @@ Status DBTestBase::CountFiles(size_t* count) {
1263
1270
  return Status::OK();
1264
1271
  }
1265
1272
 
1273
+ std::vector<FileMetaData*> DBTestBase::GetLevelFileMetadatas(int level,
1274
+ int cf) {
1275
+ VersionSet* const versions = dbfull()->GetVersionSet();
1276
+ assert(versions);
1277
+ ColumnFamilyData* const cfd =
1278
+ versions->GetColumnFamilySet()->GetColumnFamily(cf);
1279
+ assert(cfd);
1280
+ Version* const current = cfd->current();
1281
+ assert(current);
1282
+ VersionStorageInfo* const storage_info = current->storage_info();
1283
+ assert(storage_info);
1284
+ return storage_info->LevelFiles(level);
1285
+ }
1286
+
1266
1287
  Status DBTestBase::Size(const Slice& start, const Slice& limit, int cf,
1267
1288
  uint64_t* size) {
1268
1289
  Range r(start, limit);
@@ -1579,42 +1600,74 @@ std::vector<std::uint64_t> DBTestBase::ListTableFiles(Env* env,
1579
1600
  return file_numbers;
1580
1601
  }
1581
1602
 
1582
- void DBTestBase::VerifyDBFromMap(std::map<std::string, std::string> true_data,
1583
- size_t* total_reads_res, bool tailing_iter,
1584
- std::map<std::string, Status> status) {
1603
+ void DBTestBase::VerifyDBFromMap(
1604
+ std::map<std::string, std::string> true_data, size_t* total_reads_res,
1605
+ bool tailing_iter, ReadOptions* ro, ColumnFamilyHandle* cf,
1606
+ std::unordered_set<std::string>* not_found) const {
1607
+ ReadOptions temp_ro;
1608
+ if (!ro) {
1609
+ ro = &temp_ro;
1610
+ ro->verify_checksums = true;
1611
+ }
1612
+ if (!cf) {
1613
+ cf = db_->DefaultColumnFamily();
1614
+ }
1615
+
1616
+ // Get
1585
1617
  size_t total_reads = 0;
1618
+ std::string result;
1619
+ for (auto& [k, v] : true_data) {
1620
+ ASSERT_OK(db_->Get(*ro, cf, k, &result)) << "key is " << k;
1621
+ ASSERT_EQ(v, result);
1622
+ total_reads++;
1623
+ }
1624
+ if (not_found) {
1625
+ for (const auto& k : *not_found) {
1626
+ ASSERT_TRUE(db_->Get(*ro, cf, k, &result).IsNotFound())
1627
+ << "key is " << k << " val is " << result;
1628
+ }
1629
+ }
1586
1630
 
1587
- for (auto& kv : true_data) {
1588
- Status s = status[kv.first];
1589
- if (s.ok()) {
1590
- ASSERT_EQ(Get(kv.first), kv.second);
1591
- } else {
1592
- std::string value;
1593
- ASSERT_EQ(s, db_->Get(ReadOptions(), kv.first, &value));
1631
+ // MultiGet
1632
+ std::vector<Slice> key_slice;
1633
+ for (const auto& [k, _] : true_data) {
1634
+ key_slice.emplace_back(k);
1635
+ }
1636
+ std::vector<std::string> values;
1637
+ std::vector<ColumnFamilyHandle*> cfs(key_slice.size(), cf);
1638
+ std::vector<Status> status = db_->MultiGet(*ro, cfs, key_slice, &values);
1639
+ total_reads += key_slice.size();
1640
+ auto data_iter = true_data.begin();
1641
+ for (size_t i = 0; i < key_slice.size(); ++i, ++data_iter) {
1642
+ ASSERT_OK(status[i]);
1643
+ ASSERT_EQ(values[i], data_iter->second);
1644
+ }
1645
+ // MultiGet - not found
1646
+ if (not_found) {
1647
+ key_slice.clear();
1648
+ for (const auto& k : *not_found) {
1649
+ key_slice.emplace_back(k);
1650
+ }
1651
+ cfs = std::vector<ColumnFamilyHandle*>(key_slice.size(), cf);
1652
+ values.clear();
1653
+ status = db_->MultiGet(*ro, cfs, key_slice, &values);
1654
+ for (const auto& s : status) {
1655
+ ASSERT_TRUE(s.IsNotFound());
1594
1656
  }
1595
- total_reads++;
1596
1657
  }
1597
1658
 
1598
1659
  // Normal Iterator
1599
1660
  {
1600
1661
  int iter_cnt = 0;
1601
- ReadOptions ro;
1602
- ro.total_order_seek = true;
1603
- Iterator* iter = db_->NewIterator(ro);
1662
+ ReadOptions ro_ = *ro;
1663
+ ro_.total_order_seek = true;
1664
+ Iterator* iter = db_->NewIterator(ro_, cf);
1604
1665
  // Verify Iterator::Next()
1605
1666
  iter_cnt = 0;
1606
- auto data_iter = true_data.begin();
1607
- Status s;
1608
- for (iter->SeekToFirst(); iter->Valid(); iter->Next(), data_iter++) {
1667
+ data_iter = true_data.begin();
1668
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next(), ++data_iter) {
1609
1669
  ASSERT_EQ(iter->key().ToString(), data_iter->first);
1610
- Status current_status = status[data_iter->first];
1611
- if (!current_status.ok()) {
1612
- s = current_status;
1613
- }
1614
- ASSERT_EQ(iter->status(), s);
1615
- if (current_status.ok()) {
1616
1670
  ASSERT_EQ(iter->value().ToString(), data_iter->second);
1617
- }
1618
1671
  iter_cnt++;
1619
1672
  total_reads++;
1620
1673
  }
@@ -1625,20 +1678,12 @@ void DBTestBase::VerifyDBFromMap(std::map<std::string, std::string> true_data,
1625
1678
 
1626
1679
  // Verify Iterator::Prev()
1627
1680
  // Use a new iterator to make sure its status is clean.
1628
- iter = db_->NewIterator(ro);
1681
+ iter = db_->NewIterator(ro_, cf);
1629
1682
  iter_cnt = 0;
1630
- s = Status::OK();
1631
1683
  auto data_rev = true_data.rbegin();
1632
1684
  for (iter->SeekToLast(); iter->Valid(); iter->Prev(), data_rev++) {
1633
1685
  ASSERT_EQ(iter->key().ToString(), data_rev->first);
1634
- Status current_status = status[data_rev->first];
1635
- if (!current_status.ok()) {
1636
- s = current_status;
1637
- }
1638
- ASSERT_EQ(iter->status(), s);
1639
- if (current_status.ok()) {
1640
1686
  ASSERT_EQ(iter->value().ToString(), data_rev->second);
1641
- }
1642
1687
  iter_cnt++;
1643
1688
  total_reads++;
1644
1689
  }
@@ -1646,12 +1691,20 @@ void DBTestBase::VerifyDBFromMap(std::map<std::string, std::string> true_data,
1646
1691
  ASSERT_EQ(data_rev, true_data.rend())
1647
1692
  << iter_cnt << " / " << true_data.size();
1648
1693
 
1649
- // Verify Iterator::Seek()
1650
- for (const auto& kv : true_data) {
1651
- iter->Seek(kv.first);
1652
- ASSERT_EQ(kv.first, iter->key().ToString());
1653
- ASSERT_EQ(kv.second, iter->value().ToString());
1654
- total_reads++;
1694
+ // Verify Iterator::Seek() and SeekForPrev()
1695
+ for (const auto& [k, v] : true_data) {
1696
+ for (bool prev : {false, true}) {
1697
+ if (prev) {
1698
+ iter->SeekForPrev(k);
1699
+ } else {
1700
+ iter->Seek(k);
1701
+ }
1702
+ ASSERT_TRUE(iter->Valid());
1703
+ ASSERT_OK(iter->status());
1704
+ ASSERT_EQ(iter->key(), k);
1705
+ ASSERT_EQ(iter->value(), v);
1706
+ ++total_reads;
1707
+ }
1655
1708
  }
1656
1709
  delete iter;
1657
1710
  }
@@ -1659,14 +1712,14 @@ void DBTestBase::VerifyDBFromMap(std::map<std::string, std::string> true_data,
1659
1712
  if (tailing_iter) {
1660
1713
  // Tailing iterator
1661
1714
  int iter_cnt = 0;
1662
- ReadOptions ro;
1663
- ro.tailing = true;
1664
- ro.total_order_seek = true;
1665
- Iterator* iter = db_->NewIterator(ro);
1715
+ ReadOptions ro_ = *ro;
1716
+ ro_.tailing = true;
1717
+ ro_.total_order_seek = true;
1718
+ Iterator* iter = db_->NewIterator(ro_, cf);
1666
1719
 
1667
1720
  // Verify ForwardIterator::Next()
1668
1721
  iter_cnt = 0;
1669
- auto data_iter = true_data.begin();
1722
+ data_iter = true_data.begin();
1670
1723
  for (iter->SeekToFirst(); iter->Valid(); iter->Next(), data_iter++) {
1671
1724
  ASSERT_EQ(iter->key().ToString(), data_iter->first);
1672
1725
  ASSERT_EQ(iter->value().ToString(), data_iter->second);
@@ -1225,6 +1225,9 @@ class DBTestBase : public testing::Test {
1225
1225
  const Snapshot* snapshot = nullptr,
1226
1226
  const bool async = false);
1227
1227
 
1228
+ Status CompactRange(const CompactRangeOptions& options,
1229
+ std::optional<Slice> begin, std::optional<Slice> end);
1230
+
1228
1231
  uint64_t GetNumSnapshots();
1229
1232
 
1230
1233
  uint64_t GetTimeOldestSnapshots();
@@ -1273,6 +1276,8 @@ class DBTestBase : public testing::Test {
1273
1276
 
1274
1277
  Status CountFiles(size_t* count);
1275
1278
 
1279
+ std::vector<FileMetaData*> GetLevelFileMetadatas(int level, int cf = 0);
1280
+
1276
1281
  Status Size(const Slice& start, const Slice& limit, uint64_t* size) {
1277
1282
  return Size(start, limit, 0, size);
1278
1283
  }
@@ -1362,7 +1367,8 @@ class DBTestBase : public testing::Test {
1362
1367
  void VerifyDBFromMap(
1363
1368
  std::map<std::string, std::string> true_data,
1364
1369
  size_t* total_reads_res = nullptr, bool tailing_iter = false,
1365
- std::map<std::string, Status> status = std::map<std::string, Status>());
1370
+ ReadOptions* ro = nullptr, ColumnFamilyHandle* cf = nullptr,
1371
+ std::unordered_set<std::string>* not_found = nullptr) const;
1366
1372
 
1367
1373
  void VerifyDBInternal(
1368
1374
  std::vector<std::pair<std::string, std::string>> true_data);