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