]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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 | |
f67539c2 TL |
11 | #include "memory/memory_allocator.h" |
12 | #include "table/block_based/block.h" | |
13 | #include "table/block_based/block_type.h" | |
11fdf7f2 | 14 | #include "table/format.h" |
1e59de90 | 15 | #include "table/persistent_cache_options.h" |
11fdf7f2 | 16 | |
f67539c2 TL |
17 | namespace ROCKSDB_NAMESPACE { |
18 | ||
19 | // Retrieves a single block of a given file. Utilizes the prefetch buffer and/or | |
20 | // persistent cache provided (if any) to try to avoid reading from the file | |
21 | // directly. Note that both the prefetch buffer and the persistent cache are | |
1e59de90 TL |
22 | // optional; also, note that the persistent cache may be configured to store |
23 | // either compressed or uncompressed blocks. | |
f67539c2 TL |
24 | // |
25 | // If the retrieved block is compressed and the do_uncompress flag is set, | |
26 | // BlockFetcher uncompresses the block (using the uncompression dictionary, | |
27 | // if provided, to prime the compression algorithm), and returns the resulting | |
28 | // uncompressed block data. Otherwise, it returns the original block. | |
29 | // | |
30 | // Two read options affect the behavior of BlockFetcher: if verify_checksums is | |
31 | // true, the checksum of the (original) block is checked; if fill_cache is true, | |
32 | // the block is added to the persistent cache if needed. | |
33 | // | |
34 | // Memory for uncompressed and compressed blocks is allocated as needed | |
35 | // using memory_allocator and memory_allocator_compressed, respectively | |
36 | // (if provided; otherwise, the default allocator is used). | |
37 | ||
11fdf7f2 TL |
38 | class BlockFetcher { |
39 | public: | |
11fdf7f2 | 40 | BlockFetcher(RandomAccessFileReader* file, |
1e59de90 TL |
41 | FilePrefetchBuffer* prefetch_buffer, |
42 | const Footer& footer /* ref retained */, | |
43 | const ReadOptions& read_options, | |
44 | const BlockHandle& handle /* ref retained */, | |
45 | BlockContents* contents, | |
46 | const ImmutableOptions& ioptions /* ref retained */, | |
f67539c2 | 47 | bool do_uncompress, bool maybe_compressed, BlockType block_type, |
1e59de90 TL |
48 | const UncompressionDict& uncompression_dict /* ref retained */, |
49 | const PersistentCacheOptions& cache_options /* ref retained */, | |
494da23a | 50 | MemoryAllocator* memory_allocator = nullptr, |
f67539c2 TL |
51 | MemoryAllocator* memory_allocator_compressed = nullptr, |
52 | bool for_compaction = false) | |
11fdf7f2 TL |
53 | : file_(file), |
54 | prefetch_buffer_(prefetch_buffer), | |
55 | footer_(footer), | |
56 | read_options_(read_options), | |
57 | handle_(handle), | |
58 | contents_(contents), | |
59 | ioptions_(ioptions), | |
60 | do_uncompress_(do_uncompress), | |
494da23a | 61 | maybe_compressed_(maybe_compressed), |
f67539c2 | 62 | block_type_(block_type), |
20effc67 | 63 | block_size_(static_cast<size_t>(handle_.size())), |
1e59de90 | 64 | block_size_with_trailer_(block_size_ + footer.GetBlockTrailerSize()), |
494da23a TL |
65 | uncompression_dict_(uncompression_dict), |
66 | cache_options_(cache_options), | |
67 | memory_allocator_(memory_allocator), | |
f67539c2 | 68 | memory_allocator_compressed_(memory_allocator_compressed), |
1e59de90 TL |
69 | for_compaction_(for_compaction) { |
70 | io_status_.PermitUncheckedError(); // TODO(AR) can we improve on this? | |
71 | } | |
72 | ||
73 | IOStatus ReadBlockContents(); | |
74 | IOStatus ReadAsyncBlockContents(); | |
f67539c2 | 75 | |
1e59de90 TL |
76 | inline CompressionType get_compression_type() const { |
77 | return compression_type_; | |
78 | } | |
79 | inline size_t GetBlockSizeWithTrailer() const { | |
80 | return block_size_with_trailer_; | |
81 | } | |
11fdf7f2 | 82 | |
20effc67 TL |
83 | #ifndef NDEBUG |
84 | int TEST_GetNumStackBufMemcpy() const { return num_stack_buf_memcpy_; } | |
85 | int TEST_GetNumHeapBufMemcpy() const { return num_heap_buf_memcpy_; } | |
86 | int TEST_GetNumCompressedBufMemcpy() const { | |
87 | return num_compressed_buf_memcpy_; | |
88 | } | |
89 | ||
90 | #endif | |
11fdf7f2 | 91 | private: |
20effc67 TL |
92 | #ifndef NDEBUG |
93 | int num_stack_buf_memcpy_ = 0; | |
94 | int num_heap_buf_memcpy_ = 0; | |
95 | int num_compressed_buf_memcpy_ = 0; | |
96 | ||
97 | #endif | |
11fdf7f2 TL |
98 | static const uint32_t kDefaultStackBufferSize = 5000; |
99 | ||
100 | RandomAccessFileReader* file_; | |
101 | FilePrefetchBuffer* prefetch_buffer_; | |
102 | const Footer& footer_; | |
103 | const ReadOptions read_options_; | |
104 | const BlockHandle& handle_; | |
105 | BlockContents* contents_; | |
1e59de90 | 106 | const ImmutableOptions& ioptions_; |
20effc67 TL |
107 | const bool do_uncompress_; |
108 | const bool maybe_compressed_; | |
109 | const BlockType block_type_; | |
110 | const size_t block_size_; | |
111 | const size_t block_size_with_trailer_; | |
494da23a | 112 | const UncompressionDict& uncompression_dict_; |
11fdf7f2 | 113 | const PersistentCacheOptions& cache_options_; |
494da23a TL |
114 | MemoryAllocator* memory_allocator_; |
115 | MemoryAllocator* memory_allocator_compressed_; | |
1e59de90 | 116 | IOStatus io_status_; |
11fdf7f2 TL |
117 | Slice slice_; |
118 | char* used_buf_ = nullptr; | |
20effc67 | 119 | AlignedBuf direct_io_buf_; |
494da23a TL |
120 | CacheAllocationPtr heap_buf_; |
121 | CacheAllocationPtr compressed_buf_; | |
11fdf7f2 TL |
122 | char stack_buf_[kDefaultStackBufferSize]; |
123 | bool got_from_prefetch_buffer_ = false; | |
20effc67 | 124 | CompressionType compression_type_; |
f67539c2 | 125 | bool for_compaction_ = false; |
11fdf7f2 TL |
126 | |
127 | // return true if found | |
128 | bool TryGetUncompressBlockFromPersistentCache(); | |
129 | // return true if found | |
130 | bool TryGetFromPrefetchBuffer(); | |
1e59de90 | 131 | bool TryGetSerializedBlockFromPersistentCache(); |
11fdf7f2 | 132 | void PrepareBufferForBlockFromFile(); |
20effc67 TL |
133 | // Copy content from used_buf_ to new heap_buf_. |
134 | void CopyBufferToHeapBuf(); | |
135 | // Copy content from used_buf_ to new compressed_buf_. | |
136 | void CopyBufferToCompressedBuf(); | |
11fdf7f2 TL |
137 | void GetBlockContents(); |
138 | void InsertCompressedBlockToPersistentCacheIfNeeded(); | |
139 | void InsertUncompressedBlockToPersistentCacheIfNeeded(); | |
1e59de90 | 140 | void ProcessTrailerIfPresent(); |
11fdf7f2 | 141 | }; |
f67539c2 | 142 | } // namespace ROCKSDB_NAMESPACE |