@nxtedition/rocksdb 15.4.0 → 15.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.cc +24 -19
- package/cache.js +1 -1
- package/chained-batch.js +12 -3
- package/deps/rocksdb/rocksdb/.clang-tidy +86 -0
- package/deps/rocksdb/rocksdb/BUCK +42 -0
- package/deps/rocksdb/rocksdb/CMakeLists.txt +11 -0
- package/deps/rocksdb/rocksdb/Makefile +59 -32
- package/deps/rocksdb/rocksdb/cache/cache.cc +0 -5
- package/deps/rocksdb/rocksdb/cache/cache_entry_stats.h +9 -9
- package/deps/rocksdb/rocksdb/cache/cache_key.cc +3 -3
- package/deps/rocksdb/rocksdb/cache/cache_key.h +5 -5
- package/deps/rocksdb/rocksdb/cache/cache_reservation_manager.h +16 -16
- package/deps/rocksdb/rocksdb/cache/cache_test.cc +1 -1
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +258 -294
- package/deps/rocksdb/rocksdb/cache/clock_cache.h +98 -49
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +1 -5
- package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +2 -3
- package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +18 -18
- package/deps/rocksdb/rocksdb/crash_test.mk +5 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +23 -22
- package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.h +6 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_builder_test.cc +14 -16
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +38 -26
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.h +5 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +101 -18
- package/deps/rocksdb/rocksdb/db/blob/blob_index.h +12 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +6 -9
- package/deps/rocksdb/rocksdb/db/builder.cc +23 -0
- package/deps/rocksdb/rocksdb/db/builder.h +7 -0
- package/deps/rocksdb/rocksdb/db/c.cc +373 -57
- package/deps/rocksdb/rocksdb/db/c_test.c +101 -1
- package/deps/rocksdb/rocksdb/db/column_family.cc +31 -3
- package/deps/rocksdb/rocksdb/db/column_family_test.cc +10 -13
- package/deps/rocksdb/rocksdb/db/compact_files_test.cc +35 -48
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +13 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +201 -39
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +15 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_stats_test.cc +7 -7
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +2 -455
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +4 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +19 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +72 -9
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +12 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +405 -83
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +25 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +23 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +1 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +1410 -106
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +12 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +2 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +19 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +505 -45
- package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +2 -2
- package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +9 -1
- package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +7 -9
- package/deps/rocksdb/rocksdb/db/convenience.cc +4 -4
- package/deps/rocksdb/rocksdb/db/convenience_impl.h +2 -1
- package/deps/rocksdb/rocksdb/db/corruption_test.cc +60 -88
- package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +10 -12
- package/deps/rocksdb/rocksdb/db/db_basic_test.cc +471 -40
- package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +116 -2
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +5 -15
- package/deps/rocksdb/rocksdb/db/db_compaction_abort_test.cc +993 -0
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +329 -29
- package/deps/rocksdb/rocksdb/db/db_flush_test.cc +155 -13
- package/deps/rocksdb/rocksdb/db/db_impl/compacted_db_impl.cc +54 -31
- package/deps/rocksdb/rocksdb/db/db_impl/compacted_db_impl.h +1 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +232 -70
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +57 -9
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +224 -31
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +5 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +4 -2
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_follower.cc +1 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +164 -8
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +6 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.h +5 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +47 -35
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.h +22 -9
- package/deps/rocksdb/rocksdb/db/db_iter.cc +9 -0
- package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +371 -6
- package/deps/rocksdb/rocksdb/db/db_log_iter_test.cc +7 -5
- package/deps/rocksdb/rocksdb/db/db_logical_block_size_cache_test.cc +22 -23
- package/deps/rocksdb/rocksdb/db/db_memtable_test.cc +0 -2
- package/deps/rocksdb/rocksdb/db/db_merge_operator_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/db_options_test.cc +40 -0
- package/deps/rocksdb/rocksdb/db/db_properties_test.cc +32 -13
- package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_readonly_with_timestamp_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/db_secondary_test.cc +68 -15
- package/deps/rocksdb/rocksdb/db/db_sst_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_statistics_test.cc +2 -3
- package/deps/rocksdb/rocksdb/db/db_table_properties_test.cc +6 -21
- package/deps/rocksdb/rocksdb/db/db_test.cc +644 -128
- package/deps/rocksdb/rocksdb/db/db_test2.cc +198 -81
- package/deps/rocksdb/rocksdb/db/db_test_util.cc +35 -10
- package/deps/rocksdb/rocksdb/db/db_test_util.h +8 -2
- package/deps/rocksdb/rocksdb/db/db_wal_test.cc +36 -32
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +11 -7
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +499 -0
- package/deps/rocksdb/rocksdb/db/db_write_buffer_manager_test.cc +284 -20
- package/deps/rocksdb/rocksdb/db/db_write_test.cc +3 -3
- package/deps/rocksdb/rocksdb/db/dbformat.h +0 -5
- package/deps/rocksdb/rocksdb/db/error_handler.cc +24 -0
- package/deps/rocksdb/rocksdb/db/error_handler_fs_test.cc +12 -14
- package/deps/rocksdb/rocksdb/db/experimental.cc +13 -10
- package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +22 -3
- package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +21 -15
- package/deps/rocksdb/rocksdb/db/fault_injection_test.cc +4 -6
- package/deps/rocksdb/rocksdb/db/flush_job.cc +11 -3
- package/deps/rocksdb/rocksdb/db/forward_iterator_bench.cc +5 -6
- package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +4 -2
- package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +17 -17
- package/deps/rocksdb/rocksdb/db/internal_stats.cc +13 -0
- package/deps/rocksdb/rocksdb/db/internal_stats.h +2 -0
- package/deps/rocksdb/rocksdb/db/listener_test.cc +154 -27
- package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +6 -6
- package/deps/rocksdb/rocksdb/db/memtable.cc +197 -51
- package/deps/rocksdb/rocksdb/db/memtable.h +6 -0
- package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +3 -4
- package/deps/rocksdb/rocksdb/db/merge_test.cc +37 -35
- package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/options_file_test.cc +4 -4
- package/deps/rocksdb/rocksdb/db/perf_context_test.cc +9 -11
- package/deps/rocksdb/rocksdb/db/periodic_task_scheduler.cc +10 -1
- package/deps/rocksdb/rocksdb/db/periodic_task_scheduler_test.cc +292 -15
- package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +10 -17
- package/deps/rocksdb/rocksdb/db/prefix_test.cc +6 -8
- package/deps/rocksdb/rocksdb/db/repair.cc +10 -10
- package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +5 -5
- package/deps/rocksdb/rocksdb/db/table_cache.cc +142 -135
- package/deps/rocksdb/rocksdb/db/table_cache.h +30 -6
- package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +7 -7
- package/deps/rocksdb/rocksdb/db/version_builder.cc +11 -50
- package/deps/rocksdb/rocksdb/db/version_builder.h +2 -1
- package/deps/rocksdb/rocksdb/db/version_builder_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/version_edit.cc +51 -2
- package/deps/rocksdb/rocksdb/db/version_edit.h +91 -29
- package/deps/rocksdb/rocksdb/db/version_edit_handler.h +7 -7
- package/deps/rocksdb/rocksdb/db/version_set.cc +211 -50
- package/deps/rocksdb/rocksdb/db/version_set.h +40 -3
- package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +5 -0
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +294 -21
- package/deps/rocksdb/rocksdb/db/version_util.cc +96 -0
- package/deps/rocksdb/rocksdb/db/version_util.h +24 -0
- package/deps/rocksdb/rocksdb/db/wide/db_wide_basic_test.cc +5 -5
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +647 -31
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +219 -1
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +549 -12
- package/deps/rocksdb/rocksdb/db/write_callback_test.cc +3 -3
- package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +1 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +19 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +21 -4
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_env_wrapper.h +32 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +74 -22
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_listener.h +9 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +143 -61
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +15 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +76 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +92 -72
- package/deps/rocksdb/rocksdb/env/env.cc +1 -0
- package/deps/rocksdb/rocksdb/env/env_test.cc +365 -2
- package/deps/rocksdb/rocksdb/env/fs_posix.cc +31 -30
- package/deps/rocksdb/rocksdb/env/io_posix.cc +8 -11
- package/deps/rocksdb/rocksdb/env/io_posix.h +30 -1
- package/deps/rocksdb/rocksdb/env/io_posix_test.cc +43 -0
- package/deps/rocksdb/rocksdb/file/delete_scheduler.cc +1 -1
- package/deps/rocksdb/rocksdb/file/delete_scheduler_test.cc +108 -0
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +32 -4
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +4 -4
- package/deps/rocksdb/rocksdb/file/file_util.cc +8 -2
- package/deps/rocksdb/rocksdb/file/file_util.h +2 -1
- package/deps/rocksdb/rocksdb/file/prefetch_test.cc +331 -12
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +52 -35
- package/deps/rocksdb/rocksdb/folly.mk +22 -5
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_cache.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_compression.h +100 -54
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +67 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/c.h +149 -13
- package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +1 -12
- package/deps/rocksdb/rocksdb/include/rocksdb/db.h +78 -97
- package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +3 -3
- package/deps/rocksdb/rocksdb/include/rocksdb/external_table.h +2 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/file_checksum.h +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +17 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/functor_wrapper.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/io_dispatcher.h +358 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/iostats_context.h +13 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +43 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/memtablerep.h +20 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +63 -21
- package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +10 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/rate_limiter.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/slice_transform.h +2 -7
- package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_reader.h +13 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +3 -14
- package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +49 -9
- package/deps/rocksdb/rocksdb/include/rocksdb/status.h +8 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/table.h +77 -6
- package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +15 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/tool_hooks.h +16 -10
- package/deps/rocksdb/rocksdb/include/rocksdb/unique_id.h +5 -5
- package/deps/rocksdb/rocksdb/include/rocksdb/universal_compaction.h +2 -4
- package/deps/rocksdb/rocksdb/include/rocksdb/user_defined_index.h +106 -46
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/db_ttl.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd.h +14 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/memory_util.h +5 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/optimistic_transaction_db.h +2 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +7 -9
- package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
- package/deps/rocksdb/rocksdb/logging/auto_roll_logger_test.cc +1 -2
- package/deps/rocksdb/rocksdb/memory/memory_allocator_test.cc +2 -2
- package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +226 -8
- package/deps/rocksdb/rocksdb/memtable/inlineskiplist_test.cc +490 -0
- package/deps/rocksdb/rocksdb/memtable/skiplist.h +3 -3
- package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +11 -0
- package/deps/rocksdb/rocksdb/microbench/db_basic_bench.cc +4 -12
- package/deps/rocksdb/rocksdb/microbench/ribbon_bench.cc +5 -5
- package/deps/rocksdb/rocksdb/monitoring/file_read_sample.h +21 -4
- package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +9 -3
- package/deps/rocksdb/rocksdb/monitoring/statistics.cc +21 -2
- package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +2 -2
- package/deps/rocksdb/rocksdb/options/cf_options.cc +21 -1
- package/deps/rocksdb/rocksdb/options/cf_options.h +2 -0
- package/deps/rocksdb/rocksdb/options/customizable_test.cc +0 -2
- package/deps/rocksdb/rocksdb/options/db_options.cc +26 -5
- package/deps/rocksdb/rocksdb/options/db_options.h +3 -1
- package/deps/rocksdb/rocksdb/options/options.cc +5 -1
- package/deps/rocksdb/rocksdb/options/options_helper.cc +7 -2
- package/deps/rocksdb/rocksdb/options/options_settable_test.cc +109 -103
- package/deps/rocksdb/rocksdb/options/options_test.cc +14 -0
- package/deps/rocksdb/rocksdb/port/jemalloc_helper.h +15 -17
- package/deps/rocksdb/rocksdb/port/lang.h +4 -0
- package/deps/rocksdb/rocksdb/port/port_example.h +0 -23
- package/deps/rocksdb/rocksdb/port/stack_trace.cc +36 -0
- package/deps/rocksdb/rocksdb/port/stack_trace.h +9 -0
- package/deps/rocksdb/rocksdb/src.mk +12 -0
- package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.cc +1 -2
- package/deps/rocksdb/rocksdb/table/block_based/binary_search_index_reader.cc +2 -1
- package/deps/rocksdb/rocksdb/table/block_based/block.cc +571 -292
- package/deps/rocksdb/rocksdb/table/block_based/block.h +143 -53
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +154 -90
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +5 -1
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +51 -14
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +0 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +147 -734
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +30 -233
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +178 -108
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +13 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +17 -4
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +5 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +70 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_builder.cc +168 -24
- package/deps/rocksdb/rocksdb/table/block_based/block_builder.h +25 -9
- package/deps/rocksdb/rocksdb/table/block_based/block_cache.cc +7 -4
- package/deps/rocksdb/rocksdb/table/block_based/block_cache.h +9 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_test.cc +548 -169
- package/deps/rocksdb/rocksdb/table/block_based/block_type.h +30 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_util.h +156 -0
- package/deps/rocksdb/rocksdb/table/block_based/data_block_footer.cc +73 -30
- package/deps/rocksdb/rocksdb/table/block_based/data_block_footer.h +74 -7
- package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index.h +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +20 -14
- package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +22 -12
- package/deps/rocksdb/rocksdb/table/block_based/mock_block_based_table.h +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/multi_scan_index_iterator.cc +332 -0
- package/deps/rocksdb/rocksdb/table/block_based/multi_scan_index_iterator.h +133 -0
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +4 -2
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +1 -1
- package/deps/rocksdb/rocksdb/table/block_based/reader_common.cc +3 -2
- package/deps/rocksdb/rocksdb/table/block_based/reader_common.h +4 -1
- package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.h +0 -1
- package/deps/rocksdb/rocksdb/table/block_based/user_defined_index_wrapper.h +126 -46
- package/deps/rocksdb/rocksdb/table/block_fetcher.cc +31 -3
- package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +1 -2
- package/deps/rocksdb/rocksdb/table/cleanable_test.cc +3 -1
- package/deps/rocksdb/rocksdb/table/external_table.cc +25 -4
- package/deps/rocksdb/rocksdb/table/format.cc +27 -15
- package/deps/rocksdb/rocksdb/table/format.h +41 -15
- package/deps/rocksdb/rocksdb/table/merging_iterator.cc +1 -0
- package/deps/rocksdb/rocksdb/table/meta_blocks.cc +22 -12
- package/deps/rocksdb/rocksdb/table/meta_blocks.h +0 -1
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +7 -21
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +0 -1
- package/deps/rocksdb/rocksdb/table/sst_file_reader.cc +88 -13
- package/deps/rocksdb/rocksdb/table/sst_file_reader_test.cc +53 -42
- package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +3 -12
- package/deps/rocksdb/rocksdb/table/table_builder.h +0 -4
- package/deps/rocksdb/rocksdb/table/table_properties.cc +18 -0
- package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +2 -3
- package/deps/rocksdb/rocksdb/table/table_test.cc +848 -172
- package/deps/rocksdb/rocksdb/table/unique_id.cc +24 -20
- package/deps/rocksdb/rocksdb/table/unique_id_impl.h +8 -8
- package/deps/rocksdb/rocksdb/test_util/sync_point.h +5 -4
- package/deps/rocksdb/rocksdb/test_util/testutil.cc +2 -1
- package/deps/rocksdb/rocksdb/test_util/testutil.h +2 -2
- package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +2 -1
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +238 -120
- package/deps/rocksdb/rocksdb/tools/db_repl_stress.cc +2 -2
- package/deps/rocksdb/rocksdb/tools/db_sanity_test.cc +2 -4
- package/deps/rocksdb/rocksdb/tools/dump/db_dump_tool.cc +4 -8
- package/deps/rocksdb/rocksdb/tools/dump/rocksdb_undump.cc +1 -1
- package/deps/rocksdb/rocksdb/tools/io_tracer_parser_test.cc +2 -3
- package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +82 -20
- package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +41 -47
- package/deps/rocksdb/rocksdb/tools/ldb_tool.cc +9 -0
- package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +5 -6
- package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +1 -1
- package/deps/rocksdb/rocksdb/tools/tool_hooks.cc +6 -5
- package/deps/rocksdb/rocksdb/tools/trace_analyzer_test.cc +4 -4
- package/deps/rocksdb/rocksdb/tools/write_stress.cc +1 -3
- package/deps/rocksdb/rocksdb/util/atomic.h +30 -23
- package/deps/rocksdb/rocksdb/util/auto_tune_compressor.cc +6 -7
- package/deps/rocksdb/rocksdb/util/auto_tune_compressor.h +3 -3
- package/deps/rocksdb/rocksdb/util/bit_fields.h +68 -46
- package/deps/rocksdb/rocksdb/util/bloom_impl.h +16 -16
- package/deps/rocksdb/rocksdb/util/coding.h +14 -27
- package/deps/rocksdb/rocksdb/util/compression.cc +365 -207
- package/deps/rocksdb/rocksdb/util/compression.h +16 -1298
- package/deps/rocksdb/rocksdb/util/compression_test.cc +347 -61
- package/deps/rocksdb/rocksdb/util/crc32c_arm64.cc +8 -9
- package/deps/rocksdb/rocksdb/util/crc32c_arm64.h +1 -1
- package/deps/rocksdb/rocksdb/util/crc32c_ppc.h +1 -1
- package/deps/rocksdb/rocksdb/util/dynamic_bloom_test.cc +3 -3
- package/deps/rocksdb/rocksdb/util/filter_bench.cc +18 -18
- package/deps/rocksdb/rocksdb/util/gflags_compat.h +3 -3
- package/deps/rocksdb/rocksdb/util/hash_test.cc +19 -7
- package/deps/rocksdb/rocksdb/util/io_dispatcher_imp.cc +1099 -0
- package/deps/rocksdb/rocksdb/util/io_dispatcher_imp.h +36 -0
- package/deps/rocksdb/rocksdb/util/io_dispatcher_test.cc +1919 -0
- package/deps/rocksdb/rocksdb/util/math.h +3 -1
- package/deps/rocksdb/rocksdb/util/mutexlock.h +19 -19
- package/deps/rocksdb/rocksdb/util/ribbon_alg.h +25 -25
- package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.cc +5 -7
- package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.h +4 -5
- package/deps/rocksdb/rocksdb/util/slice.cc +0 -10
- package/deps/rocksdb/rocksdb/util/slice_test.cc +35 -1
- package/deps/rocksdb/rocksdb/util/slice_transform_test.cc +5 -7
- package/deps/rocksdb/rocksdb/util/status.cc +3 -1
- package/deps/rocksdb/rocksdb/util/stop_watch.h +2 -0
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +4 -1
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +123 -78
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.cc +12 -93
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.h +1 -4
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.cc +0 -21
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.h +6 -48
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.cc +94 -307
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.h +12 -58
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl_filesnapshot.cc +2 -8
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_listener.h +2 -3
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +205 -811
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_dump_tool.cc +18 -9
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.cc +2 -7
- package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.h +1 -9
- package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_functional_test.cc +17 -11
- package/deps/rocksdb/rocksdb/utilities/cassandra/test_utils.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/cassandra/test_utils.h +1 -1
- package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +68 -61
- package/deps/rocksdb/rocksdb/utilities/debug.cc +2 -1
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +105 -59
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.h +274 -7
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs_test.cc +94 -0
- package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +13 -17
- package/deps/rocksdb/rocksdb/utilities/memory/memory_util.cc +16 -3
- package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend_test.cc +25 -25
- package/deps/rocksdb/rocksdb/utilities/object_registry.cc +40 -40
- package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration.cc +2 -5
- package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +17 -19
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.cc +2 -2
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.h +2 -2
- package/deps/rocksdb/rocksdb/utilities/persistent_cache/volatile_tier_impl.cc +1 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.cc +2 -2
- package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.h +4 -13
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +3 -3
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.h +6 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_seqno_test.cc +431 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +1 -2
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.h +91 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/bitvector.cc +562 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/bitvector.h +615 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/louds_trie.cc +2575 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/louds_trie.h +685 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_db_test.cc +2843 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_factory.cc +567 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_factory.h +275 -0
- package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_test.cc +5183 -0
- package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.cc +4 -3
- package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.h +1 -1
- package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +2 -2
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +3 -3
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +93 -88
- package/deps/rocksdb/rocksdb.gyp +7 -0
- package/index.js +11 -2
- package/iterator.js +15 -7
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
- package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/lua/rocks_lua_custom_library.h +0 -43
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/lua/rocks_lua_util.h +0 -55
|
@@ -38,13 +38,11 @@ namespace ROCKSDB_NAMESPACE {
|
|
|
38
38
|
namespace clock_cache {
|
|
39
39
|
|
|
40
40
|
namespace {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
ClockHandle::kCounterMask;
|
|
45
|
-
}
|
|
41
|
+
using SlotMeta = ClockHandle::SlotMeta;
|
|
42
|
+
using AcquireCounter = SlotMeta::AcquireCounter;
|
|
43
|
+
using ReleaseCounter = SlotMeta::ReleaseCounter;
|
|
46
44
|
|
|
47
|
-
inline
|
|
45
|
+
inline uint32_t GetInitialCountdown(Cache::Priority priority) {
|
|
48
46
|
// Set initial clock data from priority
|
|
49
47
|
// TODO: configuration parameters for priority handling and clock cycle
|
|
50
48
|
// count?
|
|
@@ -65,11 +63,11 @@ inline uint64_t GetInitialCountdown(Cache::Priority priority) {
|
|
|
65
63
|
inline void MarkEmpty(ClockHandle& h) {
|
|
66
64
|
#ifndef NDEBUG
|
|
67
65
|
// Mark slot as empty, with assertion
|
|
68
|
-
|
|
69
|
-
assert(
|
|
66
|
+
auto old_meta = h.meta.Exchange({});
|
|
67
|
+
assert(old_meta.IsUnderConstruction());
|
|
70
68
|
#else
|
|
71
69
|
// Mark slot as empty
|
|
72
|
-
h.meta.Store(
|
|
70
|
+
h.meta.Store({});
|
|
73
71
|
#endif
|
|
74
72
|
}
|
|
75
73
|
|
|
@@ -85,18 +83,20 @@ inline void FreeDataMarkEmpty(ClockHandle& h, MemoryAllocator* allocator) {
|
|
|
85
83
|
|
|
86
84
|
// Called to undo the effect of referencing an entry for internal purposes,
|
|
87
85
|
// so it should not be marked as having been used.
|
|
88
|
-
inline void Unref(const ClockHandle& h,
|
|
86
|
+
inline void Unref(const ClockHandle& h, uint32_t count = 1) {
|
|
89
87
|
// Pretend we never took the reference
|
|
90
88
|
// WART: there's a tiny chance we release last ref to invisible
|
|
91
89
|
// entry here. If that happens, we let eviction take care of it.
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
SlotMeta old_meta;
|
|
91
|
+
h.meta.Apply(AcquireCounter::MinusTransformPromiseNoUnderflow(count),
|
|
92
|
+
&old_meta);
|
|
93
|
+
assert(old_meta.GetRefcount() != 0);
|
|
94
94
|
(void)old_meta;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
inline bool ClockUpdate(ClockHandle& h, BaseClockTable::EvictionData* data,
|
|
98
98
|
bool* purgeable = nullptr) {
|
|
99
|
-
|
|
99
|
+
SlotMeta meta;
|
|
100
100
|
if (purgeable) {
|
|
101
101
|
assert(*purgeable == false);
|
|
102
102
|
// In AutoHCC, our eviction process follows the chain structure, so we
|
|
@@ -110,46 +110,40 @@ inline bool ClockUpdate(ClockHandle& h, BaseClockTable::EvictionData* data,
|
|
|
110
110
|
meta = h.meta.LoadRelaxed();
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
if ((
|
|
114
|
-
0) {
|
|
113
|
+
if (!meta.IsShareable()) {
|
|
115
114
|
// Only clock update Shareable entries
|
|
116
115
|
if (purgeable) {
|
|
117
116
|
*purgeable = true;
|
|
118
117
|
// AutoHCC only: make sure we only attempt to update non-empty slots
|
|
119
|
-
assert((
|
|
120
|
-
ClockHandle::kStateOccupiedBit);
|
|
118
|
+
assert(!meta.IsEmpty());
|
|
121
119
|
}
|
|
122
120
|
return false;
|
|
123
121
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
uint64_t release_count =
|
|
127
|
-
(meta >> ClockHandle::kReleaseCounterShift) & ClockHandle::kCounterMask;
|
|
122
|
+
uint32_t acquire_count = meta.GetAcquireCounter();
|
|
123
|
+
uint32_t release_count = meta.GetReleaseCounter();
|
|
128
124
|
if (acquire_count != release_count) {
|
|
129
125
|
// Only clock update entries with no outstanding refs
|
|
130
126
|
data->seen_pinned_count++;
|
|
131
127
|
return false;
|
|
132
128
|
}
|
|
133
|
-
if ((
|
|
134
|
-
acquire_count > 0) {
|
|
129
|
+
if (meta.IsVisible() && acquire_count > 0) {
|
|
135
130
|
// Decrement clock
|
|
136
|
-
|
|
137
|
-
std::min(acquire_count - 1,
|
|
131
|
+
uint32_t new_count =
|
|
132
|
+
std::min(acquire_count - 1, uint32_t{ClockHandle::kMaxCountdown} - 1);
|
|
138
133
|
// Compare-exchange in the decremented clock info, but
|
|
139
134
|
// not aggressively
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
(new_count << ClockHandle::kReleaseCounterShift) |
|
|
144
|
-
(new_count << ClockHandle::kAcquireCounterShift);
|
|
135
|
+
SlotMeta new_meta = meta;
|
|
136
|
+
new_meta.SetReleaseCounter(new_count);
|
|
137
|
+
new_meta.SetAcquireCounter(new_count);
|
|
145
138
|
h.meta.CasStrongRelaxed(meta, new_meta);
|
|
146
139
|
return false;
|
|
147
140
|
}
|
|
148
141
|
// Otherwise, remove entry (either unreferenced invisible or
|
|
149
142
|
// unreferenced and expired visible).
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
143
|
+
SlotMeta construction_meta;
|
|
144
|
+
construction_meta.SetUnderConstruction();
|
|
145
|
+
construction_meta.SetHit(meta.GetHit());
|
|
146
|
+
if (h.meta.CasStrong(meta, construction_meta)) {
|
|
153
147
|
// Took ownership.
|
|
154
148
|
data->freed_charge += h.GetTotalCharge();
|
|
155
149
|
data->freed_count += 1;
|
|
@@ -215,39 +209,39 @@ inline bool ClockUpdate(ClockHandle& h, BaseClockTable::EvictionData* data,
|
|
|
215
209
|
// counter to reach "high" state again and bumped back to "medium." (This
|
|
216
210
|
// motivates only checking for release counter in high state, not both in high
|
|
217
211
|
// state.)
|
|
218
|
-
inline void CorrectNearOverflow(
|
|
219
|
-
|
|
212
|
+
inline void CorrectNearOverflow(SlotMeta old_meta,
|
|
213
|
+
BitFieldsAtomic<SlotMeta>& meta) {
|
|
220
214
|
// We clear both top-most counter bits at the same time.
|
|
221
|
-
constexpr
|
|
222
|
-
<< (
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
constexpr
|
|
229
|
-
(kCounterTopBit | (ClockHandle::kMaxCountdown + 1))
|
|
230
|
-
<< ClockHandle::kReleaseCounterShift;
|
|
215
|
+
constexpr uint32_t kCounterTopBit = uint32_t{1}
|
|
216
|
+
<< (SlotMeta::kCounterNumBits - 1);
|
|
217
|
+
// The threshold for correcting "near overflow" is to ensure
|
|
218
|
+
// (a) the value has a top bit set that can be cleared
|
|
219
|
+
// (b) when we clear the top bit, the eviction state will be preserved
|
|
220
|
+
// (everything >= kMaxCountdown is treated equivalently)
|
|
221
|
+
// As mentioned above, we only check the release count.
|
|
222
|
+
constexpr uint32_t kThreshold = kCounterTopBit + ClockHandle::kMaxCountdown;
|
|
231
223
|
|
|
232
|
-
if (UNLIKELY(old_meta
|
|
233
|
-
|
|
224
|
+
if (UNLIKELY(old_meta.GetReleaseCounter() > kThreshold)) {
|
|
225
|
+
auto clear_transform = AcquireCounter::AndTransform(kCounterTopBit - 1) +
|
|
226
|
+
ReleaseCounter::AndTransform(kCounterTopBit - 1);
|
|
227
|
+
meta.ApplyRelaxed(clear_transform);
|
|
234
228
|
}
|
|
235
229
|
}
|
|
236
230
|
|
|
237
231
|
inline bool BeginSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
|
|
238
|
-
|
|
232
|
+
uint32_t initial_countdown, bool* already_matches) {
|
|
239
233
|
assert(*already_matches == false);
|
|
240
234
|
// Optimistically transition the slot from "empty" to
|
|
241
235
|
// "under construction" (no effect on other states)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
236
|
+
auto set_occupied = SlotMeta::OccupiedFlag::SetTransform();
|
|
237
|
+
SlotMeta old_meta;
|
|
238
|
+
h.meta.Apply(set_occupied, &old_meta);
|
|
245
239
|
|
|
246
|
-
if (
|
|
240
|
+
if (old_meta.IsEmpty()) {
|
|
247
241
|
// We've started inserting into an available slot, and taken
|
|
248
242
|
// ownership.
|
|
249
243
|
return true;
|
|
250
|
-
} else if (
|
|
244
|
+
} else if (!old_meta.IsVisible()) {
|
|
251
245
|
// Slot not usable / touchable now
|
|
252
246
|
return false;
|
|
253
247
|
}
|
|
@@ -255,15 +249,17 @@ inline bool BeginSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
|
|
|
255
249
|
// But first, we need to acquire a ref to read it. In fact, number of
|
|
256
250
|
// refs for initial countdown, so that we boost the clock state if
|
|
257
251
|
// this is a match.
|
|
258
|
-
|
|
259
|
-
|
|
252
|
+
auto add_acquire =
|
|
253
|
+
AcquireCounter::PlusTransformPromiseNoOverflow(initial_countdown);
|
|
254
|
+
h.meta.Apply(add_acquire, &old_meta);
|
|
260
255
|
// Like Lookup
|
|
261
|
-
if ((
|
|
256
|
+
if (old_meta.IsVisible()) {
|
|
262
257
|
// Acquired a read reference
|
|
263
258
|
if (h.hashed_key == proto.hashed_key) {
|
|
264
259
|
// Match. Release in a way that boosts the clock state
|
|
265
|
-
|
|
266
|
-
|
|
260
|
+
auto add_release =
|
|
261
|
+
ReleaseCounter::PlusTransformPromiseNoOverflow(initial_countdown);
|
|
262
|
+
h.meta.Apply(add_release, &old_meta);
|
|
267
263
|
// Correct for possible (but rare) overflow
|
|
268
264
|
CorrectNearOverflow(old_meta, h.meta);
|
|
269
265
|
// Insert detached instead (only if return handle needed)
|
|
@@ -273,8 +269,7 @@ inline bool BeginSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
|
|
|
273
269
|
// Mismatch.
|
|
274
270
|
Unref(h, initial_countdown);
|
|
275
271
|
}
|
|
276
|
-
} else if (UNLIKELY((
|
|
277
|
-
ClockHandle::kStateInvisible)) {
|
|
272
|
+
} else if (UNLIKELY(old_meta.IsInvisible())) {
|
|
278
273
|
// Pretend we never took the reference
|
|
279
274
|
Unref(h, initial_countdown);
|
|
280
275
|
} else {
|
|
@@ -286,25 +281,23 @@ inline bool BeginSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
|
|
|
286
281
|
}
|
|
287
282
|
|
|
288
283
|
inline void FinishSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
|
|
289
|
-
|
|
284
|
+
uint32_t initial_countdown, bool keep_ref) {
|
|
290
285
|
// Save data fields
|
|
291
286
|
ClockHandleBasicData* h_alias = &h;
|
|
292
287
|
*h_alias = proto;
|
|
293
288
|
|
|
294
289
|
// Transition from "under construction" state to "visible" state
|
|
295
|
-
|
|
296
|
-
|
|
290
|
+
SlotMeta new_meta;
|
|
291
|
+
new_meta.SetVisible();
|
|
297
292
|
|
|
298
293
|
// Maybe with an outstanding reference
|
|
299
|
-
new_meta
|
|
300
|
-
new_meta
|
|
301
|
-
<< ClockHandle::kReleaseCounterShift;
|
|
294
|
+
new_meta.SetAcquireCounter(initial_countdown);
|
|
295
|
+
new_meta.SetReleaseCounter(initial_countdown - (keep_ref ? 1 : 0));
|
|
302
296
|
|
|
303
297
|
#ifndef NDEBUG
|
|
304
298
|
// Save the state transition, with assertion
|
|
305
|
-
|
|
306
|
-
assert(old_meta
|
|
307
|
-
ClockHandle::kStateConstruction);
|
|
299
|
+
auto old_meta = h.meta.Exchange(new_meta);
|
|
300
|
+
assert(old_meta.IsUnderConstruction());
|
|
308
301
|
#else
|
|
309
302
|
// Save the state transition
|
|
310
303
|
h.meta.Store(new_meta);
|
|
@@ -312,7 +305,7 @@ inline void FinishSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
|
|
|
312
305
|
}
|
|
313
306
|
|
|
314
307
|
bool TryInsert(const ClockHandleBasicData& proto, ClockHandle& h,
|
|
315
|
-
|
|
308
|
+
uint32_t initial_countdown, bool keep_ref,
|
|
316
309
|
bool* already_matches) {
|
|
317
310
|
bool b = BeginSlotInsert(proto, h, initial_countdown, already_matches);
|
|
318
311
|
if (b) {
|
|
@@ -326,35 +319,32 @@ template <class HandleImpl, class Func>
|
|
|
326
319
|
void ConstApplyToEntriesRange(const Func& func, const HandleImpl* begin,
|
|
327
320
|
const HandleImpl* end,
|
|
328
321
|
bool apply_if_will_be_deleted) {
|
|
329
|
-
uint64_t check_state_mask = ClockHandle::kStateShareableBit;
|
|
330
|
-
if (!apply_if_will_be_deleted) {
|
|
331
|
-
check_state_mask |= ClockHandle::kStateVisibleBit;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
322
|
for (const HandleImpl* h = begin; h < end; ++h) {
|
|
335
323
|
// Note: to avoid using compare_exchange, we have to be extra careful.
|
|
336
|
-
|
|
324
|
+
SlotMeta old_meta = h->meta.LoadRelaxed();
|
|
337
325
|
// Check if it's an entry visible to lookups
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
326
|
+
if (apply_if_will_be_deleted || old_meta.IsVisible()) {
|
|
327
|
+
if (old_meta.IsShareable()) {
|
|
328
|
+
// Increment acquire counter. Note: it's possible that the entry has
|
|
329
|
+
// completely changed since we loaded old_meta, but incrementing acquire
|
|
330
|
+
// count is always safe. (Similar to optimistic Lookup here.)
|
|
331
|
+
auto add_acquire = AcquireCounter::PlusTransformPromiseNoOverflow(1);
|
|
332
|
+
h->meta.Apply(add_acquire, &old_meta);
|
|
333
|
+
// Check whether we actually acquired a reference.
|
|
334
|
+
if (old_meta.IsShareable()) {
|
|
335
|
+
// Apply func if appropriate
|
|
336
|
+
if (apply_if_will_be_deleted || old_meta.IsVisible()) {
|
|
337
|
+
func(*h);
|
|
338
|
+
}
|
|
339
|
+
// Pretend we never took the reference
|
|
340
|
+
Unref(*h);
|
|
341
|
+
// No net change, so don't need to check for overflow
|
|
342
|
+
} else {
|
|
343
|
+
// For other states, incrementing the acquire counter has no effect
|
|
344
|
+
// so we don't need to undo it. Furthermore, we cannot safely undo
|
|
345
|
+
// it because we did not acquire a read reference to lock the
|
|
346
|
+
// entry in a Shareable state.
|
|
349
347
|
}
|
|
350
|
-
// Pretend we never took the reference
|
|
351
|
-
Unref(*h);
|
|
352
|
-
// No net change, so don't need to check for overflow
|
|
353
|
-
} else {
|
|
354
|
-
// For other states, incrementing the acquire counter has no effect
|
|
355
|
-
// so we don't need to undo it. Furthermore, we cannot safely undo
|
|
356
|
-
// it because we did not acquire a read reference to lock the
|
|
357
|
-
// entry in a Shareable state.
|
|
358
348
|
}
|
|
359
349
|
}
|
|
360
350
|
}
|
|
@@ -399,9 +389,9 @@ HandleImpl* BaseClockTable::StandaloneInsert(
|
|
|
399
389
|
h->SetStandalone();
|
|
400
390
|
// Single reference (standalone entries only created if returning a refed
|
|
401
391
|
// Handle back to user)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
meta
|
|
392
|
+
SlotMeta meta;
|
|
393
|
+
meta.SetInvisible();
|
|
394
|
+
meta.SetAcquireCounter(1);
|
|
405
395
|
h->meta.Store(meta);
|
|
406
396
|
// Keep track of how much of usage is standalone
|
|
407
397
|
standalone_usage_.FetchAddRelaxed(proto.GetTotalCharge());
|
|
@@ -564,11 +554,10 @@ void BaseClockTable::TrackAndReleaseEvictedEntry(ClockHandle* h) {
|
|
|
564
554
|
if (eviction_callback_) {
|
|
565
555
|
// For key reconstructed from hash
|
|
566
556
|
UniqueId64x2 unhashed;
|
|
567
|
-
took_value_ownership =
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
h->meta.LoadRelaxed() & ClockHandle::kHitBitMask);
|
|
557
|
+
took_value_ownership = eviction_callback_(
|
|
558
|
+
ClockCacheShard<FixedHyperClockTable>::ReverseHash(
|
|
559
|
+
h->GetHash(), &unhashed, hash_seed_),
|
|
560
|
+
static_cast<Cache::Handle*>(h), h->meta.LoadRelaxed().GetHit());
|
|
572
561
|
}
|
|
573
562
|
if (!took_value_ownership) {
|
|
574
563
|
h->FreeData(allocator_);
|
|
@@ -648,7 +637,7 @@ Status BaseClockTable::Insert(const ClockHandleBasicData& proto,
|
|
|
648
637
|
// * Have to insert into a suboptimal location (more probes) so that the
|
|
649
638
|
// old entry can be kept around as well.
|
|
650
639
|
|
|
651
|
-
|
|
640
|
+
uint32_t initial_countdown = GetInitialCountdown(priority);
|
|
652
641
|
assert(initial_countdown > 0);
|
|
653
642
|
|
|
654
643
|
HandleImpl* e =
|
|
@@ -693,34 +682,34 @@ Status BaseClockTable::Insert(const ClockHandleBasicData& proto,
|
|
|
693
682
|
|
|
694
683
|
void BaseClockTable::Ref(ClockHandle& h) {
|
|
695
684
|
// Increment acquire counter
|
|
696
|
-
|
|
685
|
+
SlotMeta old_meta;
|
|
686
|
+
h.meta.Apply(AcquireCounter::PlusTransformPromiseNoOverflow(1), &old_meta);
|
|
697
687
|
|
|
698
|
-
assert((
|
|
699
|
-
ClockHandle::kStateShareableBit);
|
|
688
|
+
assert(old_meta.IsShareable());
|
|
700
689
|
// Must have already had a reference
|
|
701
|
-
assert(GetRefcount(
|
|
690
|
+
assert(old_meta.GetRefcount() > 0);
|
|
702
691
|
(void)old_meta;
|
|
703
692
|
}
|
|
704
693
|
|
|
705
694
|
#ifndef NDEBUG
|
|
706
|
-
void BaseClockTable::TEST_RefN(ClockHandle& h,
|
|
695
|
+
void BaseClockTable::TEST_RefN(ClockHandle& h, uint32_t n) {
|
|
707
696
|
// Increment acquire counter
|
|
708
|
-
|
|
697
|
+
SlotMeta old_meta;
|
|
698
|
+
h.meta.Apply(AcquireCounter::PlusTransformPromiseNoOverflow(n), &old_meta);
|
|
709
699
|
|
|
710
|
-
assert((
|
|
711
|
-
ClockHandle::kStateShareableBit);
|
|
700
|
+
assert(old_meta.IsShareable());
|
|
712
701
|
(void)old_meta;
|
|
713
702
|
}
|
|
714
703
|
|
|
715
|
-
void BaseClockTable::TEST_ReleaseNMinus1(ClockHandle* h,
|
|
704
|
+
void BaseClockTable::TEST_ReleaseNMinus1(ClockHandle* h, uint32_t n) {
|
|
716
705
|
assert(n > 0);
|
|
717
706
|
|
|
718
707
|
// Like n-1 Releases, but assumes one more will happen in the caller to take
|
|
719
708
|
// care of anything like erasing an unreferenced, invisible entry.
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
709
|
+
SlotMeta old_meta;
|
|
710
|
+
h->meta.Apply(ReleaseCounter::PlusTransformPromiseNoOverflow(n - 1),
|
|
711
|
+
&old_meta);
|
|
712
|
+
assert(old_meta.IsShareable());
|
|
724
713
|
(void)old_meta;
|
|
725
714
|
}
|
|
726
715
|
#endif
|
|
@@ -754,23 +743,20 @@ FixedHyperClockTable::~FixedHyperClockTable() {
|
|
|
754
743
|
// in the table.
|
|
755
744
|
for (size_t i = 0; i < GetTableSize(); i++) {
|
|
756
745
|
HandleImpl& h = array_[i];
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
case ClockHandle::kStateVisible:
|
|
763
|
-
assert(GetRefcount(h.meta.LoadRelaxed()) == 0);
|
|
764
|
-
h.FreeData(allocator_);
|
|
746
|
+
SlotMeta meta = h.meta.LoadRelaxed();
|
|
747
|
+
if (meta.IsShareable()) {
|
|
748
|
+
// NOTE: Reaching here invisible is rare but possible
|
|
749
|
+
assert(meta.GetRefcount() == 0);
|
|
750
|
+
h.FreeData(allocator_);
|
|
765
751
|
#ifndef NDEBUG
|
|
766
|
-
|
|
767
|
-
|
|
752
|
+
Rollback(h.hashed_key, &h);
|
|
753
|
+
ReclaimEntryUsage(h.GetTotalCharge());
|
|
768
754
|
#endif
|
|
769
|
-
|
|
770
|
-
//
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
755
|
+
} else {
|
|
756
|
+
// Should be no transient "under construction" states unless a thread
|
|
757
|
+
// was killed or we are being destructed while another thread is still
|
|
758
|
+
// operating on the structure
|
|
759
|
+
assert(meta.IsEmpty());
|
|
774
760
|
}
|
|
775
761
|
}
|
|
776
762
|
|
|
@@ -792,7 +778,7 @@ bool FixedHyperClockTable::GrowIfNeeded(size_t new_occupancy, InsertState&) {
|
|
|
792
778
|
}
|
|
793
779
|
|
|
794
780
|
FixedHyperClockTable::HandleImpl* FixedHyperClockTable::DoInsert(
|
|
795
|
-
const ClockHandleBasicData& proto,
|
|
781
|
+
const ClockHandleBasicData& proto, uint32_t initial_countdown,
|
|
796
782
|
bool keep_ref, InsertState&) {
|
|
797
783
|
bool already_matches = false;
|
|
798
784
|
HandleImpl* e = FindSlot(
|
|
@@ -843,47 +829,46 @@ FixedHyperClockTable::HandleImpl* FixedHyperClockTable::Lookup(
|
|
|
843
829
|
HandleImpl* e = FindSlot(
|
|
844
830
|
hashed_key,
|
|
845
831
|
[&](HandleImpl* h) {
|
|
832
|
+
SlotMeta old_meta;
|
|
846
833
|
// Mostly branch-free version (similar performance)
|
|
847
834
|
/*
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
bool
|
|
851
|
-
bool visible = (
|
|
852
|
-
bool match = (h->
|
|
853
|
-
h->meta.
|
|
854
|
-
|
|
855
|
-
match;
|
|
835
|
+
h->meta.Apply(AcquireCounter::PlusTransformPromiseNoOverflow(1),
|
|
836
|
+
&old_meta);
|
|
837
|
+
bool shareable = old_meta.IsShareable();
|
|
838
|
+
bool visible = old_meta.IsVisible();
|
|
839
|
+
bool match = (h->hashed_key == hashed_key) & visible;
|
|
840
|
+
h->meta.Apply(AcquireCounter::MinusTransformPromiseNoUnderflow(
|
|
841
|
+
uint32_t{shareable} & uint32_t{!match}));
|
|
842
|
+
h->meta.Apply(SlotMeta::HitFlag::Or(match));
|
|
843
|
+
return match;
|
|
856
844
|
*/
|
|
857
845
|
// Optimistic lookup should pay off when the table is relatively
|
|
858
846
|
// sparse.
|
|
859
847
|
constexpr bool kOptimisticLookup = true;
|
|
860
|
-
uint64_t old_meta;
|
|
861
848
|
if (!kOptimisticLookup) {
|
|
862
849
|
old_meta = h->meta.Load();
|
|
863
|
-
if ((
|
|
864
|
-
ClockHandle::kStateVisible) {
|
|
850
|
+
if (!old_meta.IsVisible()) {
|
|
865
851
|
return false;
|
|
866
852
|
}
|
|
867
853
|
}
|
|
868
854
|
// (Optimistically) increment acquire counter
|
|
869
|
-
|
|
855
|
+
h->meta.Apply(AcquireCounter::PlusTransformPromiseNoOverflow(1),
|
|
856
|
+
&old_meta);
|
|
870
857
|
// Check if it's an entry visible to lookups
|
|
871
|
-
if ((
|
|
872
|
-
ClockHandle::kStateVisible) {
|
|
858
|
+
if (old_meta.IsVisible()) {
|
|
873
859
|
// Acquired a read reference
|
|
874
860
|
if (h->hashed_key == hashed_key) {
|
|
875
861
|
// Match
|
|
876
862
|
// Update the hit bit
|
|
877
863
|
if (eviction_callback_) {
|
|
878
|
-
h->meta.
|
|
864
|
+
h->meta.ApplyRelaxed(SlotMeta::HitFlag::SetTransform());
|
|
879
865
|
}
|
|
880
866
|
return true;
|
|
881
867
|
} else {
|
|
882
868
|
// Mismatch. Pretend we never took the reference
|
|
883
869
|
Unref(*h);
|
|
884
870
|
}
|
|
885
|
-
} else if (UNLIKELY((
|
|
886
|
-
ClockHandle::kStateInvisible)) {
|
|
871
|
+
} else if (UNLIKELY(old_meta.IsInvisible())) {
|
|
887
872
|
// Pretend we never took the reference
|
|
888
873
|
Unref(*h);
|
|
889
874
|
} else {
|
|
@@ -907,53 +892,49 @@ bool FixedHyperClockTable::Release(HandleImpl* h, bool useful,
|
|
|
907
892
|
// is only freed up by EvictFromClock (called by Insert when space is needed)
|
|
908
893
|
// and Erase. We do this to avoid an extra atomic read of the variable usage_.
|
|
909
894
|
|
|
910
|
-
|
|
895
|
+
SlotMeta old_meta;
|
|
911
896
|
if (useful) {
|
|
912
897
|
// Increment release counter to indicate was used
|
|
913
|
-
|
|
898
|
+
auto add_release = ReleaseCounter::PlusTransformPromiseNoOverflow(1);
|
|
899
|
+
h->meta.Apply(add_release, &old_meta);
|
|
914
900
|
} else {
|
|
915
901
|
// Decrement acquire counter to pretend it never happened
|
|
916
|
-
|
|
902
|
+
auto sub_acquire = AcquireCounter::MinusTransformPromiseNoUnderflow(1);
|
|
903
|
+
h->meta.Apply(sub_acquire, &old_meta);
|
|
917
904
|
}
|
|
918
905
|
|
|
919
|
-
assert((
|
|
920
|
-
ClockHandle::kStateShareableBit);
|
|
906
|
+
assert(old_meta.IsShareable());
|
|
921
907
|
// No underflow
|
|
922
|
-
assert((
|
|
923
|
-
ClockHandle::kCounterMask) !=
|
|
924
|
-
((old_meta >> ClockHandle::kReleaseCounterShift) &
|
|
925
|
-
ClockHandle::kCounterMask));
|
|
908
|
+
assert(old_meta.GetAcquireCounter() != old_meta.GetReleaseCounter());
|
|
926
909
|
|
|
927
|
-
if (erase_if_last_ref || UNLIKELY(old_meta
|
|
928
|
-
ClockHandle::kStateInvisible)) {
|
|
910
|
+
if (erase_if_last_ref || UNLIKELY(old_meta.IsInvisible())) {
|
|
929
911
|
// FIXME: There's a chance here that another thread could replace this
|
|
930
912
|
// entry and we end up erasing the wrong one.
|
|
931
913
|
|
|
932
|
-
// Update for last
|
|
914
|
+
// Update for last Apply op
|
|
933
915
|
if (useful) {
|
|
934
|
-
old_meta
|
|
916
|
+
old_meta.SetReleaseCounter(old_meta.GetReleaseCounter() + 1);
|
|
935
917
|
} else {
|
|
936
|
-
old_meta
|
|
918
|
+
old_meta.SetAcquireCounter(old_meta.GetAcquireCounter() - 1);
|
|
937
919
|
}
|
|
938
920
|
// Take ownership if no refs
|
|
921
|
+
SlotMeta construction_meta;
|
|
922
|
+
construction_meta.SetUnderConstruction();
|
|
939
923
|
do {
|
|
940
|
-
if (GetRefcount(
|
|
924
|
+
if (old_meta.GetRefcount() != 0) {
|
|
941
925
|
// Not last ref at some point in time during this Release call
|
|
942
926
|
// Correct for possible (but rare) overflow
|
|
943
927
|
CorrectNearOverflow(old_meta, h->meta);
|
|
944
928
|
return false;
|
|
945
929
|
}
|
|
946
|
-
if ((
|
|
947
|
-
<< ClockHandle::kStateShift)) == 0) {
|
|
930
|
+
if (!old_meta.IsShareable()) {
|
|
948
931
|
// Someone else took ownership
|
|
949
932
|
return false;
|
|
950
933
|
}
|
|
951
934
|
// Note that there's a small chance that we release, another thread
|
|
952
935
|
// replaces this entry with another, reaches zero refs, and then we end
|
|
953
936
|
// up erasing that other entry. That's an acceptable risk / imprecision.
|
|
954
|
-
} while (
|
|
955
|
-
!h->meta.CasWeak(old_meta, uint64_t{ClockHandle::kStateConstruction}
|
|
956
|
-
<< ClockHandle::kStateShift));
|
|
937
|
+
} while (!h->meta.CasWeak(old_meta, construction_meta));
|
|
957
938
|
// Took ownership
|
|
958
939
|
size_t total_charge = h->GetTotalCharge();
|
|
959
940
|
if (UNLIKELY(h->IsStandalone())) {
|
|
@@ -976,7 +957,7 @@ bool FixedHyperClockTable::Release(HandleImpl* h, bool useful,
|
|
|
976
957
|
}
|
|
977
958
|
|
|
978
959
|
#ifndef NDEBUG
|
|
979
|
-
void FixedHyperClockTable::TEST_ReleaseN(HandleImpl* h,
|
|
960
|
+
void FixedHyperClockTable::TEST_ReleaseN(HandleImpl* h, uint32_t n) {
|
|
980
961
|
if (n > 0) {
|
|
981
962
|
// Do n-1 simple releases first
|
|
982
963
|
TEST_ReleaseNMinus1(h, n);
|
|
@@ -993,30 +974,29 @@ void FixedHyperClockTable::Erase(const UniqueId64x2& hashed_key) {
|
|
|
993
974
|
[&](HandleImpl* h) {
|
|
994
975
|
// Could be multiple entries in rare cases. Erase them all.
|
|
995
976
|
// Optimistically increment acquire counter
|
|
996
|
-
|
|
977
|
+
auto add_acquire = AcquireCounter::PlusTransformPromiseNoOverflow(1);
|
|
978
|
+
SlotMeta old_meta, meta;
|
|
979
|
+
h->meta.Apply(add_acquire, &old_meta, &meta);
|
|
997
980
|
// Check if it's an entry visible to lookups
|
|
998
|
-
if ((
|
|
999
|
-
ClockHandle::kStateVisible) {
|
|
981
|
+
if (meta.IsVisible()) {
|
|
1000
982
|
// Acquired a read reference
|
|
1001
983
|
if (h->hashed_key == hashed_key) {
|
|
1002
|
-
// Match.
|
|
1003
|
-
|
|
1004
|
-
h->meta.FetchAnd(~(uint64_t{ClockHandle::kStateVisibleBit}
|
|
1005
|
-
<< ClockHandle::kStateShift));
|
|
1006
|
-
// Apply update to local copy
|
|
1007
|
-
old_meta &= ~(uint64_t{ClockHandle::kStateVisibleBit}
|
|
1008
|
-
<< ClockHandle::kStateShift);
|
|
984
|
+
// Match. Take ownership if no other refs, or set invisible other
|
|
985
|
+
// refs exist.
|
|
1009
986
|
for (;;) {
|
|
1010
|
-
|
|
987
|
+
uint32_t refcount = meta.GetRefcount();
|
|
1011
988
|
assert(refcount > 0);
|
|
1012
989
|
if (refcount > 1) {
|
|
1013
990
|
// Not last ref at some point in time during this Erase call
|
|
1014
|
-
//
|
|
991
|
+
// Set invisible
|
|
992
|
+
h->meta.Apply(SlotMeta::VisibleFlag::ClearTransform());
|
|
993
|
+
// And pretend we never took the reference
|
|
1015
994
|
Unref(*h);
|
|
1016
995
|
break;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
|
|
996
|
+
}
|
|
997
|
+
SlotMeta construction_meta;
|
|
998
|
+
construction_meta.SetUnderConstruction();
|
|
999
|
+
if (h->meta.CasWeak(meta, construction_meta)) {
|
|
1020
1000
|
// Took ownership
|
|
1021
1001
|
assert(hashed_key == h->hashed_key);
|
|
1022
1002
|
size_t total_charge = h->GetTotalCharge();
|
|
@@ -1032,8 +1012,7 @@ void FixedHyperClockTable::Erase(const UniqueId64x2& hashed_key) {
|
|
|
1032
1012
|
// Mismatch. Pretend we never took the reference
|
|
1033
1013
|
Unref(*h);
|
|
1034
1014
|
}
|
|
1035
|
-
} else if (UNLIKELY((
|
|
1036
|
-
ClockHandle::kStateInvisible)) {
|
|
1015
|
+
} else if (UNLIKELY(old_meta.IsInvisible())) {
|
|
1037
1016
|
// Pretend we never took the reference
|
|
1038
1017
|
Unref(*h);
|
|
1039
1018
|
} else {
|
|
@@ -1050,17 +1029,17 @@ void FixedHyperClockTable::EraseUnRefEntries() {
|
|
|
1050
1029
|
for (size_t i = 0; i <= this->length_bits_mask_; i++) {
|
|
1051
1030
|
HandleImpl& h = array_[i];
|
|
1052
1031
|
|
|
1053
|
-
|
|
1054
|
-
if (old_meta
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1032
|
+
SlotMeta old_meta = h.meta.LoadRelaxed();
|
|
1033
|
+
if (old_meta.IsShareable() && old_meta.GetRefcount() == 0) {
|
|
1034
|
+
SlotMeta construction_meta;
|
|
1035
|
+
construction_meta.SetUnderConstruction();
|
|
1036
|
+
if (h.meta.CasStrong(old_meta, construction_meta)) {
|
|
1037
|
+
// Took ownership
|
|
1038
|
+
size_t total_charge = h.GetTotalCharge();
|
|
1039
|
+
Rollback(h.hashed_key, &h);
|
|
1040
|
+
FreeDataMarkEmpty(h, allocator_);
|
|
1041
|
+
ReclaimEntryUsage(total_charge);
|
|
1042
|
+
}
|
|
1064
1043
|
}
|
|
1065
1044
|
}
|
|
1066
1045
|
}
|
|
@@ -1320,12 +1299,12 @@ bool ClockCacheShard<Table>::Release(HandleImpl* handle, bool useful,
|
|
|
1320
1299
|
|
|
1321
1300
|
#ifndef NDEBUG
|
|
1322
1301
|
template <class Table>
|
|
1323
|
-
void ClockCacheShard<Table>::TEST_RefN(HandleImpl* h,
|
|
1302
|
+
void ClockCacheShard<Table>::TEST_RefN(HandleImpl* h, uint32_t n) {
|
|
1324
1303
|
table_.TEST_RefN(*h, n);
|
|
1325
1304
|
}
|
|
1326
1305
|
|
|
1327
1306
|
template <class Table>
|
|
1328
|
-
void ClockCacheShard<Table>::TEST_ReleaseN(HandleImpl* h,
|
|
1307
|
+
void ClockCacheShard<Table>::TEST_ReleaseN(HandleImpl* h, uint32_t n) {
|
|
1329
1308
|
table_.TEST_ReleaseN(h, n);
|
|
1330
1309
|
}
|
|
1331
1310
|
#endif
|
|
@@ -1373,8 +1352,8 @@ size_t ClockCacheShard<Table>::GetPinnedUsage() const {
|
|
|
1373
1352
|
metadata_charge_policy_ == kFullChargeCacheMetadata;
|
|
1374
1353
|
ConstApplyToEntriesRange(
|
|
1375
1354
|
[&table_pinned_usage, charge_metadata](const HandleImpl& h) {
|
|
1376
|
-
|
|
1377
|
-
|
|
1355
|
+
SlotMeta meta = h.meta.LoadRelaxed();
|
|
1356
|
+
uint32_t refcount = meta.GetRefcount();
|
|
1378
1357
|
// Holding one ref for ConstApplyToEntriesRange
|
|
1379
1358
|
assert(refcount > 0);
|
|
1380
1359
|
if (refcount > 1) {
|
|
@@ -1494,7 +1473,7 @@ void AddShardEvaluation(const FixedHyperClockCache::Shard& shard,
|
|
|
1494
1473
|
}
|
|
1495
1474
|
|
|
1496
1475
|
bool IsSlotOccupied(const ClockHandle& h) {
|
|
1497
|
-
return
|
|
1476
|
+
return !h.meta.LoadRelaxed().IsEmpty();
|
|
1498
1477
|
}
|
|
1499
1478
|
} // namespace
|
|
1500
1479
|
|
|
@@ -1759,12 +1738,12 @@ inline bool MatchAndRef(const UniqueId64x2* hashed_key, const ClockHandle& h,
|
|
|
1759
1738
|
// Must be at least something to match
|
|
1760
1739
|
assert(hashed_key || shift > 0);
|
|
1761
1740
|
|
|
1762
|
-
|
|
1741
|
+
SlotMeta old_meta, new_meta;
|
|
1763
1742
|
// (Optimistically) increment acquire counter.
|
|
1764
|
-
|
|
1743
|
+
auto add_acquire = AcquireCounter::PlusTransformPromiseNoOverflow(1);
|
|
1744
|
+
h.meta.Apply(add_acquire, &old_meta, &new_meta);
|
|
1765
1745
|
// Check if it's a referencable (sharable) entry
|
|
1766
|
-
if ((
|
|
1767
|
-
<< ClockHandle::kStateShift)) == 0) {
|
|
1746
|
+
if (!old_meta.IsShareable()) {
|
|
1768
1747
|
// For non-sharable states, incrementing the acquire counter has no effect
|
|
1769
1748
|
// so we don't need to undo it. Furthermore, we cannot safely undo
|
|
1770
1749
|
// it because we did not acquire a read reference to lock the
|
|
@@ -1775,10 +1754,9 @@ inline bool MatchAndRef(const UniqueId64x2* hashed_key, const ClockHandle& h,
|
|
|
1775
1754
|
return false;
|
|
1776
1755
|
}
|
|
1777
1756
|
// Else acquired a read reference
|
|
1778
|
-
assert(GetRefcount(
|
|
1757
|
+
assert(new_meta.GetRefcount() > 0);
|
|
1779
1758
|
if (hashed_key && h.hashed_key == *hashed_key &&
|
|
1780
|
-
LIKELY(old_meta
|
|
1781
|
-
<< ClockHandle::kStateShift))) {
|
|
1759
|
+
LIKELY(old_meta.IsVisible())) {
|
|
1782
1760
|
// Match on full key, visible
|
|
1783
1761
|
if (full_match_or_unknown) {
|
|
1784
1762
|
*full_match_or_unknown = true;
|
|
@@ -1946,7 +1924,7 @@ class AutoHyperClockTable::ChainRewriteLock {
|
|
|
1946
1924
|
}
|
|
1947
1925
|
}
|
|
1948
1926
|
|
|
1949
|
-
|
|
1927
|
+
BitFieldsAtomic<NextWithShift>* head_ptr_;
|
|
1950
1928
|
NextWithShift saved_head_;
|
|
1951
1929
|
};
|
|
1952
1930
|
|
|
@@ -2051,7 +2029,7 @@ AutoHyperClockTable::~AutoHyperClockTable() {
|
|
|
2051
2029
|
HandleImpl::kUnusedMarker);
|
|
2052
2030
|
assert(array_[i].chain_next_with_shift.LoadRelaxed() ==
|
|
2053
2031
|
HandleImpl::kUnusedMarker);
|
|
2054
|
-
assert(array_[i].meta.LoadRelaxed() ==
|
|
2032
|
+
assert(array_[i].meta.LoadRelaxed() == SlotMeta{});
|
|
2055
2033
|
}
|
|
2056
2034
|
#endif // MUST_FREE_HEAP_ALLOCATIONS
|
|
2057
2035
|
#ifndef NDEBUG // Extra invariant checking
|
|
@@ -2060,30 +2038,27 @@ AutoHyperClockTable::~AutoHyperClockTable() {
|
|
|
2060
2038
|
#endif // !NDEBUG
|
|
2061
2039
|
for (size_t i = 0; i < used_end; i++) {
|
|
2062
2040
|
HandleImpl& h = array_[i];
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
case ClockHandle::kStateVisible:
|
|
2069
|
-
assert(GetRefcount(h.meta.LoadRelaxed()) == 0);
|
|
2070
|
-
h.FreeData(allocator_);
|
|
2041
|
+
SlotMeta meta = h.meta.LoadRelaxed();
|
|
2042
|
+
if (meta.IsShareable()) {
|
|
2043
|
+
// NOTE: Reaching here invisible is rare but possible
|
|
2044
|
+
assert(meta.GetRefcount() == 0);
|
|
2045
|
+
h.FreeData(allocator_);
|
|
2071
2046
|
#ifndef NDEBUG // Extra invariant checking
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2047
|
+
usage_.FetchSubRelaxed(h.total_charge);
|
|
2048
|
+
occupancy_.FetchSubRelaxed(1U);
|
|
2049
|
+
was_populated[i] = true;
|
|
2050
|
+
if (!h.chain_next_with_shift.LoadRelaxed().IsEnd()) {
|
|
2051
|
+
assert(!h.chain_next_with_shift.LoadRelaxed().IsLocked());
|
|
2052
|
+
size_t next = h.chain_next_with_shift.LoadRelaxed().GetNext();
|
|
2053
|
+
assert(!was_pointed_to[next]);
|
|
2054
|
+
was_pointed_to[next] = true;
|
|
2055
|
+
}
|
|
2081
2056
|
#endif // !NDEBUG
|
|
2082
|
-
|
|
2083
|
-
//
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2057
|
+
} else {
|
|
2058
|
+
// Should be no transient "under construction" states unless a thread
|
|
2059
|
+
// was killed or we are being destructed while another thread is still
|
|
2060
|
+
// operating on the structure
|
|
2061
|
+
assert(meta.IsEmpty());
|
|
2087
2062
|
}
|
|
2088
2063
|
#ifndef NDEBUG // Extra invariant checking
|
|
2089
2064
|
if (!h.head_next_with_shift.LoadRelaxed().IsEnd()) {
|
|
@@ -2691,20 +2666,17 @@ void AutoHyperClockTable::PurgeImplLocked(OpData* op_data,
|
|
|
2691
2666
|
op_data->push_back(h);
|
|
2692
2667
|
// Entries for eviction become purgeable
|
|
2693
2668
|
purgeable = true;
|
|
2694
|
-
assert(
|
|
2695
|
-
ClockHandle::kStateConstruction);
|
|
2669
|
+
assert(h->meta.Load().IsUnderConstruction());
|
|
2696
2670
|
}
|
|
2697
2671
|
} else {
|
|
2698
2672
|
(void)op_data;
|
|
2699
2673
|
(void)data;
|
|
2700
|
-
purgeable =
|
|
2701
|
-
ClockHandle::kStateShareableBit) == 0;
|
|
2674
|
+
purgeable = !h->meta.Load().IsShareable();
|
|
2702
2675
|
}
|
|
2703
2676
|
}
|
|
2704
2677
|
|
|
2705
2678
|
if (purgeable) {
|
|
2706
|
-
assert(
|
|
2707
|
-
ClockHandle::kStateConstruction);
|
|
2679
|
+
assert(h->meta.Load().IsUnderConstruction());
|
|
2708
2680
|
pending_purge = true;
|
|
2709
2681
|
} else if (pending_purge) {
|
|
2710
2682
|
if (prev_to_keep) {
|
|
@@ -2864,7 +2836,7 @@ void AutoHyperClockTable::PurgeImpl(OpData* op_data, size_t home,
|
|
|
2864
2836
|
}
|
|
2865
2837
|
|
|
2866
2838
|
AutoHyperClockTable::HandleImpl* AutoHyperClockTable::DoInsert(
|
|
2867
|
-
const ClockHandleBasicData& proto,
|
|
2839
|
+
const ClockHandleBasicData& proto, uint32_t initial_countdown,
|
|
2868
2840
|
bool take_ref, InsertState& state) {
|
|
2869
2841
|
size_t home;
|
|
2870
2842
|
int orig_home_shift;
|
|
@@ -3149,14 +3121,14 @@ AutoHyperClockTable::HandleImpl* AutoHyperClockTable::Lookup(
|
|
|
3149
3121
|
#endif
|
|
3150
3122
|
if (probably_equal) {
|
|
3151
3123
|
// Increment acquire counter for definitive check
|
|
3152
|
-
|
|
3124
|
+
auto add_acquire = AcquireCounter::PlusTransformPromiseNoOverflow(1);
|
|
3125
|
+
SlotMeta old_meta, new_meta;
|
|
3126
|
+
h->meta.Apply(add_acquire, &old_meta, &new_meta);
|
|
3153
3127
|
// Check if it's a referencable (sharable) entry
|
|
3154
|
-
if (LIKELY(old_meta
|
|
3155
|
-
|
|
3156
|
-
assert(GetRefcount(old_meta + ClockHandle::kAcquireIncrement) > 0);
|
|
3128
|
+
if (LIKELY(old_meta.IsShareable())) {
|
|
3129
|
+
assert(new_meta.GetRefcount() > 0);
|
|
3157
3130
|
if (LIKELY(h->hashed_key == hashed_key) &&
|
|
3158
|
-
LIKELY(old_meta
|
|
3159
|
-
<< ClockHandle::kStateShift))) {
|
|
3131
|
+
LIKELY(old_meta.IsVisible())) {
|
|
3160
3132
|
return h;
|
|
3161
3133
|
} else {
|
|
3162
3134
|
Unref(*h);
|
|
@@ -3277,7 +3249,7 @@ AutoHyperClockTable::HandleImpl* AutoHyperClockTable::Lookup(
|
|
|
3277
3249
|
}
|
|
3278
3250
|
// Update the hit bit
|
|
3279
3251
|
if (eviction_callback_) {
|
|
3280
|
-
h->meta.
|
|
3252
|
+
h->meta.ApplyRelaxed(SlotMeta::HitFlag::SetTransform());
|
|
3281
3253
|
}
|
|
3282
3254
|
// All done.
|
|
3283
3255
|
return h;
|
|
@@ -3317,8 +3289,7 @@ AutoHyperClockTable::HandleImpl* AutoHyperClockTable::Lookup(
|
|
|
3317
3289
|
}
|
|
3318
3290
|
|
|
3319
3291
|
void AutoHyperClockTable::Remove(HandleImpl* h) {
|
|
3320
|
-
assert(
|
|
3321
|
-
ClockHandle::kStateConstruction);
|
|
3292
|
+
assert(h->meta.Load().IsUnderConstruction());
|
|
3322
3293
|
|
|
3323
3294
|
const HandleImpl& c_h = *h;
|
|
3324
3295
|
PurgeImpl(&c_h.hashed_key);
|
|
@@ -3326,26 +3297,23 @@ void AutoHyperClockTable::Remove(HandleImpl* h) {
|
|
|
3326
3297
|
|
|
3327
3298
|
bool AutoHyperClockTable::TryEraseHandle(HandleImpl* h, bool holding_ref,
|
|
3328
3299
|
bool mark_invisible) {
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
// Set invisible
|
|
3332
|
-
meta = h->meta.FetchAnd(
|
|
3333
|
-
~(uint64_t{ClockHandle::kStateVisibleBit} << ClockHandle::kStateShift));
|
|
3334
|
-
// To local variable also
|
|
3335
|
-
meta &=
|
|
3336
|
-
~(uint64_t{ClockHandle::kStateVisibleBit} << ClockHandle::kStateShift);
|
|
3337
|
-
} else {
|
|
3338
|
-
meta = h->meta.Load();
|
|
3339
|
-
}
|
|
3300
|
+
SlotMeta meta = h->meta.Load();
|
|
3301
|
+
assert(!holding_ref || meta.IsShareable());
|
|
3340
3302
|
|
|
3341
|
-
// Take ownership if no other refs
|
|
3303
|
+
// Take ownership if no other refs, or set invisible if other refs exist (and
|
|
3304
|
+
// mark_invisible is set).
|
|
3305
|
+
SlotMeta construction_meta;
|
|
3306
|
+
construction_meta.SetUnderConstruction();
|
|
3342
3307
|
do {
|
|
3343
|
-
if (GetRefcount(
|
|
3308
|
+
if (meta.GetRefcount() != uint32_t{holding_ref}) {
|
|
3344
3309
|
// Not last ref at some point in time during this call
|
|
3310
|
+
if (mark_invisible) {
|
|
3311
|
+
// Set invisible
|
|
3312
|
+
h->meta.Apply(SlotMeta::VisibleFlag::ClearTransform());
|
|
3313
|
+
}
|
|
3345
3314
|
return false;
|
|
3346
3315
|
}
|
|
3347
|
-
if ((
|
|
3348
|
-
<< ClockHandle::kStateShift)) == 0) {
|
|
3316
|
+
if (!meta.IsShareable()) {
|
|
3349
3317
|
// Someone else took ownership
|
|
3350
3318
|
return false;
|
|
3351
3319
|
}
|
|
@@ -3353,8 +3321,7 @@ bool AutoHyperClockTable::TryEraseHandle(HandleImpl* h, bool holding_ref,
|
|
|
3353
3321
|
// another thread replaces this entry with another, reaches zero refs, and
|
|
3354
3322
|
// then we end up erasing that other entry. That's an acceptable risk /
|
|
3355
3323
|
// imprecision.
|
|
3356
|
-
} while (!h->meta.CasWeak(meta,
|
|
3357
|
-
<< ClockHandle::kStateShift));
|
|
3324
|
+
} while (!h->meta.CasWeak(meta, construction_meta));
|
|
3358
3325
|
// Took ownership
|
|
3359
3326
|
// TODO? Delay freeing?
|
|
3360
3327
|
h->FreeData(allocator_);
|
|
@@ -3381,27 +3348,24 @@ bool AutoHyperClockTable::Release(HandleImpl* h, bool useful,
|
|
|
3381
3348
|
// is needed) and Erase. We do this to avoid an extra atomic read of the
|
|
3382
3349
|
// variable usage_.
|
|
3383
3350
|
|
|
3384
|
-
|
|
3351
|
+
SlotMeta old_meta;
|
|
3385
3352
|
if (useful) {
|
|
3386
3353
|
// Increment release counter to indicate was used
|
|
3387
|
-
|
|
3354
|
+
auto add_release = ReleaseCounter::PlusTransformPromiseNoOverflow(1);
|
|
3355
|
+
h->meta.Apply(add_release, &old_meta);
|
|
3388
3356
|
// Correct for possible (but rare) overflow
|
|
3389
3357
|
CorrectNearOverflow(old_meta, h->meta);
|
|
3390
3358
|
} else {
|
|
3391
3359
|
// Decrement acquire counter to pretend it never happened
|
|
3392
|
-
|
|
3360
|
+
auto sub_acquire = AcquireCounter::MinusTransformPromiseNoUnderflow(1);
|
|
3361
|
+
h->meta.Apply(sub_acquire, &old_meta);
|
|
3393
3362
|
}
|
|
3394
3363
|
|
|
3395
|
-
assert((
|
|
3396
|
-
ClockHandle::kStateShareableBit);
|
|
3364
|
+
assert(old_meta.IsShareable());
|
|
3397
3365
|
// No underflow
|
|
3398
|
-
assert((
|
|
3399
|
-
ClockHandle::kCounterMask) !=
|
|
3400
|
-
((old_meta >> ClockHandle::kReleaseCounterShift) &
|
|
3401
|
-
ClockHandle::kCounterMask));
|
|
3366
|
+
assert(old_meta.GetAcquireCounter() != old_meta.GetReleaseCounter());
|
|
3402
3367
|
|
|
3403
|
-
if ((erase_if_last_ref || UNLIKELY(old_meta
|
|
3404
|
-
ClockHandle::kStateInvisible))) {
|
|
3368
|
+
if ((erase_if_last_ref || UNLIKELY(old_meta.IsInvisible()))) {
|
|
3405
3369
|
// FIXME: There's a chance here that another thread could replace this
|
|
3406
3370
|
// entry and we end up erasing the wrong one.
|
|
3407
3371
|
return TryEraseHandle(h, /*holding_ref=*/false, /*mark_invisible=*/false);
|
|
@@ -3411,7 +3375,7 @@ bool AutoHyperClockTable::Release(HandleImpl* h, bool useful,
|
|
|
3411
3375
|
}
|
|
3412
3376
|
|
|
3413
3377
|
#ifndef NDEBUG
|
|
3414
|
-
void AutoHyperClockTable::TEST_ReleaseN(HandleImpl* h,
|
|
3378
|
+
void AutoHyperClockTable::TEST_ReleaseN(HandleImpl* h, uint32_t n) {
|
|
3415
3379
|
if (n > 0) {
|
|
3416
3380
|
// Do n-1 simple releases first
|
|
3417
3381
|
TEST_ReleaseNMinus1(h, n);
|
|
@@ -3441,20 +3405,20 @@ void AutoHyperClockTable::EraseUnRefEntries() {
|
|
|
3441
3405
|
for (size_t i = 0; i < usable_size; i++) {
|
|
3442
3406
|
HandleImpl& h = array_[i];
|
|
3443
3407
|
|
|
3444
|
-
|
|
3445
|
-
if (old_meta
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3408
|
+
SlotMeta old_meta = h.meta.LoadRelaxed();
|
|
3409
|
+
if (old_meta.IsShareable() && old_meta.GetRefcount() == 0) {
|
|
3410
|
+
SlotMeta construction_meta;
|
|
3411
|
+
construction_meta.SetUnderConstruction();
|
|
3412
|
+
if (h.meta.CasStrong(old_meta, construction_meta)) {
|
|
3413
|
+
// Took ownership
|
|
3414
|
+
h.FreeData(allocator_);
|
|
3415
|
+
usage_.FetchSubRelaxed(h.total_charge);
|
|
3416
|
+
// NOTE: could be more efficient with a dedicated variant of
|
|
3417
|
+
// PurgeImpl, but this is not a common operation
|
|
3418
|
+
Remove(&h);
|
|
3419
|
+
MarkEmpty(h);
|
|
3420
|
+
occupancy_.FetchSub(1U);
|
|
3421
|
+
}
|
|
3458
3422
|
}
|
|
3459
3423
|
}
|
|
3460
3424
|
}
|