@nxtedition/rocksdb 8.2.0 → 8.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.cc +3 -3
- package/deps/rocksdb/rocksdb/CMakeLists.txt +16 -52
- package/deps/rocksdb/rocksdb/Makefile +10 -5
- package/deps/rocksdb/rocksdb/TARGETS +8 -345
- package/deps/rocksdb/rocksdb/cache/cache_test.cc +92 -0
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +32 -32
- package/deps/rocksdb/rocksdb/cache/clock_cache.h +12 -9
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +6 -43
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +3 -13
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +8 -5
- package/deps/rocksdb/rocksdb/cache/lru_cache.cc +21 -47
- package/deps/rocksdb/rocksdb/cache/lru_cache.h +3 -8
- package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +2 -1
- package/deps/rocksdb/rocksdb/cache/secondary_cache_adapter.cc +1 -2
- package/deps/rocksdb/rocksdb/cache/sharded_cache.cc +44 -7
- package/deps/rocksdb/rocksdb/cache/sharded_cache.h +13 -14
- package/deps/rocksdb/rocksdb/db/blob/blob_contents.h +1 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +1 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.cc +2 -2
- package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.h +2 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_cache_test.cc +17 -8
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +40 -21
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.h +5 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +41 -42
- package/deps/rocksdb/rocksdb/db/blob/blob_log_sequential_reader.cc +1 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_log_writer.cc +1 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +5 -4
- package/deps/rocksdb/rocksdb/db/blob/blob_source.h +2 -2
- package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +5 -3
- package/deps/rocksdb/rocksdb/db/builder.cc +7 -6
- package/deps/rocksdb/rocksdb/db/builder.h +2 -2
- package/deps/rocksdb/rocksdb/db/c.cc +76 -5
- package/deps/rocksdb/rocksdb/db/c_test.c +141 -0
- package/deps/rocksdb/rocksdb/db/column_family.cc +32 -0
- package/deps/rocksdb/rocksdb/db/compact_files_test.cc +3 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +5 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction.h +8 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +12 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +21 -17
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_stats_test.cc +2 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +8 -7
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +3 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +1 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +77 -50
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +4 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +55 -8
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +142 -56
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +1 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +1 -2
- package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +21 -20
- package/deps/rocksdb/rocksdb/db/convenience.cc +8 -6
- package/deps/rocksdb/rocksdb/db/corruption_test.cc +5 -4
- package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +6 -3
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +260 -220
- package/deps/rocksdb/rocksdb/db/db_clip_test.cc +142 -0
- package/deps/rocksdb/rocksdb/db/db_compaction_filter_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +333 -27
- package/deps/rocksdb/rocksdb/db/db_impl/compacted_db_impl.cc +5 -0
- package/deps/rocksdb/rocksdb/db/db_impl/compacted_db_impl.h +7 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +189 -27
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +23 -10
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +134 -90
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +2 -2
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +5 -3
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +5 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +124 -16
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +10 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.h +7 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +15 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +11 -5
- package/deps/rocksdb/rocksdb/db/db_iter.cc +7 -8
- package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +54 -3
- package/deps/rocksdb/rocksdb/db/db_merge_operator_test.cc +42 -0
- package/deps/rocksdb/rocksdb/db/db_options_test.cc +116 -1
- package/deps/rocksdb/rocksdb/db/db_properties_test.cc +3 -2
- package/deps/rocksdb/rocksdb/db/db_rate_limiter_test.cc +3 -2
- package/deps/rocksdb/rocksdb/db/db_sst_test.cc +9 -8
- package/deps/rocksdb/rocksdb/db/db_statistics_test.cc +142 -63
- package/deps/rocksdb/rocksdb/db/db_test.cc +28 -7
- package/deps/rocksdb/rocksdb/db/db_test2.cc +71 -131
- package/deps/rocksdb/rocksdb/db/db_test_util.cc +18 -0
- package/deps/rocksdb/rocksdb/db/db_test_util.h +6 -0
- package/deps/rocksdb/rocksdb/db/db_universal_compaction_test.cc +10 -10
- package/deps/rocksdb/rocksdb/db/db_wal_test.cc +25 -0
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +88 -0
- package/deps/rocksdb/rocksdb/db/db_write_buffer_manager_test.cc +67 -0
- package/deps/rocksdb/rocksdb/db/db_write_test.cc +5 -0
- package/deps/rocksdb/rocksdb/db/error_handler_fs_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/experimental.cc +4 -2
- package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +86 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +15 -2
- package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +1 -2
- package/deps/rocksdb/rocksdb/db/flush_job.cc +21 -14
- package/deps/rocksdb/rocksdb/db/forward_iterator.cc +14 -7
- package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +31 -8
- package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +21 -19
- package/deps/rocksdb/rocksdb/db/internal_stats.cc +42 -12
- package/deps/rocksdb/rocksdb/db/internal_stats.h +1 -0
- package/deps/rocksdb/rocksdb/db/kv_checksum.h +92 -6
- package/deps/rocksdb/rocksdb/db/listener_test.cc +2 -2
- package/deps/rocksdb/rocksdb/db/log_format.h +8 -4
- package/deps/rocksdb/rocksdb/db/log_reader.cc +129 -51
- package/deps/rocksdb/rocksdb/db/log_reader.h +16 -0
- package/deps/rocksdb/rocksdb/db/log_test.cc +125 -4
- package/deps/rocksdb/rocksdb/db/log_writer.cc +32 -2
- package/deps/rocksdb/rocksdb/db/log_writer.h +16 -0
- package/deps/rocksdb/rocksdb/db/memtable.cc +17 -46
- package/deps/rocksdb/rocksdb/db/memtable.h +1 -1
- package/deps/rocksdb/rocksdb/db/memtable_list.cc +8 -4
- package/deps/rocksdb/rocksdb/db/merge_helper.cc +1 -1
- package/deps/rocksdb/rocksdb/db/perf_context_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +5 -4
- package/deps/rocksdb/rocksdb/db/repair.cc +38 -11
- package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +3 -3
- package/deps/rocksdb/rocksdb/db/table_cache.cc +68 -51
- package/deps/rocksdb/rocksdb/db/table_cache.h +20 -10
- package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +2 -1
- package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +6 -3
- package/deps/rocksdb/rocksdb/db/version_builder.cc +9 -5
- package/deps/rocksdb/rocksdb/db/version_builder.h +2 -1
- package/deps/rocksdb/rocksdb/db/version_builder_test.cc +140 -120
- package/deps/rocksdb/rocksdb/db/version_edit.cc +14 -0
- package/deps/rocksdb/rocksdb/db/version_edit.h +12 -4
- package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +21 -13
- package/deps/rocksdb/rocksdb/db/version_edit_handler.h +26 -16
- package/deps/rocksdb/rocksdb/db/version_edit_test.cc +9 -9
- package/deps/rocksdb/rocksdb/db/version_set.cc +292 -96
- package/deps/rocksdb/rocksdb/db/version_set.h +53 -28
- package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -0
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +62 -22
- package/deps/rocksdb/rocksdb/db/version_util.h +5 -4
- package/deps/rocksdb/rocksdb/db/write_batch.cc +3 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/CMakeLists.txt +1 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +119 -27
- package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +123 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +4 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +7 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_env_wrapper.h +34 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +13 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +43 -33
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +29 -17
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +5 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +6 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.cc +85 -50
- package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.h +96 -54
- package/deps/rocksdb/rocksdb/db_stress_tool/expected_value.cc +122 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/expected_value.h +206 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +9 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.h +9 -3
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +322 -92
- package/deps/rocksdb/rocksdb/env/env_posix.cc +12 -8
- package/deps/rocksdb/rocksdb/env/env_test.cc +31 -0
- package/deps/rocksdb/rocksdb/env/mock_env.cc +1 -1
- package/deps/rocksdb/rocksdb/env/unique_id_gen.h +14 -0
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +1 -1
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +5 -1
- package/deps/rocksdb/rocksdb/file/file_util.cc +3 -3
- package/deps/rocksdb/rocksdb/file/file_util.h +2 -0
- package/deps/rocksdb/rocksdb/file/prefetch_test.cc +89 -0
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +22 -7
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +3 -2
- package/deps/rocksdb/rocksdb/file/readahead_raf.cc +1 -1
- package/deps/rocksdb/rocksdb/file/sequence_file_reader.cc +1 -1
- package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_cache.h +3 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +154 -74
- package/deps/rocksdb/rocksdb/include/rocksdb/c.h +27 -7
- package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +107 -28
- package/deps/rocksdb/rocksdb/include/rocksdb/db.h +19 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/env.h +8 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +2 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/memory_allocator.h +7 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +137 -152
- package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +61 -26
- package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +30 -26
- package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +33 -16
- package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +87 -8
- package/deps/rocksdb/rocksdb/include/rocksdb/table.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +1 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_util.h +1 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +7 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction.h +0 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/write_buffer_manager.h +9 -2
- package/deps/rocksdb/rocksdb/logging/env_logger.h +2 -0
- package/deps/rocksdb/rocksdb/memory/jemalloc_nodump_allocator.cc +78 -42
- package/deps/rocksdb/rocksdb/memory/jemalloc_nodump_allocator.h +14 -9
- 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.cc +4 -9
- package/deps/rocksdb/rocksdb/microbench/db_basic_bench.cc +19 -11
- package/deps/rocksdb/rocksdb/monitoring/instrumented_mutex.h +1 -1
- package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +211 -555
- package/deps/rocksdb/rocksdb/monitoring/perf_step_timer.h +1 -1
- package/deps/rocksdb/rocksdb/monitoring/statistics.cc +36 -2
- package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.cc +17 -7
- package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.h +10 -7
- package/deps/rocksdb/rocksdb/monitoring/thread_status_util.cc +19 -18
- package/deps/rocksdb/rocksdb/monitoring/thread_status_util.h +10 -2
- package/deps/rocksdb/rocksdb/monitoring/thread_status_util_debug.cc +14 -0
- package/deps/rocksdb/rocksdb/options/cf_options.cc +35 -2
- package/deps/rocksdb/rocksdb/options/cf_options.h +5 -0
- package/deps/rocksdb/rocksdb/options/customizable_test.cc +1 -1
- package/deps/rocksdb/rocksdb/options/options.cc +12 -53
- package/deps/rocksdb/rocksdb/options/options_helper.cc +4 -0
- package/deps/rocksdb/rocksdb/options/options_parser.cc +11 -0
- package/deps/rocksdb/rocksdb/options/options_settable_test.cc +32 -4
- package/deps/rocksdb/rocksdb/options/options_test.cc +89 -5
- package/deps/rocksdb/rocksdb/port/lang.h +27 -0
- package/deps/rocksdb/rocksdb/port/stack_trace.cc +67 -24
- package/deps/rocksdb/rocksdb/src.mk +2 -0
- package/deps/rocksdb/rocksdb/table/block_based/binary_search_index_reader.cc +2 -3
- package/deps/rocksdb/rocksdb/table/block_based/block.cc +195 -35
- package/deps/rocksdb/rocksdb/table/block_based/block.h +197 -24
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +71 -51
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +7 -1
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +4 -6
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +3 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +43 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +36 -6
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +266 -166
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +44 -14
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +63 -56
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +8 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_builder.h +4 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_cache.cc +10 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_cache.h +14 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_test.cc +918 -2
- package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +3 -2
- package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +10 -9
- package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +6 -8
- package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.h +2 -2
- package/deps/rocksdb/rocksdb/table/block_based/flush_block_policy.cc +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +18 -23
- package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +8 -8
- package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +16 -32
- package/deps/rocksdb/rocksdb/table/block_based/hash_index_reader.cc +7 -8
- package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.cc +4 -5
- package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.h +3 -3
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +46 -53
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +12 -12
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +7 -9
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.cc +26 -23
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.h +2 -1
- package/deps/rocksdb/rocksdb/table/block_based/reader_common.h +3 -0
- package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.cc +4 -2
- package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.h +3 -2
- package/deps/rocksdb/rocksdb/table/block_fetcher.cc +7 -1
- package/deps/rocksdb/rocksdb/table/block_fetcher.h +1 -1
- package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +2 -1
- package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder_test.cc +3 -2
- package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader.cc +5 -2
- package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader.h +4 -2
- package/deps/rocksdb/rocksdb/table/format.cc +4 -4
- package/deps/rocksdb/rocksdb/table/format.h +1 -1
- package/deps/rocksdb/rocksdb/table/get_context.cc +1 -1
- package/deps/rocksdb/rocksdb/table/meta_blocks.cc +33 -22
- package/deps/rocksdb/rocksdb/table/meta_blocks.h +4 -0
- package/deps/rocksdb/rocksdb/table/mock_table.cc +4 -2
- package/deps/rocksdb/rocksdb/table/persistent_cache_helper.h +1 -1
- package/deps/rocksdb/rocksdb/table/persistent_cache_options.h +1 -1
- package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.cc +18 -10
- package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.h +4 -3
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +10 -7
- package/deps/rocksdb/rocksdb/table/sst_file_reader.cc +4 -2
- package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +11 -0
- package/deps/rocksdb/rocksdb/table/table_builder.h +14 -5
- package/deps/rocksdb/rocksdb/table/table_properties.cc +2 -0
- package/deps/rocksdb/rocksdb/table/table_reader.h +6 -3
- package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +1 -1
- package/deps/rocksdb/rocksdb/table/table_test.cc +291 -34
- package/deps/rocksdb/rocksdb/test_util/secondary_cache_test_util.h +3 -1
- package/deps/rocksdb/rocksdb/test_util/testharness.h +5 -0
- package/deps/rocksdb/rocksdb/test_util/testutil.cc +2 -2
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +33 -17
- package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +3 -1
- package/deps/rocksdb/rocksdb/util/bloom_impl.h +2 -2
- package/deps/rocksdb/rocksdb/util/compression.h +1 -1
- package/deps/rocksdb/rocksdb/util/crc32c.cc +24 -83
- package/deps/rocksdb/rocksdb/util/crc32c_arm64.cc +7 -9
- package/deps/rocksdb/rocksdb/util/file_checksum_helper.cc +4 -1
- package/deps/rocksdb/rocksdb/util/filter_bench.cc +1 -1
- package/deps/rocksdb/rocksdb/util/gflags_compat.h +9 -10
- package/deps/rocksdb/rocksdb/util/math.h +12 -7
- package/deps/rocksdb/rocksdb/util/rate_limiter.cc +16 -18
- package/deps/rocksdb/rocksdb/util/rate_limiter_test.cc +46 -2
- package/deps/rocksdb/rocksdb/util/ribbon_test.cc +6 -6
- package/deps/rocksdb/rocksdb/util/slice_transform_test.cc +12 -7
- package/deps/rocksdb/rocksdb/util/stop_watch.h +31 -13
- package/deps/rocksdb/rocksdb/util/thread_list_test.cc +2 -0
- package/deps/rocksdb/rocksdb/util/thread_operation.h +2 -1
- package/deps/rocksdb/rocksdb/util/udt_util.h +77 -0
- package/deps/rocksdb/rocksdb/utilities/agg_merge/agg_merge.cc +2 -2
- package/deps/rocksdb/rocksdb/utilities/agg_merge/agg_merge_test.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/agg_merge/test_agg_merge.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.h +1 -1
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.cc +11 -1
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +34 -1
- package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +15 -0
- package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +5 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +29 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +0 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +0 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +6 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.cc +10 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn.cc +6 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn_db.cc +5 -0
- package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.cc +5 -0
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
- /package/deps/rocksdb/rocksdb/memory/{memory_allocator.h → memory_allocator_impl.h} +0 -0
- /package/deps/rocksdb/rocksdb/monitoring/{statistics.h → statistics_impl.h} +0 -0
- /package/deps/rocksdb/rocksdb/table/block_based/{flush_block_policy.h → flush_block_policy_impl.h} +0 -0
- /package/deps/rocksdb/rocksdb/util/{rate_limiter.h → rate_limiter_impl.h} +0 -0
- /package/deps/rocksdb/rocksdb/utilities/agg_merge/{agg_merge.h → agg_merge_impl.h} +0 -0
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#include <utility>
|
|
16
16
|
#include <vector>
|
|
17
17
|
|
|
18
|
+
#include "db/db_test_util.h"
|
|
18
19
|
#include "db/dbformat.h"
|
|
19
20
|
#include "db/memtable.h"
|
|
20
21
|
#include "db/write_batch_internal.h"
|
|
@@ -506,7 +507,7 @@ class IndexBlockTest
|
|
|
506
507
|
void GenerateRandomIndexEntries(std::vector<std::string> *separators,
|
|
507
508
|
std::vector<BlockHandle> *block_handles,
|
|
508
509
|
std::vector<std::string> *first_keys,
|
|
509
|
-
const int len) {
|
|
510
|
+
const int len, bool zero_seqno = false) {
|
|
510
511
|
Random rnd(42);
|
|
511
512
|
|
|
512
513
|
// For each of `len` blocks, we need to generate a first and last key.
|
|
@@ -514,7 +515,11 @@ void GenerateRandomIndexEntries(std::vector<std::string> *separators,
|
|
|
514
515
|
std::set<std::string> keys;
|
|
515
516
|
while ((int)keys.size() < len * 2) {
|
|
516
517
|
// Keys need to be at least 8 bytes long to look like internal keys.
|
|
517
|
-
|
|
518
|
+
std::string new_key = test::RandomKey(&rnd, 12);
|
|
519
|
+
if (zero_seqno) {
|
|
520
|
+
AppendInternalKeyFooter(&new_key, 0 /* seqno */, kTypeValue);
|
|
521
|
+
}
|
|
522
|
+
keys.insert(std::move(new_key));
|
|
518
523
|
}
|
|
519
524
|
|
|
520
525
|
uint64_t offset = 0;
|
|
@@ -618,6 +623,917 @@ INSTANTIATE_TEST_CASE_P(P, IndexBlockTest,
|
|
|
618
623
|
std::make_tuple(true, false),
|
|
619
624
|
std::make_tuple(true, true)));
|
|
620
625
|
|
|
626
|
+
class BlockPerKVChecksumTest : public DBTestBase {
|
|
627
|
+
public:
|
|
628
|
+
BlockPerKVChecksumTest()
|
|
629
|
+
: DBTestBase("block_per_kv_checksum", /*env_do_fsync=*/false) {}
|
|
630
|
+
|
|
631
|
+
template <typename TBlockIter>
|
|
632
|
+
void TestIterateForward(std::unique_ptr<TBlockIter> &biter,
|
|
633
|
+
size_t &verification_count) {
|
|
634
|
+
while (biter->Valid()) {
|
|
635
|
+
verification_count = 0;
|
|
636
|
+
biter->Next();
|
|
637
|
+
if (biter->Valid()) {
|
|
638
|
+
ASSERT_GE(verification_count, 1);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
template <typename TBlockIter>
|
|
644
|
+
void TestIterateBackward(std::unique_ptr<TBlockIter> &biter,
|
|
645
|
+
size_t &verification_count) {
|
|
646
|
+
while (biter->Valid()) {
|
|
647
|
+
verification_count = 0;
|
|
648
|
+
biter->Prev();
|
|
649
|
+
if (biter->Valid()) {
|
|
650
|
+
ASSERT_GE(verification_count, 1);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
template <typename TBlockIter>
|
|
656
|
+
void TestSeekToFirst(std::unique_ptr<TBlockIter> &biter,
|
|
657
|
+
size_t &verification_count) {
|
|
658
|
+
verification_count = 0;
|
|
659
|
+
biter->SeekToFirst();
|
|
660
|
+
ASSERT_GE(verification_count, 1);
|
|
661
|
+
TestIterateForward(biter, verification_count);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
template <typename TBlockIter>
|
|
665
|
+
void TestSeekToLast(std::unique_ptr<TBlockIter> &biter,
|
|
666
|
+
size_t &verification_count) {
|
|
667
|
+
verification_count = 0;
|
|
668
|
+
biter->SeekToLast();
|
|
669
|
+
ASSERT_GE(verification_count, 1);
|
|
670
|
+
TestIterateBackward(biter, verification_count);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
template <typename TBlockIter>
|
|
674
|
+
void TestSeekForPrev(std::unique_ptr<TBlockIter> &biter,
|
|
675
|
+
size_t &verification_count, std::string k) {
|
|
676
|
+
verification_count = 0;
|
|
677
|
+
biter->SeekForPrev(k);
|
|
678
|
+
ASSERT_GE(verification_count, 1);
|
|
679
|
+
TestIterateBackward(biter, verification_count);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
template <typename TBlockIter>
|
|
683
|
+
void TestSeek(std::unique_ptr<TBlockIter> &biter, size_t &verification_count,
|
|
684
|
+
std::string k) {
|
|
685
|
+
verification_count = 0;
|
|
686
|
+
biter->Seek(k);
|
|
687
|
+
ASSERT_GE(verification_count, 1);
|
|
688
|
+
TestIterateForward(biter, verification_count);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
bool VerifyChecksum(uint32_t checksum_len, const char *checksum_ptr,
|
|
692
|
+
const Slice &key, const Slice &val) {
|
|
693
|
+
if (!checksum_len) {
|
|
694
|
+
return checksum_ptr == nullptr;
|
|
695
|
+
}
|
|
696
|
+
return ProtectionInfo64().ProtectKV(key, val).Verify(
|
|
697
|
+
static_cast<uint8_t>(checksum_len), checksum_ptr);
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
TEST_F(BlockPerKVChecksumTest, EmptyBlock) {
|
|
702
|
+
// Tests that empty block code path is not broken by per kv checksum.
|
|
703
|
+
BlockBuilder builder(
|
|
704
|
+
16 /* block_restart_interval */, true /* use_delta_encoding */,
|
|
705
|
+
false /* use_value_delta_encoding */,
|
|
706
|
+
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch);
|
|
707
|
+
Slice raw_block = builder.Finish();
|
|
708
|
+
BlockContents contents;
|
|
709
|
+
contents.data = raw_block;
|
|
710
|
+
|
|
711
|
+
std::unique_ptr<Block_kData> data_block;
|
|
712
|
+
Options options = Options();
|
|
713
|
+
BlockBasedTableOptions tbo;
|
|
714
|
+
uint8_t protection_bytes_per_key = 8;
|
|
715
|
+
BlockCreateContext create_context{
|
|
716
|
+
&tbo, nullptr /* statistics */, false /* using_zstd */,
|
|
717
|
+
protection_bytes_per_key, options.comparator};
|
|
718
|
+
create_context.Create(&data_block, std::move(contents));
|
|
719
|
+
std::unique_ptr<DataBlockIter> biter{data_block->NewDataIterator(
|
|
720
|
+
options.comparator, kDisableGlobalSequenceNumber)};
|
|
721
|
+
biter->SeekToFirst();
|
|
722
|
+
ASSERT_FALSE(biter->Valid());
|
|
723
|
+
ASSERT_OK(biter->status());
|
|
724
|
+
Random rnd(33);
|
|
725
|
+
biter->SeekForGet(GenerateInternalKey(1, 1, 10, &rnd));
|
|
726
|
+
ASSERT_FALSE(biter->Valid());
|
|
727
|
+
ASSERT_OK(biter->status());
|
|
728
|
+
biter->SeekToLast();
|
|
729
|
+
ASSERT_FALSE(biter->Valid());
|
|
730
|
+
ASSERT_OK(biter->status());
|
|
731
|
+
biter->Seek(GenerateInternalKey(1, 1, 10, &rnd));
|
|
732
|
+
ASSERT_FALSE(biter->Valid());
|
|
733
|
+
ASSERT_OK(biter->status());
|
|
734
|
+
biter->SeekForPrev(GenerateInternalKey(1, 1, 10, &rnd));
|
|
735
|
+
ASSERT_FALSE(biter->Valid());
|
|
736
|
+
ASSERT_OK(biter->status());
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
TEST_F(BlockPerKVChecksumTest, UnsupportedOptionValue) {
|
|
740
|
+
Options options = Options();
|
|
741
|
+
options.block_protection_bytes_per_key = 128;
|
|
742
|
+
Destroy(options);
|
|
743
|
+
ASSERT_TRUE(TryReopen(options).IsNotSupported());
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
TEST_F(BlockPerKVChecksumTest, InitializeProtectionInfo) {
|
|
747
|
+
// Make sure that the checksum construction code path does not break
|
|
748
|
+
// when the block is itself already corrupted.
|
|
749
|
+
Options options = Options();
|
|
750
|
+
BlockBasedTableOptions tbo;
|
|
751
|
+
uint8_t protection_bytes_per_key = 8;
|
|
752
|
+
BlockCreateContext create_context{
|
|
753
|
+
&tbo, nullptr /* statistics */, false /* using_zstd */,
|
|
754
|
+
protection_bytes_per_key, options.comparator};
|
|
755
|
+
|
|
756
|
+
{
|
|
757
|
+
std::string invalid_content = "1";
|
|
758
|
+
Slice raw_block = invalid_content;
|
|
759
|
+
BlockContents contents;
|
|
760
|
+
contents.data = raw_block;
|
|
761
|
+
std::unique_ptr<Block_kData> data_block;
|
|
762
|
+
create_context.Create(&data_block, std::move(contents));
|
|
763
|
+
std::unique_ptr<DataBlockIter> iter{data_block->NewDataIterator(
|
|
764
|
+
options.comparator, kDisableGlobalSequenceNumber)};
|
|
765
|
+
ASSERT_TRUE(iter->status().IsCorruption());
|
|
766
|
+
}
|
|
767
|
+
{
|
|
768
|
+
std::string invalid_content = "1";
|
|
769
|
+
Slice raw_block = invalid_content;
|
|
770
|
+
BlockContents contents;
|
|
771
|
+
contents.data = raw_block;
|
|
772
|
+
std::unique_ptr<Block_kIndex> index_block;
|
|
773
|
+
create_context.Create(&index_block, std::move(contents));
|
|
774
|
+
std::unique_ptr<IndexBlockIter> iter{index_block->NewIndexIterator(
|
|
775
|
+
options.comparator, kDisableGlobalSequenceNumber, nullptr, nullptr,
|
|
776
|
+
true, false, true, true)};
|
|
777
|
+
ASSERT_TRUE(iter->status().IsCorruption());
|
|
778
|
+
}
|
|
779
|
+
{
|
|
780
|
+
std::string invalid_content = "1";
|
|
781
|
+
Slice raw_block = invalid_content;
|
|
782
|
+
BlockContents contents;
|
|
783
|
+
contents.data = raw_block;
|
|
784
|
+
std::unique_ptr<Block_kMetaIndex> meta_block;
|
|
785
|
+
create_context.Create(&meta_block, std::move(contents));
|
|
786
|
+
std::unique_ptr<MetaBlockIter> iter{meta_block->NewMetaIterator(true)};
|
|
787
|
+
ASSERT_TRUE(iter->status().IsCorruption());
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
TEST_F(BlockPerKVChecksumTest, ApproximateMemory) {
|
|
792
|
+
// Tests that ApproximateMemoryUsage() includes memory used by block kv
|
|
793
|
+
// checksum.
|
|
794
|
+
const int kNumRecords = 20;
|
|
795
|
+
std::vector<std::string> keys;
|
|
796
|
+
std::vector<std::string> values;
|
|
797
|
+
GenerateRandomKVs(&keys, &values, 0, kNumRecords, 1 /* step */,
|
|
798
|
+
24 /* padding_size */);
|
|
799
|
+
std::unique_ptr<BlockBuilder> builder;
|
|
800
|
+
auto generate_block_content = [&]() {
|
|
801
|
+
builder = std::make_unique<BlockBuilder>(16 /* restart_interval */);
|
|
802
|
+
for (int i = 0; i < kNumRecords; ++i) {
|
|
803
|
+
builder->Add(keys[i], values[i]);
|
|
804
|
+
}
|
|
805
|
+
Slice raw_block = builder->Finish();
|
|
806
|
+
BlockContents contents;
|
|
807
|
+
contents.data = raw_block;
|
|
808
|
+
return contents;
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
Options options = Options();
|
|
812
|
+
BlockBasedTableOptions tbo;
|
|
813
|
+
uint8_t protection_bytes_per_key = 8;
|
|
814
|
+
BlockCreateContext with_checksum_create_context{
|
|
815
|
+
&tbo,
|
|
816
|
+
nullptr /* statistics */,
|
|
817
|
+
false /* using_zstd */,
|
|
818
|
+
protection_bytes_per_key,
|
|
819
|
+
options.comparator,
|
|
820
|
+
true /* index_value_is_full */};
|
|
821
|
+
BlockCreateContext create_context{
|
|
822
|
+
&tbo, nullptr /* statistics */, false /* using_zstd */,
|
|
823
|
+
0, options.comparator, true /* index_value_is_full */};
|
|
824
|
+
|
|
825
|
+
{
|
|
826
|
+
std::unique_ptr<Block_kData> data_block;
|
|
827
|
+
create_context.Create(&data_block, generate_block_content());
|
|
828
|
+
size_t block_memory = data_block->ApproximateMemoryUsage();
|
|
829
|
+
std::unique_ptr<Block_kData> with_checksum_data_block;
|
|
830
|
+
with_checksum_create_context.Create(&with_checksum_data_block,
|
|
831
|
+
generate_block_content());
|
|
832
|
+
ASSERT_GT(with_checksum_data_block->ApproximateMemoryUsage() - block_memory,
|
|
833
|
+
100);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
{
|
|
837
|
+
std::unique_ptr<Block_kData> meta_block;
|
|
838
|
+
create_context.Create(&meta_block, generate_block_content());
|
|
839
|
+
size_t block_memory = meta_block->ApproximateMemoryUsage();
|
|
840
|
+
std::unique_ptr<Block_kData> with_checksum_meta_block;
|
|
841
|
+
with_checksum_create_context.Create(&with_checksum_meta_block,
|
|
842
|
+
generate_block_content());
|
|
843
|
+
// Rough comparison to avoid flaky test due to memory allocation alignment.
|
|
844
|
+
ASSERT_GT(with_checksum_meta_block->ApproximateMemoryUsage() - block_memory,
|
|
845
|
+
100);
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
{
|
|
849
|
+
// Index block has different contents.
|
|
850
|
+
std::vector<std::string> separators;
|
|
851
|
+
std::vector<BlockHandle> block_handles;
|
|
852
|
+
std::vector<std::string> first_keys;
|
|
853
|
+
GenerateRandomIndexEntries(&separators, &block_handles, &first_keys,
|
|
854
|
+
kNumRecords);
|
|
855
|
+
auto generate_index_content = [&]() {
|
|
856
|
+
builder = std::make_unique<BlockBuilder>(16 /* restart_interval */);
|
|
857
|
+
BlockHandle last_encoded_handle;
|
|
858
|
+
for (int i = 0; i < kNumRecords; ++i) {
|
|
859
|
+
IndexValue entry(block_handles[i], first_keys[i]);
|
|
860
|
+
std::string encoded_entry;
|
|
861
|
+
std::string delta_encoded_entry;
|
|
862
|
+
entry.EncodeTo(&encoded_entry, false, nullptr);
|
|
863
|
+
last_encoded_handle = entry.handle;
|
|
864
|
+
const Slice delta_encoded_entry_slice(delta_encoded_entry);
|
|
865
|
+
builder->Add(separators[i], encoded_entry, &delta_encoded_entry_slice);
|
|
866
|
+
}
|
|
867
|
+
Slice raw_block = builder->Finish();
|
|
868
|
+
BlockContents contents;
|
|
869
|
+
contents.data = raw_block;
|
|
870
|
+
return contents;
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
std::unique_ptr<Block_kIndex> index_block;
|
|
874
|
+
create_context.Create(&index_block, generate_index_content());
|
|
875
|
+
size_t block_memory = index_block->ApproximateMemoryUsage();
|
|
876
|
+
std::unique_ptr<Block_kIndex> with_checksum_index_block;
|
|
877
|
+
with_checksum_create_context.Create(&with_checksum_index_block,
|
|
878
|
+
generate_index_content());
|
|
879
|
+
ASSERT_GT(
|
|
880
|
+
with_checksum_index_block->ApproximateMemoryUsage() - block_memory,
|
|
881
|
+
100);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
std::string GetDataBlockIndexTypeStr(
|
|
886
|
+
BlockBasedTableOptions::DataBlockIndexType t) {
|
|
887
|
+
return t == BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch
|
|
888
|
+
? "BinarySearch"
|
|
889
|
+
: "BinaryAndHash";
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
class DataBlockKVChecksumTest
|
|
893
|
+
: public BlockPerKVChecksumTest,
|
|
894
|
+
public testing::WithParamInterface<std::tuple<
|
|
895
|
+
BlockBasedTableOptions::DataBlockIndexType,
|
|
896
|
+
uint8_t /* block_protection_bytes_per_key */,
|
|
897
|
+
uint32_t /* restart_interval*/, bool /* use_delta_encoding */>> {
|
|
898
|
+
public:
|
|
899
|
+
DataBlockKVChecksumTest() = default;
|
|
900
|
+
|
|
901
|
+
BlockBasedTableOptions::DataBlockIndexType GetDataBlockIndexType() const {
|
|
902
|
+
return std::get<0>(GetParam());
|
|
903
|
+
}
|
|
904
|
+
uint8_t GetChecksumLen() const { return std::get<1>(GetParam()); }
|
|
905
|
+
uint32_t GetRestartInterval() const { return std::get<2>(GetParam()); }
|
|
906
|
+
bool GetUseDeltaEncoding() const { return std::get<3>(GetParam()); }
|
|
907
|
+
|
|
908
|
+
std::unique_ptr<Block_kData> GenerateDataBlock(
|
|
909
|
+
std::vector<std::string> &keys, std::vector<std::string> &values,
|
|
910
|
+
int num_record) {
|
|
911
|
+
BlockBasedTableOptions tbo;
|
|
912
|
+
BlockCreateContext create_context{&tbo, nullptr /* statistics */,
|
|
913
|
+
false /* using_zstd */, GetChecksumLen(),
|
|
914
|
+
Options().comparator};
|
|
915
|
+
builder_ = std::make_unique<BlockBuilder>(
|
|
916
|
+
static_cast<int>(GetRestartInterval()),
|
|
917
|
+
GetUseDeltaEncoding() /* use_delta_encoding */,
|
|
918
|
+
false /* use_value_delta_encoding */, GetDataBlockIndexType());
|
|
919
|
+
for (int i = 0; i < num_record; i++) {
|
|
920
|
+
builder_->Add(keys[i], values[i]);
|
|
921
|
+
}
|
|
922
|
+
Slice raw_block = builder_->Finish();
|
|
923
|
+
BlockContents contents;
|
|
924
|
+
contents.data = raw_block;
|
|
925
|
+
std::unique_ptr<Block_kData> data_block;
|
|
926
|
+
create_context.Create(&data_block, std::move(contents));
|
|
927
|
+
return data_block;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
std::unique_ptr<BlockBuilder> builder_;
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
INSTANTIATE_TEST_CASE_P(
|
|
934
|
+
P, DataBlockKVChecksumTest,
|
|
935
|
+
::testing::Combine(
|
|
936
|
+
::testing::Values(
|
|
937
|
+
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch,
|
|
938
|
+
BlockBasedTableOptions::DataBlockIndexType::
|
|
939
|
+
kDataBlockBinaryAndHash),
|
|
940
|
+
::testing::Values(0, 1, 2, 4, 8) /* protection_bytes_per_key */,
|
|
941
|
+
::testing::Values(1, 2, 3, 8, 16) /* restart_interval */,
|
|
942
|
+
::testing::Values(false, true)) /* delta_encoding */,
|
|
943
|
+
[](const testing::TestParamInfo<std::tuple<
|
|
944
|
+
BlockBasedTableOptions::DataBlockIndexType, uint8_t, uint32_t, bool>>
|
|
945
|
+
&args) {
|
|
946
|
+
std::ostringstream oss;
|
|
947
|
+
oss << GetDataBlockIndexTypeStr(std::get<0>(args.param))
|
|
948
|
+
<< "ProtectionPerKey" << std::to_string(std::get<1>(args.param))
|
|
949
|
+
<< "RestartInterval" << std::to_string(std::get<2>(args.param))
|
|
950
|
+
<< "DeltaEncode" << std::to_string(std::get<3>(args.param));
|
|
951
|
+
return oss.str();
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
TEST_P(DataBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
955
|
+
uint8_t protection_bytes_per_key = GetChecksumLen();
|
|
956
|
+
std::vector<int> num_restart_intervals = {1, 16};
|
|
957
|
+
for (const auto num_restart_interval : num_restart_intervals) {
|
|
958
|
+
const int kNumRecords =
|
|
959
|
+
num_restart_interval * static_cast<int>(GetRestartInterval());
|
|
960
|
+
std::vector<std::string> keys;
|
|
961
|
+
std::vector<std::string> values;
|
|
962
|
+
GenerateRandomKVs(&keys, &values, 0, kNumRecords + 1, 1 /* step */,
|
|
963
|
+
24 /* padding_size */);
|
|
964
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
965
|
+
std::unique_ptr<Block_kData> data_block =
|
|
966
|
+
GenerateDataBlock(keys, values, kNumRecords);
|
|
967
|
+
|
|
968
|
+
const char *checksum_ptr = data_block->TEST_GetKVChecksum();
|
|
969
|
+
// Check checksum of correct length is generated
|
|
970
|
+
for (int i = 0; i < kNumRecords; i++) {
|
|
971
|
+
ASSERT_TRUE(VerifyChecksum(protection_bytes_per_key,
|
|
972
|
+
checksum_ptr + i * protection_bytes_per_key,
|
|
973
|
+
keys[i], values[i]));
|
|
974
|
+
}
|
|
975
|
+
std::vector<SequenceNumber> seqnos{kDisableGlobalSequenceNumber, 0};
|
|
976
|
+
|
|
977
|
+
// Could just use a boolean flag. Use a counter here just to keep open the
|
|
978
|
+
// possibility of checking the exact number of verifications in the future.
|
|
979
|
+
size_t verification_count = 0;
|
|
980
|
+
// The SyncPoint is placed before checking checksum_len == 0 in
|
|
981
|
+
// Block::VerifyChecksum(). So verification count is incremented even with
|
|
982
|
+
// protection_bytes_per_key = 0. No actual checksum computation is done in
|
|
983
|
+
// that case (see Block::VerifyChecksum()).
|
|
984
|
+
SyncPoint::GetInstance()->SetCallBack(
|
|
985
|
+
"Block::VerifyChecksum::checksum_len",
|
|
986
|
+
[&verification_count, protection_bytes_per_key](void *checksum_len) {
|
|
987
|
+
ASSERT_EQ((*static_cast<uint8_t *>(checksum_len)),
|
|
988
|
+
protection_bytes_per_key);
|
|
989
|
+
++verification_count;
|
|
990
|
+
});
|
|
991
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
992
|
+
|
|
993
|
+
for (const auto seqno : seqnos) {
|
|
994
|
+
std::unique_ptr<DataBlockIter> biter{
|
|
995
|
+
data_block->NewDataIterator(Options().comparator, seqno)};
|
|
996
|
+
|
|
997
|
+
// SeekForGet() some key that does not exist
|
|
998
|
+
biter->SeekForGet(keys[kNumRecords]);
|
|
999
|
+
TestIterateForward(biter, verification_count);
|
|
1000
|
+
|
|
1001
|
+
verification_count = 0;
|
|
1002
|
+
biter->SeekForGet(keys[kNumRecords / 2]);
|
|
1003
|
+
ASSERT_GE(verification_count, 1);
|
|
1004
|
+
TestIterateForward(biter, verification_count);
|
|
1005
|
+
|
|
1006
|
+
TestSeekToFirst(biter, verification_count);
|
|
1007
|
+
TestSeekToLast(biter, verification_count);
|
|
1008
|
+
TestSeekForPrev(biter, verification_count, keys[kNumRecords / 2]);
|
|
1009
|
+
TestSeek(biter, verification_count, keys[kNumRecords / 2]);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
class IndexBlockKVChecksumTest
|
|
1015
|
+
: public BlockPerKVChecksumTest,
|
|
1016
|
+
public testing::WithParamInterface<
|
|
1017
|
+
std::tuple<BlockBasedTableOptions::DataBlockIndexType, uint8_t,
|
|
1018
|
+
uint32_t, bool, bool>> {
|
|
1019
|
+
public:
|
|
1020
|
+
IndexBlockKVChecksumTest() = default;
|
|
1021
|
+
|
|
1022
|
+
BlockBasedTableOptions::DataBlockIndexType GetDataBlockIndexType() const {
|
|
1023
|
+
return std::get<0>(GetParam());
|
|
1024
|
+
}
|
|
1025
|
+
uint8_t GetChecksumLen() const { return std::get<1>(GetParam()); }
|
|
1026
|
+
uint32_t GetRestartInterval() const { return std::get<2>(GetParam()); }
|
|
1027
|
+
bool UseValueDeltaEncoding() const { return std::get<3>(GetParam()); }
|
|
1028
|
+
bool IncludeFirstKey() const { return std::get<4>(GetParam()); }
|
|
1029
|
+
|
|
1030
|
+
std::unique_ptr<Block_kIndex> GenerateIndexBlock(
|
|
1031
|
+
std::vector<std::string> &separators,
|
|
1032
|
+
std::vector<BlockHandle> &block_handles,
|
|
1033
|
+
std::vector<std::string> &first_keys, int num_record) {
|
|
1034
|
+
Options options = Options();
|
|
1035
|
+
BlockBasedTableOptions tbo;
|
|
1036
|
+
uint8_t protection_bytes_per_key = GetChecksumLen();
|
|
1037
|
+
BlockCreateContext create_context{
|
|
1038
|
+
&tbo,
|
|
1039
|
+
nullptr /* statistics */,
|
|
1040
|
+
false /* _using_zstd */,
|
|
1041
|
+
protection_bytes_per_key,
|
|
1042
|
+
options.comparator,
|
|
1043
|
+
!UseValueDeltaEncoding() /* value_is_full */,
|
|
1044
|
+
IncludeFirstKey()};
|
|
1045
|
+
builder_ = std::make_unique<BlockBuilder>(
|
|
1046
|
+
static_cast<int>(GetRestartInterval()), true /* use_delta_encoding */,
|
|
1047
|
+
UseValueDeltaEncoding() /* use_value_delta_encoding */,
|
|
1048
|
+
GetDataBlockIndexType());
|
|
1049
|
+
BlockHandle last_encoded_handle;
|
|
1050
|
+
for (int i = 0; i < num_record; i++) {
|
|
1051
|
+
IndexValue entry(block_handles[i], first_keys[i]);
|
|
1052
|
+
std::string encoded_entry;
|
|
1053
|
+
std::string delta_encoded_entry;
|
|
1054
|
+
entry.EncodeTo(&encoded_entry, IncludeFirstKey(), nullptr);
|
|
1055
|
+
if (UseValueDeltaEncoding() && i > 0) {
|
|
1056
|
+
entry.EncodeTo(&delta_encoded_entry, IncludeFirstKey(),
|
|
1057
|
+
&last_encoded_handle);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
last_encoded_handle = entry.handle;
|
|
1061
|
+
const Slice delta_encoded_entry_slice(delta_encoded_entry);
|
|
1062
|
+
builder_->Add(separators[i], encoded_entry, &delta_encoded_entry_slice);
|
|
1063
|
+
}
|
|
1064
|
+
// read serialized contents of the block
|
|
1065
|
+
Slice raw_block = builder_->Finish();
|
|
1066
|
+
// create block reader
|
|
1067
|
+
BlockContents contents;
|
|
1068
|
+
contents.data = raw_block;
|
|
1069
|
+
std::unique_ptr<Block_kIndex> index_block;
|
|
1070
|
+
|
|
1071
|
+
create_context.Create(&index_block, std::move(contents));
|
|
1072
|
+
return index_block;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
std::unique_ptr<BlockBuilder> builder_;
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
INSTANTIATE_TEST_CASE_P(
|
|
1079
|
+
P, IndexBlockKVChecksumTest,
|
|
1080
|
+
::testing::Combine(
|
|
1081
|
+
::testing::Values(
|
|
1082
|
+
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch,
|
|
1083
|
+
BlockBasedTableOptions::DataBlockIndexType::
|
|
1084
|
+
kDataBlockBinaryAndHash),
|
|
1085
|
+
::testing::Values(0, 1, 2, 4, 8), ::testing::Values(1, 3, 8, 16),
|
|
1086
|
+
::testing::Values(true, false), ::testing::Values(true, false)),
|
|
1087
|
+
[](const testing::TestParamInfo<
|
|
1088
|
+
std::tuple<BlockBasedTableOptions::DataBlockIndexType, uint8_t,
|
|
1089
|
+
uint32_t, bool, bool>> &args) {
|
|
1090
|
+
std::ostringstream oss;
|
|
1091
|
+
oss << GetDataBlockIndexTypeStr(std::get<0>(args.param)) << "ProtBytes"
|
|
1092
|
+
<< std::to_string(std::get<1>(args.param)) << "RestartInterval"
|
|
1093
|
+
<< std::to_string(std::get<2>(args.param)) << "ValueDeltaEncode"
|
|
1094
|
+
<< std::to_string(std::get<3>(args.param)) << "IncludeFirstKey"
|
|
1095
|
+
<< std::to_string(std::get<4>(args.param));
|
|
1096
|
+
return oss.str();
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
TEST_P(IndexBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
1100
|
+
Options options = Options();
|
|
1101
|
+
uint8_t protection_bytes_per_key = GetChecksumLen();
|
|
1102
|
+
std::vector<int> num_restart_intervals = {1, 16};
|
|
1103
|
+
std::vector<SequenceNumber> seqnos{kDisableGlobalSequenceNumber, 10001};
|
|
1104
|
+
|
|
1105
|
+
for (const auto num_restart_interval : num_restart_intervals) {
|
|
1106
|
+
const int kNumRecords =
|
|
1107
|
+
num_restart_interval * static_cast<int>(GetRestartInterval());
|
|
1108
|
+
for (const auto seqno : seqnos) {
|
|
1109
|
+
std::vector<std::string> separators;
|
|
1110
|
+
std::vector<BlockHandle> block_handles;
|
|
1111
|
+
std::vector<std::string> first_keys;
|
|
1112
|
+
GenerateRandomIndexEntries(&separators, &block_handles, &first_keys,
|
|
1113
|
+
kNumRecords,
|
|
1114
|
+
seqno != kDisableGlobalSequenceNumber);
|
|
1115
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
1116
|
+
std::unique_ptr<Block_kIndex> index_block = GenerateIndexBlock(
|
|
1117
|
+
separators, block_handles, first_keys, kNumRecords);
|
|
1118
|
+
IndexBlockIter *kNullIter = nullptr;
|
|
1119
|
+
Statistics *kNullStats = nullptr;
|
|
1120
|
+
// read contents of block sequentially
|
|
1121
|
+
std::unique_ptr<IndexBlockIter> biter{index_block->NewIndexIterator(
|
|
1122
|
+
options.comparator, seqno, kNullIter, kNullStats,
|
|
1123
|
+
true /* total_order_seek */, IncludeFirstKey() /* have_first_key */,
|
|
1124
|
+
true /* key_includes_seq */,
|
|
1125
|
+
!UseValueDeltaEncoding() /* value_is_full */,
|
|
1126
|
+
true /* block_contents_pinned */, nullptr /* prefix_index */)};
|
|
1127
|
+
biter->SeekToFirst();
|
|
1128
|
+
const char *checksum_ptr = index_block->TEST_GetKVChecksum();
|
|
1129
|
+
// Check checksum of correct length is generated
|
|
1130
|
+
for (int i = 0; i < kNumRecords; i++) {
|
|
1131
|
+
// Obtaining the actual content written as value to index block is not
|
|
1132
|
+
// trivial: delta-encoded value is only persisted when not at block
|
|
1133
|
+
// restart point and that keys share some byte (see more in
|
|
1134
|
+
// BlockBuilder::AddWithLastKeyImpl()). So here we just do verification
|
|
1135
|
+
// using value from iterator unlike tests for DataBlockIter or
|
|
1136
|
+
// MetaBlockIter.
|
|
1137
|
+
ASSERT_TRUE(VerifyChecksum(protection_bytes_per_key, checksum_ptr,
|
|
1138
|
+
biter->key(), biter->raw_value()));
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
size_t verification_count = 0;
|
|
1142
|
+
// The SyncPoint is placed before checking checksum_len == 0 in
|
|
1143
|
+
// Block::VerifyChecksum(). To make the testing code below simpler and not
|
|
1144
|
+
// having to differentiate 0 vs non-0 checksum_len, we do an explicit
|
|
1145
|
+
// assert checking on checksum_len here.
|
|
1146
|
+
SyncPoint::GetInstance()->SetCallBack(
|
|
1147
|
+
"Block::VerifyChecksum::checksum_len",
|
|
1148
|
+
[&verification_count, protection_bytes_per_key](void *checksum_len) {
|
|
1149
|
+
ASSERT_EQ((*static_cast<uint8_t *>(checksum_len)),
|
|
1150
|
+
protection_bytes_per_key);
|
|
1151
|
+
++verification_count;
|
|
1152
|
+
});
|
|
1153
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
1154
|
+
|
|
1155
|
+
TestSeekToFirst(biter, verification_count);
|
|
1156
|
+
TestSeekToLast(biter, verification_count);
|
|
1157
|
+
TestSeek(biter, verification_count, first_keys[kNumRecords / 2]);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
class MetaIndexBlockKVChecksumTest
|
|
1163
|
+
: public BlockPerKVChecksumTest,
|
|
1164
|
+
public testing::WithParamInterface<
|
|
1165
|
+
uint8_t /* block_protection_bytes_per_key */> {
|
|
1166
|
+
public:
|
|
1167
|
+
MetaIndexBlockKVChecksumTest() = default;
|
|
1168
|
+
uint8_t GetChecksumLen() const { return GetParam(); }
|
|
1169
|
+
uint32_t GetRestartInterval() const { return 1; }
|
|
1170
|
+
|
|
1171
|
+
std::unique_ptr<Block_kMetaIndex> GenerateMetaIndexBlock(
|
|
1172
|
+
std::vector<std::string> &keys, std::vector<std::string> &values,
|
|
1173
|
+
int num_record) {
|
|
1174
|
+
Options options = Options();
|
|
1175
|
+
BlockBasedTableOptions tbo;
|
|
1176
|
+
uint8_t protection_bytes_per_key = GetChecksumLen();
|
|
1177
|
+
BlockCreateContext create_context{
|
|
1178
|
+
&tbo, nullptr /* statistics */, false /* using_zstd */,
|
|
1179
|
+
protection_bytes_per_key, options.comparator};
|
|
1180
|
+
builder_ =
|
|
1181
|
+
std::make_unique<BlockBuilder>(static_cast<int>(GetRestartInterval()));
|
|
1182
|
+
// add a bunch of records to a block
|
|
1183
|
+
for (int i = 0; i < num_record; i++) {
|
|
1184
|
+
builder_->Add(keys[i], values[i]);
|
|
1185
|
+
}
|
|
1186
|
+
Slice raw_block = builder_->Finish();
|
|
1187
|
+
BlockContents contents;
|
|
1188
|
+
contents.data = raw_block;
|
|
1189
|
+
std::unique_ptr<Block_kMetaIndex> meta_block;
|
|
1190
|
+
create_context.Create(&meta_block, std::move(contents));
|
|
1191
|
+
return meta_block;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
std::unique_ptr<BlockBuilder> builder_;
|
|
1195
|
+
};
|
|
1196
|
+
|
|
1197
|
+
INSTANTIATE_TEST_CASE_P(P, MetaIndexBlockKVChecksumTest,
|
|
1198
|
+
::testing::Values(0, 1, 2, 4, 8),
|
|
1199
|
+
[](const testing::TestParamInfo<uint8_t> &args) {
|
|
1200
|
+
std::ostringstream oss;
|
|
1201
|
+
oss << "ProtBytes" << std::to_string(args.param);
|
|
1202
|
+
return oss.str();
|
|
1203
|
+
});
|
|
1204
|
+
|
|
1205
|
+
TEST_P(MetaIndexBlockKVChecksumTest, ChecksumConstructionAndVerification) {
|
|
1206
|
+
Options options = Options();
|
|
1207
|
+
BlockBasedTableOptions tbo;
|
|
1208
|
+
uint8_t protection_bytes_per_key = GetChecksumLen();
|
|
1209
|
+
BlockCreateContext create_context{
|
|
1210
|
+
&tbo, nullptr /* statistics */, false /* using_zstd */,
|
|
1211
|
+
protection_bytes_per_key, options.comparator};
|
|
1212
|
+
std::vector<int> num_restart_intervals = {1, 16};
|
|
1213
|
+
for (const auto num_restart_interval : num_restart_intervals) {
|
|
1214
|
+
const int kNumRecords = num_restart_interval * GetRestartInterval();
|
|
1215
|
+
std::vector<std::string> keys;
|
|
1216
|
+
std::vector<std::string> values;
|
|
1217
|
+
GenerateRandomKVs(&keys, &values, 0, kNumRecords + 1, 1 /* step */,
|
|
1218
|
+
24 /* padding_size */);
|
|
1219
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
1220
|
+
std::unique_ptr<Block_kMetaIndex> meta_block =
|
|
1221
|
+
GenerateMetaIndexBlock(keys, values, kNumRecords);
|
|
1222
|
+
const char *checksum_ptr = meta_block->TEST_GetKVChecksum();
|
|
1223
|
+
// Check checksum of correct length is generated
|
|
1224
|
+
for (int i = 0; i < kNumRecords; i++) {
|
|
1225
|
+
ASSERT_TRUE(VerifyChecksum(protection_bytes_per_key,
|
|
1226
|
+
checksum_ptr + i * protection_bytes_per_key,
|
|
1227
|
+
keys[i], values[i]));
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
size_t verification_count = 0;
|
|
1231
|
+
// The SyncPoint is placed before checking checksum_len == 0 in
|
|
1232
|
+
// Block::VerifyChecksum(). To make the testing code below simpler and not
|
|
1233
|
+
// having to differentiate 0 vs non-0 checksum_len, we do an explicit assert
|
|
1234
|
+
// checking on checksum_len here.
|
|
1235
|
+
SyncPoint::GetInstance()->SetCallBack(
|
|
1236
|
+
"Block::VerifyChecksum::checksum_len",
|
|
1237
|
+
[&verification_count, protection_bytes_per_key](void *checksum_len) {
|
|
1238
|
+
ASSERT_EQ((*static_cast<uint8_t *>(checksum_len)),
|
|
1239
|
+
protection_bytes_per_key);
|
|
1240
|
+
++verification_count;
|
|
1241
|
+
});
|
|
1242
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
1243
|
+
// Check that block iterator does checksum verification
|
|
1244
|
+
std::unique_ptr<MetaBlockIter> biter{
|
|
1245
|
+
meta_block->NewMetaIterator(true /* block_contents_pinned */)};
|
|
1246
|
+
TestSeekToFirst(biter, verification_count);
|
|
1247
|
+
TestSeekToLast(biter, verification_count);
|
|
1248
|
+
TestSeek(biter, verification_count, keys[kNumRecords / 2]);
|
|
1249
|
+
TestSeekForPrev(biter, verification_count, keys[kNumRecords / 2]);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
class DataBlockKVChecksumCorruptionTest : public DataBlockKVChecksumTest {
|
|
1254
|
+
public:
|
|
1255
|
+
DataBlockKVChecksumCorruptionTest() = default;
|
|
1256
|
+
|
|
1257
|
+
std::unique_ptr<DataBlockIter> GenerateDataBlockIter(
|
|
1258
|
+
std::vector<std::string> &keys, std::vector<std::string> &values,
|
|
1259
|
+
int num_record) {
|
|
1260
|
+
// During Block construction, we may create block iter to initialize per kv
|
|
1261
|
+
// checksum. Disable syncpoint that may be created for block iter methods.
|
|
1262
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
1263
|
+
block_ = GenerateDataBlock(keys, values, num_record);
|
|
1264
|
+
std::unique_ptr<DataBlockIter> biter{block_->NewDataIterator(
|
|
1265
|
+
Options().comparator, kDisableGlobalSequenceNumber)};
|
|
1266
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
1267
|
+
return biter;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
protected:
|
|
1271
|
+
std::unique_ptr<Block_kData> block_;
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
TEST_P(DataBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
1275
|
+
std::vector<int> num_restart_intervals = {1, 3};
|
|
1276
|
+
for (const auto num_restart_interval : num_restart_intervals) {
|
|
1277
|
+
const int kNumRecords =
|
|
1278
|
+
num_restart_interval * static_cast<int>(GetRestartInterval());
|
|
1279
|
+
std::vector<std::string> keys;
|
|
1280
|
+
std::vector<std::string> values;
|
|
1281
|
+
GenerateRandomKVs(&keys, &values, 0, kNumRecords + 1, 1 /* step */,
|
|
1282
|
+
24 /* padding_size */);
|
|
1283
|
+
SyncPoint::GetInstance()->SetCallBack(
|
|
1284
|
+
"BlockIter::UpdateKey::value", [](void *arg) {
|
|
1285
|
+
char *value = static_cast<char *>(arg);
|
|
1286
|
+
// values generated by GenerateRandomKVs are of length 100
|
|
1287
|
+
++value[10];
|
|
1288
|
+
});
|
|
1289
|
+
|
|
1290
|
+
// Purely for reducing the number of lines of code.
|
|
1291
|
+
typedef std::unique_ptr<DataBlockIter> IterPtr;
|
|
1292
|
+
typedef void(IterAPI)(IterPtr & iter, std::string &);
|
|
1293
|
+
|
|
1294
|
+
std::string seek_key = keys[kNumRecords / 2];
|
|
1295
|
+
auto test_seek = [&](IterAPI iter_api) {
|
|
1296
|
+
IterPtr biter = GenerateDataBlockIter(keys, values, kNumRecords);
|
|
1297
|
+
ASSERT_OK(biter->status());
|
|
1298
|
+
iter_api(biter, seek_key);
|
|
1299
|
+
ASSERT_FALSE(biter->Valid());
|
|
1300
|
+
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1301
|
+
};
|
|
1302
|
+
|
|
1303
|
+
test_seek([](IterPtr &iter, std::string &) { iter->SeekToFirst(); });
|
|
1304
|
+
test_seek([](IterPtr &iter, std::string &) { iter->SeekToLast(); });
|
|
1305
|
+
test_seek([](IterPtr &iter, std::string &k) { iter->Seek(k); });
|
|
1306
|
+
test_seek([](IterPtr &iter, std::string &k) { iter->SeekForPrev(k); });
|
|
1307
|
+
test_seek([](IterPtr &iter, std::string &k) { iter->SeekForGet(k); });
|
|
1308
|
+
|
|
1309
|
+
typedef void (DataBlockIter::*IterStepAPI)();
|
|
1310
|
+
auto test_step = [&](IterStepAPI iter_api, std::string &k) {
|
|
1311
|
+
IterPtr biter = GenerateDataBlockIter(keys, values, kNumRecords);
|
|
1312
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
1313
|
+
biter->Seek(k);
|
|
1314
|
+
ASSERT_TRUE(biter->Valid());
|
|
1315
|
+
ASSERT_OK(biter->status());
|
|
1316
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
1317
|
+
std::invoke(iter_api, biter);
|
|
1318
|
+
ASSERT_FALSE(biter->Valid());
|
|
1319
|
+
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1320
|
+
};
|
|
1321
|
+
|
|
1322
|
+
if (kNumRecords > 1) {
|
|
1323
|
+
test_step(&DataBlockIter::Prev, seek_key);
|
|
1324
|
+
test_step(&DataBlockIter::Next, seek_key);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
INSTANTIATE_TEST_CASE_P(
|
|
1330
|
+
P, DataBlockKVChecksumCorruptionTest,
|
|
1331
|
+
::testing::Combine(
|
|
1332
|
+
::testing::Values(
|
|
1333
|
+
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch,
|
|
1334
|
+
BlockBasedTableOptions::DataBlockIndexType::
|
|
1335
|
+
kDataBlockBinaryAndHash),
|
|
1336
|
+
::testing::Values(4, 8) /* block_protection_bytes_per_key */,
|
|
1337
|
+
::testing::Values(1, 3, 8, 16) /* restart_interval */,
|
|
1338
|
+
::testing::Values(false, true)),
|
|
1339
|
+
[](const testing::TestParamInfo<std::tuple<
|
|
1340
|
+
BlockBasedTableOptions::DataBlockIndexType, uint8_t, uint32_t, bool>>
|
|
1341
|
+
&args) {
|
|
1342
|
+
std::ostringstream oss;
|
|
1343
|
+
oss << GetDataBlockIndexTypeStr(std::get<0>(args.param)) << "ProtBytes"
|
|
1344
|
+
<< std::to_string(std::get<1>(args.param)) << "RestartInterval"
|
|
1345
|
+
<< std::to_string(std::get<2>(args.param)) << "DeltaEncode"
|
|
1346
|
+
<< std::to_string(std::get<3>(args.param));
|
|
1347
|
+
return oss.str();
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
class IndexBlockKVChecksumCorruptionTest : public IndexBlockKVChecksumTest {
|
|
1351
|
+
public:
|
|
1352
|
+
IndexBlockKVChecksumCorruptionTest() = default;
|
|
1353
|
+
|
|
1354
|
+
std::unique_ptr<IndexBlockIter> GenerateIndexBlockIter(
|
|
1355
|
+
std::vector<std::string> &separators,
|
|
1356
|
+
std::vector<BlockHandle> &block_handles,
|
|
1357
|
+
std::vector<std::string> &first_keys, int num_record,
|
|
1358
|
+
SequenceNumber seqno) {
|
|
1359
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
1360
|
+
block_ =
|
|
1361
|
+
GenerateIndexBlock(separators, block_handles, first_keys, num_record);
|
|
1362
|
+
std::unique_ptr<IndexBlockIter> biter{block_->NewIndexIterator(
|
|
1363
|
+
Options().comparator, seqno, nullptr, nullptr,
|
|
1364
|
+
true /* total_order_seek */, IncludeFirstKey() /* have_first_key */,
|
|
1365
|
+
true /* key_includes_seq */,
|
|
1366
|
+
!UseValueDeltaEncoding() /* value_is_full */,
|
|
1367
|
+
true /* block_contents_pinned */, nullptr /* prefix_index */)};
|
|
1368
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
1369
|
+
return biter;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
protected:
|
|
1373
|
+
std::unique_ptr<Block_kIndex> block_;
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
INSTANTIATE_TEST_CASE_P(
|
|
1377
|
+
P, IndexBlockKVChecksumCorruptionTest,
|
|
1378
|
+
::testing::Combine(
|
|
1379
|
+
::testing::Values(
|
|
1380
|
+
BlockBasedTableOptions::DataBlockIndexType::kDataBlockBinarySearch,
|
|
1381
|
+
BlockBasedTableOptions::DataBlockIndexType::
|
|
1382
|
+
kDataBlockBinaryAndHash),
|
|
1383
|
+
::testing::Values(4, 8) /* block_protection_bytes_per_key */,
|
|
1384
|
+
::testing::Values(1, 3, 8, 16) /* restart_interval */,
|
|
1385
|
+
::testing::Values(true, false), ::testing::Values(true, false)),
|
|
1386
|
+
[](const testing::TestParamInfo<
|
|
1387
|
+
std::tuple<BlockBasedTableOptions::DataBlockIndexType, uint8_t,
|
|
1388
|
+
uint32_t, bool, bool>> &args) {
|
|
1389
|
+
std::ostringstream oss;
|
|
1390
|
+
oss << GetDataBlockIndexTypeStr(std::get<0>(args.param)) << "ProtBytes"
|
|
1391
|
+
<< std::to_string(std::get<1>(args.param)) << "RestartInterval"
|
|
1392
|
+
<< std::to_string(std::get<2>(args.param)) << "ValueDeltaEncode"
|
|
1393
|
+
<< std::to_string(std::get<3>(args.param)) << "IncludeFirstKey"
|
|
1394
|
+
<< std::to_string(std::get<4>(args.param));
|
|
1395
|
+
return oss.str();
|
|
1396
|
+
});
|
|
1397
|
+
|
|
1398
|
+
TEST_P(IndexBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
1399
|
+
std::vector<int> num_restart_intervals = {1, 3};
|
|
1400
|
+
std::vector<SequenceNumber> seqnos{kDisableGlobalSequenceNumber, 10001};
|
|
1401
|
+
|
|
1402
|
+
for (const auto num_restart_interval : num_restart_intervals) {
|
|
1403
|
+
const int kNumRecords =
|
|
1404
|
+
num_restart_interval * static_cast<int>(GetRestartInterval());
|
|
1405
|
+
for (const auto seqno : seqnos) {
|
|
1406
|
+
std::vector<std::string> separators;
|
|
1407
|
+
std::vector<BlockHandle> block_handles;
|
|
1408
|
+
std::vector<std::string> first_keys;
|
|
1409
|
+
GenerateRandomIndexEntries(&separators, &block_handles, &first_keys,
|
|
1410
|
+
kNumRecords,
|
|
1411
|
+
seqno != kDisableGlobalSequenceNumber);
|
|
1412
|
+
SyncPoint::GetInstance()->SetCallBack(
|
|
1413
|
+
"BlockIter::UpdateKey::value", [](void *arg) {
|
|
1414
|
+
char *value = static_cast<char *>(arg);
|
|
1415
|
+
// value can be delta-encoded with different lengths, so we corrupt
|
|
1416
|
+
// first bytes here to be safe
|
|
1417
|
+
++value[0];
|
|
1418
|
+
});
|
|
1419
|
+
|
|
1420
|
+
typedef std::unique_ptr<IndexBlockIter> IterPtr;
|
|
1421
|
+
typedef void(IterAPI)(IterPtr & iter, std::string &);
|
|
1422
|
+
std::string seek_key = first_keys[kNumRecords / 2];
|
|
1423
|
+
auto test_seek = [&](IterAPI iter_api) {
|
|
1424
|
+
std::unique_ptr<IndexBlockIter> biter = GenerateIndexBlockIter(
|
|
1425
|
+
separators, block_handles, first_keys, kNumRecords, seqno);
|
|
1426
|
+
ASSERT_OK(biter->status());
|
|
1427
|
+
iter_api(biter, seek_key);
|
|
1428
|
+
ASSERT_FALSE(biter->Valid());
|
|
1429
|
+
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1430
|
+
};
|
|
1431
|
+
test_seek([](IterPtr &iter, std::string &) { iter->SeekToFirst(); });
|
|
1432
|
+
test_seek([](IterPtr &iter, std::string &) { iter->SeekToLast(); });
|
|
1433
|
+
test_seek([](IterPtr &iter, std::string &k) { iter->Seek(k); });
|
|
1434
|
+
|
|
1435
|
+
typedef void (IndexBlockIter::*IterStepAPI)();
|
|
1436
|
+
auto test_step = [&](IterStepAPI iter_api, std::string &k) {
|
|
1437
|
+
std::unique_ptr<IndexBlockIter> biter = GenerateIndexBlockIter(
|
|
1438
|
+
separators, block_handles, first_keys, kNumRecords, seqno);
|
|
1439
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
1440
|
+
biter->Seek(k);
|
|
1441
|
+
ASSERT_TRUE(biter->Valid());
|
|
1442
|
+
ASSERT_OK(biter->status());
|
|
1443
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
1444
|
+
std::invoke(iter_api, biter);
|
|
1445
|
+
ASSERT_FALSE(biter->Valid());
|
|
1446
|
+
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1447
|
+
};
|
|
1448
|
+
if (kNumRecords > 1) {
|
|
1449
|
+
test_step(&IndexBlockIter::Prev, seek_key);
|
|
1450
|
+
test_step(&IndexBlockIter::Next, seek_key);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
class MetaIndexBlockKVChecksumCorruptionTest
|
|
1457
|
+
: public MetaIndexBlockKVChecksumTest {
|
|
1458
|
+
public:
|
|
1459
|
+
MetaIndexBlockKVChecksumCorruptionTest() = default;
|
|
1460
|
+
|
|
1461
|
+
std::unique_ptr<MetaBlockIter> GenerateMetaIndexBlockIter(
|
|
1462
|
+
std::vector<std::string> &keys, std::vector<std::string> &values,
|
|
1463
|
+
int num_record) {
|
|
1464
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
1465
|
+
block_ = GenerateMetaIndexBlock(keys, values, num_record);
|
|
1466
|
+
std::unique_ptr<MetaBlockIter> biter{
|
|
1467
|
+
block_->NewMetaIterator(true /* block_contents_pinned */)};
|
|
1468
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
1469
|
+
return biter;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
protected:
|
|
1473
|
+
std::unique_ptr<Block_kMetaIndex> block_;
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
INSTANTIATE_TEST_CASE_P(
|
|
1477
|
+
P, MetaIndexBlockKVChecksumCorruptionTest,
|
|
1478
|
+
::testing::Values(4, 8) /* block_protection_bytes_per_key */,
|
|
1479
|
+
[](const testing::TestParamInfo<uint8_t> &args) {
|
|
1480
|
+
std::ostringstream oss;
|
|
1481
|
+
oss << "ProtBytes" << std::to_string(args.param);
|
|
1482
|
+
return oss.str();
|
|
1483
|
+
});
|
|
1484
|
+
|
|
1485
|
+
TEST_P(MetaIndexBlockKVChecksumCorruptionTest, CorruptEntry) {
|
|
1486
|
+
Options options = Options();
|
|
1487
|
+
std::vector<int> num_restart_intervals = {1, 3};
|
|
1488
|
+
for (const auto num_restart_interval : num_restart_intervals) {
|
|
1489
|
+
const int kNumRecords =
|
|
1490
|
+
num_restart_interval * static_cast<int>(GetRestartInterval());
|
|
1491
|
+
std::vector<std::string> keys;
|
|
1492
|
+
std::vector<std::string> values;
|
|
1493
|
+
GenerateRandomKVs(&keys, &values, 0, kNumRecords + 1, 1 /* step */,
|
|
1494
|
+
24 /* padding_size */);
|
|
1495
|
+
SyncPoint::GetInstance()->SetCallBack(
|
|
1496
|
+
"BlockIter::UpdateKey::value", [](void *arg) {
|
|
1497
|
+
char *value = static_cast<char *>(arg);
|
|
1498
|
+
// values generated by GenerateRandomKVs are of length 100
|
|
1499
|
+
++value[10];
|
|
1500
|
+
});
|
|
1501
|
+
|
|
1502
|
+
typedef std::unique_ptr<MetaBlockIter> IterPtr;
|
|
1503
|
+
typedef void(IterAPI)(IterPtr & iter, std::string &);
|
|
1504
|
+
typedef void (MetaBlockIter::*IterStepAPI)();
|
|
1505
|
+
std::string seek_key = keys[kNumRecords / 2];
|
|
1506
|
+
auto test_seek = [&](IterAPI iter_api) {
|
|
1507
|
+
IterPtr biter = GenerateMetaIndexBlockIter(keys, values, kNumRecords);
|
|
1508
|
+
ASSERT_OK(biter->status());
|
|
1509
|
+
iter_api(biter, seek_key);
|
|
1510
|
+
ASSERT_FALSE(biter->Valid());
|
|
1511
|
+
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1512
|
+
};
|
|
1513
|
+
|
|
1514
|
+
test_seek([](IterPtr &iter, std::string &) { iter->SeekToFirst(); });
|
|
1515
|
+
test_seek([](IterPtr &iter, std::string &) { iter->SeekToLast(); });
|
|
1516
|
+
test_seek([](IterPtr &iter, std::string &k) { iter->Seek(k); });
|
|
1517
|
+
test_seek([](IterPtr &iter, std::string &k) { iter->SeekForPrev(k); });
|
|
1518
|
+
|
|
1519
|
+
auto test_step = [&](IterStepAPI iter_api, const std::string &k) {
|
|
1520
|
+
IterPtr biter = GenerateMetaIndexBlockIter(keys, values, kNumRecords);
|
|
1521
|
+
SyncPoint::GetInstance()->DisableProcessing();
|
|
1522
|
+
biter->Seek(k);
|
|
1523
|
+
ASSERT_TRUE(biter->Valid());
|
|
1524
|
+
ASSERT_OK(biter->status());
|
|
1525
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
1526
|
+
std::invoke(iter_api, biter);
|
|
1527
|
+
ASSERT_FALSE(biter->Valid());
|
|
1528
|
+
ASSERT_TRUE(biter->status().IsCorruption());
|
|
1529
|
+
};
|
|
1530
|
+
|
|
1531
|
+
if (kNumRecords > 1) {
|
|
1532
|
+
test_step(&MetaBlockIter::Prev, seek_key);
|
|
1533
|
+
test_step(&MetaBlockIter::Next, seek_key);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
621
1537
|
} // namespace ROCKSDB_NAMESPACE
|
|
622
1538
|
|
|
623
1539
|
int main(int argc, char **argv) {
|