/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 |