@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.
- package/deps/rocksdb/rocksdb/CMakeLists.txt +13 -6
- package/deps/rocksdb/rocksdb/Makefile +1 -1
- package/deps/rocksdb/rocksdb/TARGETS +2 -0
- package/deps/rocksdb/rocksdb/cache/cache_reservation_manager_test.cc +1 -0
- package/deps/rocksdb/rocksdb/cache/cache_test.cc +4 -4
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +139 -161
- package/deps/rocksdb/rocksdb/cache/clock_cache.h +92 -82
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +16 -3
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +9 -3
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +73 -30
- package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +25 -67
- package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +41 -40
- package/deps/rocksdb/rocksdb/cache/lru_cache.cc +109 -155
- package/deps/rocksdb/rocksdb/cache/lru_cache.h +127 -149
- package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +75 -80
- package/deps/rocksdb/rocksdb/cache/sharded_cache.cc +22 -172
- package/deps/rocksdb/rocksdb/cache/sharded_cache.h +272 -85
- package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +12 -4
- package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_file_addition_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_file_builder_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_file_cache_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_file_garbage_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_garbage_meter_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +13 -4
- package/deps/rocksdb/rocksdb/db/builder.cc +1 -1
- package/deps/rocksdb/rocksdb/db/column_family.cc +15 -1
- package/deps/rocksdb/rocksdb/db/compact_files_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +25 -7
- package/deps/rocksdb/rocksdb/db/compaction/compaction.h +10 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +22 -8
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +14 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +38 -12
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +9 -6
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +408 -6
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +244 -54
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +27 -6
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +25 -30
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +87 -26
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +23 -4
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +61 -0
- package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +294 -21
- package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +28 -10
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +272 -0
- package/deps/rocksdb/rocksdb/db/db_flush_test.cc +38 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +69 -25
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +7 -3
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +29 -12
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +0 -12
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +10 -4
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +35 -22
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +5 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +40 -5
- package/deps/rocksdb/rocksdb/db/db_iter.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_iter_stress_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_iter_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +22 -0
- package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_logical_block_size_cache_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +72 -5
- package/deps/rocksdb/rocksdb/db/db_tailing_iter_test.cc +60 -21
- package/deps/rocksdb/rocksdb/db/db_test.cc +170 -1
- package/deps/rocksdb/rocksdb/db/db_test2.cc +9 -3
- package/deps/rocksdb/rocksdb/db/db_test_util.cc +19 -0
- package/deps/rocksdb/rocksdb/db/db_test_util.h +32 -0
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +444 -3
- package/deps/rocksdb/rocksdb/db/db_write_test.cc +8 -8
- package/deps/rocksdb/rocksdb/db/dbformat.cc +13 -0
- package/deps/rocksdb/rocksdb/db/dbformat.h +59 -4
- package/deps/rocksdb/rocksdb/db/dbformat_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/experimental.cc +3 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +24 -3
- package/deps/rocksdb/rocksdb/db/fault_injection_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/filename_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/flush_job.cc +4 -3
- package/deps/rocksdb/rocksdb/db/flush_job_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/forward_iterator.cc +85 -43
- package/deps/rocksdb/rocksdb/db/forward_iterator.h +3 -1
- package/deps/rocksdb/rocksdb/db/internal_stats.cc +33 -6
- package/deps/rocksdb/rocksdb/db/internal_stats.h +6 -0
- package/deps/rocksdb/rocksdb/db/listener_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/log_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/log_writer.cc +1 -1
- package/deps/rocksdb/rocksdb/db/log_writer.h +1 -1
- package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/memtable.cc +158 -56
- package/deps/rocksdb/rocksdb/db/memtable.h +2 -0
- package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/merge_helper_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/options_file_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/perf_context_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/periodic_task_scheduler_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/prefix_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/range_del_aggregator.cc +52 -9
- package/deps/rocksdb/rocksdb/db/range_del_aggregator.h +31 -2
- package/deps/rocksdb/rocksdb/db/range_del_aggregator_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.cc +81 -42
- package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +78 -12
- package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/repair_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +154 -27
- package/deps/rocksdb/rocksdb/db/seqno_to_time_mapping.cc +21 -4
- package/deps/rocksdb/rocksdb/db/seqno_to_time_mapping.h +4 -1
- package/deps/rocksdb/rocksdb/db/table_cache.cc +18 -6
- package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/version_builder_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/version_edit_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/version_set.cc +15 -7
- package/deps/rocksdb/rocksdb/db/version_set.h +2 -1
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/version_util.h +3 -1
- package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +28 -9
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +21 -0
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +30 -0
- package/deps/rocksdb/rocksdb/db/wide/wide_columns.cc +4 -0
- package/deps/rocksdb/rocksdb/db/write_batch.cc +30 -7
- package/deps/rocksdb/rocksdb/db/write_batch_internal.h +24 -13
- package/deps/rocksdb/rocksdb/db/write_batch_test.cc +5 -4
- package/deps/rocksdb/rocksdb/db/write_callback_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/write_controller_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +104 -60
- package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +199 -108
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +39 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +8 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +3 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +19 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +26 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +247 -118
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +24 -4
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +18 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.cc +129 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +22 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.h +4 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +312 -117
- package/deps/rocksdb/rocksdb/env/env_basic_test.cc +1 -0
- package/deps/rocksdb/rocksdb/env/fs_posix.cc +10 -2
- package/deps/rocksdb/rocksdb/env/io_posix_test.cc +1 -0
- package/deps/rocksdb/rocksdb/env/mock_env_test.cc +1 -0
- package/deps/rocksdb/rocksdb/file/delete_scheduler.cc +5 -1
- package/deps/rocksdb/rocksdb/file/delete_scheduler_test.cc +1 -0
- package/deps/rocksdb/rocksdb/file/prefetch_test.cc +1 -0
- package/deps/rocksdb/rocksdb/file/writable_file_writer.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +49 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +44 -18
- package/deps/rocksdb/rocksdb/include/rocksdb/db.h +8 -7
- package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +6 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +3 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +17 -4
- package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_reader.h +4 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +7 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/universal_compaction.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/wide_columns.h +9 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +3 -6
- package/deps/rocksdb/rocksdb/logging/auto_roll_logger_test.cc +1 -0
- package/deps/rocksdb/rocksdb/logging/env_logger_test.cc +1 -0
- package/deps/rocksdb/rocksdb/logging/event_logger_test.cc +1 -0
- package/deps/rocksdb/rocksdb/memory/arena.cc +23 -88
- package/deps/rocksdb/rocksdb/memory/arena.h +25 -31
- package/deps/rocksdb/rocksdb/memory/arena_test.cc +61 -0
- package/deps/rocksdb/rocksdb/memory/memory_allocator_test.cc +1 -0
- package/deps/rocksdb/rocksdb/memtable/inlineskiplist_test.cc +1 -0
- package/deps/rocksdb/rocksdb/memtable/skiplist_test.cc +1 -0
- package/deps/rocksdb/rocksdb/memtable/write_buffer_manager_test.cc +1 -0
- package/deps/rocksdb/rocksdb/monitoring/histogram_test.cc +1 -0
- package/deps/rocksdb/rocksdb/monitoring/iostats_context_test.cc +1 -0
- package/deps/rocksdb/rocksdb/options/cf_options.cc +19 -0
- package/deps/rocksdb/rocksdb/options/cf_options.h +8 -0
- package/deps/rocksdb/rocksdb/options/configurable_test.cc +1 -0
- package/deps/rocksdb/rocksdb/options/options.cc +7 -0
- package/deps/rocksdb/rocksdb/options/options_helper.cc +6 -0
- package/deps/rocksdb/rocksdb/options/options_settable_test.cc +6 -0
- package/deps/rocksdb/rocksdb/options/options_test.cc +63 -40
- package/deps/rocksdb/rocksdb/port/mmap.cc +98 -0
- package/deps/rocksdb/rocksdb/port/mmap.h +70 -0
- package/deps/rocksdb/rocksdb/port/stack_trace.cc +7 -0
- package/deps/rocksdb/rocksdb/port/stack_trace.h +4 -1
- package/deps/rocksdb/rocksdb/port/win/port_win.h +2 -7
- package/deps/rocksdb/rocksdb/src.mk +1 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +7 -7
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +3 -3
- package/deps/rocksdb/rocksdb/table/block_based/block_test.cc +1 -0
- package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +1 -0
- package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +1 -0
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +1 -0
- package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder_test.cc +1 -0
- package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader_test.cc +1 -0
- package/deps/rocksdb/rocksdb/table/get_context.cc +19 -1
- package/deps/rocksdb/rocksdb/table/get_context.h +9 -0
- package/deps/rocksdb/rocksdb/table/merger_test.cc +1 -0
- package/deps/rocksdb/rocksdb/table/merging_iterator.cc +10 -11
- package/deps/rocksdb/rocksdb/table/mock_table.cc +37 -19
- package/deps/rocksdb/rocksdb/table/mock_table.h +5 -1
- package/deps/rocksdb/rocksdb/table/sst_file_reader.cc +6 -0
- package/deps/rocksdb/rocksdb/table/sst_file_reader_test.cc +33 -0
- package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +45 -6
- package/deps/rocksdb/rocksdb/test_util/testharness.h +2 -0
- package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +1 -0
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +5 -0
- package/deps/rocksdb/rocksdb/tools/db_bench_tool_test.cc +1 -0
- package/deps/rocksdb/rocksdb/tools/io_tracer_parser_test.cc +1 -0
- package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +36 -0
- package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +1 -0
- package/deps/rocksdb/rocksdb/tools/trace_analyzer_test.cc +1 -0
- package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer_test.cc +1 -0
- package/deps/rocksdb/rocksdb/trace_replay/io_tracer_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/autovector_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/bloom_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/coding_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/crc32c_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/dynamic_bloom_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/filelock_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/gflags_compat.h +12 -7
- package/deps/rocksdb/rocksdb/util/hash_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/heap_test.cc +4 -2
- package/deps/rocksdb/rocksdb/util/random_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/rate_limiter_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/repeatable_thread_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/ribbon_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/slice_transform_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/thread_list_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/thread_local_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/timer_test.cc +1 -0
- package/deps/rocksdb/rocksdb/util/work_queue_test.cc +4 -0
- package/deps/rocksdb/rocksdb/utilities/agg_merge/agg_merge_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +13 -0
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +9 -3
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_format_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_functional_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_row_merge_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_serialize_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/env_mirror_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/env_timed_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/fault_injection_secondary_cache.h +8 -0
- package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/object_registry_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/hash_table_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/simulator_cache/cache_simulator_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/timestamped_snapshot_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_transaction_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/util_merge_operators_test.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +7 -0
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +20 -0
- package/index.js +12 -4
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- 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
|
-
.
|
|
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
|
-
.
|
|
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>=
|
|
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, ×tamp);
|
|
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, ×tamp);
|
|
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()->
|
|
456
|
+
ASSERT_TRUE(options.manual_wal_flush != dbfull()->WALBufferIsEmpty());
|
|
457
457
|
ASSERT_TRUE(dbfull()->FlushWAL(false).ok());
|
|
458
|
-
ASSERT_TRUE(dbfull()->
|
|
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()->
|
|
462
|
+
ASSERT_TRUE(options.manual_wal_flush != dbfull()->WALBufferIsEmpty());
|
|
463
463
|
ASSERT_TRUE(dbfull()->FlushWAL(false).ok());
|
|
464
|
-
ASSERT_TRUE(dbfull()->
|
|
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()->
|
|
612
|
+
ASSERT_TRUE(options.manual_wal_flush != dbfull()->WALBufferIsEmpty());
|
|
613
613
|
ASSERT_OK(dbfull()->LockWAL());
|
|
614
|
-
ASSERT_TRUE(dbfull()->
|
|
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()->
|
|
619
|
+
ASSERT_TRUE(options.manual_wal_flush != dbfull()->WALBufferIsEmpty());
|
|
620
620
|
ASSERT_OK(dbfull()->LockWAL());
|
|
621
|
-
ASSERT_TRUE(dbfull()->
|
|
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
|
|
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
|
|
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
|
-
|
|
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();
|