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