@nxtedition/rocksdb 7.1.20 → 7.1.21

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 (262) hide show
  1. package/deps/rocksdb/rocksdb/CMakeLists.txt +13 -6
  2. package/deps/rocksdb/rocksdb/Makefile +1 -1
  3. package/deps/rocksdb/rocksdb/TARGETS +2 -0
  4. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager_test.cc +1 -0
  5. package/deps/rocksdb/rocksdb/cache/cache_test.cc +4 -4
  6. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +139 -161
  7. package/deps/rocksdb/rocksdb/cache/clock_cache.h +92 -82
  8. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +16 -3
  9. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +9 -3
  10. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +73 -30
  11. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +25 -67
  12. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +41 -40
  13. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +109 -155
  14. package/deps/rocksdb/rocksdb/cache/lru_cache.h +127 -149
  15. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +75 -80
  16. package/deps/rocksdb/rocksdb/cache/sharded_cache.cc +22 -172
  17. package/deps/rocksdb/rocksdb/cache/sharded_cache.h +272 -85
  18. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +12 -4
  19. package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator_test.cc +1 -0
  20. package/deps/rocksdb/rocksdb/db/blob/blob_file_addition_test.cc +1 -0
  21. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder_test.cc +1 -0
  22. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache_test.cc +1 -0
  23. package/deps/rocksdb/rocksdb/db/blob/blob_file_garbage_test.cc +1 -0
  24. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +1 -0
  25. package/deps/rocksdb/rocksdb/db/blob/blob_garbage_meter_test.cc +1 -0
  26. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +13 -4
  27. package/deps/rocksdb/rocksdb/db/builder.cc +1 -1
  28. package/deps/rocksdb/rocksdb/db/column_family.cc +15 -1
  29. package/deps/rocksdb/rocksdb/db/compact_files_test.cc +1 -0
  30. package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator_test.cc +1 -0
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +25 -7
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +10 -0
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +22 -8
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +14 -5
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +1 -0
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +38 -12
  37. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +9 -6
  38. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +408 -6
  39. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +244 -54
  40. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +27 -6
  41. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +25 -30
  42. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +87 -26
  43. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +23 -4
  44. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +61 -0
  45. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +294 -21
  46. package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +1 -0
  47. package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +1 -0
  48. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +28 -10
  49. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +4 -4
  50. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +272 -0
  51. package/deps/rocksdb/rocksdb/db/db_flush_test.cc +38 -0
  52. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +69 -25
  53. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +7 -3
  54. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +29 -12
  55. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +0 -12
  56. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +10 -4
  57. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +35 -22
  58. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +5 -1
  59. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +40 -5
  60. package/deps/rocksdb/rocksdb/db/db_iter.cc +1 -0
  61. package/deps/rocksdb/rocksdb/db/db_iter_stress_test.cc +1 -0
  62. package/deps/rocksdb/rocksdb/db/db_iter_test.cc +1 -0
  63. package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +22 -0
  64. package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +1 -0
  65. package/deps/rocksdb/rocksdb/db/db_logical_block_size_cache_test.cc +1 -0
  66. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +72 -5
  67. package/deps/rocksdb/rocksdb/db/db_tailing_iter_test.cc +60 -21
  68. package/deps/rocksdb/rocksdb/db/db_test.cc +170 -1
  69. package/deps/rocksdb/rocksdb/db/db_test2.cc +9 -3
  70. package/deps/rocksdb/rocksdb/db/db_test_util.cc +19 -0
  71. package/deps/rocksdb/rocksdb/db/db_test_util.h +32 -0
  72. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +444 -3
  73. package/deps/rocksdb/rocksdb/db/db_write_test.cc +8 -8
  74. package/deps/rocksdb/rocksdb/db/dbformat.cc +13 -0
  75. package/deps/rocksdb/rocksdb/db/dbformat.h +59 -4
  76. package/deps/rocksdb/rocksdb/db/dbformat_test.cc +1 -0
  77. package/deps/rocksdb/rocksdb/db/experimental.cc +3 -1
  78. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +24 -3
  79. package/deps/rocksdb/rocksdb/db/fault_injection_test.cc +1 -0
  80. package/deps/rocksdb/rocksdb/db/filename_test.cc +1 -0
  81. package/deps/rocksdb/rocksdb/db/flush_job.cc +4 -3
  82. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +1 -0
  83. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +85 -43
  84. package/deps/rocksdb/rocksdb/db/forward_iterator.h +3 -1
  85. package/deps/rocksdb/rocksdb/db/internal_stats.cc +33 -6
  86. package/deps/rocksdb/rocksdb/db/internal_stats.h +6 -0
  87. package/deps/rocksdb/rocksdb/db/listener_test.cc +1 -0
  88. package/deps/rocksdb/rocksdb/db/log_test.cc +1 -0
  89. package/deps/rocksdb/rocksdb/db/log_writer.cc +1 -1
  90. package/deps/rocksdb/rocksdb/db/log_writer.h +1 -1
  91. package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +1 -0
  92. package/deps/rocksdb/rocksdb/db/memtable.cc +158 -56
  93. package/deps/rocksdb/rocksdb/db/memtable.h +2 -0
  94. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +1 -0
  95. package/deps/rocksdb/rocksdb/db/merge_helper_test.cc +1 -0
  96. package/deps/rocksdb/rocksdb/db/options_file_test.cc +1 -0
  97. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +1 -0
  98. package/deps/rocksdb/rocksdb/db/periodic_task_scheduler_test.cc +1 -0
  99. package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +1 -0
  100. package/deps/rocksdb/rocksdb/db/prefix_test.cc +1 -0
  101. package/deps/rocksdb/rocksdb/db/range_del_aggregator.cc +52 -9
  102. package/deps/rocksdb/rocksdb/db/range_del_aggregator.h +31 -2
  103. package/deps/rocksdb/rocksdb/db/range_del_aggregator_test.cc +1 -0
  104. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.cc +81 -42
  105. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +78 -12
  106. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter_test.cc +1 -0
  107. package/deps/rocksdb/rocksdb/db/repair_test.cc +1 -0
  108. package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +154 -27
  109. package/deps/rocksdb/rocksdb/db/seqno_to_time_mapping.cc +21 -4
  110. package/deps/rocksdb/rocksdb/db/seqno_to_time_mapping.h +4 -1
  111. package/deps/rocksdb/rocksdb/db/table_cache.cc +18 -6
  112. package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +1 -0
  113. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +1 -0
  114. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +1 -0
  115. package/deps/rocksdb/rocksdb/db/version_set.cc +15 -7
  116. package/deps/rocksdb/rocksdb/db/version_set.h +2 -1
  117. package/deps/rocksdb/rocksdb/db/version_set_test.cc +1 -0
  118. package/deps/rocksdb/rocksdb/db/version_util.h +3 -1
  119. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +1 -0
  120. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +28 -9
  121. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +21 -0
  122. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +30 -0
  123. package/deps/rocksdb/rocksdb/db/wide/wide_columns.cc +4 -0
  124. package/deps/rocksdb/rocksdb/db/write_batch.cc +30 -7
  125. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +24 -13
  126. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +5 -4
  127. package/deps/rocksdb/rocksdb/db/write_callback_test.cc +1 -0
  128. package/deps/rocksdb/rocksdb/db/write_controller_test.cc +1 -0
  129. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +104 -60
  130. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +199 -108
  131. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +39 -0
  132. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +8 -0
  133. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +3 -1
  134. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +19 -0
  135. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +26 -0
  136. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +247 -118
  137. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +24 -4
  138. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +18 -0
  139. package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.cc +129 -1
  140. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +22 -0
  141. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.h +4 -0
  142. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +312 -117
  143. package/deps/rocksdb/rocksdb/env/env_basic_test.cc +1 -0
  144. package/deps/rocksdb/rocksdb/env/fs_posix.cc +10 -2
  145. package/deps/rocksdb/rocksdb/env/io_posix_test.cc +1 -0
  146. package/deps/rocksdb/rocksdb/env/mock_env_test.cc +1 -0
  147. package/deps/rocksdb/rocksdb/file/delete_scheduler.cc +5 -1
  148. package/deps/rocksdb/rocksdb/file/delete_scheduler_test.cc +1 -0
  149. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +1 -0
  150. package/deps/rocksdb/rocksdb/file/writable_file_writer.h +1 -1
  151. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +49 -1
  152. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +44 -18
  153. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +8 -7
  154. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +6 -1
  155. package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +3 -0
  156. package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +17 -4
  157. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_reader.h +4 -0
  158. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +7 -0
  159. package/deps/rocksdb/rocksdb/include/rocksdb/universal_compaction.h +1 -1
  160. package/deps/rocksdb/rocksdb/include/rocksdb/wide_columns.h +9 -0
  161. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +3 -6
  162. package/deps/rocksdb/rocksdb/logging/auto_roll_logger_test.cc +1 -0
  163. package/deps/rocksdb/rocksdb/logging/env_logger_test.cc +1 -0
  164. package/deps/rocksdb/rocksdb/logging/event_logger_test.cc +1 -0
  165. package/deps/rocksdb/rocksdb/memory/arena.cc +23 -88
  166. package/deps/rocksdb/rocksdb/memory/arena.h +25 -31
  167. package/deps/rocksdb/rocksdb/memory/arena_test.cc +61 -0
  168. package/deps/rocksdb/rocksdb/memory/memory_allocator_test.cc +1 -0
  169. package/deps/rocksdb/rocksdb/memtable/inlineskiplist_test.cc +1 -0
  170. package/deps/rocksdb/rocksdb/memtable/skiplist_test.cc +1 -0
  171. package/deps/rocksdb/rocksdb/memtable/write_buffer_manager_test.cc +1 -0
  172. package/deps/rocksdb/rocksdb/monitoring/histogram_test.cc +1 -0
  173. package/deps/rocksdb/rocksdb/monitoring/iostats_context_test.cc +1 -0
  174. package/deps/rocksdb/rocksdb/options/cf_options.cc +19 -0
  175. package/deps/rocksdb/rocksdb/options/cf_options.h +8 -0
  176. package/deps/rocksdb/rocksdb/options/configurable_test.cc +1 -0
  177. package/deps/rocksdb/rocksdb/options/options.cc +7 -0
  178. package/deps/rocksdb/rocksdb/options/options_helper.cc +6 -0
  179. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +6 -0
  180. package/deps/rocksdb/rocksdb/options/options_test.cc +63 -40
  181. package/deps/rocksdb/rocksdb/port/mmap.cc +98 -0
  182. package/deps/rocksdb/rocksdb/port/mmap.h +70 -0
  183. package/deps/rocksdb/rocksdb/port/stack_trace.cc +7 -0
  184. package/deps/rocksdb/rocksdb/port/stack_trace.h +4 -1
  185. package/deps/rocksdb/rocksdb/port/win/port_win.h +2 -7
  186. package/deps/rocksdb/rocksdb/src.mk +1 -0
  187. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +7 -7
  188. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +3 -3
  189. package/deps/rocksdb/rocksdb/table/block_based/block_test.cc +1 -0
  190. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +1 -0
  191. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +1 -0
  192. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +1 -0
  193. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder_test.cc +1 -0
  194. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader_test.cc +1 -0
  195. package/deps/rocksdb/rocksdb/table/get_context.cc +19 -1
  196. package/deps/rocksdb/rocksdb/table/get_context.h +9 -0
  197. package/deps/rocksdb/rocksdb/table/merger_test.cc +1 -0
  198. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +10 -11
  199. package/deps/rocksdb/rocksdb/table/mock_table.cc +37 -19
  200. package/deps/rocksdb/rocksdb/table/mock_table.h +5 -1
  201. package/deps/rocksdb/rocksdb/table/sst_file_reader.cc +6 -0
  202. package/deps/rocksdb/rocksdb/table/sst_file_reader_test.cc +33 -0
  203. package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +45 -6
  204. package/deps/rocksdb/rocksdb/test_util/testharness.h +2 -0
  205. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +1 -0
  206. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +5 -0
  207. package/deps/rocksdb/rocksdb/tools/db_bench_tool_test.cc +1 -0
  208. package/deps/rocksdb/rocksdb/tools/io_tracer_parser_test.cc +1 -0
  209. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +36 -0
  210. package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +1 -0
  211. package/deps/rocksdb/rocksdb/tools/trace_analyzer_test.cc +1 -0
  212. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer_test.cc +1 -0
  213. package/deps/rocksdb/rocksdb/trace_replay/io_tracer_test.cc +1 -0
  214. package/deps/rocksdb/rocksdb/util/autovector_test.cc +1 -0
  215. package/deps/rocksdb/rocksdb/util/bloom_test.cc +1 -0
  216. package/deps/rocksdb/rocksdb/util/coding_test.cc +1 -0
  217. package/deps/rocksdb/rocksdb/util/crc32c_test.cc +1 -0
  218. package/deps/rocksdb/rocksdb/util/dynamic_bloom_test.cc +1 -0
  219. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +1 -0
  220. package/deps/rocksdb/rocksdb/util/filelock_test.cc +1 -0
  221. package/deps/rocksdb/rocksdb/util/gflags_compat.h +12 -7
  222. package/deps/rocksdb/rocksdb/util/hash_test.cc +1 -0
  223. package/deps/rocksdb/rocksdb/util/heap_test.cc +4 -2
  224. package/deps/rocksdb/rocksdb/util/random_test.cc +1 -0
  225. package/deps/rocksdb/rocksdb/util/rate_limiter_test.cc +1 -0
  226. package/deps/rocksdb/rocksdb/util/repeatable_thread_test.cc +1 -0
  227. package/deps/rocksdb/rocksdb/util/ribbon_test.cc +1 -0
  228. package/deps/rocksdb/rocksdb/util/slice_transform_test.cc +1 -0
  229. package/deps/rocksdb/rocksdb/util/thread_list_test.cc +1 -0
  230. package/deps/rocksdb/rocksdb/util/thread_local_test.cc +1 -0
  231. package/deps/rocksdb/rocksdb/util/timer_test.cc +1 -0
  232. package/deps/rocksdb/rocksdb/util/work_queue_test.cc +4 -0
  233. package/deps/rocksdb/rocksdb/utilities/agg_merge/agg_merge_test.cc +1 -0
  234. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +13 -0
  235. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +9 -3
  236. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +1 -0
  237. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_format_test.cc +1 -0
  238. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_functional_test.cc +1 -0
  239. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_row_merge_test.cc +1 -0
  240. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_serialize_test.cc +1 -0
  241. package/deps/rocksdb/rocksdb/utilities/env_mirror_test.cc +1 -0
  242. package/deps/rocksdb/rocksdb/utilities/env_timed_test.cc +1 -0
  243. package/deps/rocksdb/rocksdb/utilities/fault_injection_secondary_cache.h +8 -0
  244. package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +1 -0
  245. package/deps/rocksdb/rocksdb/utilities/object_registry_test.cc +1 -0
  246. package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +1 -0
  247. package/deps/rocksdb/rocksdb/utilities/persistent_cache/hash_table_test.cc +1 -0
  248. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_test.cc +1 -0
  249. package/deps/rocksdb/rocksdb/utilities/simulator_cache/cache_simulator_test.cc +1 -0
  250. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +1 -0
  251. package/deps/rocksdb/rocksdb/utilities/transactions/timestamped_snapshot_test.cc +1 -0
  252. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +1 -0
  253. package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +1 -0
  254. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_transaction_test.cc +1 -0
  255. package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +1 -0
  256. package/deps/rocksdb/rocksdb/utilities/util_merge_operators_test.cc +1 -0
  257. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +7 -0
  258. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +20 -0
  259. package/index.js +12 -4
  260. package/package.json +1 -1
  261. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  262. package/prebuilds/linux-x64/node.napi.node +0 -0
@@ -56,7 +56,7 @@ TEST_F(DBBasicTestWithTimestamp, SanityChecks) {
56
56
  db_->SingleDelete(WriteOptions(), "key", dummy_ts).IsInvalidArgument());
57
57
  ASSERT_TRUE(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
58
58
  "begin_key", "end_key", dummy_ts)
59
- .IsNotSupported());
59
+ .IsInvalidArgument());
60
60
 
61
61
  // Perform non-timestamp operations on "data" cf.
62
62
  ASSERT_TRUE(
@@ -85,6 +85,11 @@ TEST_F(DBBasicTestWithTimestamp, SanityChecks) {
85
85
  ASSERT_OK(wb.SingleDelete(handle, "key"));
86
86
  ASSERT_TRUE(db_->Write(WriteOptions(), &wb).IsInvalidArgument());
87
87
  }
88
+ {
89
+ WriteBatch wb;
90
+ ASSERT_OK(wb.DeleteRange(handle, "begin_key", "end_key"));
91
+ ASSERT_TRUE(db_->Write(WriteOptions(), &wb).IsInvalidArgument());
92
+ }
88
93
 
89
94
  // Perform timestamp operations with timestamps of incorrect size.
90
95
  const std::string wrong_ts(sizeof(uint32_t), '\0');
@@ -98,7 +103,7 @@ TEST_F(DBBasicTestWithTimestamp, SanityChecks) {
98
103
  .IsInvalidArgument());
99
104
  ASSERT_TRUE(
100
105
  db_->DeleteRange(WriteOptions(), handle, "begin_key", "end_key", wrong_ts)
101
- .IsNotSupported());
106
+ .IsInvalidArgument());
102
107
 
103
108
  delete handle;
104
109
  }
@@ -215,6 +220,10 @@ TEST_F(DBBasicTestWithTimestamp, GcPreserveLatestVersionBelowFullHistoryLow) {
215
220
  ts_str = Timestamp(4, 0);
216
221
  ASSERT_OK(db_->Put(wopts, "k1", ts_str, "v5"));
217
222
 
223
+ ts_str = Timestamp(5, 0);
224
+ ASSERT_OK(
225
+ db_->DeleteRange(wopts, db_->DefaultColumnFamily(), "k0", "k9", ts_str));
226
+
218
227
  ts_str = Timestamp(3, 0);
219
228
  Slice ts = ts_str;
220
229
  CompactRangeOptions cro;
@@ -234,6 +243,13 @@ TEST_F(DBBasicTestWithTimestamp, GcPreserveLatestVersionBelowFullHistoryLow) {
234
243
  ASSERT_TRUE(db_->Get(ropts, "k3", &value, &key_ts).IsNotFound());
235
244
  ASSERT_EQ(Timestamp(2, 0), key_ts);
236
245
 
246
+ ts_str = Timestamp(5, 0);
247
+ ts = ts_str;
248
+ ropts.timestamp = &ts;
249
+ ASSERT_TRUE(db_->Get(ropts, "k2", &value, &key_ts).IsNotFound());
250
+ ASSERT_EQ(Timestamp(5, 0), key_ts);
251
+ ASSERT_TRUE(db_->Get(ropts, "k2", &value).IsNotFound());
252
+
237
253
  Close();
238
254
  }
239
255
 
@@ -590,6 +606,19 @@ TEST_F(DBBasicTestWithTimestamp, TrimHistoryTest) {
590
606
  check_value_by_ts(db_, "k1", Timestamp(7, 0), Status::OK(), "v2",
591
607
  Timestamp(4, 0));
592
608
  Close();
609
+
610
+ Reopen(options);
611
+ ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(), "k1",
612
+ "k3", Timestamp(7, 0)));
613
+ check_value_by_ts(db_, "k1", Timestamp(8, 0), Status::NotFound(), "",
614
+ Timestamp(7, 0));
615
+ Close();
616
+ // Trim data whose timestamp > Timestamp(6, 0), read(k1, ts(8)) <- v2
617
+ ASSERT_OK(DB::OpenAndTrimHistory(db_options, dbname_, column_families,
618
+ &handles_, &db_, Timestamp(6, 0)));
619
+ check_value_by_ts(db_, "k1", Timestamp(8, 0), Status::OK(), "v2",
620
+ Timestamp(4, 0));
621
+ Close();
593
622
  }
594
623
 
595
624
  TEST_F(DBBasicTestWithTimestamp, OpenAndTrimHistoryInvalidOptionTest) {
@@ -2014,7 +2043,7 @@ constexpr int DataVisibilityTest::kTestDataSize;
2014
2043
  // seq'=11
2015
2044
  // write finishes
2016
2045
  // GetImpl(ts,seq)
2017
- // It is OK to return <k, t1, s1> if ts>=t1 AND seq>=s1. If ts>=1t1 but seq<s1,
2046
+ // It is OK to return <k, t1, s1> if ts>=t1 AND seq>=s1. If ts>=t1 but seq<s1,
2018
2047
  // the key should not be returned.
2019
2048
  TEST_F(DataVisibilityTest, PointLookupWithoutSnapshot1) {
2020
2049
  Options options = CurrentOptions();
@@ -3249,6 +3278,418 @@ TEST_F(UpdateFullHistoryTsLowTest, ConcurrentUpdate) {
3249
3278
  Close();
3250
3279
  }
3251
3280
 
3281
+ TEST_F(DBBasicTestWithTimestamp,
3282
+ GCPreserveRangeTombstoneWhenNoOrSmallFullHistoryLow) {
3283
+ Options options = CurrentOptions();
3284
+ options.env = env_;
3285
+ options.create_if_missing = true;
3286
+ const size_t kTimestampSize = Timestamp(0, 0).size();
3287
+ TestComparator test_cmp(kTimestampSize);
3288
+ options.comparator = &test_cmp;
3289
+ DestroyAndReopen(options);
3290
+
3291
+ std::string ts_str = Timestamp(1, 0);
3292
+ WriteOptions wopts;
3293
+ ASSERT_OK(db_->Put(wopts, "k1", ts_str, "v1"));
3294
+ ASSERT_OK(db_->Put(wopts, "k2", ts_str, "v2"));
3295
+ ASSERT_OK(db_->Put(wopts, "k3", ts_str, "v3"));
3296
+ ts_str = Timestamp(2, 0);
3297
+ ASSERT_OK(
3298
+ db_->DeleteRange(wopts, db_->DefaultColumnFamily(), "k1", "k3", ts_str));
3299
+
3300
+ ts_str = Timestamp(3, 0);
3301
+ Slice ts = ts_str;
3302
+ ReadOptions ropts;
3303
+ ropts.timestamp = &ts;
3304
+ CompactRangeOptions cro;
3305
+ cro.full_history_ts_low = nullptr;
3306
+ std::string value, key_ts;
3307
+ Status s;
3308
+ auto verify = [&] {
3309
+ s = db_->Get(ropts, "k1", &value);
3310
+ ASSERT_TRUE(s.IsNotFound());
3311
+
3312
+ s = db_->Get(ropts, "k2", &value, &key_ts);
3313
+ ASSERT_TRUE(s.IsNotFound());
3314
+ ASSERT_EQ(key_ts, Timestamp(2, 0));
3315
+
3316
+ ASSERT_OK(db_->Get(ropts, "k3", &value, &key_ts));
3317
+ ASSERT_EQ(value, "v3");
3318
+ ASSERT_EQ(Timestamp(1, 0), key_ts);
3319
+
3320
+ size_t batch_size = 3;
3321
+ std::vector<std::string> key_strs = {"k1", "k2", "k3"};
3322
+ std::vector<Slice> keys{key_strs.begin(), key_strs.end()};
3323
+ std::vector<PinnableSlice> values(batch_size);
3324
+ std::vector<Status> statuses(batch_size);
3325
+ db_->MultiGet(ropts, db_->DefaultColumnFamily(), batch_size, keys.data(),
3326
+ values.data(), statuses.data(), true /* sorted_input */);
3327
+ ASSERT_TRUE(statuses[0].IsNotFound());
3328
+ ASSERT_TRUE(statuses[1].IsNotFound());
3329
+ ASSERT_OK(statuses[2]);
3330
+ ;
3331
+ ASSERT_EQ(values[2], "v3");
3332
+ };
3333
+ verify();
3334
+ ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
3335
+ verify();
3336
+ std::string lb = Timestamp(0, 0);
3337
+ Slice lb_slice = lb;
3338
+ cro.full_history_ts_low = &lb_slice;
3339
+ ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
3340
+ verify();
3341
+ Close();
3342
+ }
3343
+
3344
+ TEST_F(DBBasicTestWithTimestamp,
3345
+ GCRangeTombstonesAndCoveredKeysRespectingTslow) {
3346
+ Options options = CurrentOptions();
3347
+ options.env = env_;
3348
+ options.create_if_missing = true;
3349
+ BlockBasedTableOptions bbto;
3350
+ bbto.filter_policy.reset(NewBloomFilterPolicy(10, false));
3351
+ bbto.cache_index_and_filter_blocks = true;
3352
+ bbto.whole_key_filtering = true;
3353
+ options.table_factory.reset(NewBlockBasedTableFactory(bbto));
3354
+ const size_t kTimestampSize = Timestamp(0, 0).size();
3355
+ TestComparator test_cmp(kTimestampSize);
3356
+ options.comparator = &test_cmp;
3357
+ options.num_levels = 2;
3358
+ DestroyAndReopen(options);
3359
+
3360
+ WriteOptions wopts;
3361
+ ASSERT_OK(db_->Put(wopts, "k1", Timestamp(1, 0), "v1"));
3362
+ ASSERT_OK(db_->Delete(wopts, "k2", Timestamp(2, 0)));
3363
+ ASSERT_OK(db_->DeleteRange(wopts, db_->DefaultColumnFamily(), "k1", "k3",
3364
+ Timestamp(3, 0)));
3365
+ ASSERT_OK(db_->Put(wopts, "k3", Timestamp(4, 0), "v3"));
3366
+
3367
+ ReadOptions ropts;
3368
+ std::string read_ts = Timestamp(5, 0);
3369
+ Slice read_ts_slice = read_ts;
3370
+ ropts.timestamp = &read_ts_slice;
3371
+ size_t batch_size = 3;
3372
+ std::vector<std::string> key_strs = {"k1", "k2", "k3"};
3373
+ std::vector<Slice> keys = {key_strs.begin(), key_strs.end()};
3374
+ std::vector<PinnableSlice> values(batch_size);
3375
+ std::vector<Status> statuses(batch_size);
3376
+ std::vector<std::string> timestamps(batch_size);
3377
+ db_->MultiGet(ropts, db_->DefaultColumnFamily(), batch_size, keys.data(),
3378
+ values.data(), timestamps.data(), statuses.data(),
3379
+ true /* sorted_input */);
3380
+ ASSERT_TRUE(statuses[0].IsNotFound());
3381
+ ASSERT_EQ(timestamps[0], Timestamp(3, 0));
3382
+ ASSERT_TRUE(statuses[1].IsNotFound());
3383
+ // DeleteRange has a higher timestamp than Delete for "k2"
3384
+ ASSERT_EQ(timestamps[1], Timestamp(3, 0));
3385
+ ASSERT_OK(statuses[2]);
3386
+ ASSERT_EQ(values[2], "v3");
3387
+ ASSERT_EQ(timestamps[2], Timestamp(4, 0));
3388
+
3389
+ CompactRangeOptions cro;
3390
+ // Range tombstone has timestamp >= full_history_ts_low, covered keys
3391
+ // are not dropped.
3392
+ std::string compaction_ts_str = Timestamp(2, 0);
3393
+ Slice compaction_ts = compaction_ts_str;
3394
+ cro.full_history_ts_low = &compaction_ts;
3395
+ cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
3396
+ ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
3397
+ ropts.timestamp = &compaction_ts;
3398
+ std::string value, ts;
3399
+ ASSERT_OK(db_->Get(ropts, "k1", &value, &ts));
3400
+ ASSERT_EQ(value, "v1");
3401
+ // timestamp is below full_history_ts_low, zeroed out as the key goes into
3402
+ // bottommost level
3403
+ ASSERT_EQ(ts, Timestamp(0, 0));
3404
+ ASSERT_TRUE(db_->Get(ropts, "k2", &value, &ts).IsNotFound());
3405
+ ASSERT_EQ(ts, Timestamp(2, 0));
3406
+
3407
+ compaction_ts_str = Timestamp(4, 0);
3408
+ compaction_ts = compaction_ts_str;
3409
+ cro.full_history_ts_low = &compaction_ts;
3410
+ ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
3411
+ ropts.timestamp = &read_ts_slice;
3412
+ // k1, k2 and the range tombstone should be dropped
3413
+ // k3 should still exist
3414
+ db_->MultiGet(ropts, db_->DefaultColumnFamily(), batch_size, keys.data(),
3415
+ values.data(), timestamps.data(), statuses.data(),
3416
+ true /* sorted_input */);
3417
+ ASSERT_TRUE(statuses[0].IsNotFound());
3418
+ ASSERT_TRUE(timestamps[0].empty());
3419
+ ASSERT_TRUE(statuses[1].IsNotFound());
3420
+ ASSERT_TRUE(timestamps[1].empty());
3421
+ ASSERT_OK(statuses[2]);
3422
+ ASSERT_EQ(values[2], "v3");
3423
+ ASSERT_EQ(timestamps[2], Timestamp(4, 0));
3424
+
3425
+ Close();
3426
+ }
3427
+
3428
+ TEST_P(DBBasicTestWithTimestampTableOptions, DeleteRangeBaiscReadAndIterate) {
3429
+ const int kNum = 200, kRangeBegin = 50, kRangeEnd = 150, kNumPerFile = 25;
3430
+ Options options = CurrentOptions();
3431
+ options.prefix_extractor.reset(NewFixedPrefixTransform(3));
3432
+ options.compression = kNoCompression;
3433
+ BlockBasedTableOptions bbto;
3434
+ bbto.index_type = GetParam();
3435
+ bbto.block_size = 100;
3436
+ options.table_factory.reset(NewBlockBasedTableFactory(bbto));
3437
+ options.env = env_;
3438
+ options.create_if_missing = true;
3439
+ const size_t kTimestampSize = Timestamp(0, 0).size();
3440
+ TestComparator test_cmp(kTimestampSize);
3441
+ options.comparator = &test_cmp;
3442
+ options.memtable_factory.reset(test::NewSpecialSkipListFactory(kNumPerFile));
3443
+ DestroyAndReopen(options);
3444
+
3445
+ // Write half of the keys before the tombstone and half after the tombstone.
3446
+ // Only covered keys (i.e., within the range and older than the tombstone)
3447
+ // should be deleted.
3448
+ for (int i = 0; i < kNum; ++i) {
3449
+ if (i == kNum / 2) {
3450
+ ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
3451
+ Key1(kRangeBegin), Key1(kRangeEnd),
3452
+ Timestamp(i, 0)));
3453
+ }
3454
+ ASSERT_OK(db_->Put(WriteOptions(), Key1(i), Timestamp(i, 0),
3455
+ "val" + std::to_string(i)));
3456
+ if (i == kNum - kNumPerFile) {
3457
+ ASSERT_OK(Flush());
3458
+ }
3459
+ }
3460
+
3461
+ ReadOptions read_opts;
3462
+ read_opts.total_order_seek = true;
3463
+ std::string read_ts = Timestamp(kNum, 0);
3464
+ Slice read_ts_slice = read_ts;
3465
+ read_opts.timestamp = &read_ts_slice;
3466
+ {
3467
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_opts));
3468
+ ASSERT_OK(iter->status());
3469
+
3470
+ int expected = 0;
3471
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
3472
+ ASSERT_EQ(Key1(expected), iter->key());
3473
+ if (expected == kRangeBegin - 1) {
3474
+ expected = kNum / 2;
3475
+ } else {
3476
+ ++expected;
3477
+ }
3478
+ }
3479
+ ASSERT_EQ(kNum, expected);
3480
+
3481
+ expected = kNum / 2;
3482
+ for (iter->Seek(Key1(kNum / 2)); iter->Valid(); iter->Next()) {
3483
+ ASSERT_EQ(Key1(expected), iter->key());
3484
+ ++expected;
3485
+ }
3486
+ ASSERT_EQ(kNum, expected);
3487
+
3488
+ expected = kRangeBegin - 1;
3489
+ for (iter->SeekForPrev(Key1(kNum / 2 - 1)); iter->Valid(); iter->Prev()) {
3490
+ ASSERT_EQ(Key1(expected), iter->key());
3491
+ --expected;
3492
+ }
3493
+ ASSERT_EQ(-1, expected);
3494
+
3495
+ read_ts = Timestamp(0, 0);
3496
+ read_ts_slice = read_ts;
3497
+ read_opts.timestamp = &read_ts_slice;
3498
+ iter.reset(db_->NewIterator(read_opts));
3499
+ iter->SeekToFirst();
3500
+ ASSERT_TRUE(iter->Valid());
3501
+ ASSERT_EQ(iter->key(), Key1(0));
3502
+ iter->Next();
3503
+ ASSERT_FALSE(iter->Valid());
3504
+ ASSERT_OK(iter->status());
3505
+ }
3506
+
3507
+ read_ts = Timestamp(kNum, 0);
3508
+ read_ts_slice = read_ts;
3509
+ read_opts.timestamp = &read_ts_slice;
3510
+ std::string value, timestamp;
3511
+ Status s;
3512
+ for (int i = 0; i < kNum; ++i) {
3513
+ s = db_->Get(read_opts, Key1(i), &value, &timestamp);
3514
+ if (i >= kRangeBegin && i < kNum / 2) {
3515
+ ASSERT_TRUE(s.IsNotFound());
3516
+ ASSERT_EQ(timestamp, Timestamp(kNum / 2, 0));
3517
+ } else {
3518
+ ASSERT_OK(s);
3519
+ ASSERT_EQ(value, "val" + std::to_string(i));
3520
+ ASSERT_EQ(timestamp, Timestamp(i, 0));
3521
+ }
3522
+ }
3523
+
3524
+ size_t batch_size = kNum;
3525
+ std::vector<std::string> key_strs(batch_size);
3526
+ std::vector<Slice> keys(batch_size);
3527
+ std::vector<PinnableSlice> values(batch_size);
3528
+ std::vector<Status> statuses(batch_size);
3529
+ std::vector<std::string> timestamps(batch_size);
3530
+ for (int i = 0; i < kNum; ++i) {
3531
+ key_strs[i] = Key1(i);
3532
+ keys[i] = key_strs[i];
3533
+ }
3534
+ db_->MultiGet(read_opts, db_->DefaultColumnFamily(), batch_size, keys.data(),
3535
+ values.data(), timestamps.data(), statuses.data(),
3536
+ true /* sorted_input */);
3537
+ for (int i = 0; i < kNum; ++i) {
3538
+ if (i >= kRangeBegin && i < kNum / 2) {
3539
+ ASSERT_TRUE(statuses[i].IsNotFound());
3540
+ ASSERT_EQ(timestamps[i], Timestamp(kNum / 2, 0));
3541
+ } else {
3542
+ ASSERT_OK(statuses[i]);
3543
+ ASSERT_EQ(values[i], "val" + std::to_string(i));
3544
+ ASSERT_EQ(timestamps[i], Timestamp(i, 0));
3545
+ }
3546
+ }
3547
+ Close();
3548
+ }
3549
+
3550
+ TEST_F(DBBasicTestWithTimestamp, DeleteRangeGetIteratorWithSnapshot) {
3551
+ // 4 keys 0, 1, 2, 3 at timestamps 0, 1, 2, 3 respectively.
3552
+ // A range tombstone [1, 3) at timestamp 1 and has a sequence number between
3553
+ // key 1 and 2.
3554
+ Options options = CurrentOptions();
3555
+ const size_t kTimestampSize = Timestamp(0, 0).size();
3556
+ TestComparator test_cmp(kTimestampSize);
3557
+ options.comparator = &test_cmp;
3558
+ DestroyAndReopen(options);
3559
+ WriteOptions write_opts;
3560
+ std::string put_ts = Timestamp(0, 0);
3561
+ const int kNum = 4, kNumPerFile = 1, kRangeBegin = 1, kRangeEnd = 3;
3562
+ options.memtable_factory.reset(test::NewSpecialSkipListFactory(kNumPerFile));
3563
+ const Snapshot* before_tombstone = nullptr;
3564
+ const Snapshot* after_tombstone = nullptr;
3565
+ for (int i = 0; i < kNum; ++i) {
3566
+ ASSERT_OK(db_->Put(WriteOptions(), Key1(i), Timestamp(i, 0),
3567
+ "val" + std::to_string(i)));
3568
+ if (i == kRangeBegin) {
3569
+ before_tombstone = db_->GetSnapshot();
3570
+ ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
3571
+ Key1(kRangeBegin), Key1(kRangeEnd),
3572
+ Timestamp(kRangeBegin, 0)));
3573
+ }
3574
+ if (i == kNum / 2) {
3575
+ ASSERT_OK(Flush());
3576
+ }
3577
+ }
3578
+ assert(before_tombstone);
3579
+ after_tombstone = db_->GetSnapshot();
3580
+ // snapshot and ts before tombstone
3581
+ std::string read_ts_str = Timestamp(kRangeBegin - 1, 0); // (0, 0)
3582
+ Slice read_ts = read_ts_str;
3583
+ ReadOptions read_opts;
3584
+ read_opts.timestamp = &read_ts;
3585
+ read_opts.snapshot = before_tombstone;
3586
+ std::vector<Status> expected_status = {
3587
+ Status::OK(), Status::NotFound(), Status::NotFound(), Status::NotFound()};
3588
+ std::vector<std::string> expected_values(kNum);
3589
+ expected_values[0] = "val" + std::to_string(0);
3590
+ std::vector<std::string> expected_timestamps(kNum);
3591
+ expected_timestamps[0] = Timestamp(0, 0);
3592
+
3593
+ size_t batch_size = kNum;
3594
+ std::vector<std::string> key_strs(batch_size);
3595
+ std::vector<Slice> keys(batch_size);
3596
+ std::vector<PinnableSlice> values(batch_size);
3597
+ std::vector<Status> statuses(batch_size);
3598
+ std::vector<std::string> timestamps(batch_size);
3599
+ for (int i = 0; i < kNum; ++i) {
3600
+ key_strs[i] = Key1(i);
3601
+ keys[i] = key_strs[i];
3602
+ }
3603
+
3604
+ auto verify = [&] {
3605
+ db_->MultiGet(read_opts, db_->DefaultColumnFamily(), batch_size,
3606
+ keys.data(), values.data(), timestamps.data(),
3607
+ statuses.data(), true /* sorted_input */);
3608
+ std::string value, timestamp;
3609
+ Status s;
3610
+ for (int i = 0; i < kNum; ++i) {
3611
+ s = db_->Get(read_opts, Key1(i), &value, &timestamp);
3612
+ ASSERT_EQ(s, expected_status[i]);
3613
+ ASSERT_EQ(statuses[i], expected_status[i]);
3614
+ if (s.ok()) {
3615
+ ASSERT_EQ(value, expected_values[i]);
3616
+ ASSERT_EQ(values[i], expected_values[i]);
3617
+ }
3618
+ if (!timestamp.empty()) {
3619
+ ASSERT_EQ(timestamp, expected_timestamps[i]);
3620
+ ASSERT_EQ(timestamps[i], expected_timestamps[i]);
3621
+ } else {
3622
+ ASSERT_TRUE(timestamps[i].empty());
3623
+ }
3624
+ }
3625
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_opts));
3626
+ std::unique_ptr<Iterator> iter_for_seek(db_->NewIterator(read_opts));
3627
+ iter->SeekToFirst();
3628
+ for (int i = 0; i < kNum; ++i) {
3629
+ if (expected_status[i].ok()) {
3630
+ auto verify_iter = [&](Iterator* iter_ptr) {
3631
+ ASSERT_TRUE(iter_ptr->Valid());
3632
+ ASSERT_EQ(iter_ptr->key(), keys[i]);
3633
+ ASSERT_EQ(iter_ptr->value(), expected_values[i]);
3634
+ ASSERT_EQ(iter_ptr->timestamp(), expected_timestamps[i]);
3635
+ };
3636
+ verify_iter(iter.get());
3637
+ iter->Next();
3638
+
3639
+ iter_for_seek->Seek(keys[i]);
3640
+ verify_iter(iter_for_seek.get());
3641
+
3642
+ iter_for_seek->SeekForPrev(keys[i]);
3643
+ verify_iter(iter_for_seek.get());
3644
+ }
3645
+ }
3646
+ ASSERT_FALSE(iter->Valid());
3647
+ ASSERT_OK(iter->status());
3648
+ };
3649
+
3650
+ verify();
3651
+
3652
+ // snapshot before tombstone and ts after tombstone
3653
+ read_ts_str = Timestamp(kNum, 0); // (4, 0)
3654
+ read_ts = read_ts_str;
3655
+ read_opts.timestamp = &read_ts;
3656
+ read_opts.snapshot = before_tombstone;
3657
+ expected_status[1] = Status::OK();
3658
+ expected_timestamps[1] = Timestamp(1, 0);
3659
+ expected_values[1] = "val" + std::to_string(1);
3660
+ verify();
3661
+
3662
+ // snapshot after tombstone and ts before tombstone
3663
+ read_ts_str = Timestamp(kRangeBegin - 1, 0); // (0, 0)
3664
+ read_ts = read_ts_str;
3665
+ read_opts.timestamp = &read_ts;
3666
+ read_opts.snapshot = after_tombstone;
3667
+ expected_status[1] = Status::NotFound();
3668
+ expected_timestamps[1].clear();
3669
+ expected_values[1].clear();
3670
+ verify();
3671
+
3672
+ // snapshot and ts after tombstone
3673
+ read_ts_str = Timestamp(kNum, 0); // (4, 0)
3674
+ read_ts = read_ts_str;
3675
+ read_opts.timestamp = &read_ts;
3676
+ read_opts.snapshot = after_tombstone;
3677
+ for (int i = 0; i < kNum; ++i) {
3678
+ if (i == kRangeBegin) {
3679
+ expected_status[i] = Status::NotFound();
3680
+ expected_values[i].clear();
3681
+ } else {
3682
+ expected_status[i] = Status::OK();
3683
+ expected_values[i] = "val" + std::to_string(i);
3684
+ }
3685
+ expected_timestamps[i] = Timestamp(i, 0);
3686
+ }
3687
+ verify();
3688
+
3689
+ db_->ReleaseSnapshot(before_tombstone);
3690
+ db_->ReleaseSnapshot(after_tombstone);
3691
+ Close();
3692
+ }
3252
3693
  } // namespace ROCKSDB_NAMESPACE
3253
3694
 
3254
3695
  int main(int argc, char** argv) {
@@ -453,15 +453,15 @@ TEST_P(DBWriteTest, ManualWalFlushInEffect) {
453
453
  Reopen(options);
454
454
  // try the 1st WAL created during open
455
455
  ASSERT_TRUE(Put("key" + std::to_string(0), "value").ok());
456
- ASSERT_TRUE(options.manual_wal_flush != dbfull()->TEST_WALBufferIsEmpty());
456
+ ASSERT_TRUE(options.manual_wal_flush != dbfull()->WALBufferIsEmpty());
457
457
  ASSERT_TRUE(dbfull()->FlushWAL(false).ok());
458
- ASSERT_TRUE(dbfull()->TEST_WALBufferIsEmpty());
458
+ ASSERT_TRUE(dbfull()->WALBufferIsEmpty());
459
459
  // try the 2nd wal created during SwitchWAL
460
460
  ASSERT_OK(dbfull()->TEST_SwitchWAL());
461
461
  ASSERT_TRUE(Put("key" + std::to_string(0), "value").ok());
462
- ASSERT_TRUE(options.manual_wal_flush != dbfull()->TEST_WALBufferIsEmpty());
462
+ ASSERT_TRUE(options.manual_wal_flush != dbfull()->WALBufferIsEmpty());
463
463
  ASSERT_TRUE(dbfull()->FlushWAL(false).ok());
464
- ASSERT_TRUE(dbfull()->TEST_WALBufferIsEmpty());
464
+ ASSERT_TRUE(dbfull()->WALBufferIsEmpty());
465
465
  }
466
466
 
467
467
  TEST_P(DBWriteTest, UnflushedPutRaceWithTrackedWalSync) {
@@ -609,16 +609,16 @@ TEST_P(DBWriteTest, LockWalInEffect) {
609
609
  Reopen(options);
610
610
  // try the 1st WAL created during open
611
611
  ASSERT_OK(Put("key" + std::to_string(0), "value"));
612
- ASSERT_TRUE(options.manual_wal_flush != dbfull()->TEST_WALBufferIsEmpty());
612
+ ASSERT_TRUE(options.manual_wal_flush != dbfull()->WALBufferIsEmpty());
613
613
  ASSERT_OK(dbfull()->LockWAL());
614
- ASSERT_TRUE(dbfull()->TEST_WALBufferIsEmpty(false));
614
+ ASSERT_TRUE(dbfull()->WALBufferIsEmpty(false));
615
615
  ASSERT_OK(dbfull()->UnlockWAL());
616
616
  // try the 2nd wal created during SwitchWAL
617
617
  ASSERT_OK(dbfull()->TEST_SwitchWAL());
618
618
  ASSERT_OK(Put("key" + std::to_string(0), "value"));
619
- ASSERT_TRUE(options.manual_wal_flush != dbfull()->TEST_WALBufferIsEmpty());
619
+ ASSERT_TRUE(options.manual_wal_flush != dbfull()->WALBufferIsEmpty());
620
620
  ASSERT_OK(dbfull()->LockWAL());
621
- ASSERT_TRUE(dbfull()->TEST_WALBufferIsEmpty(false));
621
+ ASSERT_TRUE(dbfull()->WALBufferIsEmpty(false));
622
622
  ASSERT_OK(dbfull()->UnlockWAL());
623
623
  }
624
624
 
@@ -88,6 +88,19 @@ void AppendKeyWithMaxTimestamp(std::string* result, const Slice& key,
88
88
  result->append(kTsMax.data(), ts_sz);
89
89
  }
90
90
 
91
+ void AppendUserKeyWithMaxTimestamp(std::string* result, const Slice& key,
92
+ size_t ts_sz) {
93
+ assert(ts_sz > 0);
94
+ result->append(key.data(), key.size() - ts_sz);
95
+
96
+ static constexpr char kTsMax[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff";
97
+ if (ts_sz < strlen(kTsMax)) {
98
+ result->append(kTsMax, ts_sz);
99
+ } else {
100
+ result->append(std::string(ts_sz, '\xff'));
101
+ }
102
+ }
103
+
91
104
  std::string ParsedInternalKey::DebugString(bool log_err_key, bool hex) const {
92
105
  std::string result = "'";
93
106
  if (log_err_key) {
@@ -182,6 +182,11 @@ extern void AppendKeyWithMinTimestamp(std::string* result, const Slice& key,
182
182
  extern void AppendKeyWithMaxTimestamp(std::string* result, const Slice& key,
183
183
  size_t ts_sz);
184
184
 
185
+ // `key` is a user key with timestamp. Append the user key without timestamp
186
+ // and the maximal timestamp to *result.
187
+ extern void AppendUserKeyWithMaxTimestamp(std::string* result, const Slice& key,
188
+ size_t ts_sz);
189
+
185
190
  // Attempt to parse an internal key from "internal_key". On success,
186
191
  // stores the parsed data in "*result", and returns true.
187
192
  //
@@ -290,6 +295,10 @@ class InternalKey {
290
295
  InternalKey(const Slice& _user_key, SequenceNumber s, ValueType t) {
291
296
  AppendInternalKey(&rep_, ParsedInternalKey(_user_key, s, t));
292
297
  }
298
+ InternalKey(const Slice& _user_key, SequenceNumber s, ValueType t, Slice ts) {
299
+ AppendInternalKeyWithDifferentTimestamp(
300
+ &rep_, ParsedInternalKey(_user_key, s, t), ts);
301
+ }
293
302
 
294
303
  // sets the internal key to be bigger or equal to all internal keys with this
295
304
  // user key
@@ -324,11 +333,24 @@ class InternalKey {
324
333
  SetFrom(ParsedInternalKey(_user_key, s, t));
325
334
  }
326
335
 
336
+ void Set(const Slice& _user_key_with_ts, SequenceNumber s, ValueType t,
337
+ const Slice& ts) {
338
+ ParsedInternalKey pik = ParsedInternalKey(_user_key_with_ts, s, t);
339
+ // Should not call pik.SetTimestamp() directly as it overwrites the buffer
340
+ // containing _user_key.
341
+ SetFrom(pik, ts);
342
+ }
343
+
327
344
  void SetFrom(const ParsedInternalKey& p) {
328
345
  rep_.clear();
329
346
  AppendInternalKey(&rep_, p);
330
347
  }
331
348
 
349
+ void SetFrom(const ParsedInternalKey& p, const Slice& ts) {
350
+ rep_.clear();
351
+ AppendInternalKeyWithDifferentTimestamp(&rep_, p, ts);
352
+ }
353
+
332
354
  void Clear() { rep_.clear(); }
333
355
 
334
356
  // The underlying representation.
@@ -518,7 +540,9 @@ class IterKey {
518
540
 
519
541
  bool IsKeyPinned() const { return (key_ != buf_); }
520
542
 
521
- // user_key does not have timestamp.
543
+ // If `ts` is provided, user_key should not contain timestamp,
544
+ // and `ts` is appended after user_key.
545
+ // TODO: more efficient storage for timestamp.
522
546
  void SetInternalKey(const Slice& key_prefix, const Slice& user_key,
523
547
  SequenceNumber s,
524
548
  ValueType value_type = kValueTypeForSeek,
@@ -671,16 +695,38 @@ extern Status ReadRecordFromWriteBatch(Slice* input, char* tag,
671
695
 
672
696
  // When user call DeleteRange() to delete a range of keys,
673
697
  // we will store a serialized RangeTombstone in MemTable and SST.
674
- // the struct here is a easy-understood form
698
+ // the struct here is an easy-understood form
675
699
  // start/end_key_ is the start/end user key of the range to be deleted
676
700
  struct RangeTombstone {
677
701
  Slice start_key_;
678
702
  Slice end_key_;
679
703
  SequenceNumber seq_;
704
+ // TODO: we should optimize the storage here when user-defined timestamp
705
+ // is NOT enabled: they currently take up (16 + 32 + 32) bytes per tombstone.
706
+ Slice ts_;
707
+ std::string pinned_start_key_;
708
+ std::string pinned_end_key_;
709
+
680
710
  RangeTombstone() = default;
681
711
  RangeTombstone(Slice sk, Slice ek, SequenceNumber sn)
682
712
  : start_key_(sk), end_key_(ek), seq_(sn) {}
683
713
 
714
+ // User-defined timestamp is enabled, `sk` and `ek` should be user key
715
+ // with timestamp, `ts` will replace the timestamps in `sk` and
716
+ // `ek`.
717
+ RangeTombstone(Slice sk, Slice ek, SequenceNumber sn, Slice ts)
718
+ : seq_(sn), ts_(ts) {
719
+ assert(!ts.empty());
720
+ pinned_start_key_.reserve(sk.size());
721
+ pinned_start_key_.append(sk.data(), sk.size() - ts.size());
722
+ pinned_start_key_.append(ts.data(), ts.size());
723
+ pinned_end_key_.reserve(ek.size());
724
+ pinned_end_key_.append(ek.data(), ek.size() - ts.size());
725
+ pinned_end_key_.append(ts.data(), ts.size());
726
+ start_key_ = pinned_start_key_;
727
+ end_key_ = pinned_end_key_;
728
+ }
729
+
684
730
  RangeTombstone(ParsedInternalKey parsed_key, Slice value) {
685
731
  start_key_ = parsed_key.user_key;
686
732
  seq_ = parsed_key.sequence;
@@ -690,8 +736,7 @@ struct RangeTombstone {
690
736
  // be careful to use Serialize(), allocates new memory
691
737
  std::pair<InternalKey, Slice> Serialize() const {
692
738
  auto key = InternalKey(start_key_, seq_, kTypeRangeDeletion);
693
- Slice value = end_key_;
694
- return std::make_pair(std::move(key), std::move(value));
739
+ return std::make_pair(std::move(key), end_key_);
695
740
  }
696
741
 
697
742
  // be careful to use SerializeKey(), allocates new memory
@@ -707,6 +752,16 @@ struct RangeTombstone {
707
752
  //
708
753
  // be careful to use SerializeEndKey(), allocates new memory
709
754
  InternalKey SerializeEndKey() const {
755
+ if (!ts_.empty()) {
756
+ static constexpr char kTsMax[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff";
757
+ if (ts_.size() <= strlen(kTsMax)) {
758
+ return InternalKey(end_key_, kMaxSequenceNumber, kTypeRangeDeletion,
759
+ Slice(kTsMax, ts_.size()));
760
+ } else {
761
+ return InternalKey(end_key_, kMaxSequenceNumber, kTypeRangeDeletion,
762
+ std::string(ts_.size(), '\xff'));
763
+ }
764
+ }
710
765
  return InternalKey(end_key_, kMaxSequenceNumber, kTypeRangeDeletion);
711
766
  }
712
767
  };
@@ -206,6 +206,7 @@ TEST_F(FormatTest, RangeTombstoneSerializeEndKey) {
206
206
  } // namespace ROCKSDB_NAMESPACE
207
207
 
208
208
  int main(int argc, char** argv) {
209
+ ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
209
210
  ::testing::InitGoogleTest(&argc, argv);
210
211
  RegisterCustomObjects(argc, argv);
211
212
  return RUN_ALL_TESTS();