]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/table/block_based/block_prefetcher.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / table / block_based / block_prefetcher.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
5 //
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9 #include "table/block_based/block_prefetcher.h"
10
11 #include "rocksdb/file_system.h"
12 #include "table/block_based/block_based_table_reader.h"
13
14 namespace ROCKSDB_NAMESPACE {
15 void BlockPrefetcher::PrefetchIfNeeded(
16 const BlockBasedTable::Rep* rep, const BlockHandle& handle,
17 const size_t readahead_size, bool is_for_compaction,
18 const bool no_sequential_checking,
19 const Env::IOPriority rate_limiter_priority) {
20 // num_file_reads is used by FilePrefetchBuffer only when
21 // implicit_auto_readahead is set.
22 if (is_for_compaction) {
23 rep->CreateFilePrefetchBufferIfNotExists(
24 compaction_readahead_size_, compaction_readahead_size_,
25 &prefetch_buffer_, /*implicit_auto_readahead=*/false,
26 /*num_file_reads=*/0, /*num_file_reads_for_auto_readahead=*/0);
27 return;
28 }
29
30 // Explicit user requested readahead.
31 if (readahead_size > 0) {
32 rep->CreateFilePrefetchBufferIfNotExists(
33 readahead_size, readahead_size, &prefetch_buffer_,
34 /*implicit_auto_readahead=*/false, /*num_file_reads=*/0,
35 /*num_file_reads_for_auto_readahead=*/0);
36 return;
37 }
38
39 // Implicit readahead.
40
41 // If max_auto_readahead_size is set to be 0 by user, no data will be
42 // prefetched.
43 size_t max_auto_readahead_size = rep->table_options.max_auto_readahead_size;
44 if (max_auto_readahead_size == 0 || initial_auto_readahead_size_ == 0) {
45 return;
46 }
47
48 if (initial_auto_readahead_size_ > max_auto_readahead_size) {
49 initial_auto_readahead_size_ = max_auto_readahead_size;
50 }
51
52 // In case of no_sequential_checking, it will skip the num_file_reads_ and
53 // will always creates the FilePrefetchBuffer.
54 if (no_sequential_checking) {
55 rep->CreateFilePrefetchBufferIfNotExists(
56 initial_auto_readahead_size_, max_auto_readahead_size,
57 &prefetch_buffer_, /*implicit_auto_readahead=*/true,
58 /*num_file_reads=*/0,
59 rep->table_options.num_file_reads_for_auto_readahead);
60 return;
61 }
62
63 size_t len = BlockBasedTable::BlockSizeWithTrailer(handle);
64 size_t offset = handle.offset();
65
66 // If FS supports prefetching (readahead_limit_ will be non zero in that case)
67 // and current block exists in prefetch buffer then return.
68 if (offset + len <= readahead_limit_) {
69 UpdateReadPattern(offset, len);
70 return;
71 }
72
73 if (!IsBlockSequential(offset)) {
74 UpdateReadPattern(offset, len);
75 ResetValues(rep->table_options.initial_auto_readahead_size);
76 return;
77 }
78 UpdateReadPattern(offset, len);
79
80 // Implicit auto readahead, which will be enabled if the number of reads
81 // reached `table_options.num_file_reads_for_auto_readahead` (default: 2) and
82 // scans are sequential.
83 num_file_reads_++;
84 if (num_file_reads_ <= rep->table_options.num_file_reads_for_auto_readahead) {
85 return;
86 }
87
88 if (rep->file->use_direct_io()) {
89 rep->CreateFilePrefetchBufferIfNotExists(
90 initial_auto_readahead_size_, max_auto_readahead_size,
91 &prefetch_buffer_, /*implicit_auto_readahead=*/true, num_file_reads_,
92 rep->table_options.num_file_reads_for_auto_readahead);
93 return;
94 }
95
96 if (readahead_size_ > max_auto_readahead_size) {
97 readahead_size_ = max_auto_readahead_size;
98 }
99
100 // If prefetch is not supported, fall back to use internal prefetch buffer.
101 // Discarding other return status of Prefetch calls intentionally, as
102 // we can fallback to reading from disk if Prefetch fails.
103 Status s = rep->file->Prefetch(
104 handle.offset(),
105 BlockBasedTable::BlockSizeWithTrailer(handle) + readahead_size_,
106 rate_limiter_priority);
107 if (s.IsNotSupported()) {
108 rep->CreateFilePrefetchBufferIfNotExists(
109 initial_auto_readahead_size_, max_auto_readahead_size,
110 &prefetch_buffer_, /*implicit_auto_readahead=*/true, num_file_reads_,
111 rep->table_options.num_file_reads_for_auto_readahead);
112 return;
113 }
114
115 readahead_limit_ = offset + len + readahead_size_;
116 // Keep exponentially increasing readahead size until
117 // max_auto_readahead_size.
118 readahead_size_ = std::min(max_auto_readahead_size, readahead_size_ * 2);
119 }
120 } // namespace ROCKSDB_NAMESPACE