@nxtedition/rocksdb 13.5.12 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.cc +33 -2
- 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 +3 -3
- 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
|
@@ -210,7 +210,15 @@ struct ShardedCacheOptions {
|
|
|
210
210
|
// shard has its own LRU list for evictions. Each shard also has a mutex for
|
|
211
211
|
// exclusive access during operations; even read operations need exclusive
|
|
212
212
|
// access in order to update the LRU list. Mutex contention is usually low
|
|
213
|
-
// with enough shards.
|
|
213
|
+
// with enough shards. However,
|
|
214
|
+
// * For a single hot block, there will be mutex contention even for reads
|
|
215
|
+
// regardless of the number of shards.
|
|
216
|
+
// * LRUCaches in the size of MBs instead of GBs can have shards small enough
|
|
217
|
+
// that there is a random probability of some modest number of large blocks
|
|
218
|
+
// (especially non-partitioned filters) thrashing a single cache shard.
|
|
219
|
+
//
|
|
220
|
+
// HYPERCLOCKCACHE IS NOW GENERALLY RECOMMENDED OVER LRUCACHE. See
|
|
221
|
+
// HyperClockCacheOptions below.
|
|
214
222
|
struct LRUCacheOptions : public ShardedCacheOptions {
|
|
215
223
|
// Ratio of cache reserved for high-priority and low-priority entries,
|
|
216
224
|
// respectively. (See Cache::Priority below more information on the levels.)
|
|
@@ -371,64 +379,50 @@ inline std::shared_ptr<SecondaryCache> NewCompressedSecondaryCache(
|
|
|
371
379
|
return opts.MakeSharedSecondaryCache();
|
|
372
380
|
}
|
|
373
381
|
|
|
374
|
-
// HyperClockCache - A lock-free Cache alternative for
|
|
375
|
-
// that offers much improved CPU efficiency vs. LRUCache
|
|
376
|
-
// load or high contention,
|
|
382
|
+
// HyperClockCache (also known as HCC) - A lock-free Cache alternative for
|
|
383
|
+
// RocksDB block cache that offers much improved CPU efficiency vs. LRUCache
|
|
384
|
+
// under high parallel load or high contention. Additionally, HCC only uses
|
|
385
|
+
// sharding for a modest performance boost, so can use much larger cache shards
|
|
386
|
+
// than LRUCache, dramatically reducing the risk of thrashing in configurations
|
|
387
|
+
// or work loads with some large blocks.
|
|
388
|
+
//
|
|
389
|
+
// HYPERCLOCKCACHE IS NOW GENERALLY RECOMMENDED OVER LRUCACHE
|
|
390
|
+
//
|
|
391
|
+
// Some caveats:
|
|
377
392
|
// * Not a general Cache implementation: can only be used for
|
|
378
393
|
// BlockBasedTableOptions::block_cache, which RocksDB uses in a way that is
|
|
379
394
|
// compatible with HyperClockCache.
|
|
380
|
-
// * Requires an extra tuning parameter: see estimated_entry_charge below.
|
|
381
|
-
// Similarly, substantially changing the capacity with SetCapacity could
|
|
382
|
-
// harm efficiency. -> EXPERIMENTAL: the tuning parameter can be set to 0
|
|
383
|
-
// to find the appropriate balance automatically.
|
|
384
395
|
// * Cache priorities are less aggressively enforced, which could cause
|
|
385
396
|
// cache dilution from long range scans (unless they use fill_cache=false).
|
|
397
|
+
// * In some configurations, depends on anonymous mmap support, available in
|
|
398
|
+
// Linux, Windows and more.
|
|
399
|
+
// * May have slightly lower (or slightly higher) cache hit rate vs. LRUCache,
|
|
400
|
+
// because of the bounded counting-CLOCK eviction algorithm.
|
|
386
401
|
//
|
|
387
402
|
// See internal cache/clock_cache.h for full description.
|
|
388
403
|
struct HyperClockCacheOptions : public ShardedCacheOptions {
|
|
389
|
-
// The estimated average `charge` associated with cache entries.
|
|
390
|
-
//
|
|
391
|
-
// EXPERIMENTAL: the field can be set to 0 to size the table dynamically
|
|
392
|
-
// and automatically. See also min_avg_entry_charge. This feature requires
|
|
393
|
-
// platform support for lazy anonymous memory mappings (incl Linux, Windows).
|
|
394
|
-
// Performance is very similar to choosing the best configuration parameter.
|
|
395
|
-
//
|
|
396
|
-
// PRODUCTION-TESTED: This is a critical configuration parameter for good
|
|
397
|
-
// performance, because having a table size that is fixed at creation time
|
|
398
|
-
// greatly reduces the required synchronization between threads.
|
|
399
|
-
// * If the estimate is substantially too low (e.g. less than half the true
|
|
400
|
-
// average) then metadata space overhead with be substantially higher (e.g.
|
|
401
|
-
// 200 bytes per entry rather than 100). With kFullChargeCacheMetadata, this
|
|
402
|
-
// can slightly reduce cache hit rates, and slightly reduce access times due
|
|
403
|
-
// to the larger working memory size.
|
|
404
|
-
// * If the estimate is substantially too high (e.g. 25% higher than the true
|
|
405
|
-
// average) then there might not be sufficient slots in the hash table for
|
|
406
|
-
// both efficient operation and capacity utilization (hit rate). The hyper
|
|
407
|
-
// cache will evict entries to prevent load factors that could dramatically
|
|
408
|
-
// affect lookup times, instead letting the hit rate suffer by not utilizing
|
|
409
|
-
// the full capacity.
|
|
404
|
+
// OPTIONAL: The estimated average `charge` associated with cache entries.
|
|
410
405
|
//
|
|
411
|
-
//
|
|
412
|
-
//
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
// assume that other memory charged to block cache could be negligible, and
|
|
416
|
-
// ignore it in making the estimate.
|
|
406
|
+
// When not provided (== 0, recommended and default), an HCC variant with a
|
|
407
|
+
// dynamically-growing table and generally good performance is used. This
|
|
408
|
+
// variant depends on anonymous mmaps so might not be available on all
|
|
409
|
+
// platforms.
|
|
417
410
|
//
|
|
418
|
-
//
|
|
419
|
-
//
|
|
420
|
-
//
|
|
421
|
-
//
|
|
422
|
-
//
|
|
423
|
-
//
|
|
424
|
-
// to estimate toward the lower side than the higher side
|
|
411
|
+
// If the average "charge" (uncompressed block size) of block cache entries
|
|
412
|
+
// is reasonably predicted and provided here, the most efficient variant of
|
|
413
|
+
// HCC is used. Performance is degraded if the prediction is inaccurate.
|
|
414
|
+
// Prediction could be difficult or impossible with cache-charging features
|
|
415
|
+
// such as WriteBufferManager. The best parameter choice based on a cache
|
|
416
|
+
// in use is roughly given by GetUsage() / GetOccupancyCount(), though it is
|
|
417
|
+
// better to estimate toward the lower side than the higher side when the
|
|
418
|
+
// ratio might vary.
|
|
425
419
|
size_t estimated_entry_charge;
|
|
426
420
|
|
|
427
|
-
//
|
|
428
|
-
//
|
|
429
|
-
//
|
|
430
|
-
//
|
|
431
|
-
//
|
|
421
|
+
// When estimated_entry_charge == 0, this parameter establishes a promised
|
|
422
|
+
// lower bound on the average charge of all entries in the table, which is
|
|
423
|
+
// roughly the average uncompressed SST block size of block cache entries,
|
|
424
|
+
// typically > 4KB. The default should generally suffice with almost no cost.
|
|
425
|
+
// (This option is ignored for estimated_entry_charge > 0.)
|
|
432
426
|
//
|
|
433
427
|
// More detail: The table for indexing cache entries will grow automatically
|
|
434
428
|
// as needed, but a hard upper bound on that size is needed at creation time.
|
|
@@ -478,8 +472,8 @@ struct HyperClockCacheOptions : public ShardedCacheOptions {
|
|
|
478
472
|
// keep operations very fast.
|
|
479
473
|
int eviction_effort_cap = 30;
|
|
480
474
|
|
|
481
|
-
HyperClockCacheOptions(
|
|
482
|
-
size_t _capacity, size_t _estimated_entry_charge,
|
|
475
|
+
explicit HyperClockCacheOptions(
|
|
476
|
+
size_t _capacity, size_t _estimated_entry_charge = 0,
|
|
483
477
|
int _num_shard_bits = -1, bool _strict_capacity_limit = false,
|
|
484
478
|
std::shared_ptr<MemoryAllocator> _memory_allocator = nullptr,
|
|
485
479
|
CacheMetadataChargePolicy _metadata_charge_policy =
|
|
@@ -24,9 +24,10 @@ struct CompactionJobStats {
|
|
|
24
24
|
// the elapsed CPU time of this compaction in microseconds.
|
|
25
25
|
uint64_t cpu_micros = 0;
|
|
26
26
|
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
27
|
+
// True if `num_input_records` is accurate across all subcompactions.
|
|
28
|
+
// See CompactionIterator::must_count_input_entries for some implementation
|
|
29
|
+
// details why `num_input_records` may not be accurate.
|
|
30
|
+
bool has_accurate_num_input_records = true;
|
|
30
31
|
// the number of compaction input records.
|
|
31
32
|
uint64_t num_input_records = 0;
|
|
32
33
|
// the number of blobs read from blob files
|
|
@@ -226,11 +226,15 @@ struct CompressionOptions {
|
|
|
226
226
|
// The training data will be used to generate a dictionary of max_dict_bytes.
|
|
227
227
|
uint32_t zstd_max_train_bytes = 0;
|
|
228
228
|
|
|
229
|
-
// Number of threads for parallel compression
|
|
230
|
-
// Parallel compression is enabled only if threads > 1.
|
|
231
|
-
//
|
|
229
|
+
// Number of threads for parallel compression for each running flush or
|
|
230
|
+
// compaction job. Parallel compression is enabled only if threads > 1. Not
|
|
231
|
+
// recommended for lightweight compression algorithms such as Snappy, LZ4, and
|
|
232
|
+
// obviously kNoCompression because there is unlikely to be a throughput gain.
|
|
232
233
|
//
|
|
233
|
-
// This option is valid only when BlockBasedTable is used
|
|
234
|
+
// This option is valid only when BlockBasedTable is used and is disabled
|
|
235
|
+
// (sanitized to 1) with any of these:
|
|
236
|
+
// * User-defined index (UserDefinedIndexFactory)
|
|
237
|
+
// * partition_filters == true && decouple_partitioned_filters == false
|
|
234
238
|
//
|
|
235
239
|
// When parallel compression is enabled, SST size file sizes might be
|
|
236
240
|
// more inflated compared to the target size, because more data of unknown
|
|
@@ -309,9 +313,7 @@ struct CompressionOptions {
|
|
|
309
313
|
max_compressed_bytes_per_kb = static_cast<int>(1024.0 / min_ratio + 0.5);
|
|
310
314
|
}
|
|
311
315
|
|
|
312
|
-
#if __cplusplus >= 202002L
|
|
313
316
|
bool operator==(const CompressionOptions& rhs) const = default;
|
|
314
|
-
#endif
|
|
315
317
|
};
|
|
316
318
|
|
|
317
319
|
// See advanced_compression.h
|
|
@@ -10,8 +10,13 @@
|
|
|
10
10
|
#include <array>
|
|
11
11
|
#include <cstddef>
|
|
12
12
|
#include <cstdint>
|
|
13
|
+
#include <functional>
|
|
14
|
+
#include <set>
|
|
15
|
+
#include <variant>
|
|
13
16
|
|
|
17
|
+
#include "rocksdb/comparator.h"
|
|
14
18
|
#include "rocksdb/rocksdb_namespace.h"
|
|
19
|
+
#include "rocksdb/slice.h"
|
|
15
20
|
|
|
16
21
|
namespace ROCKSDB_NAMESPACE {
|
|
17
22
|
|
|
@@ -281,4 +286,486 @@ class ManagedPtr {
|
|
|
281
286
|
Owner* owner_ = nullptr;
|
|
282
287
|
};
|
|
283
288
|
|
|
289
|
+
template <typename T, typename comp>
|
|
290
|
+
class Interval;
|
|
291
|
+
|
|
292
|
+
// The Interval Class is a generic class for holding a range, for example [2,
|
|
293
|
+
// 4]. It can be used within the IntervalSet class, which is able to keep an
|
|
294
|
+
// ordered, non-intersecting set of intervals within it. Intervals can have
|
|
295
|
+
// open-ended end points, (i.e., to infinity) for example [2,).
|
|
296
|
+
template <typename T, typename comp = std::less<T>>
|
|
297
|
+
class Interval {
|
|
298
|
+
public:
|
|
299
|
+
enum class End { INF };
|
|
300
|
+
struct CompareVariant {
|
|
301
|
+
comp comparator;
|
|
302
|
+
bool operator()(const std::variant<T, End>& a,
|
|
303
|
+
const std::variant<T, End>& b) const {
|
|
304
|
+
if (std::holds_alternative<T>(a) && std::holds_alternative<T>(b)) {
|
|
305
|
+
return comparator(std::get<T>(a), std::get<T>(b));
|
|
306
|
+
}
|
|
307
|
+
if (std::holds_alternative<End>(a) && std::holds_alternative<End>(b)) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
if (std::holds_alternative<T>(a) && std::holds_alternative<End>(b)) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
return true; // std::holds_alternative<End>(a) &&
|
|
314
|
+
// std::holds_alternative<T>(b)
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/* implicit */ Interval(const T& start, const T& end)
|
|
319
|
+
: start_(start), end_(end) {}
|
|
320
|
+
/* implicit */ Interval(const T& start) : start_(start), end_(End::INF) {}
|
|
321
|
+
|
|
322
|
+
// Add constructor that takes a pair
|
|
323
|
+
/* implicit */ Interval(const std::pair<T, T>& p)
|
|
324
|
+
: start_(p.first), end_(p.second) {}
|
|
325
|
+
|
|
326
|
+
T& start() { return start_; }
|
|
327
|
+
|
|
328
|
+
const T& start() const { return start_; }
|
|
329
|
+
|
|
330
|
+
bool has_end() const { return std::holds_alternative<T>(end_); }
|
|
331
|
+
|
|
332
|
+
T& end() { return std::get<T>(end_); }
|
|
333
|
+
|
|
334
|
+
const T& end() const { return std::get<T>(end_); }
|
|
335
|
+
|
|
336
|
+
// Support comparison with std::pair
|
|
337
|
+
bool operator==(const std::pair<T, T>& p) const {
|
|
338
|
+
return start_ == p.first && has_end() && end() == p.second;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Support comparison with another Interval
|
|
342
|
+
bool operator==(const Interval& other) const {
|
|
343
|
+
if (start_ != other.start_) {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Both have infinite end
|
|
348
|
+
if (!has_end() && !other.has_end()) {
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// One has infinite end, the other doesn't
|
|
353
|
+
if (has_end() != other.has_end()) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Both have finite end
|
|
358
|
+
return end() == other.end();
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Support comparison with another Interval
|
|
362
|
+
bool operator<(const Interval& other) const {
|
|
363
|
+
return comparator(start_, other.start_);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
bool Compare(const Interval& other) const {
|
|
367
|
+
return comparator(start_, other.start_);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
private:
|
|
371
|
+
T start_;
|
|
372
|
+
std::variant<T, End> end_;
|
|
373
|
+
comp comparator;
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
// Specialized version of Interval for Slice
|
|
377
|
+
template <>
|
|
378
|
+
class Interval<Slice, Comparator> {
|
|
379
|
+
public:
|
|
380
|
+
enum class End { INF };
|
|
381
|
+
|
|
382
|
+
// Constructors that take a Comparator
|
|
383
|
+
/* implicit */ Interval(const Comparator* c, const Slice& start,
|
|
384
|
+
const Slice& end)
|
|
385
|
+
: start_(start), end_(end), comparator_(c) {}
|
|
386
|
+
|
|
387
|
+
/* implicit */ Interval(const Comparator* c, const Slice& start)
|
|
388
|
+
: start_(start), end_(End::INF), comparator_(c) {}
|
|
389
|
+
|
|
390
|
+
// Constructor that takes a pair
|
|
391
|
+
/* implicit */ Interval(const Comparator* c, const std::pair<Slice, Slice>& p)
|
|
392
|
+
: start_(p.first), end_(p.second), comparator_(c) {}
|
|
393
|
+
|
|
394
|
+
Slice& start() { return start_; }
|
|
395
|
+
|
|
396
|
+
const Slice& start() const { return start_; }
|
|
397
|
+
|
|
398
|
+
bool has_end() const { return std::holds_alternative<Slice>(end_); }
|
|
399
|
+
|
|
400
|
+
Slice& end() { return std::get<Slice>(end_); }
|
|
401
|
+
|
|
402
|
+
const Slice& end() const { return std::get<Slice>(end_); }
|
|
403
|
+
|
|
404
|
+
// Support comparison with std::pair
|
|
405
|
+
bool operator==(const std::pair<Slice, Slice>& p) const {
|
|
406
|
+
return start_ == p.first && has_end() && end() == p.second;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Support comparison with another Interval
|
|
410
|
+
bool operator==(const Interval& other) const {
|
|
411
|
+
if (comparator_->Compare(start_, other.start_) != 0) {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Both have infinite end
|
|
416
|
+
if (!has_end() && !other.has_end()) {
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// One has infinite end, the other doesn't
|
|
421
|
+
if (has_end() != other.has_end()) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Both have finite end
|
|
426
|
+
return comparator_->Compare(end(), other.end()) == 0;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Support comparison with another Interval
|
|
430
|
+
bool operator<(const Interval& other) const {
|
|
431
|
+
return comparator_->Compare(start_, other.start_) < 0;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
bool Compare(const Interval& other) const {
|
|
435
|
+
return comparator_->Compare(start_, other.start_) < 0;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const Comparator* GetComparator() const { return comparator_; }
|
|
439
|
+
|
|
440
|
+
private:
|
|
441
|
+
Slice start_;
|
|
442
|
+
std::variant<Slice, End> end_;
|
|
443
|
+
const Comparator* comparator_;
|
|
444
|
+
|
|
445
|
+
std::unordered_map<std::string, std::string> property_bag;
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
template <typename T, typename Compare = std::less<T>>
|
|
449
|
+
struct CompareInterval {
|
|
450
|
+
bool operator()(const Interval<T, Compare>& a,
|
|
451
|
+
const Interval<T, Compare>& b) const {
|
|
452
|
+
return a.Compare(b);
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
// IntervalSet will be used to represent a set of intervals (including unbounded
|
|
457
|
+
// ones). The intervals are unique and disjoint. Intervals that are inserted
|
|
458
|
+
// will merge with any range they intersect with.
|
|
459
|
+
template <typename T, typename Compare = typename Interval<T>::CompareVariant>
|
|
460
|
+
class IntervalSet {
|
|
461
|
+
public:
|
|
462
|
+
IntervalSet(Compare c = Compare()) : comp_(c) {}
|
|
463
|
+
|
|
464
|
+
void insert(Interval<T>&& i) { insertImpl(i); }
|
|
465
|
+
|
|
466
|
+
void insert(const T& start, const T& end) {
|
|
467
|
+
insertImpl(Interval<T>(start, end));
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
void insert(const T& start) { insertImpl(Interval<T>(start)); }
|
|
471
|
+
|
|
472
|
+
bool empty() const { return intervals_.empty(); }
|
|
473
|
+
void clear() { intervals_.clear(); }
|
|
474
|
+
|
|
475
|
+
auto begin() { return intervals_.begin(); }
|
|
476
|
+
auto end() { return intervals_.end(); }
|
|
477
|
+
|
|
478
|
+
auto cbegin() const { return intervals_.cbegin(); }
|
|
479
|
+
auto cend() const { return intervals_.cend(); }
|
|
480
|
+
|
|
481
|
+
size_t size() const { return intervals_.size(); }
|
|
482
|
+
|
|
483
|
+
private:
|
|
484
|
+
void insertImpl(const Interval<T>& i) {
|
|
485
|
+
// Skip empty intervals
|
|
486
|
+
if (i.has_end() && !comp_(i.start(), i.end()) &&
|
|
487
|
+
!comp_(i.end(), i.start())) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// First, check if there's any infinite interval that would contain this one
|
|
492
|
+
for (auto it = intervals_.begin(); it != intervals_.end(); ++it) {
|
|
493
|
+
if (!it->has_end() && !comp_(i.start(), it->start())) {
|
|
494
|
+
// This interval starts at or after an infinite interval
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Find the position where the interval should be inserted
|
|
500
|
+
auto it = intervals_.begin();
|
|
501
|
+
while (it != intervals_.end() && comp_(it->start(), i.start())) {
|
|
502
|
+
++it;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Check if we need to consider the previous interval
|
|
506
|
+
if (it != intervals_.begin()) {
|
|
507
|
+
--it;
|
|
508
|
+
if (it->has_end() && comp_(it->end(), i.start())) {
|
|
509
|
+
++it;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
T new_start = i.start();
|
|
514
|
+
T new_end;
|
|
515
|
+
bool inf_end = false;
|
|
516
|
+
if (i.has_end()) {
|
|
517
|
+
new_end = i.end();
|
|
518
|
+
} else {
|
|
519
|
+
// For infinite end intervals, we need to merge all intervals that start
|
|
520
|
+
// after new_start
|
|
521
|
+
std::vector<decltype(it)> to_erase;
|
|
522
|
+
while (it != intervals_.end()) {
|
|
523
|
+
new_start = comp_(it->start(), new_start) ? it->start() : new_start;
|
|
524
|
+
to_erase.push_back(it++);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
for (auto& eit : to_erase) {
|
|
528
|
+
intervals_.erase(eit);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Insert the new interval with infinite end
|
|
532
|
+
intervals_.insert(Interval<T>(new_start));
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// For finite end intervals, proceed as before
|
|
537
|
+
std::vector<decltype(it)> to_erase;
|
|
538
|
+
while (it != intervals_.end() && !comp_(new_end, it->start())) {
|
|
539
|
+
if (it->has_end() && comp_(it->end(), new_start)) {
|
|
540
|
+
++it;
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
new_start = comp_(it->start(), new_start) ? it->start() : new_start;
|
|
544
|
+
if (it->has_end()) {
|
|
545
|
+
new_end = comp_(new_end, it->end()) ? it->end() : new_end;
|
|
546
|
+
} else {
|
|
547
|
+
// If we encounter an interval with infinite end, our new interval also
|
|
548
|
+
// becomes infinite
|
|
549
|
+
inf_end = true;
|
|
550
|
+
break;
|
|
551
|
+
}
|
|
552
|
+
to_erase.push_back(it++);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// Check for any infinite intervals that start after this one
|
|
556
|
+
auto check_it = it;
|
|
557
|
+
while (check_it != intervals_.end()) {
|
|
558
|
+
if (!check_it->has_end()) {
|
|
559
|
+
inf_end = true;
|
|
560
|
+
to_erase.push_back(check_it);
|
|
561
|
+
}
|
|
562
|
+
++check_it;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
for (auto& eit : to_erase) {
|
|
566
|
+
intervals_.erase(eit);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
if (inf_end) {
|
|
570
|
+
intervals_.insert(Interval<T>(new_start));
|
|
571
|
+
} else {
|
|
572
|
+
intervals_.insert(Interval<T>(new_start, new_end));
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
std::set<Interval<T>, CompareInterval<T>> intervals_;
|
|
577
|
+
Compare comp_;
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
// Specialization of IntervalSet for Slices.
|
|
581
|
+
// Slice based intervals can have properties attached to them. This is used to
|
|
582
|
+
// push down properties in the MultiScan API. We accept two modes with
|
|
583
|
+
// IntervalSet, fail_on_intersect, which imposes a restriction that inserted
|
|
584
|
+
// ranges will be disjoint, this is needed when using properties. Insert will
|
|
585
|
+
// fail if a range is found to not be disjoint. When fail_on_instersect is
|
|
586
|
+
// false, the ranges will be merged.
|
|
587
|
+
template <>
|
|
588
|
+
class IntervalSet<Slice, Comparator> {
|
|
589
|
+
public:
|
|
590
|
+
explicit IntervalSet(const Comparator* c, bool fail_on_intersect = false)
|
|
591
|
+
: comp_(c), prop_(fail_on_intersect) {}
|
|
592
|
+
|
|
593
|
+
// Insert returns true if the interval was inserted. False indicates that the
|
|
594
|
+
// interval was not inserted, this could be do to an empty range OR that the
|
|
595
|
+
// IntervalSet is in with_properties mode and the interval overlaps with an
|
|
596
|
+
// existing interval.
|
|
597
|
+
bool insert(const Slice& start, const Slice& end) {
|
|
598
|
+
return insertImpl(Interval<Slice, Comparator>(comp_, start, end));
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// Insert returns true if the interval was inserted. False indicates that the
|
|
602
|
+
// interval was not inserted, this could be do to an empty range OR that the
|
|
603
|
+
// IntervalSet is in with_properties mode and the interval overlaps with an
|
|
604
|
+
// existing interval.
|
|
605
|
+
bool insert(const Slice& start) {
|
|
606
|
+
// Create an interval with infinite end
|
|
607
|
+
Interval<Slice, Comparator> interval(comp_, start);
|
|
608
|
+
return insertImpl(interval);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
bool insert(Interval<Slice, Comparator>&& i) { return insertImpl(i); }
|
|
612
|
+
|
|
613
|
+
bool empty() const { return intervals_.empty(); }
|
|
614
|
+
void clear() { intervals_.clear(); }
|
|
615
|
+
|
|
616
|
+
auto begin() { return intervals_.begin(); }
|
|
617
|
+
auto end() { return intervals_.end(); }
|
|
618
|
+
|
|
619
|
+
auto cbegin() const { return intervals_.cbegin(); }
|
|
620
|
+
auto cend() const { return intervals_.cend(); }
|
|
621
|
+
|
|
622
|
+
size_t size() const { return intervals_.size(); }
|
|
623
|
+
|
|
624
|
+
private:
|
|
625
|
+
// Custom comparator for finding intervals in the vector
|
|
626
|
+
struct IntervalComparator {
|
|
627
|
+
explicit IntervalComparator(const Comparator* comp) : comp_(comp) {}
|
|
628
|
+
|
|
629
|
+
bool operator()(const Interval<Slice, Comparator>& a,
|
|
630
|
+
const Interval<Slice, Comparator>& b) const {
|
|
631
|
+
return comp_->Compare(a.start(), b.start()) < 0;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
const Comparator* comp_;
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
typename std::vector<Interval<Slice, Comparator>>::iterator findPosition(
|
|
638
|
+
const Interval<Slice, Comparator>& interval) {
|
|
639
|
+
// Find the position where the new interval should be inserted
|
|
640
|
+
for (auto it = intervals_.begin(); it != intervals_.end(); ++it) {
|
|
641
|
+
if (comp_->Compare(it->start(), interval.start()) >= 0) {
|
|
642
|
+
return it;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return intervals_.end();
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
bool insertImpl(const Interval<Slice, Comparator>& i) {
|
|
649
|
+
// Skip empty intervals
|
|
650
|
+
if (i.has_end() && comp_->Compare(i.start(), i.end()) >= 0) {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// Find the position where this interval would be inserted
|
|
655
|
+
// This also checks if the interval is completely contained within an
|
|
656
|
+
// existing one
|
|
657
|
+
auto it = findPosition(i);
|
|
658
|
+
|
|
659
|
+
// Check if we need to merge with previous interval
|
|
660
|
+
if (it != intervals_.begin()) {
|
|
661
|
+
auto prev = it - 1;
|
|
662
|
+
if (prev->has_end() && comp_->Compare(prev->end(), i.start()) < 0) {
|
|
663
|
+
// No overlap with previous interval
|
|
664
|
+
} else {
|
|
665
|
+
// There is overlap, adjust iterator to include previous interval
|
|
666
|
+
if (prop_) {
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
669
|
+
it = prev;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
Slice new_start = i.start();
|
|
674
|
+
Slice new_end;
|
|
675
|
+
bool inf_end = false;
|
|
676
|
+
|
|
677
|
+
if (i.has_end()) {
|
|
678
|
+
new_end = i.end();
|
|
679
|
+
} else {
|
|
680
|
+
// For infinite end intervals, we need to merge all intervals that start
|
|
681
|
+
// after new_start
|
|
682
|
+
auto erase_start = it;
|
|
683
|
+
while (it != intervals_.end()) {
|
|
684
|
+
if (comp_->Compare(it->start(), new_start) < 0) {
|
|
685
|
+
if (prop_) {
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
new_start = it->start();
|
|
689
|
+
}
|
|
690
|
+
++it;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// Erase all intervals from erase_start to end
|
|
694
|
+
if (erase_start != intervals_.end()) {
|
|
695
|
+
if (prop_) {
|
|
696
|
+
return false;
|
|
697
|
+
}
|
|
698
|
+
intervals_.erase(erase_start, intervals_.end());
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Insert the new interval with infinite end
|
|
702
|
+
Interval<Slice, Comparator> new_interval(comp_, new_start);
|
|
703
|
+
auto pos = findPosition(new_interval);
|
|
704
|
+
intervals_.insert(pos, new_interval);
|
|
705
|
+
return true;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// For finite end intervals, find all overlapping intervals
|
|
709
|
+
auto erase_start = it;
|
|
710
|
+
auto erase_end = it;
|
|
711
|
+
|
|
712
|
+
while (it != intervals_.end() &&
|
|
713
|
+
comp_->Compare(new_end, it->start()) >= 0) {
|
|
714
|
+
if (it->has_end() && comp_->Compare(it->end(), new_start) < 0) {
|
|
715
|
+
// No overlap
|
|
716
|
+
++it;
|
|
717
|
+
erase_end = it;
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
if (comp_->Compare(it->start(), new_start) < 0) {
|
|
722
|
+
new_start = it->start();
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
if (it->has_end()) {
|
|
726
|
+
if (comp_->Compare(new_end, it->end()) < 0) {
|
|
727
|
+
new_end = it->end();
|
|
728
|
+
}
|
|
729
|
+
} else {
|
|
730
|
+
// If we encounter an interval with infinite end, our new interval also
|
|
731
|
+
// becomes infinite
|
|
732
|
+
inf_end = true;
|
|
733
|
+
erase_end = intervals_.end();
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
++it;
|
|
738
|
+
erase_end = it;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// Check for any infinite intervals that start after this one
|
|
742
|
+
while (it != intervals_.end()) {
|
|
743
|
+
if (!it->has_end()) {
|
|
744
|
+
inf_end = true;
|
|
745
|
+
erase_end = intervals_.end();
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
++it;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Erase all merged intervals
|
|
752
|
+
if (erase_start != erase_end) {
|
|
753
|
+
intervals_.erase(erase_start, erase_end);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// Insert the new merged interval
|
|
757
|
+
Interval<Slice, Comparator> new_interval =
|
|
758
|
+
inf_end ? Interval<Slice, Comparator>(comp_, new_start)
|
|
759
|
+
: Interval<Slice, Comparator>(comp_, new_start, new_end);
|
|
760
|
+
|
|
761
|
+
auto pos = findPosition(new_interval);
|
|
762
|
+
intervals_.insert(pos, new_interval);
|
|
763
|
+
return true;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const Comparator* comp_;
|
|
767
|
+
std::vector<Interval<Slice, Comparator>> intervals_;
|
|
768
|
+
bool prop_;
|
|
769
|
+
};
|
|
770
|
+
|
|
284
771
|
} // namespace ROCKSDB_NAMESPACE
|