Coverage Report

Created: 2025-07-23 07:17

/src/rocksdb/db/forward_iterator.h
Line
Count
Source (jump to first uncovered line)
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
#pragma once
6
7
#include <queue>
8
#include <string>
9
#include <vector>
10
11
#include "memory/arena.h"
12
#include "rocksdb/comparator.h"
13
#include "rocksdb/db.h"
14
#include "rocksdb/iterator.h"
15
#include "rocksdb/options.h"
16
#include "table/internal_iterator.h"
17
18
namespace ROCKSDB_NAMESPACE {
19
20
class DBImpl;
21
class Env;
22
struct SuperVersion;
23
class ColumnFamilyData;
24
class ForwardLevelIterator;
25
class VersionStorageInfo;
26
struct FileMetaData;
27
28
class MinIterComparator {
29
 public:
30
  explicit MinIterComparator(const CompareInterface* comparator)
31
0
      : comparator_(comparator) {}
32
33
0
  bool operator()(InternalIterator* a, InternalIterator* b) {
34
0
    return comparator_->Compare(a->key(), b->key()) > 0;
35
0
  }
36
37
 private:
38
  const CompareInterface* comparator_;
39
};
40
41
using MinIterHeap =
42
    std::priority_queue<InternalIterator*, std::vector<InternalIterator*>,
43
                        MinIterComparator>;
44
45
// TODO: name to TailingIterator
46
/**
47
 * ForwardIterator is a special type of iterator that only supports Seek()
48
 * and Next(). It is expected to perform better than TailingIterator by
49
 * removing the encapsulation and making all information accessible within
50
 * the iterator. At the current implementation, snapshot is taken at the
51
 * time Seek() is called. The Next() followed do not see new values after.
52
 */
53
class ForwardIterator : public InternalIterator {
54
 public:
55
  ForwardIterator(DBImpl* db, const ReadOptions& read_options,
56
                  ColumnFamilyData* cfd, SuperVersion* current_sv = nullptr,
57
                  bool allow_unprepared_value = false);
58
  virtual ~ForwardIterator();
59
60
0
  void SeekForPrev(const Slice& /*target*/) override {
61
0
    status_ = Status::NotSupported("ForwardIterator::SeekForPrev()");
62
0
    valid_ = false;
63
0
  }
64
0
  void SeekToLast() override {
65
0
    status_ = Status::NotSupported("ForwardIterator::SeekToLast()");
66
0
    valid_ = false;
67
0
  }
68
0
  void Prev() override {
69
0
    status_ = Status::NotSupported("ForwardIterator::Prev");
70
0
    valid_ = false;
71
0
  }
72
73
  bool Valid() const override;
74
  void SeekToFirst() override;
75
  void Seek(const Slice& target) override;
76
  void Next() override;
77
  Slice key() const override;
78
  Slice value() const override;
79
  uint64_t write_unix_time() const override;
80
  Status status() const override;
81
  bool PrepareValue() override;
82
  Status GetProperty(std::string prop_name, std::string* prop) override;
83
  void SetPinnedItersMgr(PinnedIteratorsManager* pinned_iters_mgr) override;
84
  bool IsKeyPinned() const override;
85
  bool IsValuePinned() const override;
86
87
  bool TEST_CheckDeletedIters(int* deleted_iters, int* num_iters);
88
89
 private:
90
  void Cleanup(bool release_sv);
91
  // Unreference and, if needed, clean up the current SuperVersion. This is
92
  // either done immediately or deferred until this iterator is unpinned by
93
  // PinnedIteratorsManager.
94
  void SVCleanup();
95
  static void SVCleanup(DBImpl* db, SuperVersion* sv,
96
                        bool background_purge_on_iterator_cleanup);
97
  static void DeferredSVCleanup(void* arg);
98
99
  void RebuildIterators(bool refresh_sv);
100
  void RenewIterators();
101
  void BuildLevelIterators(const VersionStorageInfo* vstorage,
102
                           SuperVersion* sv);
103
  void ResetIncompleteIterators();
104
  void SeekInternal(const Slice& internal_key, bool seek_to_first,
105
                    bool seek_after_async_io);
106
107
  void UpdateCurrent();
108
  bool NeedToSeekImmutable(const Slice& internal_key);
109
  void DeleteCurrentIter();
110
  uint32_t FindFileInRange(const std::vector<FileMetaData*>& files,
111
                           const Slice& internal_key, uint32_t left,
112
                           uint32_t right);
113
114
  bool IsOverUpperBound(const Slice& internal_key) const;
115
116
  // Set PinnedIteratorsManager for all children Iterators, this function should
117
  // be called whenever we update children Iterators or pinned_iters_mgr_.
118
  void UpdateChildrenPinnedItersMgr();
119
120
  // A helper function that will release iter in the proper manner, or pass it
121
  // to pinned_iters_mgr_ to release it later if pinning is enabled.
122
  void DeleteIterator(InternalIterator* iter, bool is_arena = false);
123
124
  DBImpl* const db_;
125
  ReadOptions read_options_;
126
  ColumnFamilyData* const cfd_;
127
  const SliceTransform* const prefix_extractor_;
128
  const Comparator* user_comparator_;
129
  const bool allow_unprepared_value_;
130
  MinIterHeap immutable_min_heap_;
131
132
  SuperVersion* sv_;
133
  InternalIterator* mutable_iter_;
134
  std::vector<InternalIterator*> imm_iters_;
135
  std::vector<InternalIterator*> l0_iters_;
136
  std::vector<ForwardLevelIterator*> level_iters_;
137
  InternalIterator* current_;
138
  bool valid_;
139
140
  // Internal iterator status; set only by one of the unsupported methods.
141
  Status status_;
142
  // Status of immutable iterators, maintained here to avoid iterating over
143
  // all of them in status().
144
  Status immutable_status_;
145
  // Indicates that at least one of the immutable iterators pointed to a key
146
  // larger than iterate_upper_bound and was therefore destroyed. Seek() may
147
  // need to rebuild such iterators.
148
  bool has_iter_trimmed_for_upper_bound_;
149
  // Is current key larger than iterate_upper_bound? If so, makes Valid()
150
  // return false.
151
  bool current_over_upper_bound_;
152
153
  // Left endpoint of the range of keys that immutable iterators currently
154
  // cover. When Seek() is called with a key that's within that range, immutable
155
  // iterators don't need to be moved; see NeedToSeekImmutable(). This key is
156
  // included in the range after a Seek(), but excluded when advancing the
157
  // iterator using Next().
158
  IterKey prev_key_;
159
  bool is_prev_set_;
160
  bool is_prev_inclusive_;
161
162
  PinnedIteratorsManager* pinned_iters_mgr_;
163
  Arena arena_;
164
};
165
166
}  // namespace ROCKSDB_NAMESPACE