partitioned_index_iterator.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. #pragma once
  10. #include "table/block_based/block_based_table_reader.h"
  11. #include "table/block_based/block_based_table_reader_impl.h"
  12. #include "table/block_based/block_prefetcher.h"
  13. #include "table/block_based/reader_common.h"
  14. namespace ROCKSDB_NAMESPACE {
  15. // Iterator that iterates over partitioned index.
  16. // Some upper and lower bound tricks played in block based table iterators
  17. // could be played here, but it's too complicated to reason about index
  18. // keys with upper or lower bound, so we skip it for simplicity.
  19. class PartitionedIndexIterator : public InternalIteratorBase<IndexValue> {
  20. // compaction_readahead_size: its value will only be used if for_compaction =
  21. // true
  22. public:
  23. PartitionedIndexIterator(
  24. const BlockBasedTable* table, const ReadOptions& read_options,
  25. const InternalKeyComparator& icomp,
  26. std::unique_ptr<InternalIteratorBase<IndexValue>>&& index_iter,
  27. TableReaderCaller caller, size_t compaction_readahead_size = 0)
  28. : index_iter_(std::move(index_iter)),
  29. table_(table),
  30. read_options_(read_options),
  31. #ifndef NDEBUG
  32. icomp_(icomp),
  33. #endif
  34. user_comparator_(icomp.user_comparator()),
  35. block_iter_points_to_real_block_(false),
  36. lookup_context_(caller),
  37. block_prefetcher_(
  38. compaction_readahead_size,
  39. table_->get_rep()->table_options.initial_auto_readahead_size) {
  40. }
  41. ~PartitionedIndexIterator() override {}
  42. void Seek(const Slice& target) override;
  43. void SeekForPrev(const Slice&) override {
  44. // Shouldn't be called.
  45. assert(false);
  46. }
  47. void SeekToFirst() override;
  48. void SeekToLast() override;
  49. void Next() final override;
  50. bool NextAndGetResult(IterateResult*) override {
  51. assert(false);
  52. return false;
  53. }
  54. void Prev() override;
  55. bool Valid() const override {
  56. return block_iter_points_to_real_block_ && block_iter_.Valid();
  57. }
  58. Slice key() const override {
  59. assert(Valid());
  60. return block_iter_.key();
  61. }
  62. Slice user_key() const override {
  63. assert(Valid());
  64. return block_iter_.user_key();
  65. }
  66. IndexValue value() const override {
  67. assert(Valid());
  68. return block_iter_.value();
  69. }
  70. Status status() const override {
  71. // Prefix index set status to NotFound when the prefix does not exist
  72. if (!index_iter_->status().ok() && !index_iter_->status().IsNotFound()) {
  73. return index_iter_->status();
  74. } else if (block_iter_points_to_real_block_) {
  75. return block_iter_.status();
  76. } else {
  77. return Status::OK();
  78. }
  79. }
  80. inline IterBoundCheck UpperBoundCheckResult() override {
  81. return IterBoundCheck::kUnknown;
  82. }
  83. void SetPinnedItersMgr(PinnedIteratorsManager*) override {
  84. // Shouldn't be called.
  85. assert(false);
  86. }
  87. bool IsKeyPinned() const override {
  88. // Shouldn't be called.
  89. assert(false);
  90. return false;
  91. }
  92. bool IsValuePinned() const override {
  93. // Shouldn't be called.
  94. assert(false);
  95. return false;
  96. }
  97. void ResetPartitionedIndexIter() {
  98. if (block_iter_points_to_real_block_) {
  99. block_iter_.Invalidate(Status::OK());
  100. block_iter_points_to_real_block_ = false;
  101. }
  102. }
  103. void SavePrevIndexValue() {
  104. if (block_iter_points_to_real_block_) {
  105. // Reseek. If they end up with the same data block, we shouldn't re-fetch
  106. // the same data block.
  107. prev_block_offset_ = index_iter_->value().handle.offset();
  108. }
  109. }
  110. void GetReadaheadState(ReadaheadFileInfo* readahead_file_info) override {
  111. if (block_prefetcher_.prefetch_buffer() != nullptr &&
  112. read_options_.adaptive_readahead) {
  113. block_prefetcher_.prefetch_buffer()->GetReadaheadState(
  114. &(readahead_file_info->index_block_readahead_info));
  115. }
  116. }
  117. void SetReadaheadState(ReadaheadFileInfo* readahead_file_info) override {
  118. if (read_options_.adaptive_readahead) {
  119. block_prefetcher_.SetReadaheadState(
  120. &(readahead_file_info->index_block_readahead_info));
  121. }
  122. }
  123. std::unique_ptr<InternalIteratorBase<IndexValue>> index_iter_;
  124. private:
  125. friend class BlockBasedTableReaderTestVerifyChecksum_ChecksumMismatch_Test;
  126. const BlockBasedTable* table_;
  127. const ReadOptions read_options_;
  128. #ifndef NDEBUG
  129. const InternalKeyComparator& icomp_;
  130. #endif
  131. UserComparatorWrapper user_comparator_;
  132. IndexBlockIter block_iter_;
  133. // True if block_iter_ is initialized and points to the same block
  134. // as index iterator.
  135. bool block_iter_points_to_real_block_;
  136. uint64_t prev_block_offset_ = std::numeric_limits<uint64_t>::max();
  137. BlockCacheLookupContext lookup_context_;
  138. BlockPrefetcher block_prefetcher_;
  139. // If `target` is null, seek to first.
  140. void SeekImpl(const Slice* target);
  141. void InitPartitionedIndexBlock();
  142. void FindKeyForward();
  143. void FindBlockForward();
  144. void FindKeyBackward();
  145. };
  146. } // namespace ROCKSDB_NAMESPACE