Make tailing iterator show new entries in memtable.

Summary:
Reseek mutable_iter if it is invalid in Next and immutable_iter
is invalid.

Test Plan: DBTestTailingIterator.TailingIteratorSeekToNext

Reviewers: tnovak, march, sdong

Reviewed By: sdong

Subscribers: dhruba, leveldb

Differential Revision: https://reviews.facebook.net/D44865
This commit is contained in:
Venkatesh Radhakrishnan 2015-08-18 14:40:06 -07:00
parent 9ec9571593
commit e58e1b18e7
2 changed files with 14 additions and 1 deletions

View File

@ -68,6 +68,7 @@ TEST_F(DBTestTailingIterator, TailingIteratorSeekToNext) {
read_options.tailing = true; read_options.tailing = true;
std::unique_ptr<Iterator> iter(db_->NewIterator(read_options, handles_[1])); std::unique_ptr<Iterator> iter(db_->NewIterator(read_options, handles_[1]));
std::unique_ptr<Iterator> itern(db_->NewIterator(read_options, handles_[1]));
std::string value(1024, 'a'); std::string value(1024, 'a');
const int num_records = 1000; const int num_records = 1000;
@ -88,6 +89,13 @@ TEST_F(DBTestTailingIterator, TailingIteratorSeekToNext) {
iter->Seek(target); iter->Seek(target);
ASSERT_TRUE(iter->Valid()); ASSERT_TRUE(iter->Valid());
ASSERT_EQ(iter->key().compare(key), 0); ASSERT_EQ(iter->key().compare(key), 0);
if (i == 1) {
itern->SeekToFirst();
} else {
itern->Next();
}
ASSERT_TRUE(itern->Valid());
ASSERT_EQ(itern->key().compare(key), 0);
} }
for (int i = 2 * num_records; i > 0; --i) { for (int i = 2 * num_records; i > 0; --i) {
char buf1[32]; char buf1[32];

View File

@ -341,6 +341,7 @@ void ForwardIterator::SeekInternal(const Slice& internal_key,
void ForwardIterator::Next() { void ForwardIterator::Next() {
assert(valid_); assert(valid_);
bool update_prev_key = false;
if (sv_ == nullptr || if (sv_ == nullptr ||
sv_->version_number != cfd_->GetSuperVersionNumber()) { sv_->version_number != cfd_->GetSuperVersionNumber()) {
@ -355,14 +356,16 @@ void ForwardIterator::Next() {
} else if (current_ != mutable_iter_) { } else if (current_ != mutable_iter_) {
// It is going to advance immutable iterator // It is going to advance immutable iterator
bool update_prev_key = true;
if (is_prev_set_ && prefix_extractor_) { if (is_prev_set_ && prefix_extractor_) {
// advance prev_key_ to current_ only if they share the same prefix // advance prev_key_ to current_ only if they share the same prefix
update_prev_key = update_prev_key =
prefix_extractor_->Transform(prev_key_.GetKey()).compare( prefix_extractor_->Transform(prev_key_.GetKey()).compare(
prefix_extractor_->Transform(current_->key())) == 0; prefix_extractor_->Transform(current_->key())) == 0;
} else {
update_prev_key = true;
} }
if (update_prev_key) { if (update_prev_key) {
prev_key_.SetKey(current_->key()); prev_key_.SetKey(current_->key());
is_prev_set_ = true; is_prev_set_ = true;
@ -376,6 +379,8 @@ void ForwardIterator::Next() {
immutable_status_ = current_->status(); immutable_status_ = current_->status();
} else if (current_->Valid()) { } else if (current_->Valid()) {
immutable_min_heap_.push(current_); immutable_min_heap_.push(current_);
} else if ((!mutable_iter_->Valid()) && update_prev_key) {
mutable_iter_->Seek(prev_key_.GetKey());
} }
} }