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 "memory/memory_allocator.h" 12 #include "table/block_based/block.h" 13 #include "table/block_based/block_type.h" 14 #include "table/format.h" 15 16 namespace ROCKSDB_NAMESPACE { 17 18 // Retrieves a single block of a given file. Utilizes the prefetch buffer and/or 19 // persistent cache provided (if any) to try to avoid reading from the file 20 // directly. Note that both the prefetch buffer and the persistent cache are 21 // optional; also, note that the persistent cache may be configured to store either 22 // compressed or uncompressed blocks. 23 // 24 // If the retrieved block is compressed and the do_uncompress flag is set, 25 // BlockFetcher uncompresses the block (using the uncompression dictionary, 26 // if provided, to prime the compression algorithm), and returns the resulting 27 // uncompressed block data. Otherwise, it returns the original block. 28 // 29 // Two read options affect the behavior of BlockFetcher: if verify_checksums is 30 // true, the checksum of the (original) block is checked; if fill_cache is true, 31 // the block is added to the persistent cache if needed. 32 // 33 // Memory for uncompressed and compressed blocks is allocated as needed 34 // using memory_allocator and memory_allocator_compressed, respectively 35 // (if provided; otherwise, the default allocator is used). 36 37 class BlockFetcher { 38 public: 39 BlockFetcher(RandomAccessFileReader* file, 40 FilePrefetchBuffer* prefetch_buffer, const Footer& footer, 41 const ReadOptions& read_options, const BlockHandle& handle, 42 BlockContents* contents, const ImmutableCFOptions& ioptions, 43 bool do_uncompress, bool maybe_compressed, BlockType block_type, 44 const UncompressionDict& uncompression_dict, 45 const PersistentCacheOptions& cache_options, 46 MemoryAllocator* memory_allocator = nullptr, 47 MemoryAllocator* memory_allocator_compressed = nullptr, 48 bool for_compaction = false) file_(file)49 : file_(file), 50 prefetch_buffer_(prefetch_buffer), 51 footer_(footer), 52 read_options_(read_options), 53 handle_(handle), 54 contents_(contents), 55 ioptions_(ioptions), 56 do_uncompress_(do_uncompress), 57 maybe_compressed_(maybe_compressed), 58 block_type_(block_type), 59 uncompression_dict_(uncompression_dict), 60 cache_options_(cache_options), 61 memory_allocator_(memory_allocator), 62 memory_allocator_compressed_(memory_allocator_compressed), 63 for_compaction_(for_compaction) {} 64 65 Status ReadBlockContents(); get_compression_type()66 CompressionType get_compression_type() const { return compression_type_; } 67 68 private: 69 static const uint32_t kDefaultStackBufferSize = 5000; 70 71 RandomAccessFileReader* file_; 72 FilePrefetchBuffer* prefetch_buffer_; 73 const Footer& footer_; 74 const ReadOptions read_options_; 75 const BlockHandle& handle_; 76 BlockContents* contents_; 77 const ImmutableCFOptions& ioptions_; 78 bool do_uncompress_; 79 bool maybe_compressed_; 80 BlockType block_type_; 81 const UncompressionDict& uncompression_dict_; 82 const PersistentCacheOptions& cache_options_; 83 MemoryAllocator* memory_allocator_; 84 MemoryAllocator* memory_allocator_compressed_; 85 Status status_; 86 Slice slice_; 87 char* used_buf_ = nullptr; 88 size_t block_size_; 89 CacheAllocationPtr heap_buf_; 90 CacheAllocationPtr compressed_buf_; 91 char stack_buf_[kDefaultStackBufferSize]; 92 bool got_from_prefetch_buffer_ = false; 93 ROCKSDB_NAMESPACE::CompressionType compression_type_; 94 bool for_compaction_ = false; 95 96 // return true if found 97 bool TryGetUncompressBlockFromPersistentCache(); 98 // return true if found 99 bool TryGetFromPrefetchBuffer(); 100 bool TryGetCompressedBlockFromPersistentCache(); 101 void PrepareBufferForBlockFromFile(); 102 // Copy content from used_buf_ to new heap buffer. 103 void CopyBufferToHeap(); 104 void GetBlockContents(); 105 void InsertCompressedBlockToPersistentCacheIfNeeded(); 106 void InsertUncompressedBlockToPersistentCacheIfNeeded(); 107 void CheckBlockChecksum(); 108 }; 109 } // namespace ROCKSDB_NAMESPACE 110