@nxtedition/rocksdb 15.4.0 → 15.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.cc +24 -19
- package/cache.js +1 -1
- package/chained-batch.js +12 -3
- package/deps/rocksdb/rocksdb/.clang-tidy +86 -0
- package/deps/rocksdb/rocksdb/BUCK +42 -0
- package/deps/rocksdb/rocksdb/CMakeLists.txt +11 -0
- package/deps/rocksdb/rocksdb/Makefile +59 -32
- package/deps/rocksdb/rocksdb/cache/cache.cc +0 -5
- package/deps/rocksdb/rocksdb/cache/cache_entry_stats.h +9 -9
- package/deps/rocksdb/rocksdb/cache/cache_key.cc +3 -3
- package/deps/rocksdb/rocksdb/cache/cache_key.h +5 -5
- package/deps/rocksdb/rocksdb/cache/cache_reservation_manager.h +16 -16
- package/deps/rocksdb/rocksdb/cache/cache_test.cc +1 -1
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +258 -294
- package/deps/rocksdb/rocksdb/cache/clock_cache.h +98 -49
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +1 -5
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +2 -3
- package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +18 -18
- package/deps/rocksdb/rocksdb/crash_test.mk +5 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +23 -22
- package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.h +6 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_builder_test.cc +14 -16
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +38 -26
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.h +5 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +101 -18
- package/deps/rocksdb/rocksdb/db/blob/blob_index.h +12 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +6 -9
- package/deps/rocksdb/rocksdb/db/builder.cc +23 -0
- package/deps/rocksdb/rocksdb/db/builder.h +7 -0
- package/deps/rocksdb/rocksdb/db/c.cc +373 -57
- package/deps/rocksdb/rocksdb/db/c_test.c +101 -1
- package/deps/rocksdb/rocksdb/db/column_family.cc +31 -3
- package/deps/rocksdb/rocksdb/db/column_family_test.cc +10 -13
- package/deps/rocksdb/rocksdb/db/compact_files_test.cc +35 -48
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +13 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +201 -39
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +15 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_stats_test.cc +7 -7
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +2 -455
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +4 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +19 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +72 -9
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +12 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +405 -83
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +25 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +23 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +1 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +1410 -106
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +12 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +2 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +19 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +505 -45
- package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +2 -2
- package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +9 -1
- package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +7 -9
- package/deps/rocksdb/rocksdb/db/convenience.cc +4 -4
- package/deps/rocksdb/rocksdb/db/convenience_impl.h +2 -1
- package/deps/rocksdb/rocksdb/db/corruption_test.cc +60 -88
- package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +10 -12
- package/deps/rocksdb/rocksdb/db/db_basic_test.cc +471 -40
- package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +116 -2
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +5 -15
- package/deps/rocksdb/rocksdb/db/db_compaction_abort_test.cc +993 -0
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +329 -29
- package/deps/rocksdb/rocksdb/db/db_flush_test.cc +155 -13
- package/deps/rocksdb/rocksdb/db/db_impl/compacted_db_impl.cc +54 -31
- package/deps/rocksdb/rocksdb/db/db_impl/compacted_db_impl.h +1 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +232 -70
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +57 -9
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +224 -31
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +5 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +4 -2
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_follower.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +164 -8
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +6 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.h +5 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +47 -35
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.h +22 -9
- package/deps/rocksdb/rocksdb/db/db_iter.cc +9 -0
- package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +371 -6
- package/deps/rocksdb/rocksdb/db/db_log_iter_test.cc +7 -5
- package/deps/rocksdb/rocksdb/db/db_logical_block_size_cache_test.cc +22 -23
- package/deps/rocksdb/rocksdb/db/db_memtable_test.cc +0 -2
- package/deps/rocksdb/rocksdb/db/db_merge_operator_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/db_options_test.cc +40 -0
- package/deps/rocksdb/rocksdb/db/db_properties_test.cc +32 -13
- package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_readonly_with_timestamp_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/db_secondary_test.cc +68 -15
- package/deps/rocksdb/rocksdb/db/db_sst_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_statistics_test.cc +2 -3
- package/deps/rocksdb/rocksdb/db/db_table_properties_test.cc +6 -21
- package/deps/rocksdb/rocksdb/db/db_test.cc +644 -128
- package/deps/rocksdb/rocksdb/db/db_test2.cc +198 -81
- package/deps/rocksdb/rocksdb/db/db_test_util.cc +35 -10
- package/deps/rocksdb/rocksdb/db/db_test_util.h +8 -2
- package/deps/rocksdb/rocksdb/db/db_wal_test.cc +36 -32
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +11 -7
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +499 -0
- package/deps/rocksdb/rocksdb/db/db_write_buffer_manager_test.cc +284 -20
- package/deps/rocksdb/rocksdb/db/db_write_test.cc +3 -3
- package/deps/rocksdb/rocksdb/db/dbformat.h +0 -5
- package/deps/rocksdb/rocksdb/db/error_handler.cc +24 -0
- package/deps/rocksdb/rocksdb/db/error_handler_fs_test.cc +12 -14
- package/deps/rocksdb/rocksdb/db/experimental.cc +13 -10
- package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +22 -3
- package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +21 -15
- package/deps/rocksdb/rocksdb/db/fault_injection_test.cc +4 -6
- package/deps/rocksdb/rocksdb/db/flush_job.cc +11 -3
- package/deps/rocksdb/rocksdb/db/forward_iterator_bench.cc +5 -6
- package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +4 -2
- package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +17 -17
- package/deps/rocksdb/rocksdb/db/internal_stats.cc +13 -0
- package/deps/rocksdb/rocksdb/db/internal_stats.h +2 -0
- package/deps/rocksdb/rocksdb/db/listener_test.cc +154 -27
- package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +6 -6
- package/deps/rocksdb/rocksdb/db/memtable.cc +197 -51
- package/deps/rocksdb/rocksdb/db/memtable.h +6 -0
- package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +3 -4
- package/deps/rocksdb/rocksdb/db/merge_test.cc +37 -35
- package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/options_file_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/perf_context_test.cc +9 -11
- package/deps/rocksdb/rocksdb/db/periodic_task_scheduler.cc +10 -1
- package/deps/rocksdb/rocksdb/db/periodic_task_scheduler_test.cc +292 -15
- package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +10 -17
- package/deps/rocksdb/rocksdb/db/prefix_test.cc +6 -8
- package/deps/rocksdb/rocksdb/db/repair.cc +10 -10
- package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +5 -5
- package/deps/rocksdb/rocksdb/db/table_cache.cc +142 -135
- package/deps/rocksdb/rocksdb/db/table_cache.h +30 -6
- package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +7 -7
- package/deps/rocksdb/rocksdb/db/version_builder.cc +11 -50
- package/deps/rocksdb/rocksdb/db/version_builder.h +2 -1
- package/deps/rocksdb/rocksdb/db/version_builder_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/version_edit.cc +51 -2
- package/deps/rocksdb/rocksdb/db/version_edit.h +91 -29
- package/deps/rocksdb/rocksdb/db/version_edit_handler.h +7 -7
- package/deps/rocksdb/rocksdb/db/version_set.cc +211 -50
- package/deps/rocksdb/rocksdb/db/version_set.h +40 -3
- package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +5 -0
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +294 -21
- package/deps/rocksdb/rocksdb/db/version_util.cc +96 -0
- package/deps/rocksdb/rocksdb/db/version_util.h +24 -0
- package/deps/rocksdb/rocksdb/db/wide/db_wide_basic_test.cc +5 -5
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +647 -31
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +219 -1
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +549 -12
- package/deps/rocksdb/rocksdb/db/write_callback_test.cc +3 -3
- package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +1 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +19 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +21 -4
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_env_wrapper.h +32 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +74 -22
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_listener.h +9 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +143 -61
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +15 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +76 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +92 -72
- package/deps/rocksdb/rocksdb/env/env.cc +1 -0
- package/deps/rocksdb/rocksdb/env/env_test.cc +365 -2
- package/deps/rocksdb/rocksdb/env/fs_posix.cc +31 -30
- package/deps/rocksdb/rocksdb/env/io_posix.cc +8 -11
- package/deps/rocksdb/rocksdb/env/io_posix.h +30 -1
- package/deps/rocksdb/rocksdb/env/io_posix_test.cc +43 -0
- package/deps/rocksdb/rocksdb/file/delete_scheduler.cc +1 -1
- package/deps/rocksdb/rocksdb/file/delete_scheduler_test.cc +108 -0
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +32 -4
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +4 -4
- package/deps/rocksdb/rocksdb/file/file_util.cc +8 -2
- package/deps/rocksdb/rocksdb/file/file_util.h +2 -1
- package/deps/rocksdb/rocksdb/file/prefetch_test.cc +331 -12
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +52 -35
- package/deps/rocksdb/rocksdb/folly.mk +22 -5
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_cache.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_compression.h +100 -54
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +67 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/c.h +149 -13
- package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +1 -12
- package/deps/rocksdb/rocksdb/include/rocksdb/db.h +78 -97
- package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +3 -3
- package/deps/rocksdb/rocksdb/include/rocksdb/external_table.h +2 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/file_checksum.h +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +17 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/functor_wrapper.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/io_dispatcher.h +358 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/iostats_context.h +13 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +43 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/memtablerep.h +20 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +63 -21
- package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +10 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/rate_limiter.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/slice_transform.h +2 -7
- package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_reader.h +13 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +3 -14
- package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +49 -9
- package/deps/rocksdb/rocksdb/include/rocksdb/status.h +8 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/table.h +77 -6
- package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +15 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/tool_hooks.h +16 -10
- package/deps/rocksdb/rocksdb/include/rocksdb/unique_id.h +5 -5
- package/deps/rocksdb/rocksdb/include/rocksdb/universal_compaction.h +2 -4
- package/deps/rocksdb/rocksdb/include/rocksdb/user_defined_index.h +106 -46
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/db_ttl.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd.h +14 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/memory_util.h +5 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/optimistic_transaction_db.h +2 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +7 -9
- package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
- package/deps/rocksdb/rocksdb/logging/auto_roll_logger_test.cc +1 -2
- package/deps/rocksdb/rocksdb/memory/memory_allocator_test.cc +2 -2
- package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +226 -8
- package/deps/rocksdb/rocksdb/memtable/inlineskiplist_test.cc +490 -0
- package/deps/rocksdb/rocksdb/memtable/skiplist.h +3 -3
- package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +11 -0
- package/deps/rocksdb/rocksdb/microbench/db_basic_bench.cc +4 -12
- package/deps/rocksdb/rocksdb/microbench/ribbon_bench.cc +5 -5
- package/deps/rocksdb/rocksdb/monitoring/file_read_sample.h +21 -4
- package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +9 -3
- package/deps/rocksdb/rocksdb/monitoring/statistics.cc +21 -2
- package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +2 -2
- package/deps/rocksdb/rocksdb/options/cf_options.cc +21 -1
- package/deps/rocksdb/rocksdb/options/cf_options.h +2 -0
- package/deps/rocksdb/rocksdb/options/customizable_test.cc +0 -2
- package/deps/rocksdb/rocksdb/options/db_options.cc +26 -5
- package/deps/rocksdb/rocksdb/options/db_options.h +3 -1
- package/deps/rocksdb/rocksdb/options/options.cc +5 -1
- package/deps/rocksdb/rocksdb/options/options_helper.cc +7 -2
- package/deps/rocksdb/rocksdb/options/options_settable_test.cc +109 -103
- package/deps/rocksdb/rocksdb/options/options_test.cc +14 -0
- package/deps/rocksdb/rocksdb/port/jemalloc_helper.h +15 -17
- package/deps/rocksdb/rocksdb/port/lang.h +4 -0
- package/deps/rocksdb/rocksdb/port/port_example.h +0 -23
- package/deps/rocksdb/rocksdb/port/stack_trace.cc +36 -0
- package/deps/rocksdb/rocksdb/port/stack_trace.h +9 -0
- package/deps/rocksdb/rocksdb/src.mk +12 -0
- package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.cc +1 -2
- package/deps/rocksdb/rocksdb/table/block_based/binary_search_index_reader.cc +2 -1
- package/deps/rocksdb/rocksdb/table/block_based/block.cc +571 -292
- package/deps/rocksdb/rocksdb/table/block_based/block.h +143 -53
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +154 -90
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +5 -1
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +51 -14
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +0 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +147 -734
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +30 -233
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +178 -108
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +13 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +17 -4
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +5 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +70 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_builder.cc +168 -24
- package/deps/rocksdb/rocksdb/table/block_based/block_builder.h +25 -9
- package/deps/rocksdb/rocksdb/table/block_based/block_cache.cc +7 -4
- package/deps/rocksdb/rocksdb/table/block_based/block_cache.h +9 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_test.cc +548 -169
- package/deps/rocksdb/rocksdb/table/block_based/block_type.h +30 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_util.h +156 -0
- package/deps/rocksdb/rocksdb/table/block_based/data_block_footer.cc +73 -30
- package/deps/rocksdb/rocksdb/table/block_based/data_block_footer.h +74 -7
- package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index.h +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +20 -14
- package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +22 -12
- package/deps/rocksdb/rocksdb/table/block_based/mock_block_based_table.h +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/multi_scan_index_iterator.cc +332 -0
- package/deps/rocksdb/rocksdb/table/block_based/multi_scan_index_iterator.h +133 -0
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +4 -2
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/reader_common.cc +3 -2
- package/deps/rocksdb/rocksdb/table/block_based/reader_common.h +4 -1
- package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.h +0 -1
- package/deps/rocksdb/rocksdb/table/block_based/user_defined_index_wrapper.h +126 -46
- package/deps/rocksdb/rocksdb/table/block_fetcher.cc +31 -3
- package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +1 -2
- package/deps/rocksdb/rocksdb/table/cleanable_test.cc +3 -1
- package/deps/rocksdb/rocksdb/table/external_table.cc +25 -4
- package/deps/rocksdb/rocksdb/table/format.cc +27 -15
- package/deps/rocksdb/rocksdb/table/format.h +41 -15
- package/deps/rocksdb/rocksdb/table/merging_iterator.cc +1 -0
- package/deps/rocksdb/rocksdb/table/meta_blocks.cc +22 -12
- package/deps/rocksdb/rocksdb/table/meta_blocks.h +0 -1
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +7 -21
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +0 -1
- package/deps/rocksdb/rocksdb/table/sst_file_reader.cc +88 -13
- package/deps/rocksdb/rocksdb/table/sst_file_reader_test.cc +53 -42
- package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +3 -12
- package/deps/rocksdb/rocksdb/table/table_builder.h +0 -4
- package/deps/rocksdb/rocksdb/table/table_properties.cc +18 -0
- package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +2 -3
- package/deps/rocksdb/rocksdb/table/table_test.cc +848 -172
- package/deps/rocksdb/rocksdb/table/unique_id.cc +24 -20
- package/deps/rocksdb/rocksdb/table/unique_id_impl.h +8 -8
- package/deps/rocksdb/rocksdb/test_util/sync_point.h +5 -4
- package/deps/rocksdb/rocksdb/test_util/testutil.cc +2 -1
- package/deps/rocksdb/rocksdb/test_util/testutil.h +2 -2
- package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +2 -1
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +238 -120
- package/deps/rocksdb/rocksdb/tools/db_repl_stress.cc +2 -2
- package/deps/rocksdb/rocksdb/tools/db_sanity_test.cc +2 -4
- package/deps/rocksdb/rocksdb/tools/dump/db_dump_tool.cc +4 -8
- package/deps/rocksdb/rocksdb/tools/dump/rocksdb_undump.cc +1 -1
- package/deps/rocksdb/rocksdb/tools/io_tracer_parser_test.cc +2 -3
- package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +82 -20
- package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +41 -47
- package/deps/rocksdb/rocksdb/tools/ldb_tool.cc +9 -0
- package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +5 -6
- package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +1 -1
- package/deps/rocksdb/rocksdb/tools/tool_hooks.cc +6 -5
- package/deps/rocksdb/rocksdb/tools/trace_analyzer_test.cc +4 -4
- package/deps/rocksdb/rocksdb/tools/write_stress.cc +1 -3
- package/deps/rocksdb/rocksdb/util/atomic.h +30 -23
- package/deps/rocksdb/rocksdb/util/auto_tune_compressor.cc +6 -7
- package/deps/rocksdb/rocksdb/util/auto_tune_compressor.h +3 -3
- package/deps/rocksdb/rocksdb/util/bit_fields.h +68 -46
- package/deps/rocksdb/rocksdb/util/bloom_impl.h +16 -16
- package/deps/rocksdb/rocksdb/util/coding.h +14 -27
- package/deps/rocksdb/rocksdb/util/compression.cc +365 -207
- package/deps/rocksdb/rocksdb/util/compression.h +16 -1298
- package/deps/rocksdb/rocksdb/util/compression_test.cc +347 -61
- package/deps/rocksdb/rocksdb/util/crc32c_arm64.cc +8 -9
- package/deps/rocksdb/rocksdb/util/crc32c_arm64.h +1 -1
- package/deps/rocksdb/rocksdb/util/crc32c_ppc.h +1 -1
- package/deps/rocksdb/rocksdb/util/dynamic_bloom_test.cc +3 -3
- package/deps/rocksdb/rocksdb/util/filter_bench.cc +18 -18
- package/deps/rocksdb/rocksdb/util/gflags_compat.h +3 -3
- package/deps/rocksdb/rocksdb/util/hash_test.cc +19 -7
- package/deps/rocksdb/rocksdb/util/io_dispatcher_imp.cc +1099 -0
- package/deps/rocksdb/rocksdb/util/io_dispatcher_imp.h +36 -0
- package/deps/rocksdb/rocksdb/util/io_dispatcher_test.cc +1919 -0
- package/deps/rocksdb/rocksdb/util/math.h +3 -1
- package/deps/rocksdb/rocksdb/util/mutexlock.h +19 -19
- package/deps/rocksdb/rocksdb/util/ribbon_alg.h +25 -25
- package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.cc +5 -7
- package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.h +4 -5
- package/deps/rocksdb/rocksdb/util/slice.cc +0 -10
- package/deps/rocksdb/rocksdb/util/slice_test.cc +35 -1
- package/deps/rocksdb/rocksdb/util/slice_transform_test.cc +5 -7
- package/deps/rocksdb/rocksdb/util/status.cc +3 -1
- package/deps/rocksdb/rocksdb/util/stop_watch.h +2 -0
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +4 -1
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +123 -78
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.cc +12 -93
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.h +1 -4
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.cc +0 -21
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.h +6 -48
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.cc +94 -307
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.h +12 -58
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl_filesnapshot.cc +2 -8
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_listener.h +2 -3
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +205 -811
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_dump_tool.cc +18 -9
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.cc +2 -7
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.h +1 -9
- package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_functional_test.cc +17 -11
- package/deps/rocksdb/rocksdb/utilities/cassandra/test_utils.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/cassandra/test_utils.h +1 -1
- package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +68 -61
- package/deps/rocksdb/rocksdb/utilities/debug.cc +2 -1
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +105 -59
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.h +274 -7
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs_test.cc +94 -0
- package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +13 -17
- package/deps/rocksdb/rocksdb/utilities/memory/memory_util.cc +16 -3
- package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend_test.cc +25 -25
- package/deps/rocksdb/rocksdb/utilities/object_registry.cc +40 -40
- package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration.cc +2 -5
- package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +17 -19
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.cc +2 -2
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.h +2 -2
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/volatile_tier_impl.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.cc +2 -2
- package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.h +4 -13
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +3 -3
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.h +6 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_seqno_test.cc +431 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +1 -2
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.h +91 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/bitvector.cc +562 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/bitvector.h +615 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/louds_trie.cc +2575 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/louds_trie.h +685 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_db_test.cc +2843 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_factory.cc +567 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_factory.h +275 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_test.cc +5183 -0
- package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.cc +4 -3
- package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.h +1 -1
- package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +2 -2
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +3 -3
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +93 -88
- package/deps/rocksdb/rocksdb.gyp +7 -0
- package/index.js +11 -2
- package/iterator.js +15 -7
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
- package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/lua/rocks_lua_custom_library.h +0 -43
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/lua/rocks_lua_util.h +0 -55
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
#include "rocksdb/table.h"
|
|
26
26
|
#include "table/block_based/block_based_table_reader.h"
|
|
27
27
|
#include "table/block_based/block_builder.h"
|
|
28
|
+
#include "table/block_based/data_block_footer.h"
|
|
28
29
|
#include "table/format.h"
|
|
29
30
|
#include "test_util/testharness.h"
|
|
30
31
|
#include "test_util/testutil.h"
|
|
@@ -33,10 +34,10 @@
|
|
|
33
34
|
namespace ROCKSDB_NAMESPACE {
|
|
34
35
|
|
|
35
36
|
std::string GenerateInternalKey(int primary_key, int secondary_key,
|
|
36
|
-
int padding_size, Random
|
|
37
|
+
int padding_size, Random* rnd,
|
|
37
38
|
size_t ts_sz = 0) {
|
|
38
39
|
char buf[50];
|
|
39
|
-
char
|
|
40
|
+
char* p = &buf[0];
|
|
40
41
|
snprintf(buf, sizeof(buf), "%6d%4d", primary_key, secondary_key);
|
|
41
42
|
std::string k(p);
|
|
42
43
|
if (padding_size) {
|
|
@@ -55,8 +56,8 @@ std::string GenerateInternalKey(int primary_key, int secondary_key,
|
|
|
55
56
|
// Generate random key value pairs.
|
|
56
57
|
// The generated key will be sorted. You can tune the parameters to generated
|
|
57
58
|
// different kinds of test key/value pairs for different scenario.
|
|
58
|
-
void GenerateRandomKVs(std::vector<std::string
|
|
59
|
-
std::vector<std::string
|
|
59
|
+
void GenerateRandomKVs(std::vector<std::string>* keys,
|
|
60
|
+
std::vector<std::string>* values, const int from,
|
|
60
61
|
const int len, const int step = 1,
|
|
61
62
|
const int padding_size = 0,
|
|
62
63
|
const int keys_share_prefix = 1, size_t ts_sz = 0) {
|
|
@@ -75,13 +76,16 @@ void GenerateRandomKVs(std::vector<std::string> *keys,
|
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
// Test Param
|
|
79
|
-
// Test Param
|
|
80
|
-
// Test Param
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
// Test Param 0): key use delta encoding.
|
|
80
|
+
// Test Param 1): user-defined timestamp test mode.
|
|
81
|
+
// Test Param 2): data block index type.
|
|
82
|
+
// Test Param 3): restart interval.
|
|
83
|
+
// Test Param 4): use separated KV storage.
|
|
84
|
+
class BlockTest
|
|
85
|
+
: public testing::Test,
|
|
86
|
+
public testing::WithParamInterface<std::tuple<
|
|
87
|
+
bool, test::UserDefinedTimestampTestMode,
|
|
88
|
+
BlockBasedTableOptions::DataBlockIndexType, uint32_t, bool>> {
|
|
85
89
|
public:
|
|
86
90
|
bool keyUseDeltaEncoding() const { return std::get<0>(GetParam()); }
|
|
87
91
|
bool isUDTEnabled() const {
|
|
@@ -94,6 +98,10 @@ class BlockTest : public testing::Test,
|
|
|
94
98
|
BlockBasedTableOptions::DataBlockIndexType dataBlockIndexType() const {
|
|
95
99
|
return std::get<2>(GetParam());
|
|
96
100
|
}
|
|
101
|
+
|
|
102
|
+
uint32_t getRestartInterval() const { return std::get<3>(GetParam()); }
|
|
103
|
+
|
|
104
|
+
bool useSeparatedKVStorage() const { return std::get<4>(GetParam()); }
|
|
97
105
|
};
|
|
98
106
|
|
|
99
107
|
// block test
|
|
@@ -110,11 +118,12 @@ TEST_P(BlockTest, SimpleTest) {
|
|
|
110
118
|
BlockBasedTableOptions::DataBlockIndexType index_type =
|
|
111
119
|
isUDTEnabled() ? BlockBasedTableOptions::kDataBlockBinarySearch
|
|
112
120
|
: dataBlockIndexType();
|
|
113
|
-
BlockBuilder builder(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
BlockBuilder builder(
|
|
122
|
+
static_cast<int>(getRestartInterval()), keyUseDeltaEncoding(),
|
|
123
|
+
false /* use_value_delta_encoding */, index_type,
|
|
124
|
+
0.75 /* data_block_hash_table_util_ratio */, ts_sz, shouldPersistUDT(),
|
|
125
|
+
false /* is_user_key */, useSeparatedKVStorage());
|
|
126
|
+
int num_records = 20;
|
|
118
127
|
|
|
119
128
|
GenerateRandomKVs(&keys, &values, 0, num_records, 1 /* step */,
|
|
120
129
|
0 /* padding_size */, 1 /* keys_share_prefix */, ts_sz);
|
|
@@ -129,11 +138,12 @@ TEST_P(BlockTest, SimpleTest) {
|
|
|
129
138
|
// create block reader
|
|
130
139
|
BlockContents contents;
|
|
131
140
|
contents.data = rawblock;
|
|
132
|
-
Block reader(std::move(contents)
|
|
141
|
+
Block reader(std::move(contents), 0 /* read_amp_bytes_per_bit */,
|
|
142
|
+
nullptr /* statistics */, getRestartInterval());
|
|
133
143
|
|
|
134
144
|
// read contents of block sequentially
|
|
135
145
|
int count = 0;
|
|
136
|
-
InternalIterator
|
|
146
|
+
InternalIterator* iter = reader.NewDataIterator(
|
|
137
147
|
options.comparator, kDisableGlobalSequenceNumber, nullptr /* iter */,
|
|
138
148
|
nullptr /* stats */, false /* block_contents_pinned */,
|
|
139
149
|
shouldPersistUDT());
|
|
@@ -169,17 +179,18 @@ TEST_P(BlockTest, SimpleTest) {
|
|
|
169
179
|
|
|
170
180
|
// return the block contents
|
|
171
181
|
BlockContents GetBlockContents(
|
|
172
|
-
std::unique_ptr<BlockBuilder
|
|
173
|
-
const std::vector<std::string
|
|
174
|
-
const std::vector<std::string
|
|
182
|
+
std::unique_ptr<BlockBuilder>* builder,
|
|
183
|
+
const std::vector<std::string>& keys,
|
|
184
|
+
const std::vector<std::string>& values, bool key_use_delta_encoding,
|
|
175
185
|
size_t ts_sz, bool should_persist_udt, const int /*prefix_group_size*/ = 1,
|
|
176
186
|
BlockBasedTableOptions::DataBlockIndexType dblock_index_type =
|
|
177
|
-
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
187
|
+
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch,
|
|
188
|
+
bool use_separated_kv_storage = false, uint32_t restart_interval = 1) {
|
|
189
|
+
builder->reset(new BlockBuilder(
|
|
190
|
+
static_cast<int>(restart_interval), key_use_delta_encoding,
|
|
191
|
+
false /* use_value_delta_encoding */, dblock_index_type,
|
|
192
|
+
0.75 /* data_block_hash_table_util_ratio */, ts_sz, should_persist_udt,
|
|
193
|
+
false /* is_user_key */, use_separated_kv_storage));
|
|
183
194
|
|
|
184
195
|
// Add only half of the keys
|
|
185
196
|
for (size_t i = 0; i < keys.size(); ++i) {
|
|
@@ -194,14 +205,17 @@ BlockContents GetBlockContents(
|
|
|
194
205
|
}
|
|
195
206
|
|
|
196
207
|
void CheckBlockContents(BlockContents contents, const int max_key,
|
|
197
|
-
const std::vector<std::string
|
|
198
|
-
const std::vector<std::string
|
|
199
|
-
bool is_udt_enabled, bool should_persist_udt
|
|
208
|
+
const std::vector<std::string>& keys,
|
|
209
|
+
const std::vector<std::string>& values,
|
|
210
|
+
bool is_udt_enabled, bool should_persist_udt,
|
|
211
|
+
uint32_t restart_interval) {
|
|
200
212
|
const size_t prefix_size = 6;
|
|
201
213
|
// create block reader
|
|
202
214
|
BlockContents contents_ref(contents.data);
|
|
203
|
-
Block reader1(std::move(contents)
|
|
204
|
-
|
|
215
|
+
Block reader1(std::move(contents), 0 /* read_amp_bytes_per_bit */,
|
|
216
|
+
nullptr /* statistics */, restart_interval);
|
|
217
|
+
Block reader2(std::move(contents_ref), 0 /* read_amp_bytes_per_bit */,
|
|
218
|
+
nullptr /* statistics */, restart_interval);
|
|
205
219
|
|
|
206
220
|
std::unique_ptr<const SliceTransform> prefix_extractor(
|
|
207
221
|
NewFixedPrefixTransform(prefix_size));
|
|
@@ -253,10 +267,11 @@ TEST_P(BlockTest, SimpleIndexHash) {
|
|
|
253
267
|
1 /* prefix_group_size */,
|
|
254
268
|
isUDTEnabled()
|
|
255
269
|
? BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch
|
|
256
|
-
: dataBlockIndexType()
|
|
270
|
+
: dataBlockIndexType(),
|
|
271
|
+
useSeparatedKVStorage(), getRestartInterval());
|
|
257
272
|
|
|
258
273
|
CheckBlockContents(std::move(contents), kMaxKey, keys, values, isUDTEnabled(),
|
|
259
|
-
shouldPersistUDT());
|
|
274
|
+
shouldPersistUDT(), getRestartInterval());
|
|
260
275
|
}
|
|
261
276
|
|
|
262
277
|
TEST_P(BlockTest, IndexHashWithSharedPrefix) {
|
|
@@ -276,14 +291,15 @@ TEST_P(BlockTest, IndexHashWithSharedPrefix) {
|
|
|
276
291
|
std::unique_ptr<BlockBuilder> builder;
|
|
277
292
|
|
|
278
293
|
auto contents = GetBlockContents(
|
|
279
|
-
&builder, keys, values, keyUseDeltaEncoding(),
|
|
280
|
-
|
|
294
|
+
&builder, keys, values, keyUseDeltaEncoding(), ts_sz, shouldPersistUDT(),
|
|
295
|
+
kPrefixGroup,
|
|
281
296
|
isUDTEnabled()
|
|
282
297
|
? BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch
|
|
283
|
-
: dataBlockIndexType()
|
|
298
|
+
: dataBlockIndexType(),
|
|
299
|
+
useSeparatedKVStorage(), getRestartInterval());
|
|
284
300
|
|
|
285
301
|
CheckBlockContents(std::move(contents), kMaxKey, keys, values, isUDTEnabled(),
|
|
286
|
-
shouldPersistUDT());
|
|
302
|
+
shouldPersistUDT(), getRestartInterval());
|
|
287
303
|
}
|
|
288
304
|
|
|
289
305
|
// Param 0: key use delta encoding
|
|
@@ -292,6 +308,8 @@ TEST_P(BlockTest, IndexHashWithSharedPrefix) {
|
|
|
292
308
|
// compatible with `kDataBlockBinaryAndHash` data block index type because the
|
|
293
309
|
// user comparator doesn't provide a `CanKeysWithDifferentByteContentsBeEqual`
|
|
294
310
|
// override. This combination is disabled.
|
|
311
|
+
// Param 3: restart interval
|
|
312
|
+
// Param 4: use separated KV storage
|
|
295
313
|
INSTANTIATE_TEST_CASE_P(
|
|
296
314
|
P, BlockTest,
|
|
297
315
|
::testing::Combine(
|
|
@@ -299,7 +317,8 @@ INSTANTIATE_TEST_CASE_P(
|
|
|
299
317
|
::testing::Values(
|
|
300
318
|
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch,
|
|
301
319
|
BlockBasedTableOptions::DataBlockIndexType::
|
|
302
|
-
kDataBlockBinaryAndHash)
|
|
320
|
+
kDataBlockBinaryAndHash),
|
|
321
|
+
::testing::Values(1, 8, 16), ::testing::Bool()));
|
|
303
322
|
|
|
304
323
|
// A slow and accurate version of BlockReadAmpBitmap that simply store
|
|
305
324
|
// all the marked ranges in a set.
|
|
@@ -356,8 +375,8 @@ class BlockReadAmpBitmapSlowAndAccurate {
|
|
|
356
375
|
TEST_F(BlockTest, BlockReadAmpBitmap) {
|
|
357
376
|
uint32_t pin_offset = 0;
|
|
358
377
|
SyncPoint::GetInstance()->SetCallBack(
|
|
359
|
-
"BlockReadAmpBitmap:rnd", [&pin_offset](void
|
|
360
|
-
pin_offset = *(static_cast<uint32_t
|
|
378
|
+
"BlockReadAmpBitmap:rnd", [&pin_offset](void* arg) {
|
|
379
|
+
pin_offset = *(static_cast<uint32_t*>(arg));
|
|
361
380
|
});
|
|
362
381
|
SyncPoint::GetInstance()->EnableProcessing();
|
|
363
382
|
std::vector<size_t> block_sizes = {
|
|
@@ -414,7 +433,7 @@ TEST_F(BlockTest, BlockReadAmpBitmap) {
|
|
|
414
433
|
|
|
415
434
|
for (size_t i = 0; i < random_entries.size(); i++) {
|
|
416
435
|
read_amp_slow_and_accurate.ResetCheckSequence();
|
|
417
|
-
auto
|
|
436
|
+
auto& current_entry = random_entries[rnd.Next() % random_entries.size()];
|
|
418
437
|
|
|
419
438
|
read_amp_bitmap.Mark(static_cast<uint32_t>(current_entry.first),
|
|
420
439
|
static_cast<uint32_t>(current_entry.second));
|
|
@@ -465,7 +484,7 @@ TEST_F(BlockTest, BlockWithReadAmpBitmap) {
|
|
|
465
484
|
|
|
466
485
|
// read contents of block sequentially
|
|
467
486
|
size_t read_bytes = 0;
|
|
468
|
-
DataBlockIter
|
|
487
|
+
DataBlockIter* iter = reader.NewDataIterator(
|
|
469
488
|
options.comparator, kDisableGlobalSequenceNumber, nullptr, stats.get());
|
|
470
489
|
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
|
471
490
|
iter->value();
|
|
@@ -496,7 +515,7 @@ TEST_F(BlockTest, BlockWithReadAmpBitmap) {
|
|
|
496
515
|
Block reader(std::move(contents), kBytesPerBit, stats.get());
|
|
497
516
|
|
|
498
517
|
size_t read_bytes = 0;
|
|
499
|
-
DataBlockIter
|
|
518
|
+
DataBlockIter* iter = reader.NewDataIterator(
|
|
500
519
|
options.comparator, kDisableGlobalSequenceNumber, nullptr, stats.get());
|
|
501
520
|
for (int i = 0; i < num_records; i++) {
|
|
502
521
|
Slice k(keys[i]);
|
|
@@ -530,7 +549,7 @@ TEST_F(BlockTest, BlockWithReadAmpBitmap) {
|
|
|
530
549
|
Block reader(std::move(contents), kBytesPerBit, stats.get());
|
|
531
550
|
|
|
532
551
|
size_t read_bytes = 0;
|
|
533
|
-
DataBlockIter
|
|
552
|
+
DataBlockIter* iter = reader.NewDataIterator(
|
|
534
553
|
options.comparator, kDisableGlobalSequenceNumber, nullptr, stats.get());
|
|
535
554
|
std::unordered_set<int> read_keys;
|
|
536
555
|
for (int i = 0; i < num_records; i++) {
|
|
@@ -576,41 +595,103 @@ TEST_F(BlockTest, ReadAmpBitmapPow2) {
|
|
|
576
595
|
ASSERT_EQ(BlockReadAmpBitmap(100, 35, stats.get()).GetBytesPerBit(), 32u);
|
|
577
596
|
}
|
|
578
597
|
|
|
598
|
+
void AddIndexBlockEntry(BlockBuilder& builder, const Slice& key,
|
|
599
|
+
const BlockHandle& bh, const BlockHandle* prev,
|
|
600
|
+
bool include_first_key,
|
|
601
|
+
const Slice& first_internal_key = Slice()) {
|
|
602
|
+
IndexValue entry(bh, first_internal_key);
|
|
603
|
+
std::string encoded_entry;
|
|
604
|
+
entry.EncodeTo(&encoded_entry, include_first_key, nullptr);
|
|
605
|
+
std::string delta_encoded_entry;
|
|
606
|
+
if (prev) {
|
|
607
|
+
entry.EncodeTo(&delta_encoded_entry, include_first_key, prev);
|
|
608
|
+
}
|
|
609
|
+
const Slice delta_slice(delta_encoded_entry);
|
|
610
|
+
builder.Add(key, encoded_entry, &delta_slice);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
enum class KeyDistribution { kUniform, kNonUniform };
|
|
614
|
+
|
|
579
615
|
class IndexBlockTest
|
|
580
616
|
: public testing::Test,
|
|
581
617
|
public testing::WithParamInterface<
|
|
582
|
-
std::tuple<bool, bool, bool, test::UserDefinedTimestampTestMode
|
|
618
|
+
std::tuple<bool, bool, bool, bool, test::UserDefinedTimestampTestMode,
|
|
619
|
+
BlockBasedTableOptions::BlockSearchType, int, int, int,
|
|
620
|
+
std::pair<int, KeyDistribution>>> {
|
|
583
621
|
public:
|
|
584
622
|
IndexBlockTest() = default;
|
|
585
623
|
|
|
586
624
|
bool keyIncludesSeq() const { return std::get<0>(GetParam()); }
|
|
587
625
|
bool useValueDeltaEncoding() const { return std::get<1>(GetParam()); }
|
|
588
626
|
bool includeFirstKey() const { return std::get<2>(GetParam()); }
|
|
627
|
+
bool useSeparatedKVStorage() const { return std::get<3>(GetParam()); }
|
|
589
628
|
bool isUDTEnabled() const {
|
|
590
|
-
return test::IsUDTEnabled(std::get<
|
|
629
|
+
return test::IsUDTEnabled(std::get<4>(GetParam()));
|
|
591
630
|
}
|
|
592
631
|
bool shouldPersistUDT() const {
|
|
593
|
-
return test::ShouldPersistUDT(std::get<
|
|
632
|
+
return test::ShouldPersistUDT(std::get<4>(GetParam()));
|
|
633
|
+
}
|
|
634
|
+
BlockBasedTableOptions::BlockSearchType indexSearchType() const {
|
|
635
|
+
return isUDTEnabled() ? BlockBasedTableOptions::kBinary
|
|
636
|
+
: std::get<5>(GetParam());
|
|
637
|
+
}
|
|
638
|
+
int numRecords() const {
|
|
639
|
+
return std::min(1 << keyLength(), std::get<6>(GetParam()));
|
|
640
|
+
}
|
|
641
|
+
int indexBlockRestartInterval() const { return std::get<7>(GetParam()); }
|
|
642
|
+
int keyLength() const { return std::get<8>(GetParam()); }
|
|
643
|
+
// prefix_length and key_distribution are bundled into a std::pair to stay
|
|
644
|
+
// within gtest 1.8.1's 10-parameter Combine limit.
|
|
645
|
+
int prefixLength() const { return std::get<9>(GetParam()).first; }
|
|
646
|
+
KeyDistribution keyDistribution() const {
|
|
647
|
+
return std::get<9>(GetParam()).second;
|
|
594
648
|
}
|
|
595
649
|
};
|
|
596
650
|
|
|
597
|
-
// Similar to GenerateRandomKVs but for index block contents.
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
651
|
+
// Similar to GenerateRandomKVs but for index block contents. Keys always
|
|
652
|
+
// contain a 0-sequence number, callers may extract the user key if needed.
|
|
653
|
+
void GenerateRandomIndexEntries(
|
|
654
|
+
std::vector<std::string>* separators,
|
|
655
|
+
std::vector<BlockHandle>* block_handles,
|
|
656
|
+
std::vector<std::string>* first_keys, const int len, size_t ts_sz = 0,
|
|
657
|
+
int key_length = 12, int prefix_length = 0,
|
|
658
|
+
KeyDistribution distribution = KeyDistribution::kUniform) {
|
|
603
659
|
Random rnd(42);
|
|
660
|
+
std::string prefix(prefix_length, 'x');
|
|
604
661
|
|
|
605
662
|
// For each of `len` blocks, we need to generate a first and last key.
|
|
606
|
-
//
|
|
663
|
+
// Generate n*2 random keys, sort them, group into consecutive pairs.
|
|
607
664
|
std::set<std::string> keys;
|
|
665
|
+
|
|
666
|
+
// Two clusters with shared prefixes of effective_key_length - 2. This
|
|
667
|
+
// stresses interpolation search's uniform distribution assumption.
|
|
668
|
+
int cluster_prefix_len = std::max(0, key_length - 5);
|
|
669
|
+
std::string cluster1_prefix = prefix + rnd.RandomString(cluster_prefix_len);
|
|
670
|
+
std::string cluster2_prefix = prefix + rnd.RandomString(cluster_prefix_len);
|
|
671
|
+
|
|
608
672
|
while ((int)keys.size() < len * 2) {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
673
|
+
std::string new_key;
|
|
674
|
+
if (distribution == KeyDistribution::kNonUniform) {
|
|
675
|
+
int remaining = key_length - cluster_prefix_len;
|
|
676
|
+
const std::string& cp =
|
|
677
|
+
(keys.size() % 2 == 0) ? cluster1_prefix : cluster2_prefix;
|
|
678
|
+
new_key = cp + rnd.RandomString(std::max(1, remaining));
|
|
679
|
+
} else {
|
|
680
|
+
// Generate evenly-spaced keys to ensure numeric uniformity.
|
|
681
|
+
// Encode the key index as big-endian with jitter to avoid
|
|
682
|
+
// perfectly equal gaps while maintaining uniformity.
|
|
683
|
+
uint64_t base =
|
|
684
|
+
static_cast<uint64_t>(keys.size()) * 1000 + rnd.Uniform(100);
|
|
685
|
+
std::string key_bytes(key_length, '\0');
|
|
686
|
+
// Write big-endian uint64 into the last 8 bytes (or fewer if shorter)
|
|
687
|
+
for (int j = key_length - 1; j >= 0 && base > 0; j--) {
|
|
688
|
+
key_bytes[j] = static_cast<char>(base & 0xFF);
|
|
689
|
+
base >>= 8;
|
|
690
|
+
}
|
|
691
|
+
new_key = prefix + key_bytes;
|
|
613
692
|
}
|
|
693
|
+
|
|
694
|
+
AppendInternalKeyFooter(&new_key, 0 /* seqno */, kTypeValue);
|
|
614
695
|
if (ts_sz > 0) {
|
|
615
696
|
std::string key;
|
|
616
697
|
PadInternalKeyWithMinTimestamp(&key, new_key, ts_sz);
|
|
@@ -643,15 +724,18 @@ TEST_P(IndexBlockTest, IndexValueEncodingTest) {
|
|
|
643
724
|
std::vector<BlockHandle> block_handles;
|
|
644
725
|
std::vector<std::string> first_keys;
|
|
645
726
|
const bool kUseDeltaEncoding = true;
|
|
646
|
-
BlockBuilder builder(
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
727
|
+
BlockBuilder builder(
|
|
728
|
+
indexBlockRestartInterval(), kUseDeltaEncoding, useValueDeltaEncoding(),
|
|
729
|
+
BlockBasedTableOptions::kDataBlockBinarySearch,
|
|
730
|
+
0.75 /* data_block_hash_table_util_ratio */, ts_sz, shouldPersistUDT(),
|
|
731
|
+
!keyIncludesSeq(), useSeparatedKVStorage(), nullptr /* statistics */,
|
|
732
|
+
0.2 /* uniform_cv_threshold */);
|
|
650
733
|
|
|
651
|
-
int num_records =
|
|
734
|
+
int num_records = numRecords();
|
|
652
735
|
|
|
653
736
|
GenerateRandomIndexEntries(&separators, &block_handles, &first_keys,
|
|
654
|
-
num_records, ts_sz,
|
|
737
|
+
num_records, ts_sz, keyLength(), prefixLength(),
|
|
738
|
+
keyDistribution());
|
|
655
739
|
BlockHandle last_encoded_handle;
|
|
656
740
|
for (int i = 0; i < num_records; i++) {
|
|
657
741
|
std::string first_key_to_persist_buf;
|
|
@@ -661,23 +745,13 @@ TEST_P(IndexBlockTest, IndexValueEncodingTest) {
|
|
|
661
745
|
ts_sz);
|
|
662
746
|
first_internal_key = first_key_to_persist_buf;
|
|
663
747
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
}
|
|
672
|
-
last_encoded_handle = entry.handle;
|
|
673
|
-
const Slice delta_encoded_entry_slice(delta_encoded_entry);
|
|
674
|
-
|
|
675
|
-
if (keyIncludesSeq()) {
|
|
676
|
-
builder.Add(separators[i], encoded_entry, &delta_encoded_entry_slice);
|
|
677
|
-
} else {
|
|
678
|
-
const Slice user_key = ExtractUserKey(separators[i]);
|
|
679
|
-
builder.Add(user_key, encoded_entry, &delta_encoded_entry_slice);
|
|
680
|
-
}
|
|
748
|
+
const BlockHandle* prev =
|
|
749
|
+
(useValueDeltaEncoding() && i > 0) ? &last_encoded_handle : nullptr;
|
|
750
|
+
Slice add_key =
|
|
751
|
+
keyIncludesSeq() ? Slice(separators[i]) : ExtractUserKey(separators[i]);
|
|
752
|
+
AddIndexBlockEntry(builder, add_key, block_handles[i], prev,
|
|
753
|
+
includeFirstKey(), first_internal_key);
|
|
754
|
+
last_encoded_handle = block_handles[i];
|
|
681
755
|
}
|
|
682
756
|
|
|
683
757
|
// read serialized contents of the block
|
|
@@ -686,17 +760,19 @@ TEST_P(IndexBlockTest, IndexValueEncodingTest) {
|
|
|
686
760
|
// create block reader
|
|
687
761
|
BlockContents contents;
|
|
688
762
|
contents.data = rawblock;
|
|
689
|
-
Block reader(std::move(contents)
|
|
763
|
+
Block reader(std::move(contents), 0 /* read_amp_bytes_per_bit */,
|
|
764
|
+
nullptr /* statistics */,
|
|
765
|
+
static_cast<uint32_t>(indexBlockRestartInterval()));
|
|
690
766
|
|
|
691
767
|
const bool kTotalOrderSeek = true;
|
|
692
|
-
IndexBlockIter
|
|
693
|
-
Statistics
|
|
768
|
+
IndexBlockIter* kNullIter = nullptr;
|
|
769
|
+
Statistics* kNullStats = nullptr;
|
|
694
770
|
// read contents of block sequentially
|
|
695
|
-
InternalIteratorBase<IndexValue
|
|
771
|
+
InternalIteratorBase<IndexValue>* iter = reader.NewIndexIterator(
|
|
696
772
|
options.comparator, kDisableGlobalSequenceNumber, kNullIter, kNullStats,
|
|
697
773
|
kTotalOrderSeek, includeFirstKey(), keyIncludesSeq(),
|
|
698
774
|
!useValueDeltaEncoding(), false /* block_contents_pinned */,
|
|
699
|
-
shouldPersistUDT());
|
|
775
|
+
shouldPersistUDT(), nullptr /* prefix_index */, indexSearchType());
|
|
700
776
|
iter->SeekToFirst();
|
|
701
777
|
for (int index = 0; index < num_records; ++index) {
|
|
702
778
|
ASSERT_TRUE(iter->Valid());
|
|
@@ -719,12 +795,22 @@ TEST_P(IndexBlockTest, IndexValueEncodingTest) {
|
|
|
719
795
|
}
|
|
720
796
|
delete iter;
|
|
721
797
|
|
|
798
|
+
// ScanForUniformity requires at least 3 restart points to determine
|
|
799
|
+
// uniformity. With fewer restarts, is_uniform is always false.
|
|
800
|
+
// When UDT is enabled, min-timestamps alter the key byte distribution,
|
|
801
|
+
// so skip the uniformity check.
|
|
802
|
+
if (!isUDTEnabled()) {
|
|
803
|
+
bool expect_uniform = reader.NumRestarts() >= 3 &&
|
|
804
|
+
keyDistribution() == KeyDistribution::kUniform;
|
|
805
|
+
EXPECT_EQ(reader.IsUniform(), expect_uniform);
|
|
806
|
+
}
|
|
807
|
+
|
|
722
808
|
// read block contents randomly
|
|
723
809
|
iter = reader.NewIndexIterator(
|
|
724
810
|
options.comparator, kDisableGlobalSequenceNumber, kNullIter, kNullStats,
|
|
725
811
|
kTotalOrderSeek, includeFirstKey(), keyIncludesSeq(),
|
|
726
812
|
!useValueDeltaEncoding(), false /* block_contents_pinned */,
|
|
727
|
-
shouldPersistUDT());
|
|
813
|
+
shouldPersistUDT(), nullptr /* prefix_index */, indexSearchType());
|
|
728
814
|
for (int i = 0; i < num_records * 2; i++) {
|
|
729
815
|
// find a random key in the lookaside array
|
|
730
816
|
int index = rnd.Uniform(num_records);
|
|
@@ -752,11 +838,208 @@ TEST_P(IndexBlockTest, IndexValueEncodingTest) {
|
|
|
752
838
|
// key as key entry in index block).
|
|
753
839
|
// Param 1: use value delta encoding
|
|
754
840
|
// Param 2: include first key
|
|
755
|
-
// Param 3:
|
|
841
|
+
// Param 3: use separated KV storage
|
|
842
|
+
// Param 4: user-defined timestamp test mode
|
|
843
|
+
// Param 5: index search type (binary search or interpolation search)
|
|
844
|
+
// Param 6: number of records
|
|
845
|
+
// Param 7: index block restart interval
|
|
846
|
+
// Param 8: key length
|
|
847
|
+
// Param 9: (prefix_length, key_distribution) pair
|
|
756
848
|
INSTANTIATE_TEST_CASE_P(
|
|
757
849
|
P, IndexBlockTest,
|
|
758
|
-
::testing::Combine(
|
|
759
|
-
|
|
850
|
+
::testing::Combine(
|
|
851
|
+
::testing::Bool(), ::testing::Bool(), ::testing::Bool(),
|
|
852
|
+
::testing::Bool(), ::testing::ValuesIn(test::GetUDTTestModes()),
|
|
853
|
+
::testing::Values(
|
|
854
|
+
BlockBasedTableOptions::BlockSearchType::kBinary,
|
|
855
|
+
BlockBasedTableOptions::BlockSearchType::kInterpolation,
|
|
856
|
+
BlockBasedTableOptions::BlockSearchType::kAuto),
|
|
857
|
+
::testing::Values(1, 100), // num_records
|
|
858
|
+
::testing::Values(1, 16), // index_block_restart_interval
|
|
859
|
+
::testing::Values(1, 8, 12), // key_length
|
|
860
|
+
::testing::Values(std::make_pair(0, KeyDistribution::kUniform),
|
|
861
|
+
std::make_pair(0, KeyDistribution::kNonUniform),
|
|
862
|
+
std::make_pair(50, KeyDistribution::kUniform),
|
|
863
|
+
std::make_pair(50, KeyDistribution::kNonUniform))));
|
|
864
|
+
|
|
865
|
+
TEST(IndexBlockTest, InterpolationSearchPrefixBoundary) {
|
|
866
|
+
const bool kIncludeFirstKey = false;
|
|
867
|
+
const bool kUseValueDeltaEncoding = true;
|
|
868
|
+
const uint64_t kBlockSize = 50;
|
|
869
|
+
|
|
870
|
+
// 20 user keys sharing prefix "ABCDEFGHIJ" with evenly spaced suffixes.
|
|
871
|
+
const std::string kPrefix = "ABCDEFGHIJ";
|
|
872
|
+
const int kNumKeys = 20;
|
|
873
|
+
std::vector<std::string> keys;
|
|
874
|
+
keys.reserve(kNumKeys);
|
|
875
|
+
for (int i = 0; i < kNumKeys; i++) {
|
|
876
|
+
std::string suffix = std::to_string(i);
|
|
877
|
+
char formatted_suffix[4];
|
|
878
|
+
snprintf(formatted_suffix, sizeof(formatted_suffix), "%03d", i);
|
|
879
|
+
keys.push_back(kPrefix + formatted_suffix);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
std::vector<BlockHandle> handles;
|
|
883
|
+
handles.reserve(kNumKeys);
|
|
884
|
+
for (int i = 0; i < kNumKeys; i++) {
|
|
885
|
+
handles.emplace_back(i * (kBlockSize + BlockBasedTable::kBlockTrailerSize),
|
|
886
|
+
kBlockSize);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
BlockBuilder builder(
|
|
890
|
+
1 /* restart_interval */, true /* use_delta_encoding */,
|
|
891
|
+
kUseValueDeltaEncoding, BlockBasedTableOptions::kDataBlockBinarySearch,
|
|
892
|
+
0.75 /* data_block_hash_table_util_ratio */, 0 /* ts_sz */,
|
|
893
|
+
false /* persist_udt */, true /* is_user_key */);
|
|
894
|
+
|
|
895
|
+
for (int i = 0; i < kNumKeys; i++) {
|
|
896
|
+
BlockHandle* prev = i > 0 ? &handles[i - 1] : nullptr;
|
|
897
|
+
AddIndexBlockEntry(builder, keys[i], handles[i], prev, kIncludeFirstKey);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
Slice rawblock = builder.Finish();
|
|
901
|
+
BlockContents contents;
|
|
902
|
+
contents.data = rawblock;
|
|
903
|
+
Block reader(std::move(contents));
|
|
904
|
+
|
|
905
|
+
// Seek targets must be internal keys since SeekImpl calls ExtractUserKey().
|
|
906
|
+
auto make_target = [](const std::string& user_key) {
|
|
907
|
+
std::string target = user_key;
|
|
908
|
+
AppendInternalKeyFooter(&target, kMaxSequenceNumber, kValueTypeForSeek);
|
|
909
|
+
return target;
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
std::unique_ptr<InternalIteratorBase<IndexValue>> iter(
|
|
913
|
+
reader.NewIndexIterator(
|
|
914
|
+
BytewiseComparator(), kDisableGlobalSequenceNumber,
|
|
915
|
+
nullptr /* iter */, nullptr /* stats */, true /* total_order_seek */,
|
|
916
|
+
kIncludeFirstKey, false /* key_includes_seq */,
|
|
917
|
+
!kUseValueDeltaEncoding /* value_is_full */,
|
|
918
|
+
false /* block_contents_pinned */,
|
|
919
|
+
true /* user_defined_timestamps_persisted */,
|
|
920
|
+
nullptr /* prefix_index */,
|
|
921
|
+
BlockBasedTableOptions::BlockSearchType::kInterpolation));
|
|
922
|
+
|
|
923
|
+
// Case 1: target prefix < shared prefix
|
|
924
|
+
iter->Seek(make_target("AAAAAA"));
|
|
925
|
+
ASSERT_TRUE(iter->Valid());
|
|
926
|
+
EXPECT_EQ(iter->key(), keys[0]);
|
|
927
|
+
|
|
928
|
+
iter->Seek(make_target(""));
|
|
929
|
+
ASSERT_TRUE(iter->Valid());
|
|
930
|
+
EXPECT_EQ(iter->key(), keys[0]);
|
|
931
|
+
|
|
932
|
+
// Case 2: target prefix > shared prefix
|
|
933
|
+
iter->Seek(make_target("ABCDEFGHZZ"));
|
|
934
|
+
ASSERT_FALSE(iter->Valid());
|
|
935
|
+
|
|
936
|
+
// Case 3: target is the prefix
|
|
937
|
+
iter->Seek(make_target("ABCDEFGHIJ"));
|
|
938
|
+
ASSERT_TRUE(iter->Valid());
|
|
939
|
+
EXPECT_EQ(iter->key(), keys[0]);
|
|
940
|
+
|
|
941
|
+
// Case 4: target a subset of the prefix
|
|
942
|
+
iter->Seek(make_target("ABCDEFG"));
|
|
943
|
+
ASSERT_TRUE(iter->Valid());
|
|
944
|
+
EXPECT_EQ(iter->key(), keys[0]);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// Like the above test, but extend the shared prefix into internal bytes
|
|
948
|
+
TEST(IndexBlockTest, InterpolationSearchPrefixBoundary2) {
|
|
949
|
+
const bool kIncludeFirstKey = false;
|
|
950
|
+
const bool kUseValueDeltaEncoding = true;
|
|
951
|
+
const uint64_t kBlockSize = 50;
|
|
952
|
+
|
|
953
|
+
// 20 internal keys with the same user key but decreasing sequence numbers
|
|
954
|
+
// (which is ascending InternalKeyComparator order).
|
|
955
|
+
const std::string kUserKey = "ABCDEFGHIJ";
|
|
956
|
+
const int kNumKeys = 20;
|
|
957
|
+
std::vector<std::string> keys;
|
|
958
|
+
keys.reserve(kNumKeys);
|
|
959
|
+
for (int i = 0; i < kNumKeys; i++) {
|
|
960
|
+
std::string ikey = kUserKey;
|
|
961
|
+
SequenceNumber seq = static_cast<SequenceNumber>(kNumKeys - i);
|
|
962
|
+
AppendInternalKeyFooter(&ikey, seq, kTypeValue);
|
|
963
|
+
keys.push_back(ikey);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
std::vector<BlockHandle> handles;
|
|
967
|
+
handles.reserve(kNumKeys);
|
|
968
|
+
for (int i = 0; i < kNumKeys; i++) {
|
|
969
|
+
handles.emplace_back(i * (kBlockSize + BlockBasedTable::kBlockTrailerSize),
|
|
970
|
+
kBlockSize);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
BlockBuilder builder(
|
|
974
|
+
1 /* restart_interval */, true /* use_delta_encoding */,
|
|
975
|
+
kUseValueDeltaEncoding, BlockBasedTableOptions::kDataBlockBinarySearch,
|
|
976
|
+
0.75 /* data_block_hash_table_util_ratio */, 0 /* ts_sz */,
|
|
977
|
+
false /* persist_udt */, false /* is_user_key */);
|
|
978
|
+
|
|
979
|
+
for (int i = 0; i < kNumKeys; i++) {
|
|
980
|
+
BlockHandle* prev = i > 0 ? &handles[i - 1] : nullptr;
|
|
981
|
+
AddIndexBlockEntry(builder, keys[i], handles[i], prev, kIncludeFirstKey);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
Slice rawblock = builder.Finish();
|
|
985
|
+
BlockContents contents;
|
|
986
|
+
contents.data = rawblock;
|
|
987
|
+
Block reader(std::move(contents));
|
|
988
|
+
|
|
989
|
+
auto make_target = [&](const std::string& user_key,
|
|
990
|
+
SequenceNumber seq = kMaxSequenceNumber) {
|
|
991
|
+
std::string target = user_key;
|
|
992
|
+
AppendInternalKeyFooter(&target, seq, kTypeValue);
|
|
993
|
+
return target;
|
|
994
|
+
};
|
|
995
|
+
|
|
996
|
+
std::unique_ptr<InternalIteratorBase<IndexValue>> iter(
|
|
997
|
+
reader.NewIndexIterator(
|
|
998
|
+
BytewiseComparator(), kDisableGlobalSequenceNumber,
|
|
999
|
+
nullptr /* iter */, nullptr /* stats */, true /* total_order_seek */,
|
|
1000
|
+
kIncludeFirstKey, true /* key_includes_seq */,
|
|
1001
|
+
!kUseValueDeltaEncoding /* value_is_full */,
|
|
1002
|
+
false /* block_contents_pinned */,
|
|
1003
|
+
true /* user_defined_timestamps_persisted */,
|
|
1004
|
+
nullptr /* prefix_index */,
|
|
1005
|
+
BlockBasedTableOptions::BlockSearchType::kInterpolation));
|
|
1006
|
+
|
|
1007
|
+
// Seek to each existing sequence number
|
|
1008
|
+
for (int i = 0; i < kNumKeys; i++) {
|
|
1009
|
+
SequenceNumber seq = static_cast<SequenceNumber>(kNumKeys - i);
|
|
1010
|
+
iter->Seek(make_target(kUserKey, seq));
|
|
1011
|
+
ASSERT_TRUE(iter->Valid());
|
|
1012
|
+
EXPECT_EQ(iter->key(), keys[i]);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Case 1: target prefix < shared prefix
|
|
1016
|
+
iter->Seek(make_target("AAAAAA"));
|
|
1017
|
+
ASSERT_TRUE(iter->Valid());
|
|
1018
|
+
EXPECT_EQ(iter->key(), keys[0]);
|
|
1019
|
+
|
|
1020
|
+
iter->Seek(make_target(""));
|
|
1021
|
+
ASSERT_TRUE(iter->Valid());
|
|
1022
|
+
EXPECT_EQ(iter->key(), keys[0]);
|
|
1023
|
+
|
|
1024
|
+
// Case 2: target prefix > shared prefix
|
|
1025
|
+
iter->Seek(make_target("ABCDEFGHZZ"));
|
|
1026
|
+
ASSERT_FALSE(iter->Valid());
|
|
1027
|
+
|
|
1028
|
+
// Case 3: target has the same user key with kMaxSequenceNumber
|
|
1029
|
+
iter->Seek(make_target("ABCDEFGHIJ"));
|
|
1030
|
+
ASSERT_TRUE(iter->Valid());
|
|
1031
|
+
EXPECT_EQ(iter->key(), keys[0]);
|
|
1032
|
+
|
|
1033
|
+
// Case 4: target a subset of the prefix
|
|
1034
|
+
iter->Seek(make_target("ABCDEFG"));
|
|
1035
|
+
ASSERT_TRUE(iter->Valid());
|
|
1036
|
+
EXPECT_EQ(iter->key(), keys[0]);
|
|
1037
|
+
|
|
1038
|
+
// Case 5: target key is a prefix that also extends into the internal bytes
|
|
1039
|
+
// footer
|
|
1040
|
+
iter->Seek(make_target("ABCDEFGHIJ" + std::string(1, kTypeValue)));
|
|
1041
|
+
ASSERT_FALSE(iter->Valid());
|
|
1042
|
+
}
|
|
760
1043
|
|
|
761
1044
|
class BlockPerKVChecksumTest : public DBTestBase {
|
|
762
1045
|
public:
|
|
@@ -764,8 +1047,8 @@ class BlockPerKVChecksumTest : public DBTestBase {
|
|
|
764
1047
|
: DBTestBase("block_per_kv_checksum", /*env_do_fsync=*/false) {}
|
|
765
1048
|
|
|
766
1049
|
template <typename TBlockIter>
|
|
767
|
-
void TestIterateForward(std::unique_ptr<TBlockIter
|
|
768
|
-
size_t
|
|
1050
|
+
void TestIterateForward(std::unique_ptr<TBlockIter>& biter,
|
|
1051
|
+
size_t& verification_count) {
|
|
769
1052
|
while (biter->Valid()) {
|
|
770
1053
|
verification_count = 0;
|
|
771
1054
|
biter->Next();
|
|
@@ -776,8 +1059,8 @@ class BlockPerKVChecksumTest : public DBTestBase {
|
|
|
776
1059
|
}
|
|
777
1060
|
|
|
778
1061
|
template <typename TBlockIter>
|
|
779
|
-
void TestIterateBackward(std::unique_ptr<TBlockIter
|
|
780
|
-
size_t
|
|
1062
|
+
void TestIterateBackward(std::unique_ptr<TBlockIter>& biter,
|
|
1063
|
+
size_t& verification_count) {
|
|
781
1064
|
while (biter->Valid()) {
|
|
782
1065
|
verification_count = 0;
|
|
783
1066
|
biter->Prev();
|
|
@@ -788,8 +1071,8 @@ class BlockPerKVChecksumTest : public DBTestBase {
|
|
|
788
1071
|
}
|
|
789
1072
|
|
|
790
1073
|
template <typename TBlockIter>
|
|
791
|
-
void TestSeekToFirst(std::unique_ptr<TBlockIter
|
|
792
|
-
size_t
|
|
1074
|
+
void TestSeekToFirst(std::unique_ptr<TBlockIter>& biter,
|
|
1075
|
+
size_t& verification_count) {
|
|
793
1076
|
verification_count = 0;
|
|
794
1077
|
biter->SeekToFirst();
|
|
795
1078
|
ASSERT_GE(verification_count, 1);
|
|
@@ -797,8 +1080,8 @@ class BlockPerKVChecksumTest : public DBTestBase {
|
|
|
797
1080
|
}
|
|
798
1081
|
|
|
799
1082
|
template <typename TBlockIter>
|
|
800
|
-
void TestSeekToLast(std::unique_ptr<TBlockIter
|
|
801
|
-
size_t
|
|
1083
|
+
void TestSeekToLast(std::unique_ptr<TBlockIter>& biter,
|
|
1084
|
+
size_t& verification_count) {
|
|
802
1085
|
verification_count = 0;
|
|
803
1086
|
biter->SeekToLast();
|
|
804
1087
|
ASSERT_GE(verification_count, 1);
|
|
@@ -806,8 +1089,8 @@ class BlockPerKVChecksumTest : public DBTestBase {
|
|
|
806
1089
|
}
|
|
807
1090
|
|
|
808
1091
|
template <typename TBlockIter>
|
|
809
|
-
void TestSeekForPrev(std::unique_ptr<TBlockIter
|
|
810
|
-
size_t
|
|
1092
|
+
void TestSeekForPrev(std::unique_ptr<TBlockIter>& biter,
|
|
1093
|
+
size_t& verification_count, const std::string& k) {
|
|
811
1094
|
verification_count = 0;
|
|
812
1095
|
biter->SeekForPrev(k);
|
|
813
1096
|
ASSERT_GE(verification_count, 1);
|
|
@@ -815,16 +1098,16 @@ class BlockPerKVChecksumTest : public DBTestBase {
|
|
|
815
1098
|
}
|
|
816
1099
|
|
|
817
1100
|
template <typename TBlockIter>
|
|
818
|
-
void TestSeek(std::unique_ptr<TBlockIter
|
|
819
|
-
std::string k) {
|
|
1101
|
+
void TestSeek(std::unique_ptr<TBlockIter>& biter, size_t& verification_count,
|
|
1102
|
+
const std::string& k) {
|
|
820
1103
|
verification_count = 0;
|
|
821
1104
|
biter->Seek(k);
|
|
822
1105
|
ASSERT_GE(verification_count, 1);
|
|
823
1106
|
TestIterateForward(biter, verification_count);
|
|
824
1107
|
}
|
|
825
1108
|
|
|
826
|
-
bool VerifyChecksum(uint32_t checksum_len, const char
|
|
827
|
-
const Slice
|
|
1109
|
+
bool VerifyChecksum(uint32_t checksum_len, const char* checksum_ptr,
|
|
1110
|
+
const Slice& key, const Slice& val) {
|
|
828
1111
|
if (!checksum_len) {
|
|
829
1112
|
return checksum_ptr == nullptr;
|
|
830
1113
|
}
|
|
@@ -834,13 +1117,12 @@ class BlockPerKVChecksumTest : public DBTestBase {
|
|
|
834
1117
|
};
|
|
835
1118
|
|
|
836
1119
|
namespace {
|
|
837
|
-
const BlockBasedTableOptions
|
|
1120
|
+
const BlockBasedTableOptions* kTableOptions() {
|
|
838
1121
|
static BlockBasedTableOptions opts{};
|
|
839
1122
|
return &opts;
|
|
840
1123
|
}
|
|
841
|
-
Decompressor
|
|
842
|
-
static auto mgr =
|
|
843
|
-
GetCompressFormatForVersion(kTableOptions()->format_version));
|
|
1124
|
+
Decompressor* kDecompressor() {
|
|
1125
|
+
static auto mgr = GetBuiltinV2CompressionManager();
|
|
844
1126
|
static auto decomp = mgr->GetDecompressor();
|
|
845
1127
|
return decomp.get();
|
|
846
1128
|
}
|
|
@@ -1057,7 +1339,7 @@ class DataBlockKVChecksumTest
|
|
|
1057
1339
|
bool GetUseDeltaEncoding() const { return std::get<3>(GetParam()); }
|
|
1058
1340
|
|
|
1059
1341
|
std::unique_ptr<Block_kData> GenerateDataBlock(
|
|
1060
|
-
std::vector<std::string
|
|
1342
|
+
std::vector<std::string>& keys, std::vector<std::string>& values,
|
|
1061
1343
|
int num_record) {
|
|
1062
1344
|
BlockCreateContext create_context{
|
|
1063
1345
|
kTableOptions(), nullptr /* statistics */, nullptr /* ioptions */,
|
|
@@ -1090,9 +1372,9 @@ INSTANTIATE_TEST_CASE_P(
|
|
|
1090
1372
|
::testing::Values(0, 1, 2, 4, 8) /* protection_bytes_per_key */,
|
|
1091
1373
|
::testing::Values(1, 2, 3, 8, 16) /* restart_interval */,
|
|
1092
1374
|
::testing::Values(false, true)) /* delta_encoding */,
|
|
1093
|
-
[](const testing::TestParamInfo<
|
|
1094
|
-
|
|
1095
|
-
|
|
1375
|
+
[](const testing::TestParamInfo<
|
|
1376
|
+
std::tuple<BlockBasedTableOptions::DataBlockIndexType, uint8_t,
|
|
1377
|
+
uint32_t, bool>>& args) {
|
|
1096
1378
|
std::ostringstream oss;
|
|
1097
1379
|
oss << GetDataBlockIndexTypeStr(std::get<0>(args.param))
|
|
1098
1380
|
<< "ProtectionPerKey" << std::to_string(std::get<1>(args.param))
|
|
@@ -1115,7 +1397,7 @@ TEST_P(DataBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
|
1115
1397
|
std::unique_ptr<Block_kData> data_block =
|
|
1116
1398
|
GenerateDataBlock(keys, values, kNumRecords);
|
|
1117
1399
|
|
|
1118
|
-
const char
|
|
1400
|
+
const char* checksum_ptr = data_block->TEST_GetKVChecksum();
|
|
1119
1401
|
// Check checksum of correct length is generated
|
|
1120
1402
|
for (int i = 0; i < kNumRecords; i++) {
|
|
1121
1403
|
ASSERT_TRUE(VerifyChecksum(protection_bytes_per_key,
|
|
@@ -1133,8 +1415,8 @@ TEST_P(DataBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
|
1133
1415
|
// that case (see Block::VerifyChecksum()).
|
|
1134
1416
|
SyncPoint::GetInstance()->SetCallBack(
|
|
1135
1417
|
"Block::VerifyChecksum::checksum_len",
|
|
1136
|
-
[&verification_count, protection_bytes_per_key](void
|
|
1137
|
-
ASSERT_EQ((*static_cast<uint8_t
|
|
1418
|
+
[&verification_count, protection_bytes_per_key](void* checksum_len) {
|
|
1419
|
+
ASSERT_EQ((*static_cast<uint8_t*>(checksum_len)),
|
|
1138
1420
|
protection_bytes_per_key);
|
|
1139
1421
|
++verification_count;
|
|
1140
1422
|
});
|
|
@@ -1178,9 +1460,9 @@ class IndexBlockKVChecksumTest
|
|
|
1178
1460
|
bool IncludeFirstKey() const { return std::get<4>(GetParam()); }
|
|
1179
1461
|
|
|
1180
1462
|
std::unique_ptr<Block_kIndex> GenerateIndexBlock(
|
|
1181
|
-
std::vector<std::string
|
|
1182
|
-
std::vector<BlockHandle
|
|
1183
|
-
std::vector<std::string
|
|
1463
|
+
std::vector<std::string>& separators,
|
|
1464
|
+
std::vector<BlockHandle>& block_handles,
|
|
1465
|
+
std::vector<std::string>& first_keys, int num_record) {
|
|
1184
1466
|
Options options = Options();
|
|
1185
1467
|
uint8_t protection_bytes_per_key = GetChecksumLen();
|
|
1186
1468
|
BlockCreateContext create_context{
|
|
@@ -1236,7 +1518,7 @@ INSTANTIATE_TEST_CASE_P(
|
|
|
1236
1518
|
::testing::Values(true, false), ::testing::Values(true, false)),
|
|
1237
1519
|
[](const testing::TestParamInfo<
|
|
1238
1520
|
std::tuple<BlockBasedTableOptions::DataBlockIndexType, uint8_t,
|
|
1239
|
-
uint32_t, bool, bool
|
|
1521
|
+
uint32_t, bool, bool>>& args) {
|
|
1240
1522
|
std::ostringstream oss;
|
|
1241
1523
|
oss << GetDataBlockIndexTypeStr(std::get<0>(args.param)) << "ProtBytes"
|
|
1242
1524
|
<< std::to_string(std::get<1>(args.param)) << "RestartInterval"
|
|
@@ -1260,13 +1542,12 @@ TEST_P(IndexBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
|
1260
1542
|
std::vector<BlockHandle> block_handles;
|
|
1261
1543
|
std::vector<std::string> first_keys;
|
|
1262
1544
|
GenerateRandomIndexEntries(&separators, &block_handles, &first_keys,
|
|
1263
|
-
kNumRecords, 0 /* ts_sz
|
|
1264
|
-
seqno != kDisableGlobalSequenceNumber);
|
|
1545
|
+
kNumRecords, 0 /* ts_sz */);
|
|
1265
1546
|
SyncPoint::GetInstance()->DisableProcessing();
|
|
1266
1547
|
std::unique_ptr<Block_kIndex> index_block = GenerateIndexBlock(
|
|
1267
1548
|
separators, block_handles, first_keys, kNumRecords);
|
|
1268
|
-
IndexBlockIter
|
|
1269
|
-
Statistics
|
|
1549
|
+
IndexBlockIter* kNullIter = nullptr;
|
|
1550
|
+
Statistics* kNullStats = nullptr;
|
|
1270
1551
|
// read contents of block sequentially
|
|
1271
1552
|
std::unique_ptr<IndexBlockIter> biter{index_block->NewIndexIterator(
|
|
1272
1553
|
options.comparator, seqno, kNullIter, kNullStats,
|
|
@@ -1277,7 +1558,7 @@ TEST_P(IndexBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
|
1277
1558
|
true /* user_defined_timestamps_persisted */,
|
|
1278
1559
|
nullptr /* prefix_index */)};
|
|
1279
1560
|
biter->SeekToFirst();
|
|
1280
|
-
const char
|
|
1561
|
+
const char* checksum_ptr = index_block->TEST_GetKVChecksum();
|
|
1281
1562
|
// Check checksum of correct length is generated
|
|
1282
1563
|
for (int i = 0; i < kNumRecords; i++) {
|
|
1283
1564
|
// Obtaining the actual content written as value to index block is not
|
|
@@ -1297,8 +1578,8 @@ TEST_P(IndexBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
|
1297
1578
|
// assert checking on checksum_len here.
|
|
1298
1579
|
SyncPoint::GetInstance()->SetCallBack(
|
|
1299
1580
|
"Block::VerifyChecksum::checksum_len",
|
|
1300
|
-
[&verification_count, protection_bytes_per_key](void
|
|
1301
|
-
ASSERT_EQ((*static_cast<uint8_t
|
|
1581
|
+
[&verification_count, protection_bytes_per_key](void* checksum_len) {
|
|
1582
|
+
ASSERT_EQ((*static_cast<uint8_t*>(checksum_len)),
|
|
1302
1583
|
protection_bytes_per_key);
|
|
1303
1584
|
++verification_count;
|
|
1304
1585
|
});
|
|
@@ -1321,7 +1602,7 @@ class MetaIndexBlockKVChecksumTest
|
|
|
1321
1602
|
uint32_t GetRestartInterval() const { return 1; }
|
|
1322
1603
|
|
|
1323
1604
|
std::unique_ptr<Block_kMetaIndex> GenerateMetaIndexBlock(
|
|
1324
|
-
std::vector<std::string
|
|
1605
|
+
std::vector<std::string>& keys, std::vector<std::string>& values,
|
|
1325
1606
|
int num_record) {
|
|
1326
1607
|
Options options = Options();
|
|
1327
1608
|
uint8_t protection_bytes_per_key = GetChecksumLen();
|
|
@@ -1347,7 +1628,7 @@ class MetaIndexBlockKVChecksumTest
|
|
|
1347
1628
|
|
|
1348
1629
|
INSTANTIATE_TEST_CASE_P(P, MetaIndexBlockKVChecksumTest,
|
|
1349
1630
|
::testing::Values(0, 1, 2, 4, 8),
|
|
1350
|
-
[](const testing::TestParamInfo<uint8_t
|
|
1631
|
+
[](const testing::TestParamInfo<uint8_t>& args) {
|
|
1351
1632
|
std::ostringstream oss;
|
|
1352
1633
|
oss << "ProtBytes" << std::to_string(args.param);
|
|
1353
1634
|
return oss.str();
|
|
@@ -1369,7 +1650,7 @@ TEST_P(MetaIndexBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
|
1369
1650
|
SyncPoint::GetInstance()->DisableProcessing();
|
|
1370
1651
|
std::unique_ptr<Block_kMetaIndex> meta_block =
|
|
1371
1652
|
GenerateMetaIndexBlock(keys, values, kNumRecords);
|
|
1372
|
-
const char
|
|
1653
|
+
const char* checksum_ptr = meta_block->TEST_GetKVChecksum();
|
|
1373
1654
|
// Check checksum of correct length is generated
|
|
1374
1655
|
for (int i = 0; i < kNumRecords; i++) {
|
|
1375
1656
|
ASSERT_TRUE(VerifyChecksum(protection_bytes_per_key,
|
|
@@ -1384,8 +1665,8 @@ TEST_P(MetaIndexBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
|
1384
1665
|
// checking on checksum_len here.
|
|
1385
1666
|
SyncPoint::GetInstance()->SetCallBack(
|
|
1386
1667
|
"Block::VerifyChecksum::checksum_len",
|
|
1387
|
-
[&verification_count, protection_bytes_per_key](void
|
|
1388
|
-
ASSERT_EQ((*static_cast<uint8_t
|
|
1668
|
+
[&verification_count, protection_bytes_per_key](void* checksum_len) {
|
|
1669
|
+
ASSERT_EQ((*static_cast<uint8_t*>(checksum_len)),
|
|
1389
1670
|
protection_bytes_per_key);
|
|
1390
1671
|
++verification_count;
|
|
1391
1672
|
});
|
|
@@ -1405,7 +1686,7 @@ class DataBlockKVChecksumCorruptionTest : public DataBlockKVChecksumTest {
|
|
|
1405
1686
|
DataBlockKVChecksumCorruptionTest() = default;
|
|
1406
1687
|
|
|
1407
1688
|
std::unique_ptr<DataBlockIter> GenerateDataBlockIter(
|
|
1408
|
-
std::vector<std::string
|
|
1689
|
+
std::vector<std::string>& keys, std::vector<std::string>& values,
|
|
1409
1690
|
int num_record) {
|
|
1410
1691
|
// During Block construction, we may create block iter to initialize per kv
|
|
1411
1692
|
// checksum. Disable syncpoint that may be created for block iter methods.
|
|
@@ -1431,15 +1712,15 @@ TEST_P(DataBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
|
1431
1712
|
GenerateRandomKVs(&keys, &values, 0, kNumRecords + 1, 1 /* step */,
|
|
1432
1713
|
24 /* padding_size */);
|
|
1433
1714
|
SyncPoint::GetInstance()->SetCallBack(
|
|
1434
|
-
"BlockIter::UpdateKey::value", [](void
|
|
1435
|
-
char
|
|
1715
|
+
"BlockIter::UpdateKey::value", [](void* arg) {
|
|
1716
|
+
char* value = static_cast<char*>(arg);
|
|
1436
1717
|
// values generated by GenerateRandomKVs are of length 100
|
|
1437
1718
|
++value[10];
|
|
1438
1719
|
});
|
|
1439
1720
|
|
|
1440
1721
|
// Purely for reducing the number of lines of code.
|
|
1441
1722
|
typedef std::unique_ptr<DataBlockIter> IterPtr;
|
|
1442
|
-
typedef void(IterAPI)(IterPtr & iter, std::string
|
|
1723
|
+
typedef void(IterAPI)(IterPtr & iter, std::string&);
|
|
1443
1724
|
|
|
1444
1725
|
std::string seek_key = keys[kNumRecords / 2];
|
|
1445
1726
|
auto test_seek = [&](IterAPI iter_api) {
|
|
@@ -1450,14 +1731,14 @@ TEST_P(DataBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
|
1450
1731
|
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1451
1732
|
};
|
|
1452
1733
|
|
|
1453
|
-
test_seek([](IterPtr
|
|
1454
|
-
test_seek([](IterPtr
|
|
1455
|
-
test_seek([](IterPtr
|
|
1456
|
-
test_seek([](IterPtr
|
|
1457
|
-
test_seek([](IterPtr
|
|
1734
|
+
test_seek([](IterPtr& iter, std::string&) { iter->SeekToFirst(); });
|
|
1735
|
+
test_seek([](IterPtr& iter, std::string&) { iter->SeekToLast(); });
|
|
1736
|
+
test_seek([](IterPtr& iter, std::string& k) { iter->Seek(k); });
|
|
1737
|
+
test_seek([](IterPtr& iter, std::string& k) { iter->SeekForPrev(k); });
|
|
1738
|
+
test_seek([](IterPtr& iter, std::string& k) { iter->SeekForGet(k); });
|
|
1458
1739
|
|
|
1459
1740
|
typedef void (DataBlockIter::*IterStepAPI)();
|
|
1460
|
-
auto test_step = [&](IterStepAPI iter_api, std::string
|
|
1741
|
+
auto test_step = [&](IterStepAPI iter_api, std::string& k) {
|
|
1461
1742
|
IterPtr biter = GenerateDataBlockIter(keys, values, kNumRecords);
|
|
1462
1743
|
SyncPoint::GetInstance()->DisableProcessing();
|
|
1463
1744
|
biter->Seek(k);
|
|
@@ -1486,9 +1767,9 @@ INSTANTIATE_TEST_CASE_P(
|
|
|
1486
1767
|
::testing::Values(4, 8) /* block_protection_bytes_per_key */,
|
|
1487
1768
|
::testing::Values(1, 3, 8, 16) /* restart_interval */,
|
|
1488
1769
|
::testing::Values(false, true)),
|
|
1489
|
-
[](const testing::TestParamInfo<
|
|
1490
|
-
|
|
1491
|
-
|
|
1770
|
+
[](const testing::TestParamInfo<
|
|
1771
|
+
std::tuple<BlockBasedTableOptions::DataBlockIndexType, uint8_t,
|
|
1772
|
+
uint32_t, bool>>& args) {
|
|
1492
1773
|
std::ostringstream oss;
|
|
1493
1774
|
oss << GetDataBlockIndexTypeStr(std::get<0>(args.param)) << "ProtBytes"
|
|
1494
1775
|
<< std::to_string(std::get<1>(args.param)) << "RestartInterval"
|
|
@@ -1502,9 +1783,9 @@ class IndexBlockKVChecksumCorruptionTest : public IndexBlockKVChecksumTest {
|
|
|
1502
1783
|
IndexBlockKVChecksumCorruptionTest() = default;
|
|
1503
1784
|
|
|
1504
1785
|
std::unique_ptr<IndexBlockIter> GenerateIndexBlockIter(
|
|
1505
|
-
std::vector<std::string
|
|
1506
|
-
std::vector<BlockHandle
|
|
1507
|
-
std::vector<std::string
|
|
1786
|
+
std::vector<std::string>& separators,
|
|
1787
|
+
std::vector<BlockHandle>& block_handles,
|
|
1788
|
+
std::vector<std::string>& first_keys, int num_record,
|
|
1508
1789
|
SequenceNumber seqno) {
|
|
1509
1790
|
SyncPoint::GetInstance()->DisableProcessing();
|
|
1510
1791
|
block_ =
|
|
@@ -1537,7 +1818,7 @@ INSTANTIATE_TEST_CASE_P(
|
|
|
1537
1818
|
::testing::Values(true, false), ::testing::Values(true, false)),
|
|
1538
1819
|
[](const testing::TestParamInfo<
|
|
1539
1820
|
std::tuple<BlockBasedTableOptions::DataBlockIndexType, uint8_t,
|
|
1540
|
-
uint32_t, bool, bool
|
|
1821
|
+
uint32_t, bool, bool>>& args) {
|
|
1541
1822
|
std::ostringstream oss;
|
|
1542
1823
|
oss << GetDataBlockIndexTypeStr(std::get<0>(args.param)) << "ProtBytes"
|
|
1543
1824
|
<< std::to_string(std::get<1>(args.param)) << "RestartInterval"
|
|
@@ -1559,18 +1840,17 @@ TEST_P(IndexBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
|
1559
1840
|
std::vector<BlockHandle> block_handles;
|
|
1560
1841
|
std::vector<std::string> first_keys;
|
|
1561
1842
|
GenerateRandomIndexEntries(&separators, &block_handles, &first_keys,
|
|
1562
|
-
kNumRecords, 0 /* ts_sz
|
|
1563
|
-
seqno != kDisableGlobalSequenceNumber);
|
|
1843
|
+
kNumRecords, 0 /* ts_sz */);
|
|
1564
1844
|
SyncPoint::GetInstance()->SetCallBack(
|
|
1565
|
-
"BlockIter::UpdateKey::value", [](void
|
|
1566
|
-
char
|
|
1845
|
+
"BlockIter::UpdateKey::value", [](void* arg) {
|
|
1846
|
+
char* value = static_cast<char*>(arg);
|
|
1567
1847
|
// value can be delta-encoded with different lengths, so we corrupt
|
|
1568
1848
|
// first bytes here to be safe
|
|
1569
1849
|
++value[0];
|
|
1570
1850
|
});
|
|
1571
1851
|
|
|
1572
1852
|
typedef std::unique_ptr<IndexBlockIter> IterPtr;
|
|
1573
|
-
typedef void(IterAPI)(IterPtr & iter, std::string
|
|
1853
|
+
typedef void(IterAPI)(IterPtr & iter, std::string&);
|
|
1574
1854
|
std::string seek_key = first_keys[kNumRecords / 2];
|
|
1575
1855
|
auto test_seek = [&](IterAPI iter_api) {
|
|
1576
1856
|
std::unique_ptr<IndexBlockIter> biter = GenerateIndexBlockIter(
|
|
@@ -1580,12 +1860,12 @@ TEST_P(IndexBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
|
1580
1860
|
ASSERT_FALSE(biter->Valid());
|
|
1581
1861
|
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1582
1862
|
};
|
|
1583
|
-
test_seek([](IterPtr
|
|
1584
|
-
test_seek([](IterPtr
|
|
1585
|
-
test_seek([](IterPtr
|
|
1863
|
+
test_seek([](IterPtr& iter, std::string&) { iter->SeekToFirst(); });
|
|
1864
|
+
test_seek([](IterPtr& iter, std::string&) { iter->SeekToLast(); });
|
|
1865
|
+
test_seek([](IterPtr& iter, std::string& k) { iter->Seek(k); });
|
|
1586
1866
|
|
|
1587
1867
|
typedef void (IndexBlockIter::*IterStepAPI)();
|
|
1588
|
-
auto test_step = [&](IterStepAPI iter_api, std::string
|
|
1868
|
+
auto test_step = [&](IterStepAPI iter_api, std::string& k) {
|
|
1589
1869
|
std::unique_ptr<IndexBlockIter> biter = GenerateIndexBlockIter(
|
|
1590
1870
|
separators, block_handles, first_keys, kNumRecords, seqno);
|
|
1591
1871
|
SyncPoint::GetInstance()->DisableProcessing();
|
|
@@ -1611,7 +1891,7 @@ class MetaIndexBlockKVChecksumCorruptionTest
|
|
|
1611
1891
|
MetaIndexBlockKVChecksumCorruptionTest() = default;
|
|
1612
1892
|
|
|
1613
1893
|
std::unique_ptr<MetaBlockIter> GenerateMetaIndexBlockIter(
|
|
1614
|
-
std::vector<std::string
|
|
1894
|
+
std::vector<std::string>& keys, std::vector<std::string>& values,
|
|
1615
1895
|
int num_record) {
|
|
1616
1896
|
SyncPoint::GetInstance()->DisableProcessing();
|
|
1617
1897
|
block_ = GenerateMetaIndexBlock(keys, values, num_record);
|
|
@@ -1628,7 +1908,7 @@ class MetaIndexBlockKVChecksumCorruptionTest
|
|
|
1628
1908
|
INSTANTIATE_TEST_CASE_P(
|
|
1629
1909
|
P, MetaIndexBlockKVChecksumCorruptionTest,
|
|
1630
1910
|
::testing::Values(4, 8) /* block_protection_bytes_per_key */,
|
|
1631
|
-
[](const testing::TestParamInfo<uint8_t
|
|
1911
|
+
[](const testing::TestParamInfo<uint8_t>& args) {
|
|
1632
1912
|
std::ostringstream oss;
|
|
1633
1913
|
oss << "ProtBytes" << std::to_string(args.param);
|
|
1634
1914
|
return oss.str();
|
|
@@ -1645,14 +1925,14 @@ TEST_P(MetaIndexBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
|
1645
1925
|
GenerateRandomKVs(&keys, &values, 0, kNumRecords + 1, 1 /* step */,
|
|
1646
1926
|
24 /* padding_size */);
|
|
1647
1927
|
SyncPoint::GetInstance()->SetCallBack(
|
|
1648
|
-
"BlockIter::UpdateKey::value", [](void
|
|
1649
|
-
char
|
|
1928
|
+
"BlockIter::UpdateKey::value", [](void* arg) {
|
|
1929
|
+
char* value = static_cast<char*>(arg);
|
|
1650
1930
|
// values generated by GenerateRandomKVs are of length 100
|
|
1651
1931
|
++value[10];
|
|
1652
1932
|
});
|
|
1653
1933
|
|
|
1654
1934
|
typedef std::unique_ptr<MetaBlockIter> IterPtr;
|
|
1655
|
-
typedef void(IterAPI)(IterPtr & iter, std::string
|
|
1935
|
+
typedef void(IterAPI)(IterPtr & iter, std::string&);
|
|
1656
1936
|
typedef void (MetaBlockIter::*IterStepAPI)();
|
|
1657
1937
|
std::string seek_key = keys[kNumRecords / 2];
|
|
1658
1938
|
auto test_seek = [&](IterAPI iter_api) {
|
|
@@ -1663,12 +1943,12 @@ TEST_P(MetaIndexBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
|
1663
1943
|
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1664
1944
|
};
|
|
1665
1945
|
|
|
1666
|
-
test_seek([](IterPtr
|
|
1667
|
-
test_seek([](IterPtr
|
|
1668
|
-
test_seek([](IterPtr
|
|
1669
|
-
test_seek([](IterPtr
|
|
1946
|
+
test_seek([](IterPtr& iter, std::string&) { iter->SeekToFirst(); });
|
|
1947
|
+
test_seek([](IterPtr& iter, std::string&) { iter->SeekToLast(); });
|
|
1948
|
+
test_seek([](IterPtr& iter, std::string& k) { iter->Seek(k); });
|
|
1949
|
+
test_seek([](IterPtr& iter, std::string& k) { iter->SeekForPrev(k); });
|
|
1670
1950
|
|
|
1671
|
-
auto test_step = [&](IterStepAPI iter_api, const std::string
|
|
1951
|
+
auto test_step = [&](IterStepAPI iter_api, const std::string& k) {
|
|
1672
1952
|
IterPtr biter = GenerateMetaIndexBlockIter(keys, values, kNumRecords);
|
|
1673
1953
|
SyncPoint::GetInstance()->DisableProcessing();
|
|
1674
1954
|
biter->Seek(k);
|
|
@@ -1686,9 +1966,108 @@ TEST_P(MetaIndexBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
|
1686
1966
|
}
|
|
1687
1967
|
}
|
|
1688
1968
|
}
|
|
1969
|
+
|
|
1970
|
+
class MetaBlockEntryCorruptionTest : public testing::TestWithParam<bool> {
|
|
1971
|
+
public:
|
|
1972
|
+
bool useSeparatedKVStorage() const { return GetParam(); }
|
|
1973
|
+
|
|
1974
|
+
std::string BuildBlock() {
|
|
1975
|
+
BlockBuilder builder(1 /* restart_interval */,
|
|
1976
|
+
true /* use_delta_encoding */,
|
|
1977
|
+
false /* use_value_delta_encoding */,
|
|
1978
|
+
BlockBasedTableOptions::kDataBlockBinarySearch,
|
|
1979
|
+
0 /* data_block_hash_table_util_ratio */,
|
|
1980
|
+
0 /* ts_sz */, false /* persist_udt */,
|
|
1981
|
+
true /* is_user_key */, useSeparatedKVStorage());
|
|
1982
|
+
builder.Add("key001", "val01");
|
|
1983
|
+
builder.Add("key002", "val02");
|
|
1984
|
+
builder.Add("key003", "val03");
|
|
1985
|
+
builder.Add("key004", "val04");
|
|
1986
|
+
Slice raw = builder.Finish();
|
|
1987
|
+
return std::string(raw.data(), raw.size());
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
// Get the restart offset for a given restart index from the raw block data.
|
|
1991
|
+
uint32_t GetRestartOffset(const std::string& block_data, int restart_idx) {
|
|
1992
|
+
size_t footer_size = useSeparatedKVStorage() ? 8 : 4;
|
|
1993
|
+
uint32_t packed = DecodeFixed32(block_data.data() + block_data.size() - 4);
|
|
1994
|
+
uint32_t num_restarts = packed & DataBlockFooter::kMaxNumRestarts;
|
|
1995
|
+
size_t restarts_start =
|
|
1996
|
+
block_data.size() - footer_size - num_restarts * sizeof(uint32_t);
|
|
1997
|
+
return DecodeFixed32(block_data.data() + restarts_start +
|
|
1998
|
+
restart_idx * sizeof(uint32_t));
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
uint32_t GetKeyEnd(const std::string& block_data) {
|
|
2002
|
+
size_t footer_size = useSeparatedKVStorage() ? 8 : 4;
|
|
2003
|
+
uint32_t packed = DecodeFixed32(block_data.data() + block_data.size() - 4);
|
|
2004
|
+
uint32_t num_restarts = packed & DataBlockFooter::kMaxNumRestarts;
|
|
2005
|
+
uint32_t restarts_start = static_cast<uint32_t>(
|
|
2006
|
+
block_data.size() - footer_size - num_restarts * sizeof(uint32_t));
|
|
2007
|
+
if (useSeparatedKVStorage()) {
|
|
2008
|
+
// values_section_offset is stored as the 4 bytes before the packed word.
|
|
2009
|
+
return DecodeFixed32(block_data.data() + block_data.size() - 8);
|
|
2010
|
+
}
|
|
2011
|
+
return restarts_start;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
uint32_t GetValueEnd(const std::string& block_data) {
|
|
2015
|
+
size_t footer_size = useSeparatedKVStorage() ? 8 : 4;
|
|
2016
|
+
uint32_t packed = DecodeFixed32(block_data.data() + block_data.size() - 4);
|
|
2017
|
+
uint32_t num_restarts = packed & DataBlockFooter::kMaxNumRestarts;
|
|
2018
|
+
return static_cast<uint32_t>(block_data.size() - footer_size -
|
|
2019
|
+
num_restarts * sizeof(uint32_t));
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
|
|
2023
|
+
INSTANTIATE_TEST_CASE_P(P, MetaBlockEntryCorruptionTest, ::testing::Bool(),
|
|
2024
|
+
[](const testing::TestParamInfo<bool>& args) {
|
|
2025
|
+
return args.param ? "SeparatedKV" : "InlineKV";
|
|
2026
|
+
});
|
|
2027
|
+
|
|
2028
|
+
TEST_P(MetaBlockEntryCorruptionTest, CorruptedKeyLengthPastKeyEnd) {
|
|
2029
|
+
std::string block_data = BuildBlock();
|
|
2030
|
+
uint32_t key_end = GetKeyEnd(block_data);
|
|
2031
|
+
|
|
2032
|
+
// Corrupt the key length of the first entry so that
|
|
2033
|
+
// the key data would extend past the keys-end boundary.
|
|
2034
|
+
uint32_t first_entry_offset = GetRestartOffset(block_data, 0);
|
|
2035
|
+
block_data[first_entry_offset + 1] = static_cast<char>(key_end);
|
|
2036
|
+
|
|
2037
|
+
BlockContents contents;
|
|
2038
|
+
contents.data = Slice(block_data);
|
|
2039
|
+
Block block(std::move(contents), 0, nullptr, 1 /* restart_interval */);
|
|
2040
|
+
std::unique_ptr<MetaBlockIter> iter(block.NewMetaIterator());
|
|
2041
|
+
|
|
2042
|
+
// SeekToFirst should hit the corrupted first entry immediately.
|
|
2043
|
+
iter->SeekToFirst();
|
|
2044
|
+
ASSERT_FALSE(iter->Valid());
|
|
2045
|
+
ASSERT_TRUE(iter->status().IsCorruption());
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
TEST_P(MetaBlockEntryCorruptionTest, CorruptedValueLengthPastValueEnd) {
|
|
2049
|
+
std::string block_data = BuildBlock();
|
|
2050
|
+
uint32_t value_end = GetValueEnd(block_data);
|
|
2051
|
+
|
|
2052
|
+
// Corrupt the first entry so that its value would extend past the
|
|
2053
|
+
// values-end boundary (start of the restart array).
|
|
2054
|
+
uint32_t first_entry_offset = GetRestartOffset(block_data, 0);
|
|
2055
|
+
block_data[first_entry_offset + 2] = static_cast<char>(value_end);
|
|
2056
|
+
|
|
2057
|
+
BlockContents contents;
|
|
2058
|
+
contents.data = Slice(block_data);
|
|
2059
|
+
Block block(std::move(contents), 0, nullptr, 1 /* restart_interval */);
|
|
2060
|
+
std::unique_ptr<MetaBlockIter> iter(block.NewMetaIterator());
|
|
2061
|
+
|
|
2062
|
+
// SeekToFirst should hit the corrupted first entry immediately.
|
|
2063
|
+
iter->SeekToFirst();
|
|
2064
|
+
ASSERT_FALSE(iter->Valid());
|
|
2065
|
+
ASSERT_TRUE(iter->status().IsCorruption());
|
|
2066
|
+
}
|
|
2067
|
+
|
|
1689
2068
|
} // namespace ROCKSDB_NAMESPACE
|
|
1690
2069
|
|
|
1691
|
-
int main(int argc, char
|
|
2070
|
+
int main(int argc, char** argv) {
|
|
1692
2071
|
ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
|
|
1693
2072
|
::testing::InitGoogleTest(&argc, argv);
|
|
1694
2073
|
return RUN_ALL_TESTS();
|