@@ -26,6 +26,7 @@ class MergingIterator : public Iterator {
26
26
: comparator_(comparator),
27
27
children_ (n),
28
28
current_(nullptr ),
29
+ use_heap_(true ),
29
30
direction_(kForward ),
30
31
maxHeap_(NewMaxIterHeap(comparator_)),
31
32
minHeap_ (NewMinIterHeap(comparator_)) {
@@ -70,14 +71,38 @@ class MergingIterator : public Iterator {
70
71
}
71
72
72
73
virtual void Seek (const Slice& target) {
73
- ClearHeaps ();
74
+ // Invalidate the heap.
75
+ use_heap_ = false ;
76
+ IteratorWrapper* first_child = nullptr ;
74
77
for (auto & child : children_) {
75
78
child.Seek (target);
76
79
if (child.Valid ()) {
77
- minHeap_.push (&child);
80
+ // This child has valid key
81
+ if (!use_heap_) {
82
+ if (first_child == nullptr ) {
83
+ // It's the first child has valid key. Only put it int
84
+ // current_. Now the values in the heap should be invalid.
85
+ first_child = &child;
86
+ } else {
87
+ // We have more than one children with valid keys. Initialize
88
+ // the heap and put the first child into the heap.
89
+ ClearHeaps ();
90
+ minHeap_.push (first_child);
91
+ }
92
+ }
93
+ if (use_heap_) {
94
+ minHeap_.push (&child);
95
+ }
78
96
}
79
97
}
80
- FindSmallest ();
98
+ if (use_heap_) {
99
+ // If heap is valid, need to put the smallest key to curent_.
100
+ FindSmallest ();
101
+ } else {
102
+ // The heap is not valid, then the current_ iterator is the first
103
+ // one, or null if there is no first child.
104
+ current_ = first_child;
105
+ }
81
106
direction_ = kForward ;
82
107
}
83
108
@@ -109,10 +134,14 @@ class MergingIterator : public Iterator {
109
134
// as the current points to the current record. move the iterator forward.
110
135
// and if it is valid add it to the heap.
111
136
current_->Next ();
112
- if (current_->Valid ()){
113
- minHeap_.push (current_);
137
+ if (use_heap_) {
138
+ if (current_->Valid ()) {
139
+ minHeap_.push (current_);
140
+ }
141
+ FindSmallest ();
142
+ } else if (!current_->Valid ()) {
143
+ current_ = nullptr ;
114
144
}
115
- FindSmallest ();
116
145
}
117
146
118
147
virtual void Prev () {
@@ -178,6 +207,10 @@ class MergingIterator : public Iterator {
178
207
const Comparator* comparator_;
179
208
std::vector<IteratorWrapper> children_;
180
209
IteratorWrapper* current_;
210
+ // If the value is true, both of iterators in the heap and current_
211
+ // contain valid rows. If it is false, only current_ can possibly contain
212
+ // valid rows.
213
+ bool use_heap_;
181
214
// Which direction is the iterator moving?
182
215
enum Direction {
183
216
kForward ,
@@ -189,6 +222,7 @@ class MergingIterator : public Iterator {
189
222
};
190
223
191
224
void MergingIterator::FindSmallest () {
225
+ assert (use_heap_);
192
226
if (minHeap_.empty ()) {
193
227
current_ = nullptr ;
194
228
} else {
@@ -199,6 +233,7 @@ void MergingIterator::FindSmallest() {
199
233
}
200
234
201
235
void MergingIterator::FindLargest () {
236
+ assert (use_heap_);
202
237
if (maxHeap_.empty ()) {
203
238
current_ = nullptr ;
204
239
} else {
@@ -209,6 +244,7 @@ void MergingIterator::FindLargest() {
209
244
}
210
245
211
246
void MergingIterator::ClearHeaps () {
247
+ use_heap_ = true ;
212
248
maxHeap_ = NewMaxIterHeap (comparator_);
213
249
minHeap_ = NewMinIterHeap (comparator_);
214
250
}
0 commit comments