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 10 #pragma once 11 #include <atomic> 12 #include <sstream> 13 #include <string> 14 #include "file/random_access_file_reader.h" 15 #include "port/port.h" 16 #include "rocksdb/env.h" 17 #include "util/aligned_buffer.h" 18 19 namespace ROCKSDB_NAMESPACE { 20 21 // FilePrefetchBuffer is a smart buffer to store and read data from a file. 22 class FilePrefetchBuffer { 23 public: 24 // Constructor. 25 // 26 // All arguments are optional. 27 // file_reader : the file reader to use. Can be a nullptr. 28 // readahead_size : the initial readahead size. 29 // max_readahead_size : the maximum readahead size. 30 // If max_readahead_size > readahead_size, the readahead size will be 31 // doubled on every IO until max_readahead_size is hit. 32 // Typically this is set as a multiple of readahead_size. 33 // max_readahead_size should be greater than equal to readahead_size. 34 // enable : controls whether reading from the buffer is enabled. 35 // If false, TryReadFromCache() always return false, and we only take stats 36 // for the minimum offset if track_min_offset = true. 37 // track_min_offset : Track the minimum offset ever read and collect stats on 38 // it. Used for adaptable readahead of the file footer/metadata. 39 // 40 // Automatic readhead is enabled for a file if file_reader, readahead_size, 41 // and max_readahead_size are passed in. 42 // If file_reader is a nullptr, setting readadhead_size and max_readahead_size 43 // does not make any sense. So it does nothing. 44 // A user can construct a FilePrefetchBuffer without any arguments, but use 45 // `Prefetch` to load data into the buffer. 46 FilePrefetchBuffer(RandomAccessFileReader* file_reader = nullptr, 47 size_t readadhead_size = 0, size_t max_readahead_size = 0, 48 bool enable = true, bool track_min_offset = false) 49 : buffer_offset_(0), 50 file_reader_(file_reader), 51 readahead_size_(readadhead_size), 52 max_readahead_size_(max_readahead_size), 53 min_offset_read_(port::kMaxSizet), 54 enable_(enable), 55 track_min_offset_(track_min_offset) {} 56 57 // Load data into the buffer from a file. 58 // reader : the file reader. 59 // offset : the file offset to start reading from. 60 // n : the number of bytes to read. 61 // for_compaction : if prefetch is done for compaction read. 62 Status Prefetch(RandomAccessFileReader* reader, uint64_t offset, size_t n, 63 bool for_compaction = false); 64 65 // Tries returning the data for a file raed from this buffer, if that data is 66 // in the buffer. 67 // It handles tracking the minimum read offset if track_min_offset = true. 68 // It also does the exponential readahead when readadhead_size is set as part 69 // of the constructor. 70 // 71 // offset : the file offset. 72 // n : the number of bytes. 73 // result : output buffer to put the data into. 74 // for_compaction : if cache read is done for compaction read. 75 bool TryReadFromCache(uint64_t offset, size_t n, Slice* result, 76 bool for_compaction = false); 77 78 // The minimum `offset` ever passed to TryReadFromCache(). This will nly be 79 // tracked if track_min_offset = true. min_offset_read()80 size_t min_offset_read() const { return min_offset_read_; } 81 82 private: 83 AlignedBuffer buffer_; 84 uint64_t buffer_offset_; 85 RandomAccessFileReader* file_reader_; 86 size_t readahead_size_; 87 size_t max_readahead_size_; 88 // The minimum `offset` ever passed to TryReadFromCache(). 89 size_t min_offset_read_; 90 // if false, TryReadFromCache() always return false, and we only take stats 91 // for track_min_offset_ if track_min_offset_ = true 92 bool enable_; 93 // If true, track minimum `offset` ever passed to TryReadFromCache(), which 94 // can be fetched from min_offset_read(). 95 bool track_min_offset_; 96 }; 97 } // namespace ROCKSDB_NAMESPACE 98