]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
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 | namespace ROCKSDB_NAMESPACE { | |
12 | void BlockPrefetcher::PrefetchIfNeeded(const BlockBasedTable::Rep* rep, | |
13 | const BlockHandle& handle, | |
14 | size_t readahead_size, | |
15 | bool is_for_compaction) { | |
16 | if (is_for_compaction) { | |
17 | rep->CreateFilePrefetchBufferIfNotExists(compaction_readahead_size_, | |
18 | compaction_readahead_size_, | |
19 | &prefetch_buffer_); | |
20 | return; | |
21 | } | |
22 | ||
23 | // Explicit user requested readahead | |
24 | if (readahead_size > 0) { | |
25 | rep->CreateFilePrefetchBufferIfNotExists(readahead_size, readahead_size, | |
26 | &prefetch_buffer_); | |
27 | return; | |
28 | } | |
29 | ||
30 | // Implicit auto readahead, which will be enabled if the number of reads | |
31 | // reached `kMinNumFileReadsToStartAutoReadahead` (default: 2). | |
32 | num_file_reads_++; | |
33 | if (num_file_reads_ <= | |
34 | BlockBasedTable::kMinNumFileReadsToStartAutoReadahead) { | |
35 | return; | |
36 | } | |
37 | ||
38 | if (rep->file->use_direct_io()) { | |
39 | rep->CreateFilePrefetchBufferIfNotExists( | |
40 | BlockBasedTable::kInitAutoReadaheadSize, | |
41 | BlockBasedTable::kMaxAutoReadaheadSize, &prefetch_buffer_); | |
42 | return; | |
43 | } | |
44 | ||
45 | if (handle.offset() + static_cast<size_t>(block_size(handle)) <= | |
46 | readahead_limit_) { | |
47 | return; | |
48 | } | |
49 | ||
50 | // If prefetch is not supported, fall back to use internal prefetch buffer. | |
51 | // Discarding other return status of Prefetch calls intentionally, as | |
52 | // we can fallback to reading from disk if Prefetch fails. | |
53 | Status s = rep->file->Prefetch(handle.offset(), readahead_size_); | |
54 | if (s.IsNotSupported()) { | |
55 | rep->CreateFilePrefetchBufferIfNotExists( | |
56 | BlockBasedTable::kInitAutoReadaheadSize, | |
57 | BlockBasedTable::kMaxAutoReadaheadSize, &prefetch_buffer_); | |
58 | return; | |
59 | } | |
60 | readahead_limit_ = static_cast<size_t>(handle.offset() + readahead_size_); | |
61 | // Keep exponentially increasing readahead size until | |
62 | // kMaxAutoReadaheadSize. | |
63 | readahead_size_ = | |
64 | std::min(BlockBasedTable::kMaxAutoReadaheadSize, readahead_size_ * 2); | |
65 | } | |
66 | } // namespace ROCKSDB_NAMESPACE |