use union for minHeap_ and maxHeap_
This commit is contained in:
parent
ab6755711b
commit
09e55c7596
@ -73,6 +73,7 @@ class MergingIterator : public InternalIterator {
|
|||||||
child.DeleteIter(is_arena_mode_);
|
child.DeleteIter(is_arena_mode_);
|
||||||
}
|
}
|
||||||
status_.PermitUncheckedError();
|
status_.PermitUncheckedError();
|
||||||
|
minHeap_.~MergerMinIterHeap();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Valid() const override { return current_ != nullptr && status_.ok(); }
|
bool Valid() const override { return current_ != nullptr && status_.ok(); }
|
||||||
@ -80,7 +81,7 @@ class MergingIterator : public InternalIterator {
|
|||||||
Status status() const override { return status_; }
|
Status status() const override { return status_; }
|
||||||
|
|
||||||
void SeekToFirst() override {
|
void SeekToFirst() override {
|
||||||
ClearHeaps();
|
InitMinHeap();
|
||||||
status_ = Status::OK();
|
status_ = Status::OK();
|
||||||
for (auto& child : children_) {
|
for (auto& child : children_) {
|
||||||
child.SeekToFirst();
|
child.SeekToFirst();
|
||||||
@ -91,7 +92,6 @@ class MergingIterator : public InternalIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SeekToLast() override {
|
void SeekToLast() override {
|
||||||
ClearHeaps();
|
|
||||||
InitMaxHeap();
|
InitMaxHeap();
|
||||||
status_ = Status::OK();
|
status_ = Status::OK();
|
||||||
for (auto& child : children_) {
|
for (auto& child : children_) {
|
||||||
@ -103,7 +103,7 @@ class MergingIterator : public InternalIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Seek(const Slice& target) override {
|
void Seek(const Slice& target) override {
|
||||||
ClearHeaps();
|
InitMinHeap();
|
||||||
status_ = Status::OK();
|
status_ = Status::OK();
|
||||||
for (auto& child : children_) {
|
for (auto& child : children_) {
|
||||||
{
|
{
|
||||||
@ -127,7 +127,6 @@ class MergingIterator : public InternalIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SeekForPrev(const Slice& target) override {
|
void SeekForPrev(const Slice& target) override {
|
||||||
ClearHeaps();
|
|
||||||
InitMaxHeap();
|
InitMaxHeap();
|
||||||
status_ = Status::OK();
|
status_ = Status::OK();
|
||||||
|
|
||||||
@ -216,11 +215,11 @@ class MergingIterator : public InternalIterator {
|
|||||||
// replace_top() to restore the heap property. When the same child
|
// replace_top() to restore the heap property. When the same child
|
||||||
// iterator yields a sequence of keys, this is cheap.
|
// iterator yields a sequence of keys, this is cheap.
|
||||||
assert(current_->status().ok());
|
assert(current_->status().ok());
|
||||||
maxHeap_->replace_top(current_);
|
maxHeap_.replace_top(current_);
|
||||||
} else {
|
} else {
|
||||||
// current stopped being valid, remove it from the heap.
|
// current stopped being valid, remove it from the heap.
|
||||||
considerStatus(current_->status());
|
considerStatus(current_->status());
|
||||||
maxHeap_->pop();
|
maxHeap_.pop();
|
||||||
}
|
}
|
||||||
current_ = CurrentReverse();
|
current_ = CurrentReverse();
|
||||||
}
|
}
|
||||||
@ -280,11 +279,8 @@ class MergingIterator : public InternalIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Clears heaps for both directions, used when changing direction or seeking
|
|
||||||
void ClearHeaps();
|
|
||||||
// Ensures that maxHeap_ is initialized when starting to go in the reverse
|
|
||||||
// direction
|
|
||||||
void InitMaxHeap();
|
void InitMaxHeap();
|
||||||
|
void InitMinHeap();
|
||||||
|
|
||||||
bool is_arena_mode_;
|
bool is_arena_mode_;
|
||||||
bool prefix_seek_mode_;
|
bool prefix_seek_mode_;
|
||||||
@ -300,11 +296,11 @@ class MergingIterator : public InternalIterator {
|
|||||||
IteratorWrapper* current_;
|
IteratorWrapper* current_;
|
||||||
// If any of the children have non-ok status, this is one of them.
|
// If any of the children have non-ok status, this is one of them.
|
||||||
Status status_;
|
Status status_;
|
||||||
MergerMinIterHeap minHeap_;
|
union {
|
||||||
|
MergerMinIterHeap minHeap_;
|
||||||
|
MergerMaxIterHeap maxHeap_;
|
||||||
|
};
|
||||||
|
|
||||||
// Max heap is used for reverse iteration, which is way less common than
|
|
||||||
// forward. Lazily initialize it to save memory.
|
|
||||||
std::unique_ptr<MergerMaxIterHeap> maxHeap_;
|
|
||||||
PinnedIteratorsManager* pinned_iters_mgr_;
|
PinnedIteratorsManager* pinned_iters_mgr_;
|
||||||
|
|
||||||
// In forward direction, process a child that is not in the min heap.
|
// In forward direction, process a child that is not in the min heap.
|
||||||
@ -328,8 +324,7 @@ class MergingIterator : public InternalIterator {
|
|||||||
|
|
||||||
IteratorWrapper* CurrentReverse() const {
|
IteratorWrapper* CurrentReverse() const {
|
||||||
assert(direction_ == kReverse);
|
assert(direction_ == kReverse);
|
||||||
assert(maxHeap_);
|
return !maxHeap_.empty() ? maxHeap_.top() : nullptr;
|
||||||
return !maxHeap_->empty() ? maxHeap_->top() : nullptr;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -345,7 +340,7 @@ void MergingIterator::AddToMinHeapOrCheckStatus(IteratorWrapper* child) {
|
|||||||
void MergingIterator::AddToMaxHeapOrCheckStatus(IteratorWrapper* child) {
|
void MergingIterator::AddToMaxHeapOrCheckStatus(IteratorWrapper* child) {
|
||||||
if (child->Valid()) {
|
if (child->Valid()) {
|
||||||
assert(child->status().ok());
|
assert(child->status().ok());
|
||||||
maxHeap_->push(child);
|
maxHeap_.push(child);
|
||||||
} else {
|
} else {
|
||||||
considerStatus(child->status());
|
considerStatus(child->status());
|
||||||
}
|
}
|
||||||
@ -354,7 +349,7 @@ void MergingIterator::AddToMaxHeapOrCheckStatus(IteratorWrapper* child) {
|
|||||||
void MergingIterator::SwitchToForward() {
|
void MergingIterator::SwitchToForward() {
|
||||||
// Otherwise, advance the non-current children. We advance current_
|
// Otherwise, advance the non-current children. We advance current_
|
||||||
// just after the if-block.
|
// just after the if-block.
|
||||||
ClearHeaps();
|
InitMinHeap();
|
||||||
Slice target = key();
|
Slice target = key();
|
||||||
for (auto& child : children_) {
|
for (auto& child : children_) {
|
||||||
if (&child != current_) {
|
if (&child != current_) {
|
||||||
@ -370,7 +365,6 @@ void MergingIterator::SwitchToForward() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MergingIterator::SwitchToBackward() {
|
void MergingIterator::SwitchToBackward() {
|
||||||
ClearHeaps();
|
|
||||||
InitMaxHeap();
|
InitMaxHeap();
|
||||||
Slice target = key();
|
Slice target = key();
|
||||||
for (auto& child : children_) {
|
for (auto& child : children_) {
|
||||||
@ -395,17 +389,37 @@ void MergingIterator::SwitchToBackward() {
|
|||||||
assert(current_ == CurrentReverse());
|
assert(current_ == CurrentReverse());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergingIterator::ClearHeaps() {
|
void MergingIterator::InitMinHeap() {
|
||||||
minHeap_.clear();
|
#if 0
|
||||||
if (maxHeap_) {
|
// this can be simplified because maxHeap_ and minHeap_ are physical identical,
|
||||||
maxHeap_->clear();
|
// the only difference between them are logical(the interpretation of comparator)
|
||||||
|
if (kReverse == direction_) {
|
||||||
|
maxHeap_.~MergerMaxIterHeap();
|
||||||
|
new(&minHeap_)MergerMinIterHeap(comparator_);
|
||||||
|
direction_ = kForward;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
minHeap_.clear();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
minHeap_.clear();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergingIterator::InitMaxHeap() {
|
void MergingIterator::InitMaxHeap() {
|
||||||
if (!maxHeap_) {
|
#if 0
|
||||||
maxHeap_.reset(new MergerMaxIterHeap(comparator_));
|
if (kForward == direction_) {
|
||||||
|
minHeap_.~MergerMinIterHeap();
|
||||||
|
new(&maxHeap_)MergerMaxIterHeap(comparator_);
|
||||||
|
direction_ = kReverse;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
maxHeap_.clear();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// use InitMinHeap(), because maxHeap_ and minHeap_ are physical identical
|
||||||
|
InitMinHeap();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalIterator* NewMergingIterator(const InternalKeyComparator* cmp,
|
InternalIterator* NewMergingIterator(const InternalKeyComparator* cmp,
|
||||||
|
Loading…
Reference in New Issue
Block a user