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).
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.
10 #include "table/block_based/block_based_table_reader.h"
12 #include "table/block_based/block_based_table_reader_impl.h"
13 #include "table/block_based/block_prefetcher.h"
14 #include "table/block_based/reader_common.h"
16 namespace ROCKSDB_NAMESPACE
{
17 // Iterator that iterates over partitioned index.
18 // Some upper and lower bound tricks played in block based table iterators
19 // could be played here, but it's too complicated to reason about index
20 // keys with upper or lower bound, so we skip it for simplicity.
21 class PartitionedIndexIterator
: public InternalIteratorBase
<IndexValue
> {
22 // compaction_readahead_size: its value will only be used if for_compaction =
25 PartitionedIndexIterator(
26 const BlockBasedTable
* table
, const ReadOptions
& read_options
,
27 const InternalKeyComparator
& icomp
,
28 std::unique_ptr
<InternalIteratorBase
<IndexValue
>>&& index_iter
,
29 TableReaderCaller caller
, size_t compaction_readahead_size
= 0)
31 read_options_(read_options
),
35 user_comparator_(icomp
.user_comparator()),
36 index_iter_(std::move(index_iter
)),
37 block_iter_points_to_real_block_(false),
38 lookup_context_(caller
),
39 block_prefetcher_(compaction_readahead_size
) {}
41 ~PartitionedIndexIterator() override
{}
43 void Seek(const Slice
& target
) override
;
44 void SeekForPrev(const Slice
&) override
{
45 // Shouldn't be called.
48 void SeekToFirst() override
;
49 void SeekToLast() override
;
50 void Next() final override
;
51 bool NextAndGetResult(IterateResult
*) override
{
56 bool Valid() const override
{
57 return block_iter_points_to_real_block_
&& block_iter_
.Valid();
59 Slice
key() const override
{
61 return block_iter_
.key();
63 Slice
user_key() const override
{
65 return block_iter_
.user_key();
67 IndexValue
value() const override
{
69 return block_iter_
.value();
71 Status
status() const override
{
72 // Prefix index set status to NotFound when the prefix does not exist
73 if (!index_iter_
->status().ok() && !index_iter_
->status().IsNotFound()) {
74 return index_iter_
->status();
75 } else if (block_iter_points_to_real_block_
) {
76 return block_iter_
.status();
81 inline IterBoundCheck
UpperBoundCheckResult() override
{
82 // Shouldn't be called.
84 return IterBoundCheck::kUnknown
;
86 void SetPinnedItersMgr(PinnedIteratorsManager
*) override
{
87 // Shouldn't be called.
90 bool IsKeyPinned() const override
{
91 // Shouldn't be called.
95 bool IsValuePinned() const override
{
96 // Shouldn't be called.
101 void ResetPartitionedIndexIter() {
102 if (block_iter_points_to_real_block_
) {
103 block_iter_
.Invalidate(Status::OK());
104 block_iter_points_to_real_block_
= false;
108 void SavePrevIndexValue() {
109 if (block_iter_points_to_real_block_
) {
110 // Reseek. If they end up with the same data block, we shouldn't re-fetch
111 // the same data block.
112 prev_block_offset_
= index_iter_
->value().handle
.offset();
117 friend class BlockBasedTableReaderTestVerifyChecksum_ChecksumMismatch_Test
;
118 const BlockBasedTable
* table_
;
119 const ReadOptions read_options_
;
121 const InternalKeyComparator
& icomp_
;
123 UserComparatorWrapper user_comparator_
;
124 std::unique_ptr
<InternalIteratorBase
<IndexValue
>> index_iter_
;
125 IndexBlockIter block_iter_
;
127 // True if block_iter_ is initialized and points to the same block
128 // as index iterator.
129 bool block_iter_points_to_real_block_
;
130 uint64_t prev_block_offset_
= std::numeric_limits
<uint64_t>::max();
131 BlockCacheLookupContext lookup_context_
;
132 BlockPrefetcher block_prefetcher_
;
134 // If `target` is null, seek to first.
135 void SeekImpl(const Slice
* target
);
137 void InitPartitionedIndexBlock();
138 void FindKeyForward();
139 void FindBlockForward();
140 void FindKeyBackward();
142 } // namespace ROCKSDB_NAMESPACE