@nxtedition/rocksdb 13.5.13 → 15.0.1
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 +55 -180
- package/binding.gyp +2 -2
- package/chained-batch.js +9 -16
- package/deps/rocksdb/rocksdb/BUCK +18 -1
- package/deps/rocksdb/rocksdb/CMakeLists.txt +10 -3
- package/deps/rocksdb/rocksdb/Makefile +20 -9
- package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +90 -13
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +88 -75
- package/deps/rocksdb/rocksdb/cache/clock_cache.h +44 -36
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +184 -148
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +5 -11
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +116 -47
- package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +1 -1
- package/deps/rocksdb/rocksdb/cache/secondary_cache_adapter.cc +3 -6
- package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.h +1 -1
- package/deps/rocksdb/rocksdb/db/builder.cc +4 -2
- package/deps/rocksdb/rocksdb/db/c.cc +207 -0
- package/deps/rocksdb/rocksdb/db/c_test.c +72 -0
- package/deps/rocksdb/rocksdb/db/column_family.cc +3 -2
- package/deps/rocksdb/rocksdb/db/column_family.h +5 -0
- package/deps/rocksdb/rocksdb/db/compact_files_test.cc +4 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +2 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +51 -38
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +29 -12
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +5 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +566 -366
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +131 -4
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +1 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +7 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +4 -4
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +13 -14
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +12 -7
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +8 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +97 -76
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +11 -14
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +1 -1
- package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +8 -0
- package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +16 -3
- package/deps/rocksdb/rocksdb/db/db_basic_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +448 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +22 -20
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +4 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +5 -5
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +7 -3
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_iter.cc +104 -0
- package/deps/rocksdb/rocksdb/db/db_iter.h +4 -11
- package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +331 -58
- package/deps/rocksdb/rocksdb/db/db_memtable_test.cc +129 -0
- package/deps/rocksdb/rocksdb/db/db_sst_test.cc +64 -0
- package/deps/rocksdb/rocksdb/db/db_table_properties_test.cc +40 -0
- package/deps/rocksdb/rocksdb/db/db_test2.cc +25 -15
- package/deps/rocksdb/rocksdb/db/db_test_util.cc +42 -24
- package/deps/rocksdb/rocksdb/db/db_test_util.h +29 -14
- package/deps/rocksdb/rocksdb/db/db_universal_compaction_test.cc +69 -36
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +0 -1
- package/deps/rocksdb/rocksdb/db/event_helpers.cc +1 -0
- package/deps/rocksdb/rocksdb/db/experimental.cc +5 -4
- package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +8 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +275 -79
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +23 -5
- package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +591 -175
- package/deps/rocksdb/rocksdb/db/flush_job.cc +3 -4
- package/deps/rocksdb/rocksdb/db/log_reader.cc +5 -2
- package/deps/rocksdb/rocksdb/db/memtable.cc +84 -35
- package/deps/rocksdb/rocksdb/db/memtable.h +39 -34
- package/deps/rocksdb/rocksdb/db/merge_helper.cc +1 -0
- package/deps/rocksdb/rocksdb/db/merge_operator.cc +1 -1
- package/deps/rocksdb/rocksdb/db/multi_scan.cc +11 -5
- package/deps/rocksdb/rocksdb/db/version_edit.cc +1 -1
- package/deps/rocksdb/rocksdb/db/version_edit.h +1 -1
- package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +34 -14
- package/deps/rocksdb/rocksdb/db/version_edit_handler.h +28 -5
- package/deps/rocksdb/rocksdb/db/version_set.cc +159 -14
- package/deps/rocksdb/rocksdb/db/version_set.h +2 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/CMakeLists.txt +1 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +60 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +16 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_compaction_service.h +75 -10
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_compression_manager.cc +28 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_compression_manager.h +2 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +31 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +50 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +57 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_stat.h +0 -4
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +266 -35
- 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 +0 -6
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +18 -2
- package/deps/rocksdb/rocksdb/env/env.cc +12 -0
- package/deps/rocksdb/rocksdb/env/env_test.cc +18 -0
- package/deps/rocksdb/rocksdb/env/file_system_tracer.cc +2 -0
- package/deps/rocksdb/rocksdb/env/fs_posix.cc +9 -5
- package/deps/rocksdb/rocksdb/env/io_posix.cc +4 -2
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +19 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_compression.h +33 -31
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +42 -9
- package/deps/rocksdb/rocksdb/include/rocksdb/c.h +93 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +43 -49
- package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +4 -3
- package/deps/rocksdb/rocksdb/include/rocksdb/compression_type.h +8 -6
- package/deps/rocksdb/rocksdb/include/rocksdb/data_structure.h +487 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/db.h +11 -12
- package/deps/rocksdb/rocksdb/include/rocksdb/env.h +135 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/iostats_context.h +12 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/iterator.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/ldb_tool.h +8 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/memtablerep.h +12 -8
- package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +3 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/multi_scan.h +19 -9
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +219 -24
- package/deps/rocksdb/rocksdb/include/rocksdb/point_lock_bench_tool.h +14 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +2 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/slice.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +7 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/status.h +16 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/table.h +16 -4
- package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +13 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/types.h +4 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/universal_compaction.h +0 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/user_defined_index.h +45 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/cache_dump_load.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction.h +6 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db.h +21 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
- package/deps/rocksdb/rocksdb/memory/memory_allocator_impl.h +3 -3
- package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +77 -51
- package/deps/rocksdb/rocksdb/memtable/skiplist.h +10 -13
- package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +16 -7
- package/deps/rocksdb/rocksdb/memtable/vectorrep.cc +9 -4
- package/deps/rocksdb/rocksdb/monitoring/iostats_context.cc +2 -0
- package/deps/rocksdb/rocksdb/monitoring/statistics.cc +6 -0
- package/deps/rocksdb/rocksdb/options/cf_options.cc +13 -1
- package/deps/rocksdb/rocksdb/options/cf_options.h +6 -2
- package/deps/rocksdb/rocksdb/options/options.cc +2 -0
- package/deps/rocksdb/rocksdb/options/options_helper.cc +9 -8
- package/deps/rocksdb/rocksdb/options/options_settable_test.cc +9 -5
- package/deps/rocksdb/rocksdb/port/mmap.cc +1 -1
- package/deps/rocksdb/rocksdb/port/win/xpress_win.cc +51 -0
- package/deps/rocksdb/rocksdb/port/win/xpress_win.h +4 -0
- package/deps/rocksdb/rocksdb/src.mk +8 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +1125 -765
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +35 -24
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +29 -4
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +732 -256
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +225 -16
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +102 -26
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +2 -75
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +433 -141
- package/deps/rocksdb/rocksdb/table/block_based/block_builder.h +2 -0
- package/deps/rocksdb/rocksdb/table/block_based/flush_block_policy.cc +17 -10
- package/deps/rocksdb/rocksdb/table/block_based/flush_block_policy_impl.h +20 -0
- package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +112 -85
- package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +191 -36
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +2 -2
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/user_defined_index_wrapper.h +108 -31
- package/deps/rocksdb/rocksdb/table/external_table.cc +7 -3
- package/deps/rocksdb/rocksdb/table/format.cc +6 -12
- package/deps/rocksdb/rocksdb/table/format.h +10 -0
- package/deps/rocksdb/rocksdb/table/internal_iterator.h +1 -1
- package/deps/rocksdb/rocksdb/table/iterator_wrapper.h +1 -1
- package/deps/rocksdb/rocksdb/table/merging_iterator.cc +1 -1
- package/deps/rocksdb/rocksdb/table/meta_blocks.cc +5 -0
- package/deps/rocksdb/rocksdb/table/multiget_context.h +3 -1
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +118 -46
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +9 -8
- package/deps/rocksdb/rocksdb/table/table_builder.h +5 -0
- package/deps/rocksdb/rocksdb/table/table_properties.cc +16 -0
- package/deps/rocksdb/rocksdb/table/table_test.cc +1540 -155
- package/deps/rocksdb/rocksdb/test_util/testutil.h +21 -5
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +26 -5
- package/deps/rocksdb/rocksdb/tools/ldb.cc +1 -2
- package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +2 -0
- package/deps/rocksdb/rocksdb/tools/ldb_tool.cc +9 -3
- package/deps/rocksdb/rocksdb/tools/sst_dump_test.cc +133 -165
- package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +173 -64
- package/deps/rocksdb/rocksdb/util/aligned_buffer.h +69 -0
- package/deps/rocksdb/rocksdb/util/atomic.h +6 -0
- package/deps/rocksdb/rocksdb/util/auto_tune_compressor.cc +29 -20
- package/deps/rocksdb/rocksdb/util/auto_tune_compressor.h +10 -6
- package/deps/rocksdb/rocksdb/util/bit_fields.h +338 -0
- package/deps/rocksdb/rocksdb/util/coding.h +3 -3
- package/deps/rocksdb/rocksdb/util/compaction_job_stats_impl.cc +2 -2
- package/deps/rocksdb/rocksdb/util/compression.cc +777 -82
- package/deps/rocksdb/rocksdb/util/compression.h +5 -0
- package/deps/rocksdb/rocksdb/util/compression_test.cc +5 -3
- package/deps/rocksdb/rocksdb/util/dynamic_bloom.cc +2 -2
- package/deps/rocksdb/rocksdb/util/dynamic_bloom.h +15 -14
- package/deps/rocksdb/rocksdb/util/interval_test.cc +102 -0
- package/deps/rocksdb/rocksdb/util/semaphore.h +164 -0
- package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.cc +10 -6
- package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.h +4 -2
- package/deps/rocksdb/rocksdb/util/slice_test.cc +136 -0
- package/deps/rocksdb/rocksdb/util/status.cc +1 -0
- package/deps/rocksdb/rocksdb/util/string_util.cc +2 -16
- package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +1 -1
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +7 -4
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.h +35 -14
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/hash_table_test.cc +2 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/lock_manager.cc +5 -2
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/any_lock_manager_test.h +244 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_bench.cc +18 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_bench_tool.cc +159 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager.cc +1244 -161
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager.h +66 -12
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_stress_test.cc +103 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_test.cc +1275 -8
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_test.h +40 -262
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_test_common.h +78 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_validation_test_runner.h +469 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_locking_test.cc +2 -6
- package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +4 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.h +9 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/timestamped_snapshot_test.cc +18 -9
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.h +2 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_db_mutex_impl.cc +2 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +72 -44
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.h +92 -15
- package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +6 -20
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +143 -112
- package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_transaction_test.cc +23 -16
- package/index.js +18 -42
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
- package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
- package/util.h +38 -12
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_stat.cc +0 -17
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
#include "rocksdb/comparator.h"
|
|
19
19
|
#include "table/block_based/block_based_table_factory.h"
|
|
20
20
|
#include "table/block_based/block_builder.h"
|
|
21
|
+
#include "table/block_based/flush_block_policy_impl.h"
|
|
21
22
|
#include "table/format.h"
|
|
22
23
|
|
|
23
24
|
namespace ROCKSDB_NAMESPACE {
|
|
@@ -76,6 +77,49 @@ class IndexBuilder {
|
|
|
76
77
|
const BlockHandle& block_handle,
|
|
77
78
|
std::string* separator_scratch) = 0;
|
|
78
79
|
|
|
80
|
+
// An abstract (extensible) holder for passing data from PrepareIndexEntry to
|
|
81
|
+
// FinishIndexEntry (see below).
|
|
82
|
+
struct PreparedIndexEntry {
|
|
83
|
+
virtual ~PreparedIndexEntry() = default;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Parallel compression/construction alternative to AddIndexEntry, 1/3
|
|
87
|
+
//
|
|
88
|
+
// This function creates a holder for data that needs to be passed from
|
|
89
|
+
// PrepareIndexEntry to FinishIndexEntry, depending on the implementation
|
|
90
|
+
// of those. Few of these are created and reused, so construction/destruction
|
|
91
|
+
// performance is not critical.
|
|
92
|
+
virtual std::unique_ptr<PreparedIndexEntry> CreatePreparedIndexEntry() = 0;
|
|
93
|
+
|
|
94
|
+
// Parallel compression/construction alternative to AddIndexEntry, 2/3
|
|
95
|
+
//
|
|
96
|
+
// One thread calls this function for successive index entries to compute and
|
|
97
|
+
// record in `out` what is needed to build the index entry EXCEPT for the
|
|
98
|
+
// BlockHandle, which will only be known later. That thread is generally the
|
|
99
|
+
// same thread as calls every other function such as OnKeyAdded EXCEPT
|
|
100
|
+
// FinishIndexEntry (see below). This function should be considered "mostly
|
|
101
|
+
// stateless" but might modify state distinct from what is modified by
|
|
102
|
+
// FinishIndexEntry. Ideally synchronization within the IndexBuilder can be
|
|
103
|
+
// avoided.
|
|
104
|
+
//
|
|
105
|
+
// The passed-in PreparedIndexEntry object is likely reused so might be
|
|
106
|
+
// passed-in in any state.
|
|
107
|
+
virtual void PrepareIndexEntry(const Slice& last_key_in_current_block,
|
|
108
|
+
const Slice* first_key_in_next_block,
|
|
109
|
+
PreparedIndexEntry* out) = 0;
|
|
110
|
+
|
|
111
|
+
// Parallel compression/construction alternative to AddIndexEntry, 3/3
|
|
112
|
+
//
|
|
113
|
+
// This function is called by a different thread than PrepareIndexEntry, but
|
|
114
|
+
// is called on entries in the same order as PrepareIndexEntry, passed in the
|
|
115
|
+
// PreparedIndexEntry objects populated by PrepareIndexEntry. This function
|
|
116
|
+
// finishes the same effect of AddIndexEntry but split across a few functions.
|
|
117
|
+
//
|
|
118
|
+
// External synchronization ensures Finish is only called after all the
|
|
119
|
+
// FinishIndexEntry calls have completed.
|
|
120
|
+
virtual void FinishIndexEntry(const BlockHandle& block_handle,
|
|
121
|
+
PreparedIndexEntry* entry) = 0;
|
|
122
|
+
|
|
79
123
|
// This method will be called whenever a key is added. The subclasses may
|
|
80
124
|
// override OnKeyAdded() if they need to collect additional information.
|
|
81
125
|
virtual void OnKeyAdded(const Slice& /*key*/,
|
|
@@ -109,7 +153,7 @@ class IndexBuilder {
|
|
|
109
153
|
// Get the size for index block. Must be called after ::Finish.
|
|
110
154
|
virtual size_t IndexSize() const = 0;
|
|
111
155
|
|
|
112
|
-
virtual bool
|
|
156
|
+
virtual bool separator_is_key_plus_seq() { return true; }
|
|
113
157
|
|
|
114
158
|
protected:
|
|
115
159
|
// Given the last key in current block and the first key in the next block,
|
|
@@ -117,7 +161,7 @@ class IndexBuilder {
|
|
|
117
161
|
// can be used as separator.
|
|
118
162
|
inline bool ShouldUseKeyPlusSeqAsSeparator(
|
|
119
163
|
const Slice& last_key_in_current_block,
|
|
120
|
-
const Slice& first_key_in_next_block) {
|
|
164
|
+
const Slice& first_key_in_next_block) const {
|
|
121
165
|
Slice l_user_key = ExtractUserKey(last_key_in_current_block);
|
|
122
166
|
Slice r_user_key = ExtractUserKey(first_key_in_next_block);
|
|
123
167
|
// If user defined timestamps are not persisted. All the user keys will
|
|
@@ -178,7 +222,7 @@ class ShortenedIndexBuilder : public IndexBuilder {
|
|
|
178
222
|
include_first_key_(include_first_key),
|
|
179
223
|
shortening_mode_(shortening_mode) {
|
|
180
224
|
// Making the default true will disable the feature for old versions
|
|
181
|
-
|
|
225
|
+
must_use_separator_with_seq_ = (format_version <= 2);
|
|
182
226
|
}
|
|
183
227
|
|
|
184
228
|
void OnKeyAdded(const Slice& key,
|
|
@@ -188,49 +232,61 @@ class ShortenedIndexBuilder : public IndexBuilder {
|
|
|
188
232
|
}
|
|
189
233
|
}
|
|
190
234
|
|
|
191
|
-
Slice
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
Slice separator;
|
|
235
|
+
Slice GetSeparatorWithSeq(const Slice& last_key_in_current_block,
|
|
236
|
+
const Slice* first_key_in_next_block,
|
|
237
|
+
std::string* separator_scratch) {
|
|
238
|
+
Slice separator_with_seq;
|
|
196
239
|
if (first_key_in_next_block != nullptr) {
|
|
197
240
|
if (shortening_mode_ !=
|
|
198
241
|
BlockBasedTableOptions::IndexShorteningMode::kNoShortening) {
|
|
199
|
-
|
|
242
|
+
separator_with_seq = FindShortestInternalKeySeparator(
|
|
200
243
|
*comparator_->user_comparator(), last_key_in_current_block,
|
|
201
244
|
*first_key_in_next_block, separator_scratch);
|
|
202
245
|
} else {
|
|
203
|
-
|
|
246
|
+
separator_with_seq = last_key_in_current_block;
|
|
204
247
|
}
|
|
205
|
-
if (!
|
|
248
|
+
if (!must_use_separator_with_seq_ &&
|
|
206
249
|
ShouldUseKeyPlusSeqAsSeparator(last_key_in_current_block,
|
|
207
250
|
*first_key_in_next_block)) {
|
|
208
|
-
|
|
251
|
+
must_use_separator_with_seq_ = true;
|
|
209
252
|
}
|
|
210
253
|
} else {
|
|
211
254
|
if (shortening_mode_ == BlockBasedTableOptions::IndexShorteningMode::
|
|
212
255
|
kShortenSeparatorsAndSuccessor) {
|
|
213
|
-
|
|
256
|
+
separator_with_seq = FindShortInternalKeySuccessor(
|
|
214
257
|
*comparator_->user_comparator(), last_key_in_current_block,
|
|
215
258
|
separator_scratch);
|
|
216
259
|
} else {
|
|
217
|
-
|
|
260
|
+
separator_with_seq = last_key_in_current_block;
|
|
218
261
|
}
|
|
219
262
|
}
|
|
263
|
+
return separator_with_seq;
|
|
264
|
+
}
|
|
220
265
|
|
|
221
|
-
|
|
266
|
+
Slice GetFirstInternalKey(std::string* first_internal_key_buf) const {
|
|
267
|
+
if (!include_first_key_) {
|
|
268
|
+
return Slice();
|
|
269
|
+
}
|
|
270
|
+
assert(!current_block_first_internal_key_.empty());
|
|
222
271
|
// When UDT should not be persisted, the index block builders take care of
|
|
223
272
|
// stripping UDT from the key, for the first internal key contained in the
|
|
224
273
|
// IndexValue, we need to explicitly do the stripping here before passing
|
|
225
274
|
// it to the block builders.
|
|
226
|
-
std::string first_internal_key_buf;
|
|
227
275
|
Slice first_internal_key = current_block_first_internal_key_;
|
|
228
276
|
if (!current_block_first_internal_key_.empty() && ts_sz_ > 0 &&
|
|
229
277
|
!persist_user_defined_timestamps_) {
|
|
230
|
-
|
|
278
|
+
first_internal_key_buf->clear();
|
|
279
|
+
StripTimestampFromInternalKey(first_internal_key_buf,
|
|
231
280
|
current_block_first_internal_key_, ts_sz_);
|
|
232
|
-
first_internal_key = first_internal_key_buf;
|
|
281
|
+
first_internal_key = *first_internal_key_buf;
|
|
233
282
|
}
|
|
283
|
+
return first_internal_key;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
void AddIndexEntryImpl(const Slice& separator_with_seq,
|
|
287
|
+
const Slice& first_internal_key,
|
|
288
|
+
const BlockHandle& block_handle,
|
|
289
|
+
bool must_use_separator_with_seq) {
|
|
234
290
|
IndexValue entry(block_handle, first_internal_key);
|
|
235
291
|
std::string encoded_entry;
|
|
236
292
|
std::string delta_encoded_entry;
|
|
@@ -254,21 +310,91 @@ class ShortenedIndexBuilder : public IndexBuilder {
|
|
|
254
310
|
// away the UDT from key in index block as data block does the same thing.
|
|
255
311
|
// What are the implications if a "FindShortInternalKeySuccessor"
|
|
256
312
|
// optimization is provided.
|
|
257
|
-
index_block_builder_.Add(
|
|
313
|
+
index_block_builder_.Add(separator_with_seq, encoded_entry,
|
|
258
314
|
&delta_encoded_entry_slice);
|
|
259
|
-
if (!
|
|
260
|
-
index_block_builder_without_seq_.Add(
|
|
261
|
-
|
|
315
|
+
if (!must_use_separator_with_seq) {
|
|
316
|
+
index_block_builder_without_seq_.Add(ExtractUserKey(separator_with_seq),
|
|
317
|
+
encoded_entry,
|
|
318
|
+
&delta_encoded_entry_slice);
|
|
262
319
|
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
Slice AddIndexEntry(const Slice& last_key_in_current_block,
|
|
323
|
+
const Slice* first_key_in_next_block,
|
|
324
|
+
const BlockHandle& block_handle,
|
|
325
|
+
std::string* separator_scratch) override {
|
|
326
|
+
Slice separator_with_seq = GetSeparatorWithSeq(
|
|
327
|
+
last_key_in_current_block, first_key_in_next_block, separator_scratch);
|
|
263
328
|
|
|
329
|
+
std::string first_internal_key_buf;
|
|
330
|
+
Slice first_internal_key = GetFirstInternalKey(&first_internal_key_buf);
|
|
331
|
+
|
|
332
|
+
AddIndexEntryImpl(separator_with_seq, first_internal_key, block_handle,
|
|
333
|
+
must_use_separator_with_seq_);
|
|
334
|
+
current_block_first_internal_key_.clear();
|
|
335
|
+
return separator_with_seq;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
struct ShortenedPreparedIndexEntry : public PreparedIndexEntry {
|
|
339
|
+
std::string separator_with_seq;
|
|
340
|
+
std::string first_internal_key;
|
|
341
|
+
bool must_use_separator_with_seq = false;
|
|
342
|
+
void SaveFrom(const Slice& from_separator,
|
|
343
|
+
const Slice& from_first_internal_key,
|
|
344
|
+
bool from_must_use_separator_with_seq) {
|
|
345
|
+
assert(from_separator.size() >= kNumInternalBytes);
|
|
346
|
+
if (from_separator.data() == separator_with_seq.data()) {
|
|
347
|
+
// No need to copy
|
|
348
|
+
assert(from_separator.size() == separator_with_seq.size());
|
|
349
|
+
} else {
|
|
350
|
+
// Copy the separator
|
|
351
|
+
separator_with_seq.assign(from_separator.data(), from_separator.size());
|
|
352
|
+
}
|
|
353
|
+
// first_internal_key is optional, so it may be empty.
|
|
354
|
+
assert(from_first_internal_key.empty() ||
|
|
355
|
+
from_first_internal_key.size() >= kNumInternalBytes);
|
|
356
|
+
if (from_first_internal_key.data() == first_internal_key.data()) {
|
|
357
|
+
// No need to copy
|
|
358
|
+
assert(from_first_internal_key.size() == first_internal_key.size());
|
|
359
|
+
} else {
|
|
360
|
+
// Copy the first internal key
|
|
361
|
+
first_internal_key.assign(from_first_internal_key.data(),
|
|
362
|
+
from_first_internal_key.size());
|
|
363
|
+
}
|
|
364
|
+
must_use_separator_with_seq = from_must_use_separator_with_seq;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
std::unique_ptr<PreparedIndexEntry> CreatePreparedIndexEntry() override {
|
|
369
|
+
return std::make_unique<ShortenedPreparedIndexEntry>();
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
void PrepareIndexEntry(const Slice& last_key_in_current_block,
|
|
373
|
+
const Slice* first_key_in_next_block,
|
|
374
|
+
PreparedIndexEntry* out) override {
|
|
375
|
+
ShortenedPreparedIndexEntry* entry =
|
|
376
|
+
static_cast<ShortenedPreparedIndexEntry*>(out);
|
|
377
|
+
Slice separator =
|
|
378
|
+
GetSeparatorWithSeq(last_key_in_current_block, first_key_in_next_block,
|
|
379
|
+
&entry->separator_with_seq);
|
|
380
|
+
Slice first_internal_key = GetFirstInternalKey(&entry->first_internal_key);
|
|
381
|
+
entry->SaveFrom(separator, first_internal_key,
|
|
382
|
+
must_use_separator_with_seq_);
|
|
264
383
|
current_block_first_internal_key_.clear();
|
|
265
|
-
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
void FinishIndexEntry(const BlockHandle& block_handle,
|
|
387
|
+
PreparedIndexEntry* base_entry) override {
|
|
388
|
+
ShortenedPreparedIndexEntry* entry =
|
|
389
|
+
static_cast<ShortenedPreparedIndexEntry*>(base_entry);
|
|
390
|
+
AddIndexEntryImpl(entry->separator_with_seq, entry->first_internal_key,
|
|
391
|
+
block_handle, entry->must_use_separator_with_seq);
|
|
266
392
|
}
|
|
267
393
|
|
|
268
394
|
using IndexBuilder::Finish;
|
|
269
395
|
Status Finish(IndexBlocks* index_blocks,
|
|
270
396
|
const BlockHandle& /*last_partition_block_handle*/) override {
|
|
271
|
-
if (
|
|
397
|
+
if (must_use_separator_with_seq_) {
|
|
272
398
|
index_blocks->index_block_contents = index_block_builder_.Finish();
|
|
273
399
|
} else {
|
|
274
400
|
index_blocks->index_block_contents =
|
|
@@ -280,8 +406,8 @@ class ShortenedIndexBuilder : public IndexBuilder {
|
|
|
280
406
|
|
|
281
407
|
size_t IndexSize() const override { return index_size_; }
|
|
282
408
|
|
|
283
|
-
bool
|
|
284
|
-
return
|
|
409
|
+
bool separator_is_key_plus_seq() override {
|
|
410
|
+
return must_use_separator_with_seq_;
|
|
285
411
|
}
|
|
286
412
|
|
|
287
413
|
// Changes *key to a short string >= *key.
|
|
@@ -299,9 +425,13 @@ class ShortenedIndexBuilder : public IndexBuilder {
|
|
|
299
425
|
|
|
300
426
|
private:
|
|
301
427
|
BlockBuilder index_block_builder_;
|
|
428
|
+
// TODO: consider optimizing to only one builder. When discovering that
|
|
429
|
+
// sequence numbers are needed, read existing entries without seq and rewrite
|
|
430
|
+
// them with seq (which should be trivial to populate since seq wasn't needed
|
|
431
|
+
// before).
|
|
302
432
|
BlockBuilder index_block_builder_without_seq_;
|
|
303
433
|
const bool use_value_delta_encoding_;
|
|
304
|
-
bool
|
|
434
|
+
bool must_use_separator_with_seq_;
|
|
305
435
|
const bool include_first_key_;
|
|
306
436
|
BlockBasedTableOptions::IndexShorteningMode shortening_mode_;
|
|
307
437
|
BlockHandle last_encoded_handle_ = BlockHandle::NullBlockHandle();
|
|
@@ -360,6 +490,23 @@ class HashIndexBuilder : public IndexBuilder {
|
|
|
360
490
|
separator_scratch);
|
|
361
491
|
}
|
|
362
492
|
|
|
493
|
+
std::unique_ptr<PreparedIndexEntry> CreatePreparedIndexEntry() override {
|
|
494
|
+
return primary_index_builder_.CreatePreparedIndexEntry();
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
void PrepareIndexEntry(const Slice& last_key_in_current_block,
|
|
498
|
+
const Slice* first_key_in_next_block,
|
|
499
|
+
PreparedIndexEntry* out) override {
|
|
500
|
+
++current_restart_index_;
|
|
501
|
+
primary_index_builder_.PrepareIndexEntry(last_key_in_current_block,
|
|
502
|
+
first_key_in_next_block, out);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
void FinishIndexEntry(const BlockHandle& block_handle,
|
|
506
|
+
PreparedIndexEntry* entry) override {
|
|
507
|
+
primary_index_builder_.FinishIndexEntry(block_handle, entry);
|
|
508
|
+
}
|
|
509
|
+
|
|
363
510
|
void OnKeyAdded(const Slice& key,
|
|
364
511
|
const std::optional<Slice>& /*value*/) override {
|
|
365
512
|
auto key_prefix = hash_key_extractor_->Transform(key);
|
|
@@ -407,8 +554,8 @@ class HashIndexBuilder : public IndexBuilder {
|
|
|
407
554
|
prefix_meta_block_.size();
|
|
408
555
|
}
|
|
409
556
|
|
|
410
|
-
bool
|
|
411
|
-
return primary_index_builder_.
|
|
557
|
+
bool separator_is_key_plus_seq() override {
|
|
558
|
+
return primary_index_builder_.separator_is_key_plus_seq();
|
|
412
559
|
}
|
|
413
560
|
|
|
414
561
|
private:
|
|
@@ -466,6 +613,14 @@ class PartitionedIndexBuilder : public IndexBuilder {
|
|
|
466
613
|
const BlockHandle& block_handle,
|
|
467
614
|
std::string* separator_scratch) override;
|
|
468
615
|
|
|
616
|
+
std::unique_ptr<PreparedIndexEntry> CreatePreparedIndexEntry() override;
|
|
617
|
+
void PrepareIndexEntry(const Slice& last_key_in_current_block,
|
|
618
|
+
const Slice* first_key_in_next_block,
|
|
619
|
+
PreparedIndexEntry* out) override;
|
|
620
|
+
void FinishIndexEntry(const BlockHandle& block_handle,
|
|
621
|
+
PreparedIndexEntry* entry) override;
|
|
622
|
+
void MaybeFlush(const Slice& index_key, const BlockHandle& index_value);
|
|
623
|
+
|
|
469
624
|
Status Finish(IndexBlocks* index_blocks,
|
|
470
625
|
const BlockHandle& last_partition_block_handle) override;
|
|
471
626
|
|
|
@@ -491,8 +646,8 @@ class PartitionedIndexBuilder : public IndexBuilder {
|
|
|
491
646
|
// cutting the next partition
|
|
492
647
|
void RequestPartitionCut();
|
|
493
648
|
|
|
494
|
-
bool
|
|
495
|
-
return
|
|
649
|
+
bool separator_is_key_plus_seq() override {
|
|
650
|
+
return must_use_separator_with_seq_;
|
|
496
651
|
}
|
|
497
652
|
|
|
498
653
|
bool get_use_value_delta_encoding() const {
|
|
@@ -518,14 +673,14 @@ class PartitionedIndexBuilder : public IndexBuilder {
|
|
|
518
673
|
std::list<Entry> entries_;
|
|
519
674
|
BlockBuilder index_block_builder_; // top-level index builder
|
|
520
675
|
BlockBuilder index_block_builder_without_seq_; // same for user keys
|
|
521
|
-
// the active partition index builder
|
|
522
|
-
|
|
676
|
+
// the active partition index builder (owned by an Entry in entries_)
|
|
677
|
+
ShortenedIndexBuilder* sub_index_builder_;
|
|
523
678
|
// the last key in the active partition index builder
|
|
524
|
-
std::unique_ptr<
|
|
679
|
+
std::unique_ptr<RetargetableFlushBlockPolicy> flush_policy_;
|
|
525
680
|
// true if Finish is called once but not complete yet.
|
|
526
|
-
bool
|
|
681
|
+
bool finishing_indexes_ = false;
|
|
527
682
|
const BlockBasedTableOptions& table_opt_;
|
|
528
|
-
bool
|
|
683
|
+
bool must_use_separator_with_seq_;
|
|
529
684
|
bool use_value_delta_encoding_;
|
|
530
685
|
// true if an external entity (such as filter partition builder) request
|
|
531
686
|
// cutting the next partition
|
|
@@ -240,7 +240,7 @@ Status PartitionedFilterBlockBuilder::Finish(
|
|
|
240
240
|
|
|
241
241
|
index_on_filter_block_builder_.Add(e.ikey, handle_encoding,
|
|
242
242
|
&handle_delta_encoding_slice);
|
|
243
|
-
if (!p_index_builder_->
|
|
243
|
+
if (!p_index_builder_->separator_is_key_plus_seq()) {
|
|
244
244
|
index_on_filter_block_builder_without_seq_.Add(
|
|
245
245
|
ExtractUserKey(e.ikey), handle_encoding,
|
|
246
246
|
&handle_delta_encoding_slice);
|
|
@@ -267,7 +267,7 @@ Status PartitionedFilterBlockBuilder::Finish(
|
|
|
267
267
|
if (UNLIKELY(filters_.empty())) {
|
|
268
268
|
if (!index_on_filter_block_builder_.empty()) {
|
|
269
269
|
// Simplest to just add them all at the end
|
|
270
|
-
if (p_index_builder_->
|
|
270
|
+
if (p_index_builder_->separator_is_key_plus_seq()) {
|
|
271
271
|
*filter = index_on_filter_block_builder_.Finish();
|
|
272
272
|
} else {
|
|
273
273
|
*filter = index_on_filter_block_builder_without_seq_.Finish();
|
|
@@ -27,7 +27,7 @@ class MockedBlockBasedTable : public BlockBasedTable {
|
|
|
27
27
|
MockedBlockBasedTable(Rep* rep, PartitionedIndexBuilder* pib)
|
|
28
28
|
: BlockBasedTable(rep, /*block_cache_tracer=*/nullptr) {
|
|
29
29
|
// Initialize what Open normally does as much as necessary for the test
|
|
30
|
-
rep->index_key_includes_seq = pib->
|
|
30
|
+
rep->index_key_includes_seq = pib->separator_is_key_plus_seq();
|
|
31
31
|
rep->index_value_is_full = !pib->get_use_value_delta_encoding();
|
|
32
32
|
}
|
|
33
33
|
};
|
|
@@ -46,23 +46,57 @@ class UserDefinedIndexBuilderWrapper : public IndexBuilder {
|
|
|
46
46
|
handle.offset = block_handle.offset();
|
|
47
47
|
handle.size = block_handle.size();
|
|
48
48
|
// Forward the call to both index builders
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
ParsedInternalKey pkey_last;
|
|
50
|
+
ParsedInternalKey pkey_first;
|
|
51
|
+
// There's no way to return an error here, so we remember the statsu and
|
|
52
|
+
// return it in Finish()
|
|
53
|
+
if (status_.ok()) {
|
|
54
|
+
status_ = ParseInternalKey(last_key_in_current_block, &pkey_last,
|
|
55
|
+
/*lof_err_key*/ false);
|
|
56
|
+
}
|
|
57
|
+
if (status_.ok() && first_key_in_next_block) {
|
|
58
|
+
status_ = ParseInternalKey(*first_key_in_next_block, &pkey_first,
|
|
59
|
+
/*lof_err_key*/ false);
|
|
60
|
+
}
|
|
61
|
+
if (status_.ok()) {
|
|
62
|
+
user_defined_index_builder_->AddIndexEntry(
|
|
63
|
+
pkey_last.user_key,
|
|
64
|
+
first_key_in_next_block ? &pkey_first.user_key : nullptr, handle,
|
|
65
|
+
separator_scratch);
|
|
66
|
+
}
|
|
52
67
|
return internal_index_builder_->AddIndexEntry(
|
|
53
68
|
last_key_in_current_block, first_key_in_next_block, block_handle,
|
|
54
69
|
separator_scratch);
|
|
55
70
|
}
|
|
56
71
|
|
|
72
|
+
// Not supported with parallel compression
|
|
73
|
+
std::unique_ptr<PreparedIndexEntry> CreatePreparedIndexEntry() override {
|
|
74
|
+
return nullptr;
|
|
75
|
+
}
|
|
76
|
+
void PrepareIndexEntry(const Slice& last_key_in_current_block,
|
|
77
|
+
const Slice* first_key_in_next_block,
|
|
78
|
+
PreparedIndexEntry* out) override {
|
|
79
|
+
(void)last_key_in_current_block;
|
|
80
|
+
(void)first_key_in_next_block;
|
|
81
|
+
(void)out;
|
|
82
|
+
assert(false);
|
|
83
|
+
}
|
|
84
|
+
void FinishIndexEntry(const BlockHandle& block_handle,
|
|
85
|
+
PreparedIndexEntry* entry) override {
|
|
86
|
+
(void)block_handle;
|
|
87
|
+
(void)entry;
|
|
88
|
+
assert(false);
|
|
89
|
+
}
|
|
90
|
+
|
|
57
91
|
void OnKeyAdded(const Slice& key,
|
|
58
92
|
const std::optional<Slice>& value) override {
|
|
93
|
+
ParsedInternalKey pkey;
|
|
59
94
|
if (status_.ok()) {
|
|
60
95
|
if (!value.has_value()) {
|
|
61
96
|
status_ = Status::InvalidArgument(
|
|
62
97
|
"user_defined_index_factory not supported with parallel "
|
|
63
98
|
"compression");
|
|
64
99
|
} else {
|
|
65
|
-
ParsedInternalKey pkey;
|
|
66
100
|
status_ = ParseInternalKey(key, &pkey, /*lof_err_key*/ false);
|
|
67
101
|
if (status_.ok() && pkey.type != ValueType::kTypeValue) {
|
|
68
102
|
status_ = Status::InvalidArgument(
|
|
@@ -76,16 +110,38 @@ class UserDefinedIndexBuilderWrapper : public IndexBuilder {
|
|
|
76
110
|
|
|
77
111
|
// Forward the call to both index builders
|
|
78
112
|
internal_index_builder_->OnKeyAdded(key, value);
|
|
113
|
+
|
|
114
|
+
// Pass the user key to the UDI. We don't expect multiple entries with
|
|
115
|
+
// different sequence numbers for the same key in the file. RocksDB may
|
|
116
|
+
// enforce it in the future by allowing UDIs only for read only
|
|
117
|
+
// bulkloaded use cases, and only allow ingestion of files with
|
|
118
|
+
// sequence number 0.
|
|
79
119
|
user_defined_index_builder_->OnKeyAdded(
|
|
80
|
-
|
|
120
|
+
pkey.user_key, UserDefinedIndexBuilder::ValueType::kValue,
|
|
121
|
+
value.value());
|
|
81
122
|
}
|
|
82
123
|
|
|
83
124
|
Status Finish(IndexBlocks* index_blocks,
|
|
84
125
|
const BlockHandle& last_partition_block_handle) override {
|
|
85
|
-
if (!status_.ok()) {
|
|
126
|
+
if (!status_.ok() && !status_.IsIncomplete()) {
|
|
86
127
|
return status_;
|
|
87
128
|
}
|
|
88
129
|
|
|
130
|
+
if (!udi_finished_) {
|
|
131
|
+
// Finish the user defined index builder
|
|
132
|
+
Slice user_index_contents;
|
|
133
|
+
status_ = user_defined_index_builder_->Finish(&user_index_contents);
|
|
134
|
+
if (!status_.ok()) {
|
|
135
|
+
return status_;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Add the user defined index to the meta blocks
|
|
139
|
+
std::string block_name = kUserDefinedIndexPrefix + name_;
|
|
140
|
+
index_blocks->meta_blocks.insert(
|
|
141
|
+
{block_name, {BlockType::kUserDefinedIndex, user_index_contents}});
|
|
142
|
+
udi_finished_ = true;
|
|
143
|
+
}
|
|
144
|
+
|
|
89
145
|
// Finish the internal index builder
|
|
90
146
|
status_ = internal_index_builder_->Finish(index_blocks,
|
|
91
147
|
last_partition_block_handle);
|
|
@@ -93,26 +149,14 @@ class UserDefinedIndexBuilderWrapper : public IndexBuilder {
|
|
|
93
149
|
return status_;
|
|
94
150
|
}
|
|
95
151
|
|
|
96
|
-
// Finish the user defined index builder
|
|
97
|
-
Slice user_index_contents;
|
|
98
|
-
status_ = user_defined_index_builder_->Finish(&user_index_contents);
|
|
99
|
-
if (!status_.ok()) {
|
|
100
|
-
return status_;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Add the user defined index to the meta blocks
|
|
104
|
-
std::string block_name = kUserDefinedIndexPrefix + name_;
|
|
105
|
-
index_blocks->meta_blocks.insert(
|
|
106
|
-
{block_name, {BlockType::kUserDefinedIndex, user_index_contents}});
|
|
107
|
-
|
|
108
152
|
index_size_ = internal_index_builder_->IndexSize();
|
|
109
153
|
return status_;
|
|
110
154
|
}
|
|
111
155
|
|
|
112
156
|
size_t IndexSize() const override { return index_size_; }
|
|
113
157
|
|
|
114
|
-
bool
|
|
115
|
-
return internal_index_builder_->
|
|
158
|
+
bool separator_is_key_plus_seq() override {
|
|
159
|
+
return internal_index_builder_->separator_is_key_plus_seq();
|
|
116
160
|
}
|
|
117
161
|
|
|
118
162
|
private:
|
|
@@ -120,6 +164,7 @@ class UserDefinedIndexBuilderWrapper : public IndexBuilder {
|
|
|
120
164
|
std::unique_ptr<IndexBuilder> internal_index_builder_;
|
|
121
165
|
std::unique_ptr<UserDefinedIndexBuilder> user_defined_index_builder_;
|
|
122
166
|
Status status_;
|
|
167
|
+
bool udi_finished_ = false;
|
|
123
168
|
};
|
|
124
169
|
|
|
125
170
|
class UserDefinedIndexIteratorWrapper
|
|
@@ -144,23 +189,41 @@ class UserDefinedIndexIteratorWrapper
|
|
|
144
189
|
status_ = ParseInternalKey(target, &pkey, /*log_err_key=*/false);
|
|
145
190
|
if (status_.ok()) {
|
|
146
191
|
status_ = udi_iter_->SeekAndGetResult(pkey.user_key, &result_);
|
|
147
|
-
|
|
148
|
-
|
|
192
|
+
}
|
|
193
|
+
if (status_.ok()) {
|
|
194
|
+
valid_ = result_.bound_check_result == IterBoundCheck::kInbound;
|
|
195
|
+
if (valid_) {
|
|
196
|
+
ikey_.Set(result_.key, 0, ValueType::kTypeValue);
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
valid_ = false;
|
|
149
200
|
}
|
|
150
201
|
}
|
|
151
202
|
|
|
152
203
|
void Next() override {
|
|
153
204
|
status_ = udi_iter_->NextAndGetResult(&result_);
|
|
154
|
-
|
|
155
|
-
|
|
205
|
+
if (status_.ok()) {
|
|
206
|
+
valid_ = result_.bound_check_result == IterBoundCheck::kInbound;
|
|
207
|
+
if (valid_) {
|
|
208
|
+
ikey_.Set(result_.key, 0, ValueType::kTypeValue);
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
valid_ = false;
|
|
212
|
+
}
|
|
156
213
|
}
|
|
157
214
|
|
|
158
215
|
bool NextAndGetResult(IterateResult* result) override {
|
|
159
216
|
status_ = udi_iter_->NextAndGetResult(&result_);
|
|
160
|
-
valid_ =
|
|
161
|
-
status_.ok() && result_.bound_check_result == IterBoundCheck::kInbound;
|
|
162
217
|
if (status_.ok()) {
|
|
163
|
-
|
|
218
|
+
valid_ = result_.bound_check_result == IterBoundCheck::kInbound;
|
|
219
|
+
if (valid_) {
|
|
220
|
+
ikey_.Set(result_.key, 0, ValueType::kTypeValue);
|
|
221
|
+
}
|
|
222
|
+
if (status_.ok()) {
|
|
223
|
+
*result = result_;
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
valid_ = false;
|
|
164
227
|
}
|
|
165
228
|
return valid_;
|
|
166
229
|
}
|
|
@@ -171,7 +234,7 @@ class UserDefinedIndexIteratorWrapper
|
|
|
171
234
|
|
|
172
235
|
void Prev() override { status_ = Status::NotSupported("Prev not supported"); }
|
|
173
236
|
|
|
174
|
-
Slice key() const override { return
|
|
237
|
+
Slice key() const override { return Slice(*ikey_.const_rep()); }
|
|
175
238
|
|
|
176
239
|
IndexValue value() const override {
|
|
177
240
|
auto handle = udi_iter_->value();
|
|
@@ -181,13 +244,21 @@ class UserDefinedIndexIteratorWrapper
|
|
|
181
244
|
|
|
182
245
|
Status status() const override { return status_; }
|
|
183
246
|
|
|
184
|
-
void Prepare(const
|
|
185
|
-
|
|
247
|
+
void Prepare(const MultiScanArgs* scan_opts) override {
|
|
248
|
+
if (scan_opts) {
|
|
249
|
+
udi_iter_->Prepare(scan_opts->GetScanRanges().data(),
|
|
250
|
+
scan_opts->GetScanRanges().size());
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
IterBoundCheck UpperBoundCheckResult() override {
|
|
255
|
+
return result_.bound_check_result;
|
|
186
256
|
}
|
|
187
257
|
|
|
188
258
|
private:
|
|
189
259
|
std::unique_ptr<UserDefinedIndexIterator> udi_iter_;
|
|
190
260
|
IterateResult result_;
|
|
261
|
+
InternalKey ikey_;
|
|
191
262
|
Status status_;
|
|
192
263
|
bool valid_;
|
|
193
264
|
};
|
|
@@ -218,7 +289,13 @@ class UserDefinedIndexReaderWrapper : public BlockBasedTable::IndexReader {
|
|
|
218
289
|
}
|
|
219
290
|
std::unique_ptr<UserDefinedIndexIterator> udi_iter =
|
|
220
291
|
udi_reader_->NewIterator(read_options);
|
|
221
|
-
|
|
292
|
+
if (udi_iter) {
|
|
293
|
+
InternalIteratorBase<IndexValue>* wrap_iter =
|
|
294
|
+
new UserDefinedIndexIteratorWrapper(std::move(udi_iter));
|
|
295
|
+
return wrap_iter;
|
|
296
|
+
}
|
|
297
|
+
return NewErrorInternalIterator<IndexValue>(
|
|
298
|
+
Status::NotFound("COuld not create UDI iterator"));
|
|
222
299
|
}
|
|
223
300
|
|
|
224
301
|
virtual Status CacheDependencies(
|
|
@@ -131,9 +131,11 @@ class ExternalTableIteratorAdapter : public InternalIterator {
|
|
|
131
131
|
|
|
132
132
|
Status status() const override { return status_; }
|
|
133
133
|
|
|
134
|
-
void Prepare(const
|
|
135
|
-
if (iterator_) {
|
|
136
|
-
iterator_->Prepare(scan_opts->data(), scan_opts->size());
|
|
134
|
+
void Prepare(const MultiScanArgs* scan_opts) override {
|
|
135
|
+
if (iterator_ && scan_opts) {
|
|
136
|
+
iterator_->Prepare(scan_opts->GetScanRanges().data(), scan_opts->size());
|
|
137
|
+
} else if (iterator_) {
|
|
138
|
+
iterator_->Prepare(nullptr, 0);
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
|
|
@@ -224,6 +226,7 @@ class ExternalTableReaderAdapter : public TableReader {
|
|
|
224
226
|
// external table reader
|
|
225
227
|
props = std::make_shared<TableProperties>(*reader_->GetTableProperties());
|
|
226
228
|
props->key_largest_seqno = 0;
|
|
229
|
+
props->key_smallest_seqno = 0;
|
|
227
230
|
}
|
|
228
231
|
return props;
|
|
229
232
|
}
|
|
@@ -260,6 +263,7 @@ class ExternalTableBuilderAdapter : public TableBuilder {
|
|
|
260
263
|
properties_.filter_size = 0;
|
|
261
264
|
properties_.format_version = 0;
|
|
262
265
|
properties_.key_largest_seqno = 0;
|
|
266
|
+
properties_.key_smallest_seqno = 0;
|
|
263
267
|
properties_.column_family_id = topts.column_family_id;
|
|
264
268
|
properties_.column_family_name = topts.column_family_name;
|
|
265
269
|
properties_.db_id = topts.db_id;
|