@nxtedition/rocksdb 13.1.5 → 13.2.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 +37 -12
- package/deps/rocksdb/rocksdb/{TARGETS → BUCK} +27 -0
- package/deps/rocksdb/rocksdb/CMakeLists.txt +3 -1
- package/deps/rocksdb/rocksdb/Makefile +2 -2
- package/deps/rocksdb/rocksdb/cache/cache.cc +3 -1
- package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.h +2 -0
- package/deps/rocksdb/rocksdb/db/attribute_group_iterator_impl.h +34 -9
- package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +7 -6
- package/deps/rocksdb/rocksdb/db/blob/blob_source.h +5 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +22 -14
- package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +149 -0
- package/deps/rocksdb/rocksdb/db/builder.cc +13 -24
- package/deps/rocksdb/rocksdb/db/coalescing_iterator.h +35 -10
- package/deps/rocksdb/rocksdb/db/column_family.cc +21 -10
- package/deps/rocksdb/rocksdb/db/column_family.h +15 -8
- package/deps/rocksdb/rocksdb/db/column_family_test.cc +98 -7
- package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +126 -16
- package/deps/rocksdb/rocksdb/db/compaction/compaction.h +51 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +2 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +2 -8
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +24 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +52 -22
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +9 -7
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +36 -9
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +6 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +30 -17
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +26 -23
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +43 -33
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +6 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +19 -9
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +6 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +632 -411
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +171 -51
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +7 -5
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +37 -10
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +51 -11
- package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +10 -3
- package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +350 -154
- package/deps/rocksdb/rocksdb/db/convenience.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +62 -27
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +68 -1
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +91 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +134 -70
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +71 -23
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +43 -16
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +47 -33
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +27 -19
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +38 -25
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +3 -3
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +7 -4
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +258 -42
- package/deps/rocksdb/rocksdb/db/db_io_failure_test.cc +161 -9
- package/deps/rocksdb/rocksdb/db/db_iter.cc +118 -86
- package/deps/rocksdb/rocksdb/db/db_iter.h +44 -17
- package/deps/rocksdb/rocksdb/db/db_options_test.cc +27 -6
- package/deps/rocksdb/rocksdb/db/db_test.cc +48 -16
- package/deps/rocksdb/rocksdb/db/db_test2.cc +60 -15
- package/deps/rocksdb/rocksdb/db/db_test_util.cc +97 -44
- package/deps/rocksdb/rocksdb/db/db_test_util.h +7 -1
- package/deps/rocksdb/rocksdb/db/dbformat.cc +15 -5
- package/deps/rocksdb/rocksdb/db/dbformat.h +137 -55
- package/deps/rocksdb/rocksdb/db/event_helpers.cc +1 -0
- package/deps/rocksdb/rocksdb/db/experimental.cc +54 -0
- package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +663 -8
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +152 -91
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +134 -11
- package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +55 -9
- package/deps/rocksdb/rocksdb/db/flush_job.cc +52 -29
- package/deps/rocksdb/rocksdb/db/flush_job.h +5 -3
- package/deps/rocksdb/rocksdb/db/flush_job_test.cc +18 -12
- package/deps/rocksdb/rocksdb/db/forward_iterator.cc +23 -29
- package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +3 -2
- package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +2 -0
- package/deps/rocksdb/rocksdb/db/internal_stats.cc +9 -6
- package/deps/rocksdb/rocksdb/db/internal_stats.h +54 -0
- package/deps/rocksdb/rocksdb/db/job_context.h +1 -1
- package/deps/rocksdb/rocksdb/db/log_reader.cc +6 -7
- package/deps/rocksdb/rocksdb/db/manifest_ops.cc +47 -0
- package/deps/rocksdb/rocksdb/db/manifest_ops.h +20 -0
- package/deps/rocksdb/rocksdb/db/memtable.cc +165 -64
- package/deps/rocksdb/rocksdb/db/memtable.h +422 -243
- package/deps/rocksdb/rocksdb/db/memtable_list.cc +99 -68
- package/deps/rocksdb/rocksdb/db/memtable_list.h +63 -38
- package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +28 -25
- package/deps/rocksdb/rocksdb/db/multi_cf_iterator_impl.h +118 -60
- package/deps/rocksdb/rocksdb/db/multi_cf_iterator_test.cc +344 -89
- package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +2 -3
- package/deps/rocksdb/rocksdb/db/repair.cc +15 -14
- package/deps/rocksdb/rocksdb/db/repair_test.cc +0 -13
- package/deps/rocksdb/rocksdb/db/snapshot_checker.h +7 -0
- package/deps/rocksdb/rocksdb/db/table_cache.cc +62 -65
- package/deps/rocksdb/rocksdb/db/table_cache.h +70 -76
- package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +5 -6
- package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/transaction_log_impl.cc +8 -7
- package/deps/rocksdb/rocksdb/db/version_builder.cc +17 -19
- package/deps/rocksdb/rocksdb/db/version_builder.h +13 -12
- package/deps/rocksdb/rocksdb/db/version_edit.h +30 -0
- package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +3 -5
- package/deps/rocksdb/rocksdb/db/version_set.cc +89 -129
- package/deps/rocksdb/rocksdb/db/version_set.h +12 -4
- package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -2
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +12 -8
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +0 -15
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +0 -2
- package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +9 -7
- package/deps/rocksdb/rocksdb/db/wide/wide_columns_helper.cc +0 -8
- package/deps/rocksdb/rocksdb/db/wide/wide_columns_helper.h +28 -2
- package/deps/rocksdb/rocksdb/db/write_batch.cc +32 -10
- package/deps/rocksdb/rocksdb/db/write_batch_internal.h +9 -0
- package/deps/rocksdb/rocksdb/db/write_batch_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/write_thread.cc +3 -1
- package/deps/rocksdb/rocksdb/db/write_thread.h +6 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +15 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +7 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +4 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +18 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +100 -22
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +15 -4
- package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +34 -8
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +223 -78
- package/deps/rocksdb/rocksdb/env/file_system.cc +6 -1
- package/deps/rocksdb/rocksdb/env/fs_posix.cc +53 -0
- package/deps/rocksdb/rocksdb/env/io_posix.cc +63 -17
- package/deps/rocksdb/rocksdb/env/io_posix.h +30 -1
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +132 -48
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +92 -24
- package/deps/rocksdb/rocksdb/file/prefetch_test.cc +727 -109
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +3 -4
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +1 -1
- package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +8 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/attribute_groups.h +20 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +9 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/configurable.h +9 -5
- package/deps/rocksdb/rocksdb/include/rocksdb/convenience.h +2 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/db.h +10 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/env.h +1 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +7 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +34 -37
- package/deps/rocksdb/rocksdb/include/rocksdb/iterator_base.h +21 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +56 -28
- package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +3 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/table.h +36 -28
- package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +11 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +1 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_type.h +84 -60
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/secondary_index.h +102 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/table_properties_collectors.h +89 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction.h +32 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db.h +30 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +23 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
- package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +2 -0
- package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +79 -21
- package/deps/rocksdb/rocksdb/memtable/skiplist.h +41 -18
- package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +1 -5
- package/deps/rocksdb/rocksdb/memtable/wbwi_memtable.cc +169 -0
- package/deps/rocksdb/rocksdb/memtable/wbwi_memtable.h +400 -0
- package/deps/rocksdb/rocksdb/monitoring/thread_status_util_debug.cc +2 -0
- package/deps/rocksdb/rocksdb/options/cf_options.cc +137 -82
- package/deps/rocksdb/rocksdb/options/cf_options.h +18 -6
- package/deps/rocksdb/rocksdb/options/configurable.cc +31 -17
- package/deps/rocksdb/rocksdb/options/configurable_helper.h +7 -6
- package/deps/rocksdb/rocksdb/options/options_helper.cc +10 -8
- package/deps/rocksdb/rocksdb/options/options_parser.cc +74 -54
- package/deps/rocksdb/rocksdb/options/options_settable_test.cc +89 -0
- package/deps/rocksdb/rocksdb/options/options_test.cc +112 -26
- package/deps/rocksdb/rocksdb/port/port.h +5 -9
- package/deps/rocksdb/rocksdb/src.mk +8 -0
- package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.h +4 -0
- package/deps/rocksdb/rocksdb/table/block_based/block.h +1 -7
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +2 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +62 -80
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +13 -3
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +16 -5
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +38 -7
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +12 -4
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +4 -1
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +4 -1
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +204 -1
- package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +3 -3
- package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +2 -1
- package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_factory.h +4 -0
- package/deps/rocksdb/rocksdb/table/format.cc +3 -3
- package/deps/rocksdb/rocksdb/table/meta_blocks.cc +4 -1
- package/deps/rocksdb/rocksdb/table/mock_table.cc +0 -50
- package/deps/rocksdb/rocksdb/table/mock_table.h +53 -0
- package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.h +4 -0
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +1 -1
- package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +10 -5
- package/deps/rocksdb/rocksdb/table/table_builder.h +3 -1
- package/deps/rocksdb/rocksdb/table/table_properties.cc +181 -0
- package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +5 -5
- package/deps/rocksdb/rocksdb/table/table_test.cc +71 -64
- package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim.py +45 -45
- package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim_test.py +35 -35
- package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py +43 -43
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +41 -4
- package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +1 -0
- package/deps/rocksdb/rocksdb/tools/sst_dump_test.cc +1 -1
- package/deps/rocksdb/rocksdb/unreleased_history/add.sh +13 -0
- package/deps/rocksdb/rocksdb/util/aligned_buffer.h +24 -5
- package/deps/rocksdb/rocksdb/util/compaction_job_stats_impl.cc +7 -0
- package/deps/rocksdb/rocksdb/util/file_checksum_helper.cc +0 -52
- package/deps/rocksdb/rocksdb/util/file_checksum_helper.h +1 -10
- package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +92 -0
- package/deps/rocksdb/rocksdb/util/thread_operation.h +1 -0
- package/deps/rocksdb/rocksdb/util/udt_util.cc +50 -4
- package/deps/rocksdb/rocksdb/util/udt_util.h +24 -11
- package/deps/rocksdb/rocksdb/util/udt_util_test.cc +26 -13
- package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +1 -16
- package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +2 -0
- package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index.cc +214 -0
- package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index.h +60 -0
- package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index_test.cc +124 -0
- package/deps/rocksdb/rocksdb/utilities/secondary_index/secondary_index_mixin.h +441 -0
- package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_for_tiering_collector.cc +34 -3
- package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_for_tiering_collector.h +7 -2
- package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +437 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +34 -11
- package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.h +14 -7
- package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.cc +7 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/snapshot_checker.cc +17 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +69 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.h +20 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +1290 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +324 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +18 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.h +8 -1
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +57 -12
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +32 -3
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +33 -2
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +721 -9
- package/deps/rocksdb/rocksdb.gyp +2 -0
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
- package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
#ifdef GFLAGS
|
|
12
12
|
#include "tools/io_tracer_parser_tool.h"
|
|
13
13
|
#endif
|
|
14
|
+
#include "rocksdb/flush_block_policy.h"
|
|
14
15
|
#include "util/random.h"
|
|
15
16
|
|
|
16
17
|
namespace {
|
|
@@ -121,6 +122,81 @@ class PrefetchTest
|
|
|
121
122
|
table_options.index_type =
|
|
122
123
|
BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
|
|
123
124
|
}
|
|
125
|
+
|
|
126
|
+
void VerifyScan(ReadOptions& iter_ro, ReadOptions& cmp_iter_ro,
|
|
127
|
+
const Slice* seek_key, const Slice* iterate_upper_bound,
|
|
128
|
+
bool prefix_same_as_start) const {
|
|
129
|
+
assert(!(seek_key == nullptr));
|
|
130
|
+
iter_ro.iterate_upper_bound = cmp_iter_ro.iterate_upper_bound =
|
|
131
|
+
iterate_upper_bound;
|
|
132
|
+
iter_ro.prefix_same_as_start = cmp_iter_ro.prefix_same_as_start =
|
|
133
|
+
prefix_same_as_start;
|
|
134
|
+
|
|
135
|
+
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(iter_ro));
|
|
136
|
+
auto cmp_iter = std::unique_ptr<Iterator>(db_->NewIterator(cmp_iter_ro));
|
|
137
|
+
|
|
138
|
+
iter->Seek(*seek_key);
|
|
139
|
+
cmp_iter->Seek(*seek_key);
|
|
140
|
+
|
|
141
|
+
while (iter->Valid() && cmp_iter->Valid()) {
|
|
142
|
+
if (iter->key() != cmp_iter->key()) {
|
|
143
|
+
// Error
|
|
144
|
+
ASSERT_TRUE(false);
|
|
145
|
+
}
|
|
146
|
+
iter->Next();
|
|
147
|
+
cmp_iter->Next();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
ASSERT_TRUE(!cmp_iter->Valid() && !iter->Valid());
|
|
151
|
+
ASSERT_TRUE(cmp_iter->status().ok() && iter->status().ok());
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
void VerifySeekPrevSeek(ReadOptions& iter_ro, ReadOptions& cmp_iter_ro,
|
|
155
|
+
const Slice* seek_key,
|
|
156
|
+
const Slice* iterate_upper_bound,
|
|
157
|
+
bool prefix_same_as_start) {
|
|
158
|
+
assert(!(seek_key == nullptr));
|
|
159
|
+
iter_ro.iterate_upper_bound = cmp_iter_ro.iterate_upper_bound =
|
|
160
|
+
iterate_upper_bound;
|
|
161
|
+
iter_ro.prefix_same_as_start = cmp_iter_ro.prefix_same_as_start =
|
|
162
|
+
prefix_same_as_start;
|
|
163
|
+
|
|
164
|
+
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(iter_ro));
|
|
165
|
+
auto cmp_iter = std::unique_ptr<Iterator>(db_->NewIterator(cmp_iter_ro));
|
|
166
|
+
|
|
167
|
+
// Seek
|
|
168
|
+
cmp_iter->Seek(*seek_key);
|
|
169
|
+
ASSERT_TRUE(cmp_iter->Valid());
|
|
170
|
+
ASSERT_OK(cmp_iter->status());
|
|
171
|
+
|
|
172
|
+
iter->Seek(*seek_key);
|
|
173
|
+
ASSERT_TRUE(iter->Valid());
|
|
174
|
+
ASSERT_OK(iter->status());
|
|
175
|
+
|
|
176
|
+
ASSERT_EQ(iter->key(), cmp_iter->key());
|
|
177
|
+
|
|
178
|
+
// Prev op should pass
|
|
179
|
+
cmp_iter->Prev();
|
|
180
|
+
ASSERT_TRUE(cmp_iter->Valid());
|
|
181
|
+
ASSERT_OK(cmp_iter->status());
|
|
182
|
+
|
|
183
|
+
iter->Prev();
|
|
184
|
+
ASSERT_TRUE(iter->Valid());
|
|
185
|
+
ASSERT_OK(iter->status());
|
|
186
|
+
|
|
187
|
+
ASSERT_EQ(iter->key(), cmp_iter->key());
|
|
188
|
+
|
|
189
|
+
// Reseek would follow as usual
|
|
190
|
+
cmp_iter->Seek(*seek_key);
|
|
191
|
+
ASSERT_TRUE(cmp_iter->Valid());
|
|
192
|
+
ASSERT_OK(cmp_iter->status());
|
|
193
|
+
|
|
194
|
+
iter->Seek(*seek_key);
|
|
195
|
+
ASSERT_TRUE(iter->Valid());
|
|
196
|
+
ASSERT_OK(iter->status());
|
|
197
|
+
|
|
198
|
+
ASSERT_EQ(iter->key(), cmp_iter->key());
|
|
199
|
+
}
|
|
124
200
|
};
|
|
125
201
|
|
|
126
202
|
INSTANTIATE_TEST_CASE_P(PrefetchTest, PrefetchTest,
|
|
@@ -599,6 +675,8 @@ TEST_P(PrefetchTest, ConfigureAutoMaxReadaheadSize) {
|
|
|
599
675
|
default:
|
|
600
676
|
assert(false);
|
|
601
677
|
}
|
|
678
|
+
ASSERT_OK(iter->status());
|
|
679
|
+
ASSERT_OK(iter->Refresh()); // Update to latest mutable options
|
|
602
680
|
|
|
603
681
|
for (int i = 0; i < num_keys_per_level; ++i) {
|
|
604
682
|
iter->Seek(Key(key_count++));
|
|
@@ -726,6 +804,8 @@ TEST_P(PrefetchTest, ConfigureInternalAutoReadaheadSize) {
|
|
|
726
804
|
default:
|
|
727
805
|
assert(false);
|
|
728
806
|
}
|
|
807
|
+
ASSERT_OK(iter->status());
|
|
808
|
+
ASSERT_OK(iter->Refresh()); // Update to latest mutable options
|
|
729
809
|
|
|
730
810
|
for (int i = 0; i < num_keys_per_level; ++i) {
|
|
731
811
|
iter->Seek(Key(key_count++));
|
|
@@ -1262,6 +1342,8 @@ TEST_P(PrefetchTest, PrefetchWithBlockLookupAutoTuneTest) {
|
|
|
1262
1342
|
Options options;
|
|
1263
1343
|
SetGenericOptions(env.get(), /*use_direct_io=*/false, options);
|
|
1264
1344
|
options.statistics = CreateDBStatistics();
|
|
1345
|
+
const std::string prefix = "my_key_";
|
|
1346
|
+
options.prefix_extractor.reset(NewFixedPrefixTransform(prefix.size()));
|
|
1265
1347
|
BlockBasedTableOptions table_options;
|
|
1266
1348
|
SetBlockBasedTableOptions(table_options);
|
|
1267
1349
|
options.table_factory.reset(NewBlockBasedTableFactory(table_options));
|
|
@@ -1272,8 +1354,9 @@ TEST_P(PrefetchTest, PrefetchWithBlockLookupAutoTuneTest) {
|
|
|
1272
1354
|
Random rnd(309);
|
|
1273
1355
|
WriteBatch batch;
|
|
1274
1356
|
|
|
1357
|
+
// Create the DB with keys from "my_key_aaaaaaaaaa" to "my_key_zzzzzzzzzz"
|
|
1275
1358
|
for (int i = 0; i < 26; i++) {
|
|
1276
|
-
std::string key =
|
|
1359
|
+
std::string key = prefix;
|
|
1277
1360
|
|
|
1278
1361
|
for (int j = 0; j < 10; j++) {
|
|
1279
1362
|
key += char('a' + i);
|
|
@@ -1282,9 +1365,9 @@ TEST_P(PrefetchTest, PrefetchWithBlockLookupAutoTuneTest) {
|
|
|
1282
1365
|
}
|
|
1283
1366
|
ASSERT_OK(db_->Write(WriteOptions(), &batch));
|
|
1284
1367
|
|
|
1285
|
-
std::string start_key = "
|
|
1368
|
+
std::string start_key = prefix + "a";
|
|
1286
1369
|
|
|
1287
|
-
std::string end_key =
|
|
1370
|
+
std::string end_key = prefix;
|
|
1288
1371
|
for (int j = 0; j < 10; j++) {
|
|
1289
1372
|
end_key += char('a' + 25);
|
|
1290
1373
|
}
|
|
@@ -1309,32 +1392,30 @@ TEST_P(PrefetchTest, PrefetchWithBlockLookupAutoTuneTest) {
|
|
|
1309
1392
|
{
|
|
1310
1393
|
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ReadOptions()));
|
|
1311
1394
|
|
|
1312
|
-
iter->Seek("
|
|
1395
|
+
iter->Seek(prefix + "bbb");
|
|
1313
1396
|
ASSERT_TRUE(iter->Valid());
|
|
1314
1397
|
|
|
1315
|
-
iter->Seek("
|
|
1398
|
+
iter->Seek(prefix + "ccccccccc");
|
|
1316
1399
|
ASSERT_TRUE(iter->Valid());
|
|
1317
1400
|
|
|
1318
|
-
iter->Seek("
|
|
1401
|
+
iter->Seek(prefix + "ddd");
|
|
1319
1402
|
ASSERT_TRUE(iter->Valid());
|
|
1320
1403
|
|
|
1321
|
-
iter->Seek("
|
|
1404
|
+
iter->Seek(prefix + "ddddddd");
|
|
1322
1405
|
ASSERT_TRUE(iter->Valid());
|
|
1323
1406
|
|
|
1324
|
-
iter->Seek("
|
|
1407
|
+
iter->Seek(prefix + "e");
|
|
1325
1408
|
ASSERT_TRUE(iter->Valid());
|
|
1326
1409
|
|
|
1327
|
-
iter->Seek("
|
|
1410
|
+
iter->Seek(prefix + "eeeee");
|
|
1328
1411
|
ASSERT_TRUE(iter->Valid());
|
|
1329
1412
|
|
|
1330
|
-
iter->Seek("
|
|
1413
|
+
iter->Seek(prefix + "eeeeeeeee");
|
|
1331
1414
|
ASSERT_TRUE(iter->Valid());
|
|
1332
1415
|
}
|
|
1333
1416
|
|
|
1334
1417
|
ReadOptions ropts;
|
|
1335
|
-
ropts.auto_readahead_size = true;
|
|
1336
1418
|
ReadOptions cmp_ro;
|
|
1337
|
-
cmp_ro.auto_readahead_size = false;
|
|
1338
1419
|
|
|
1339
1420
|
if (std::get<0>(GetParam())) {
|
|
1340
1421
|
ropts.readahead_size = cmp_ro.readahead_size = 32768;
|
|
@@ -1345,61 +1426,31 @@ TEST_P(PrefetchTest, PrefetchWithBlockLookupAutoTuneTest) {
|
|
|
1345
1426
|
}
|
|
1346
1427
|
|
|
1347
1428
|
// With and without tuning readahead_size.
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
ASSERT_OK(cmp_iter->status());
|
|
1374
|
-
ASSERT_OK(iter->status());
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
// Reseek with new upper_bound_iterator.
|
|
1378
|
-
{
|
|
1379
|
-
Slice ub = Slice("my_key_y");
|
|
1380
|
-
ropts.iterate_upper_bound = &ub;
|
|
1381
|
-
cmp_ro.iterate_upper_bound = &ub;
|
|
1382
|
-
|
|
1383
|
-
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ropts));
|
|
1384
|
-
auto cmp_iter = std::unique_ptr<Iterator>(db_->NewIterator(cmp_ro));
|
|
1385
|
-
|
|
1386
|
-
Slice reseek_key = Slice("my_key_v");
|
|
1387
|
-
iter->Seek(reseek_key);
|
|
1388
|
-
cmp_iter->Seek(reseek_key);
|
|
1389
|
-
|
|
1390
|
-
while (iter->Valid() && cmp_iter->Valid()) {
|
|
1391
|
-
if (iter->key() != cmp_iter->key()) {
|
|
1392
|
-
// Error
|
|
1393
|
-
ASSERT_TRUE(false);
|
|
1394
|
-
}
|
|
1395
|
-
iter->Next();
|
|
1396
|
-
cmp_iter->Next();
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
ASSERT_OK(cmp_iter->status());
|
|
1400
|
-
ASSERT_OK(iter->status());
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1429
|
+
ropts.auto_readahead_size = true;
|
|
1430
|
+
cmp_ro.auto_readahead_size = false;
|
|
1431
|
+
ASSERT_OK(options.statistics->Reset());
|
|
1432
|
+
// Seek with a upper bound
|
|
1433
|
+
const std::string seek_key_str = prefix + "aaa";
|
|
1434
|
+
const Slice seek_key(seek_key_str);
|
|
1435
|
+
const std::string ub_str = prefix + "uuu";
|
|
1436
|
+
const Slice ub(ub_str);
|
|
1437
|
+
VerifyScan(ropts /* iter_ro */, cmp_ro /* cmp_iter_ro */,
|
|
1438
|
+
&seek_key /* seek_key */, &ub /* iterate_upper_bound */,
|
|
1439
|
+
false /* prefix_same_as_start */);
|
|
1440
|
+
|
|
1441
|
+
// Seek with a new seek key and upper bound
|
|
1442
|
+
const std::string seek_key_new_str = prefix + "v";
|
|
1443
|
+
const Slice seek_key_new(seek_key_new_str);
|
|
1444
|
+
const std::string ub_new_str = prefix + "y";
|
|
1445
|
+
const Slice ub_new(ub_new_str);
|
|
1446
|
+
VerifyScan(ropts /* iter_ro */, cmp_ro /* cmp_iter_ro */,
|
|
1447
|
+
&seek_key_new /* seek_key */, &ub_new /* iterate_upper_bound */,
|
|
1448
|
+
false /* prefix_same_as_start */);
|
|
1449
|
+
|
|
1450
|
+
// Seek with no upper bound, prefix_same_as_start = true
|
|
1451
|
+
VerifyScan(ropts /* iter_ro */, cmp_ro /* cmp_iter_ro */,
|
|
1452
|
+
&seek_key /* seek_key */, nullptr /* iterate_upper_bound */,
|
|
1453
|
+
true /* prefix_same_as_start */);
|
|
1403
1454
|
Close();
|
|
1404
1455
|
}
|
|
1405
1456
|
}
|
|
@@ -1418,6 +1469,8 @@ TEST_F(PrefetchTest, PrefetchWithBlockLookupAutoTuneWithPrev) {
|
|
|
1418
1469
|
Options options;
|
|
1419
1470
|
SetGenericOptions(env.get(), /*use_direct_io=*/false, options);
|
|
1420
1471
|
options.statistics = CreateDBStatistics();
|
|
1472
|
+
const std::string prefix = "my_key_";
|
|
1473
|
+
options.prefix_extractor.reset(NewFixedPrefixTransform(prefix.size()));
|
|
1421
1474
|
BlockBasedTableOptions table_options;
|
|
1422
1475
|
SetBlockBasedTableOptions(table_options);
|
|
1423
1476
|
std::shared_ptr<Cache> cache = NewLRUCache(1024 * 1024, 2);
|
|
@@ -1432,7 +1485,7 @@ TEST_F(PrefetchTest, PrefetchWithBlockLookupAutoTuneWithPrev) {
|
|
|
1432
1485
|
WriteBatch batch;
|
|
1433
1486
|
|
|
1434
1487
|
for (int i = 0; i < 26; i++) {
|
|
1435
|
-
std::string key =
|
|
1488
|
+
std::string key = prefix;
|
|
1436
1489
|
|
|
1437
1490
|
for (int j = 0; j < 10; j++) {
|
|
1438
1491
|
key += char('a' + i);
|
|
@@ -1441,9 +1494,9 @@ TEST_F(PrefetchTest, PrefetchWithBlockLookupAutoTuneWithPrev) {
|
|
|
1441
1494
|
}
|
|
1442
1495
|
ASSERT_OK(db_->Write(WriteOptions(), &batch));
|
|
1443
1496
|
|
|
1444
|
-
std::string start_key = "
|
|
1497
|
+
std::string start_key = prefix + "a";
|
|
1445
1498
|
|
|
1446
|
-
std::string end_key =
|
|
1499
|
+
std::string end_key = prefix;
|
|
1447
1500
|
for (int j = 0; j < 10; j++) {
|
|
1448
1501
|
end_key += char('a' + 25);
|
|
1449
1502
|
}
|
|
@@ -1455,58 +1508,147 @@ TEST_F(PrefetchTest, PrefetchWithBlockLookupAutoTuneWithPrev) {
|
|
|
1455
1508
|
|
|
1456
1509
|
ReadOptions ropts;
|
|
1457
1510
|
ropts.auto_readahead_size = true;
|
|
1511
|
+
ReadOptions cmp_readopts = ropts;
|
|
1512
|
+
cmp_readopts.auto_readahead_size = false;
|
|
1513
|
+
|
|
1514
|
+
const std::string seek_key_str = prefix + "bbb";
|
|
1515
|
+
const Slice seek_key(seek_key_str);
|
|
1516
|
+
const std::string ub_key = prefix + "uuu";
|
|
1517
|
+
const Slice ub(ub_key);
|
|
1518
|
+
|
|
1519
|
+
VerifySeekPrevSeek(ropts /* iter_ro */, cmp_readopts /* cmp_iter_ro */,
|
|
1520
|
+
&seek_key /* seek_key */, &ub /* iterate_upper_bound */,
|
|
1521
|
+
false /* prefix_same_as_start */);
|
|
1522
|
+
|
|
1523
|
+
VerifySeekPrevSeek(ropts /* iter_ro */, cmp_readopts /* cmp_iter_ro */,
|
|
1524
|
+
&seek_key /* seek_key */,
|
|
1525
|
+
nullptr /* iterate_upper_bound */,
|
|
1526
|
+
true /* prefix_same_as_start */);
|
|
1527
|
+
Close();
|
|
1528
|
+
}
|
|
1458
1529
|
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1530
|
+
class PrefetchTrimReadaheadTestParam
|
|
1531
|
+
: public DBTestBase,
|
|
1532
|
+
public ::testing::WithParamInterface<
|
|
1533
|
+
std::tuple<BlockBasedTableOptions::IndexShorteningMode, bool>> {
|
|
1534
|
+
public:
|
|
1535
|
+
const std::string kPrefix = "a_prefix_";
|
|
1536
|
+
Random rnd = Random(309);
|
|
1465
1537
|
|
|
1466
|
-
|
|
1467
|
-
|
|
1538
|
+
PrefetchTrimReadaheadTestParam()
|
|
1539
|
+
: DBTestBase("prefetch_trim_readahead_test_param", true) {}
|
|
1540
|
+
virtual void SetGenericOptions(Env* env, Options& options) {
|
|
1541
|
+
options = CurrentOptions();
|
|
1542
|
+
options.env = env;
|
|
1543
|
+
options.create_if_missing = true;
|
|
1544
|
+
options.disable_auto_compactions = true;
|
|
1545
|
+
options.statistics = CreateDBStatistics();
|
|
1468
1546
|
|
|
1469
|
-
|
|
1470
|
-
|
|
1547
|
+
// To make all the data bocks fit in one file for testing purpose
|
|
1548
|
+
options.write_buffer_size = 1024 * 1024 * 1024;
|
|
1549
|
+
options.prefix_extractor.reset(NewFixedPrefixTransform(kPrefix.size()));
|
|
1550
|
+
}
|
|
1471
1551
|
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
ASSERT_TRUE(cmp_iter->Valid());
|
|
1476
|
-
ASSERT_OK(cmp_iter->status());
|
|
1552
|
+
void SetBlockBasedTableOptions(BlockBasedTableOptions& table_options) {
|
|
1553
|
+
table_options.no_block_cache = false;
|
|
1554
|
+
table_options.index_shortening = std::get<0>(GetParam());
|
|
1477
1555
|
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1556
|
+
// To force keys with different prefixes are in different data blocks of the
|
|
1557
|
+
// file for testing purpose
|
|
1558
|
+
table_options.block_size = 1;
|
|
1559
|
+
table_options.flush_block_policy_factory.reset(
|
|
1560
|
+
new FlushBlockBySizePolicyFactory());
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1481
1563
|
|
|
1482
|
-
|
|
1483
|
-
|
|
1564
|
+
INSTANTIATE_TEST_CASE_P(
|
|
1565
|
+
PrefetchTrimReadaheadTestParam, PrefetchTrimReadaheadTestParam,
|
|
1566
|
+
::testing::Combine(
|
|
1567
|
+
// Params are as follows -
|
|
1568
|
+
// Param 0 - TableOptions::index_shortening
|
|
1569
|
+
// Param 2 - ReadOptinos::auto_readahead_size
|
|
1570
|
+
::testing::Values(
|
|
1571
|
+
BlockBasedTableOptions::IndexShorteningMode::kNoShortening,
|
|
1572
|
+
BlockBasedTableOptions::IndexShorteningMode::kShortenSeparators,
|
|
1573
|
+
BlockBasedTableOptions::IndexShorteningMode::
|
|
1574
|
+
kShortenSeparatorsAndSuccessor),
|
|
1575
|
+
::testing::Bool()));
|
|
1576
|
+
|
|
1577
|
+
TEST_P(PrefetchTrimReadaheadTestParam, PrefixSameAsStart) {
|
|
1578
|
+
if (mem_env_ || encrypted_env_) {
|
|
1579
|
+
ROCKSDB_GTEST_SKIP("Test requires non-mem or non-encrypted environment");
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
const bool auto_readahead_size = std::get<1>(GetParam());
|
|
1484
1583
|
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1584
|
+
std::shared_ptr<MockFS> fs = std::make_shared<MockFS>(
|
|
1585
|
+
FileSystem::Default(), false /* support_prefetch */,
|
|
1586
|
+
true /* small_buffer_alignment */);
|
|
1587
|
+
std::unique_ptr<Env> env(new CompositeEnvWrapper(env_, fs));
|
|
1588
|
+
Options options;
|
|
1589
|
+
SetGenericOptions(env.get(), options);
|
|
1590
|
+
BlockBasedTableOptions table_optoins;
|
|
1591
|
+
SetBlockBasedTableOptions(table_optoins);
|
|
1592
|
+
options.table_factory.reset(NewBlockBasedTableFactory(table_optoins));
|
|
1490
1593
|
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
ASSERT_TRUE(iter->Valid());
|
|
1594
|
+
Status s = TryReopen(options);
|
|
1595
|
+
ASSERT_OK(s);
|
|
1494
1596
|
|
|
1495
|
-
|
|
1496
|
-
|
|
1597
|
+
// To create a DB with data block layout (denoted as "[...]" below ) as the
|
|
1598
|
+
// following:
|
|
1599
|
+
// ["a_prefix_0": random value]
|
|
1600
|
+
// ["a_prefix_1": random value]
|
|
1601
|
+
// ...
|
|
1602
|
+
// ["a_prefix_9": random value]
|
|
1603
|
+
// ["c_prefix_0": random value]
|
|
1604
|
+
// ["d_prefix_1": random value]
|
|
1605
|
+
// ...
|
|
1606
|
+
// ["l_prefix_9": random value]
|
|
1607
|
+
//
|
|
1608
|
+
// We want to verify keys not with prefix "a_prefix_" are not prefetched due
|
|
1609
|
+
// to trimming
|
|
1610
|
+
WriteBatch prefix_batch;
|
|
1611
|
+
for (int i = 0; i < 10; i++) {
|
|
1612
|
+
std::string key = kPrefix + std::to_string(i);
|
|
1613
|
+
ASSERT_OK(prefix_batch.Put(key, rnd.RandomString(100)));
|
|
1614
|
+
}
|
|
1615
|
+
ASSERT_OK(db_->Write(WriteOptions(), &prefix_batch));
|
|
1616
|
+
|
|
1617
|
+
WriteBatch diff_prefix_batch;
|
|
1618
|
+
for (int i = 0; i < 10; i++) {
|
|
1619
|
+
std::string diff_prefix = std::string(1, char('c' + i)) + kPrefix.substr(1);
|
|
1620
|
+
std::string key = diff_prefix + std::to_string(i);
|
|
1621
|
+
ASSERT_OK(diff_prefix_batch.Put(key, rnd.RandomString(100)));
|
|
1622
|
+
}
|
|
1623
|
+
ASSERT_OK(db_->Write(WriteOptions(), &diff_prefix_batch));
|
|
1497
1624
|
|
|
1498
|
-
|
|
1499
|
-
{
|
|
1500
|
-
cmp_iter->Seek(seek_key);
|
|
1501
|
-
ASSERT_TRUE(cmp_iter->Valid());
|
|
1502
|
-
ASSERT_OK(cmp_iter->status());
|
|
1625
|
+
ASSERT_OK(db_->Flush(FlushOptions()));
|
|
1503
1626
|
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1627
|
+
// To verify readahead is trimmed based on prefix by checking the counter
|
|
1628
|
+
// READAHEAD_TRIMMED
|
|
1629
|
+
ReadOptions ro;
|
|
1630
|
+
ro.prefix_same_as_start = true;
|
|
1631
|
+
ro.auto_readahead_size = auto_readahead_size;
|
|
1632
|
+
// Set a large readahead size to introduce readahead waste when without
|
|
1633
|
+
// trimming based on prefix
|
|
1634
|
+
ro.readahead_size = 1024 * 1024 * 1024;
|
|
1635
|
+
|
|
1636
|
+
ASSERT_OK(options.statistics->Reset());
|
|
1637
|
+
{
|
|
1638
|
+
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ro));
|
|
1639
|
+
for (iter->Seek(kPrefix); iter->status().ok() && iter->Valid();
|
|
1640
|
+
iter->Next()) {
|
|
1508
1641
|
}
|
|
1509
1642
|
}
|
|
1643
|
+
|
|
1644
|
+
auto readahead_trimmed =
|
|
1645
|
+
options.statistics->getTickerCount(READAHEAD_TRIMMED);
|
|
1646
|
+
|
|
1647
|
+
if (auto_readahead_size) {
|
|
1648
|
+
ASSERT_GT(readahead_trimmed, 0);
|
|
1649
|
+
} else {
|
|
1650
|
+
ASSERT_EQ(readahead_trimmed, 0);
|
|
1651
|
+
}
|
|
1510
1652
|
Close();
|
|
1511
1653
|
}
|
|
1512
1654
|
|
|
@@ -3148,6 +3290,482 @@ TEST_F(FilePrefetchBufferTest, SyncReadaheadStats) {
|
|
|
3148
3290
|
/* 24576(end offset of the buffer) - 16000(requested offset) =*/8576);
|
|
3149
3291
|
}
|
|
3150
3292
|
|
|
3293
|
+
class FSBufferPrefetchTest : public testing::Test,
|
|
3294
|
+
public ::testing::WithParamInterface<bool> {
|
|
3295
|
+
public:
|
|
3296
|
+
// Mock file system supporting the kFSBuffer buffer reuse operation
|
|
3297
|
+
class BufferReuseFS : public FileSystemWrapper {
|
|
3298
|
+
public:
|
|
3299
|
+
explicit BufferReuseFS(const std::shared_ptr<FileSystem>& _target)
|
|
3300
|
+
: FileSystemWrapper(_target) {}
|
|
3301
|
+
~BufferReuseFS() override {}
|
|
3302
|
+
const char* Name() const override { return "BufferReuseFS"; }
|
|
3303
|
+
|
|
3304
|
+
IOStatus NewRandomAccessFile(const std::string& fname,
|
|
3305
|
+
const FileOptions& opts,
|
|
3306
|
+
std::unique_ptr<FSRandomAccessFile>* result,
|
|
3307
|
+
IODebugContext* dbg) override {
|
|
3308
|
+
class WrappedRandomAccessFile : public FSRandomAccessFileOwnerWrapper {
|
|
3309
|
+
public:
|
|
3310
|
+
explicit WrappedRandomAccessFile(
|
|
3311
|
+
std::unique_ptr<FSRandomAccessFile>& file)
|
|
3312
|
+
: FSRandomAccessFileOwnerWrapper(std::move(file)) {}
|
|
3313
|
+
|
|
3314
|
+
IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
|
|
3315
|
+
const IOOptions& options,
|
|
3316
|
+
IODebugContext* dbg) override {
|
|
3317
|
+
for (size_t i = 0; i < num_reqs; ++i) {
|
|
3318
|
+
FSReadRequest& req = reqs[i];
|
|
3319
|
+
FSAllocationPtr buffer(new char[req.len], [](void* ptr) {
|
|
3320
|
+
delete[] static_cast<char*>(ptr);
|
|
3321
|
+
});
|
|
3322
|
+
req.fs_scratch = std::move(buffer);
|
|
3323
|
+
req.status = Read(req.offset, req.len, options, &req.result,
|
|
3324
|
+
static_cast<char*>(req.fs_scratch.get()), dbg);
|
|
3325
|
+
}
|
|
3326
|
+
return IOStatus::OK();
|
|
3327
|
+
}
|
|
3328
|
+
};
|
|
3329
|
+
|
|
3330
|
+
std::unique_ptr<FSRandomAccessFile> file;
|
|
3331
|
+
IOStatus s = target()->NewRandomAccessFile(fname, opts, &file, dbg);
|
|
3332
|
+
EXPECT_OK(s);
|
|
3333
|
+
result->reset(new WrappedRandomAccessFile(file));
|
|
3334
|
+
return s;
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3337
|
+
void SupportedOps(int64_t& supported_ops) override {
|
|
3338
|
+
supported_ops = 1 << FSSupportedOps::kAsyncIO;
|
|
3339
|
+
supported_ops |= 1 << FSSupportedOps::kFSBuffer;
|
|
3340
|
+
}
|
|
3341
|
+
};
|
|
3342
|
+
|
|
3343
|
+
void SetUp() override {
|
|
3344
|
+
SetupSyncPointsToMockDirectIO();
|
|
3345
|
+
env_ = Env::Default();
|
|
3346
|
+
bool use_async_prefetch = GetParam();
|
|
3347
|
+
if (use_async_prefetch) {
|
|
3348
|
+
fs_ = FileSystem::Default();
|
|
3349
|
+
} else {
|
|
3350
|
+
fs_ = std::make_shared<BufferReuseFS>(FileSystem::Default());
|
|
3351
|
+
}
|
|
3352
|
+
|
|
3353
|
+
test_dir_ = test::PerThreadDBPath("fs_buffer_prefetch_test");
|
|
3354
|
+
ASSERT_OK(fs_->CreateDir(test_dir_, IOOptions(), nullptr));
|
|
3355
|
+
stats_ = CreateDBStatistics();
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3358
|
+
void TearDown() override { EXPECT_OK(DestroyDir(env_, test_dir_)); }
|
|
3359
|
+
|
|
3360
|
+
void Write(const std::string& fname, const std::string& content) {
|
|
3361
|
+
std::unique_ptr<FSWritableFile> f;
|
|
3362
|
+
ASSERT_OK(fs_->NewWritableFile(Path(fname), FileOptions(), &f, nullptr));
|
|
3363
|
+
ASSERT_OK(f->Append(content, IOOptions(), nullptr));
|
|
3364
|
+
ASSERT_OK(f->Close(IOOptions(), nullptr));
|
|
3365
|
+
}
|
|
3366
|
+
|
|
3367
|
+
void Read(const std::string& fname, const FileOptions& opts,
|
|
3368
|
+
std::unique_ptr<RandomAccessFileReader>* reader) {
|
|
3369
|
+
std::string fpath = Path(fname);
|
|
3370
|
+
std::unique_ptr<FSRandomAccessFile> f;
|
|
3371
|
+
ASSERT_OK(fs_->NewRandomAccessFile(fpath, opts, &f, nullptr));
|
|
3372
|
+
reader->reset(new RandomAccessFileReader(
|
|
3373
|
+
std::move(f), fpath, env_->GetSystemClock().get(),
|
|
3374
|
+
/*io_tracer=*/nullptr, stats_.get()));
|
|
3375
|
+
}
|
|
3376
|
+
|
|
3377
|
+
FileSystem* fs() { return fs_.get(); }
|
|
3378
|
+
Statistics* stats() { return stats_.get(); }
|
|
3379
|
+
SystemClock* clock() { return env_->GetSystemClock().get(); }
|
|
3380
|
+
|
|
3381
|
+
private:
|
|
3382
|
+
Env* env_;
|
|
3383
|
+
std::shared_ptr<FileSystem> fs_;
|
|
3384
|
+
std::string test_dir_;
|
|
3385
|
+
std::shared_ptr<Statistics> stats_;
|
|
3386
|
+
|
|
3387
|
+
std::string Path(const std::string& fname) { return test_dir_ + "/" + fname; }
|
|
3388
|
+
};
|
|
3389
|
+
|
|
3390
|
+
INSTANTIATE_TEST_CASE_P(FSBufferPrefetchTest, FSBufferPrefetchTest,
|
|
3391
|
+
::testing::Bool());
|
|
3392
|
+
|
|
3393
|
+
TEST_P(FSBufferPrefetchTest, FSBufferPrefetchStatsInternals) {
|
|
3394
|
+
// Check that the main buffer, the overlap_buf_, and the secondary buffer (in
|
|
3395
|
+
// the case of num_buffers_ > 1) are populated correctly while reading a 32
|
|
3396
|
+
// KiB file
|
|
3397
|
+
std::string fname = "fs-buffer-prefetch-stats-internals";
|
|
3398
|
+
Random rand(0);
|
|
3399
|
+
std::string content = rand.RandomString(32768);
|
|
3400
|
+
Write(fname, content);
|
|
3401
|
+
|
|
3402
|
+
FileOptions opts;
|
|
3403
|
+
std::unique_ptr<RandomAccessFileReader> r;
|
|
3404
|
+
Read(fname, opts, &r);
|
|
3405
|
+
|
|
3406
|
+
std::shared_ptr<Statistics> stats = CreateDBStatistics();
|
|
3407
|
+
ReadaheadParams readahead_params;
|
|
3408
|
+
readahead_params.initial_readahead_size = 8192;
|
|
3409
|
+
readahead_params.max_readahead_size = 8192;
|
|
3410
|
+
bool use_async_prefetch = GetParam();
|
|
3411
|
+
size_t num_buffers = use_async_prefetch ? 2 : 1;
|
|
3412
|
+
readahead_params.num_buffers = num_buffers;
|
|
3413
|
+
|
|
3414
|
+
FilePrefetchBuffer fpb(readahead_params, true, false, fs(), clock(),
|
|
3415
|
+
stats.get());
|
|
3416
|
+
|
|
3417
|
+
int overlap_buffer_write_ct = 0;
|
|
3418
|
+
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
|
|
3419
|
+
"FilePrefetchBuffer::CopyDataToOverlapBuffer:Complete",
|
|
3420
|
+
[&](void* /*arg*/) { overlap_buffer_write_ct++; });
|
|
3421
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
3422
|
+
|
|
3423
|
+
Slice result;
|
|
3424
|
+
// Read 4096 bytes at offset 0.
|
|
3425
|
+
Status s;
|
|
3426
|
+
std::vector<std::tuple<uint64_t, size_t, bool>> buffer_info(num_buffers);
|
|
3427
|
+
std::pair<uint64_t, size_t> overlap_buffer_info;
|
|
3428
|
+
bool could_read_from_cache =
|
|
3429
|
+
fpb.TryReadFromCache(IOOptions(), r.get(), 0, 4096, &result, &s);
|
|
3430
|
+
// Platforms that don't have IO uring may not support async IO.
|
|
3431
|
+
if (use_async_prefetch && s.IsNotSupported()) {
|
|
3432
|
+
return;
|
|
3433
|
+
}
|
|
3434
|
+
ASSERT_TRUE(could_read_from_cache);
|
|
3435
|
+
ASSERT_EQ(s, Status::OK());
|
|
3436
|
+
ASSERT_EQ(stats->getAndResetTickerCount(PREFETCH_HITS), 0);
|
|
3437
|
+
ASSERT_EQ(stats->getAndResetTickerCount(PREFETCH_BYTES_USEFUL), 0);
|
|
3438
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(0, 4096).c_str(), 4096), 0);
|
|
3439
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3440
|
+
fpb.TEST_GetBufferOffsetandSize(buffer_info);
|
|
3441
|
+
if (use_async_prefetch) {
|
|
3442
|
+
// Cut the readahead of 8192 in half.
|
|
3443
|
+
// Overlap buffer is not used
|
|
3444
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3445
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3446
|
+
// Buffers: 0-8192, 8192-12288
|
|
3447
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 0);
|
|
3448
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 4096 + 8192 / 2);
|
|
3449
|
+
ASSERT_EQ(std::get<0>(buffer_info[1]), 4096 + 8192 / 2);
|
|
3450
|
+
ASSERT_EQ(std::get<1>(buffer_info[1]), 8192 / 2);
|
|
3451
|
+
} else {
|
|
3452
|
+
// Read at offset 0 with length 4096 + 8192 = 12288.
|
|
3453
|
+
// Overlap buffer is not used
|
|
3454
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3455
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3456
|
+
// Main buffer contains the requested data + the 8192 of prefetched data
|
|
3457
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 0);
|
|
3458
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 4096 + 8192);
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
// Simulate a block cache hit
|
|
3462
|
+
fpb.UpdateReadPattern(4096, 4096, false);
|
|
3463
|
+
ASSERT_TRUE(
|
|
3464
|
+
fpb.TryReadFromCache(IOOptions(), r.get(), 8192, 8192, &result, &s));
|
|
3465
|
+
ASSERT_EQ(s, Status::OK());
|
|
3466
|
+
ASSERT_EQ(stats->getAndResetTickerCount(PREFETCH_HITS), 0);
|
|
3467
|
+
ASSERT_EQ(stats->getAndResetTickerCount(PREFETCH_BYTES_USEFUL),
|
|
3468
|
+
4096); // 8192-12288
|
|
3469
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(8192, 8192).c_str(), 8192),
|
|
3470
|
+
0);
|
|
3471
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3472
|
+
fpb.TEST_GetBufferOffsetandSize(buffer_info);
|
|
3473
|
+
|
|
3474
|
+
if (use_async_prefetch) {
|
|
3475
|
+
// Our buffers were 0-8192, 8192-12288 at the start so we had some
|
|
3476
|
+
// overlapping data in the second buffer
|
|
3477
|
+
// We clean up outdated buffers so 0-8192 gets freed for more prefetching.
|
|
3478
|
+
// Our remaining buffer 8192-12288 has data that we want, so we can reuse it
|
|
3479
|
+
// We end up with: 8192-20480, 20480-24576
|
|
3480
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3481
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3482
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 8192);
|
|
3483
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 8192 + 8192 / 2);
|
|
3484
|
+
ASSERT_EQ(std::get<0>(buffer_info[1]), 8192 + (8192 + 8192 / 2));
|
|
3485
|
+
ASSERT_EQ(std::get<1>(buffer_info[1]), 8192 / 2);
|
|
3486
|
+
} else {
|
|
3487
|
+
// We only have 0-12288 cached, so reading from 8192-16384 will trigger a
|
|
3488
|
+
// prefetch up through 16384 + 8192 = 24576.
|
|
3489
|
+
// Overlap buffer reuses bytes 8192 to 12288
|
|
3490
|
+
ASSERT_EQ(overlap_buffer_info.first, 8192);
|
|
3491
|
+
ASSERT_EQ(overlap_buffer_info.second, 8192);
|
|
3492
|
+
ASSERT_EQ(overlap_buffer_write_ct, 2);
|
|
3493
|
+
// We spill to the overlap buffer so the remaining buffer only has the
|
|
3494
|
+
// missing and prefetched part
|
|
3495
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 12288);
|
|
3496
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 12288);
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3499
|
+
ASSERT_TRUE(
|
|
3500
|
+
fpb.TryReadFromCache(IOOptions(), r.get(), 12288, 4096, &result, &s));
|
|
3501
|
+
ASSERT_EQ(s, Status::OK());
|
|
3502
|
+
ASSERT_EQ(stats->getAndResetTickerCount(PREFETCH_HITS), 1);
|
|
3503
|
+
ASSERT_EQ(stats->getAndResetTickerCount(PREFETCH_BYTES_USEFUL),
|
|
3504
|
+
4096); // 12288-16384
|
|
3505
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(12288, 4096).c_str(), 4096),
|
|
3506
|
+
0);
|
|
3507
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3508
|
+
fpb.TEST_GetBufferOffsetandSize(buffer_info);
|
|
3509
|
+
|
|
3510
|
+
if (use_async_prefetch) {
|
|
3511
|
+
// Same as before: 8192-20480, 20480-24576 (cache hit in first buffer)
|
|
3512
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3513
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3514
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 8192);
|
|
3515
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 8192 + 8192 / 2);
|
|
3516
|
+
ASSERT_EQ(std::get<0>(buffer_info[1]), 8192 + (8192 + 8192 / 2));
|
|
3517
|
+
ASSERT_EQ(std::get<1>(buffer_info[1]), 8192 / 2);
|
|
3518
|
+
} else {
|
|
3519
|
+
// The main buffer has 12288-24576, so 12288-16384 is a cache hit.
|
|
3520
|
+
// Overlap buffer does not get used
|
|
3521
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3522
|
+
ASSERT_EQ(overlap_buffer_info.first, 8192);
|
|
3523
|
+
ASSERT_EQ(overlap_buffer_info.second, 8192);
|
|
3524
|
+
ASSERT_EQ(overlap_buffer_write_ct, 2);
|
|
3525
|
+
// Main buffer stays the same
|
|
3526
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 12288);
|
|
3527
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 12288);
|
|
3528
|
+
}
|
|
3529
|
+
|
|
3530
|
+
// Read from 16000-26000 (start and end do not meet normal alignment)
|
|
3531
|
+
ASSERT_TRUE(
|
|
3532
|
+
fpb.TryReadFromCache(IOOptions(), r.get(), 16000, 10000, &result, &s));
|
|
3533
|
+
ASSERT_EQ(s, Status::OK());
|
|
3534
|
+
ASSERT_EQ(stats->getAndResetTickerCount(PREFETCH_HITS), 0);
|
|
3535
|
+
ASSERT_EQ(
|
|
3536
|
+
stats->getAndResetTickerCount(PREFETCH_BYTES_USEFUL),
|
|
3537
|
+
/* 24576(end offset of the buffer) - 16000(requested offset) =*/8576);
|
|
3538
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(16000, 10000).c_str(), 10000),
|
|
3539
|
+
0);
|
|
3540
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3541
|
+
fpb.TEST_GetBufferOffsetandSize(buffer_info);
|
|
3542
|
+
if (use_async_prefetch) {
|
|
3543
|
+
// Overlap buffer reuses bytes 16000 to 20480
|
|
3544
|
+
ASSERT_EQ(overlap_buffer_info.first, 16000);
|
|
3545
|
+
ASSERT_EQ(overlap_buffer_info.second, 10000);
|
|
3546
|
+
// First 2 writes are reusing existing 2 buffers. Last write fills in
|
|
3547
|
+
// what could not be found in either.
|
|
3548
|
+
ASSERT_EQ(overlap_buffer_write_ct, 3);
|
|
3549
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 24576);
|
|
3550
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 32768 - 24576);
|
|
3551
|
+
ASSERT_EQ(std::get<0>(buffer_info[1]), 32768);
|
|
3552
|
+
ASSERT_EQ(std::get<1>(buffer_info[1]), 4096);
|
|
3553
|
+
ASSERT_TRUE(std::get<2>(
|
|
3554
|
+
buffer_info[1])); // in progress async request (otherwise we should not
|
|
3555
|
+
// be getting 4096 for the size)
|
|
3556
|
+
} else {
|
|
3557
|
+
// Overlap buffer reuses bytes 16000 to 24576
|
|
3558
|
+
ASSERT_EQ(overlap_buffer_info.first, 16000);
|
|
3559
|
+
ASSERT_EQ(overlap_buffer_info.second, 10000);
|
|
3560
|
+
ASSERT_EQ(overlap_buffer_write_ct, 4);
|
|
3561
|
+
// Even if you try to readahead to offset 16000 + 10000 + 8192, there are
|
|
3562
|
+
// only 32768 bytes in the original file
|
|
3563
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 12288 + 12288);
|
|
3564
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 8192);
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
|
|
3568
|
+
TEST_P(FSBufferPrefetchTest, FSBufferPrefetchUnalignedReads) {
|
|
3569
|
+
// Check that the main buffer, the overlap_buf_, and the secondary buffer (in
|
|
3570
|
+
// the case of num_buffers_ > 1) are populated correctly
|
|
3571
|
+
// while reading with no regard to alignment
|
|
3572
|
+
std::string fname = "fs-buffer-prefetch-unaligned-reads";
|
|
3573
|
+
Random rand(0);
|
|
3574
|
+
std::string content = rand.RandomString(1000);
|
|
3575
|
+
Write(fname, content);
|
|
3576
|
+
|
|
3577
|
+
FileOptions opts;
|
|
3578
|
+
std::unique_ptr<RandomAccessFileReader> r;
|
|
3579
|
+
Read(fname, opts, &r);
|
|
3580
|
+
|
|
3581
|
+
std::shared_ptr<Statistics> stats = CreateDBStatistics();
|
|
3582
|
+
ReadaheadParams readahead_params;
|
|
3583
|
+
// Readahead size will double each time
|
|
3584
|
+
readahead_params.initial_readahead_size = 5;
|
|
3585
|
+
readahead_params.max_readahead_size = 100;
|
|
3586
|
+
bool use_async_prefetch = GetParam();
|
|
3587
|
+
size_t num_buffers = use_async_prefetch ? 2 : 1;
|
|
3588
|
+
readahead_params.num_buffers = num_buffers;
|
|
3589
|
+
FilePrefetchBuffer fpb(readahead_params, true, false, fs(), clock(),
|
|
3590
|
+
stats.get());
|
|
3591
|
+
|
|
3592
|
+
int overlap_buffer_write_ct = 0;
|
|
3593
|
+
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
|
|
3594
|
+
"FilePrefetchBuffer::CopyDataToOverlapBuffer:Complete",
|
|
3595
|
+
[&](void* /*arg*/) { overlap_buffer_write_ct++; });
|
|
3596
|
+
SyncPoint::GetInstance()->EnableProcessing();
|
|
3597
|
+
|
|
3598
|
+
Slice result;
|
|
3599
|
+
// Read 3 bytes at offset 5
|
|
3600
|
+
Status s;
|
|
3601
|
+
std::vector<std::tuple<uint64_t, size_t, bool>> buffer_info(num_buffers);
|
|
3602
|
+
std::pair<uint64_t, size_t> overlap_buffer_info;
|
|
3603
|
+
bool could_read_from_cache =
|
|
3604
|
+
fpb.TryReadFromCache(IOOptions(), r.get(), 5, 3, &result, &s);
|
|
3605
|
+
// Platforms that don't have IO uring may not support async IO.
|
|
3606
|
+
if (use_async_prefetch && s.IsNotSupported()) {
|
|
3607
|
+
return;
|
|
3608
|
+
}
|
|
3609
|
+
ASSERT_TRUE(could_read_from_cache);
|
|
3610
|
+
ASSERT_EQ(s, Status::OK());
|
|
3611
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(5, 3).c_str(), 3), 0);
|
|
3612
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3613
|
+
fpb.TEST_GetBufferOffsetandSize(buffer_info);
|
|
3614
|
+
if (use_async_prefetch) {
|
|
3615
|
+
// Overlap buffer is not used
|
|
3616
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3617
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3618
|
+
// With async prefetching, we still try to align to 4096 bytes, so
|
|
3619
|
+
// our main buffer read and secondary buffer prefetch are rounded up
|
|
3620
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 0);
|
|
3621
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 1000);
|
|
3622
|
+
// This buffer won't actually get filled up with data since there is nothing
|
|
3623
|
+
// after 1000
|
|
3624
|
+
ASSERT_EQ(std::get<0>(buffer_info[1]), 4096);
|
|
3625
|
+
ASSERT_EQ(std::get<1>(buffer_info[1]), 4096);
|
|
3626
|
+
ASSERT_TRUE(std::get<2>(buffer_info[1])); // in progress async request
|
|
3627
|
+
} else {
|
|
3628
|
+
// Overlap buffer is not used
|
|
3629
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3630
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3631
|
+
// Main buffer contains the requested data + 5 of prefetched data (5 - 13)
|
|
3632
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 5);
|
|
3633
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 3 + 5);
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3636
|
+
ASSERT_TRUE(fpb.TryReadFromCache(IOOptions(), r.get(), 16, 7, &result, &s));
|
|
3637
|
+
ASSERT_EQ(s, Status::OK());
|
|
3638
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(16, 7).c_str(), 7), 0);
|
|
3639
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3640
|
+
fpb.TEST_GetBufferOffsetandSize(buffer_info);
|
|
3641
|
+
if (use_async_prefetch) {
|
|
3642
|
+
// Complete hit since we have the entire file loaded in the main buffer
|
|
3643
|
+
// The remaining requests will be the same when use_async_prefetch is true
|
|
3644
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3645
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3646
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 0);
|
|
3647
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 1000);
|
|
3648
|
+
} else {
|
|
3649
|
+
// Complete miss: read 7 bytes at offset 16
|
|
3650
|
+
// Overlap buffer is not used (no partial hit)
|
|
3651
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3652
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3653
|
+
// Main buffer contains the requested data + 10 of prefetched data (16 - 33)
|
|
3654
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 16);
|
|
3655
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 7 + 10);
|
|
3656
|
+
}
|
|
3657
|
+
|
|
3658
|
+
// Go backwards
|
|
3659
|
+
if (use_async_prefetch) {
|
|
3660
|
+
ASSERT_TRUE(fpb.TryReadFromCache(IOOptions(), r.get(), 10, 8, &result, &s));
|
|
3661
|
+
} else {
|
|
3662
|
+
// TryReadFromCacheUntracked returns false since the offset
|
|
3663
|
+
// requested is less than the start of our buffer
|
|
3664
|
+
ASSERT_FALSE(
|
|
3665
|
+
fpb.TryReadFromCache(IOOptions(), r.get(), 10, 8, &result, &s));
|
|
3666
|
+
}
|
|
3667
|
+
ASSERT_EQ(s, Status::OK());
|
|
3668
|
+
|
|
3669
|
+
ASSERT_TRUE(fpb.TryReadFromCache(IOOptions(), r.get(), 27, 6, &result, &s));
|
|
3670
|
+
ASSERT_EQ(s, Status::OK());
|
|
3671
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(27, 6).c_str(), 6), 0);
|
|
3672
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3673
|
+
fpb.TEST_GetBufferOffsetandSize(buffer_info);
|
|
3674
|
+
if (use_async_prefetch) {
|
|
3675
|
+
// Complete hit since we have the entire file loaded in the main buffer
|
|
3676
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3677
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3678
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 0);
|
|
3679
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 1000);
|
|
3680
|
+
} else {
|
|
3681
|
+
// Complete hit
|
|
3682
|
+
// Overlap buffer still not used
|
|
3683
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3684
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3685
|
+
// Main buffer unchanged
|
|
3686
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 16);
|
|
3687
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 7 + 10);
|
|
3688
|
+
}
|
|
3689
|
+
|
|
3690
|
+
ASSERT_TRUE(fpb.TryReadFromCache(IOOptions(), r.get(), 30, 20, &result, &s));
|
|
3691
|
+
ASSERT_EQ(s, Status::OK());
|
|
3692
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(30, 20).c_str(), 20), 0);
|
|
3693
|
+
fpb.TEST_GetOverlapBufferOffsetandSize(overlap_buffer_info);
|
|
3694
|
+
fpb.TEST_GetBufferOffsetandSize(buffer_info);
|
|
3695
|
+
if (use_async_prefetch) {
|
|
3696
|
+
// Complete hit since we have the entire file loaded in the main buffer
|
|
3697
|
+
ASSERT_EQ(overlap_buffer_info.first, 0);
|
|
3698
|
+
ASSERT_EQ(overlap_buffer_info.second, 0);
|
|
3699
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 0);
|
|
3700
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), 1000);
|
|
3701
|
+
} else {
|
|
3702
|
+
// Partial hit (overlapping with end of main buffer)
|
|
3703
|
+
// Overlap buffer is used because we already had 30-33
|
|
3704
|
+
ASSERT_EQ(overlap_buffer_info.first, 30);
|
|
3705
|
+
ASSERT_EQ(overlap_buffer_info.second, 20);
|
|
3706
|
+
ASSERT_EQ(overlap_buffer_write_ct, 2);
|
|
3707
|
+
// Main buffer has up to offset 50 + 20 of prefetched data
|
|
3708
|
+
ASSERT_EQ(std::get<0>(buffer_info[0]), 33);
|
|
3709
|
+
ASSERT_EQ(std::get<1>(buffer_info[0]), (50 - 33) + 20);
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
|
|
3713
|
+
TEST_P(FSBufferPrefetchTest, FSBufferPrefetchForCompaction) {
|
|
3714
|
+
// Quick test to make sure file system buffer reuse is disabled for compaction
|
|
3715
|
+
// reads. Will update once it is re-enabled
|
|
3716
|
+
// Primarily making sure we do not hit unsigned integer overflow issues
|
|
3717
|
+
std::string fname = "fs-buffer-prefetch-for-compaction";
|
|
3718
|
+
Random rand(0);
|
|
3719
|
+
std::string content = rand.RandomString(32768);
|
|
3720
|
+
Write(fname, content);
|
|
3721
|
+
|
|
3722
|
+
FileOptions opts;
|
|
3723
|
+
std::unique_ptr<RandomAccessFileReader> r;
|
|
3724
|
+
Read(fname, opts, &r);
|
|
3725
|
+
|
|
3726
|
+
std::shared_ptr<Statistics> stats = CreateDBStatistics();
|
|
3727
|
+
ReadaheadParams readahead_params;
|
|
3728
|
+
readahead_params.initial_readahead_size = 8192;
|
|
3729
|
+
readahead_params.max_readahead_size = 8192;
|
|
3730
|
+
bool use_async_prefetch = GetParam();
|
|
3731
|
+
// Async IO is not enabled for compaction prefetching
|
|
3732
|
+
if (use_async_prefetch) {
|
|
3733
|
+
return;
|
|
3734
|
+
}
|
|
3735
|
+
readahead_params.num_buffers = 1;
|
|
3736
|
+
|
|
3737
|
+
FilePrefetchBuffer fpb(readahead_params, true, false, fs(), clock(),
|
|
3738
|
+
stats.get());
|
|
3739
|
+
|
|
3740
|
+
Slice result;
|
|
3741
|
+
Status s;
|
|
3742
|
+
ASSERT_TRUE(
|
|
3743
|
+
fpb.TryReadFromCache(IOOptions(), r.get(), 0, 4096, &result, &s, true));
|
|
3744
|
+
ASSERT_EQ(s, Status::OK());
|
|
3745
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(0, 4096).c_str(), 4096), 0);
|
|
3746
|
+
|
|
3747
|
+
fpb.UpdateReadPattern(4096, 4096, false);
|
|
3748
|
+
|
|
3749
|
+
ASSERT_TRUE(fpb.TryReadFromCache(IOOptions(), r.get(), 8192, 8192, &result,
|
|
3750
|
+
&s, true));
|
|
3751
|
+
ASSERT_EQ(s, Status::OK());
|
|
3752
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(8192, 8192).c_str(), 8192),
|
|
3753
|
+
0);
|
|
3754
|
+
|
|
3755
|
+
ASSERT_TRUE(fpb.TryReadFromCache(IOOptions(), r.get(), 12288, 4096, &result,
|
|
3756
|
+
&s, true));
|
|
3757
|
+
ASSERT_EQ(s, Status::OK());
|
|
3758
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(12288, 4096).c_str(), 4096),
|
|
3759
|
+
0);
|
|
3760
|
+
|
|
3761
|
+
// Read from 16000-26000 (start and end do not meet normal alignment)
|
|
3762
|
+
ASSERT_TRUE(fpb.TryReadFromCache(IOOptions(), r.get(), 16000, 10000, &result,
|
|
3763
|
+
&s, true));
|
|
3764
|
+
ASSERT_EQ(s, Status::OK());
|
|
3765
|
+
ASSERT_EQ(strncmp(result.data(), content.substr(16000, 10000).c_str(), 10000),
|
|
3766
|
+
0);
|
|
3767
|
+
}
|
|
3768
|
+
|
|
3151
3769
|
} // namespace ROCKSDB_NAMESPACE
|
|
3152
3770
|
|
|
3153
3771
|
int main(int argc, char** argv) {
|