@ -26,6 +26,7 @@ class MergingIterator : public Iterator {
: comparator_ ( comparator ) ,
: comparator_ ( comparator ) ,
children_ ( n ) ,
children_ ( n ) ,
current_ ( nullptr ) ,
current_ ( nullptr ) ,
use_heap_ ( true ) ,
direction_ ( kForward ) ,
direction_ ( kForward ) ,
maxHeap_ ( NewMaxIterHeap ( comparator_ ) ) ,
maxHeap_ ( NewMaxIterHeap ( comparator_ ) ) ,
minHeap_ ( NewMinIterHeap ( comparator_ ) ) {
minHeap_ ( NewMinIterHeap ( comparator_ ) ) {
@ -70,14 +71,38 @@ class MergingIterator : public Iterator {
}
}
virtual void Seek ( const Slice & target ) {
virtual void Seek ( const Slice & target ) {
ClearHeaps ( ) ;
// Invalidate the heap.
use_heap_ = false ;
IteratorWrapper * first_child = nullptr ;
for ( auto & child : children_ ) {
for ( auto & child : children_ ) {
child . Seek ( target ) ;
child . Seek ( target ) ;
if ( child . Valid ( ) ) {
if ( child . Valid ( ) ) {
minHeap_ . push ( & child ) ;
// This child has valid key
if ( ! use_heap_ ) {
if ( first_child = = nullptr ) {
// It's the first child has valid key. Only put it int
// current_. Now the values in the heap should be invalid.
first_child = & child ;
} else {
// We have more than one children with valid keys. Initialize
// the heap and put the first child into the heap.
ClearHeaps ( ) ;
minHeap_ . push ( first_child ) ;
}
}
if ( use_heap_ ) {
minHeap_ . push ( & child ) ;
}
}
}
}
}
FindSmallest ( ) ;
if ( use_heap_ ) {
// If heap is valid, need to put the smallest key to curent_.
FindSmallest ( ) ;
} else {
// The heap is not valid, then the current_ iterator is the first
// one, or null if there is no first child.
current_ = first_child ;
}
direction_ = kForward ;
direction_ = kForward ;
}
}
@ -109,10 +134,14 @@ class MergingIterator : public Iterator {
// as the current points to the current record. move the iterator forward.
// as the current points to the current record. move the iterator forward.
// and if it is valid add it to the heap.
// and if it is valid add it to the heap.
current_ - > Next ( ) ;
current_ - > Next ( ) ;
if ( current_ - > Valid ( ) ) {
if ( use_heap_ ) {
minHeap_ . push ( current_ ) ;
if ( current_ - > Valid ( ) ) {
minHeap_ . push ( current_ ) ;
}
FindSmallest ( ) ;
} else if ( ! current_ - > Valid ( ) ) {
current_ = nullptr ;
}
}
FindSmallest ( ) ;
}
}
virtual void Prev ( ) {
virtual void Prev ( ) {
@ -178,6 +207,10 @@ class MergingIterator : public Iterator {
const Comparator * comparator_ ;
const Comparator * comparator_ ;
std : : vector < IteratorWrapper > children_ ;
std : : vector < IteratorWrapper > children_ ;
IteratorWrapper * current_ ;
IteratorWrapper * current_ ;
// If the value is true, both of iterators in the heap and current_
// contain valid rows. If it is false, only current_ can possibly contain
// valid rows.
bool use_heap_ ;
// Which direction is the iterator moving?
// Which direction is the iterator moving?
enum Direction {
enum Direction {
kForward ,
kForward ,
@ -189,6 +222,7 @@ class MergingIterator : public Iterator {
} ;
} ;
void MergingIterator : : FindSmallest ( ) {
void MergingIterator : : FindSmallest ( ) {
assert ( use_heap_ ) ;
if ( minHeap_ . empty ( ) ) {
if ( minHeap_ . empty ( ) ) {
current_ = nullptr ;
current_ = nullptr ;
} else {
} else {
@ -199,6 +233,7 @@ void MergingIterator::FindSmallest() {
}
}
void MergingIterator : : FindLargest ( ) {
void MergingIterator : : FindLargest ( ) {
assert ( use_heap_ ) ;
if ( maxHeap_ . empty ( ) ) {
if ( maxHeap_ . empty ( ) ) {
current_ = nullptr ;
current_ = nullptr ;
} else {
} else {
@ -209,6 +244,7 @@ void MergingIterator::FindLargest() {
}
}
void MergingIterator : : ClearHeaps ( ) {
void MergingIterator : : ClearHeaps ( ) {
use_heap_ = true ;
maxHeap_ = NewMaxIterHeap ( comparator_ ) ;
maxHeap_ = NewMaxIterHeap ( comparator_ ) ;
minHeap_ = NewMinIterHeap ( comparator_ ) ;
minHeap_ = NewMinIterHeap ( comparator_ ) ;
}
}