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 {
PrefetchIfNeeded(const BlockBasedTable::Rep * rep,const BlockHandle & handle,size_t readahead_size,bool is_for_compaction)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 if (readahead_size == 0) {
18 // Implicit auto readahead
19 num_file_reads_++;
20 if (num_file_reads_ >
21 BlockBasedTable::kMinNumFileReadsToStartAutoReadahead) {
22 if (!rep->file->use_direct_io() &&
23 (handle.offset() + static_cast<size_t>(block_size(handle)) >
24 readahead_limit_)) {
25 // Buffered I/O
26 // Discarding the return status of Prefetch calls intentionally, as
27 // we can fallback to reading from disk if Prefetch fails.
28 rep->file->Prefetch(handle.offset(), readahead_size_);
29 readahead_limit_ =
30 static_cast<size_t>(handle.offset() + readahead_size_);
31 // Keep exponentially increasing readahead size until
32 // kMaxAutoReadaheadSize.
33 readahead_size_ = std::min(BlockBasedTable::kMaxAutoReadaheadSize,
34 readahead_size_ * 2);
35 } else if (rep->file->use_direct_io() && !prefetch_buffer_) {
36 // Direct I/O
37 // Let FilePrefetchBuffer take care of the readahead.
38 rep->CreateFilePrefetchBuffer(BlockBasedTable::kInitAutoReadaheadSize,
39 BlockBasedTable::kMaxAutoReadaheadSize,
40 &prefetch_buffer_);
41 }
42 }
43 } else if (!prefetch_buffer_) {
44 // Explicit user requested readahead
45 // The actual condition is:
46 // if (readahead_size != 0 && !prefetch_buffer_)
47 rep->CreateFilePrefetchBuffer(readahead_size, readahead_size,
48 &prefetch_buffer_);
49 }
50 } else if (!prefetch_buffer_) {
51 rep->CreateFilePrefetchBuffer(compaction_readahead_size_,
52 compaction_readahead_size_,
53 &prefetch_buffer_);
54 }
55 }
56 } // namespace ROCKSDB_NAMESPACE
57