|
|
|
@ -887,7 +887,7 @@ class LevelIterator final : public InternalIterator { |
|
|
|
|
void SeekToFirst() override; |
|
|
|
|
void SeekToLast() override; |
|
|
|
|
void Next() final override; |
|
|
|
|
bool NextAndGetResult(Slice* ret_key) override; |
|
|
|
|
bool NextAndGetResult(IterateResult* result) override; |
|
|
|
|
void Prev() override; |
|
|
|
|
|
|
|
|
|
bool Valid() const override { return file_iter_.Valid(); } |
|
|
|
@ -895,23 +895,38 @@ class LevelIterator final : public InternalIterator { |
|
|
|
|
assert(Valid()); |
|
|
|
|
return file_iter_.key(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Slice value() const override { |
|
|
|
|
assert(Valid()); |
|
|
|
|
return file_iter_.value(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Status status() const override { |
|
|
|
|
return file_iter_.iter() ? file_iter_.status() : Status::OK(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline bool MayBeOutOfLowerBound() override { |
|
|
|
|
assert(Valid()); |
|
|
|
|
return may_be_out_of_lower_bound_ && file_iter_.MayBeOutOfLowerBound(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline bool MayBeOutOfUpperBound() override { |
|
|
|
|
assert(Valid()); |
|
|
|
|
return file_iter_.MayBeOutOfUpperBound(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SetPinnedItersMgr(PinnedIteratorsManager* pinned_iters_mgr) override { |
|
|
|
|
pinned_iters_mgr_ = pinned_iters_mgr; |
|
|
|
|
if (file_iter_.iter()) { |
|
|
|
|
file_iter_.SetPinnedItersMgr(pinned_iters_mgr); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool IsKeyPinned() const override { |
|
|
|
|
return pinned_iters_mgr_ && pinned_iters_mgr_->PinningEnabled() && |
|
|
|
|
file_iter_.iter() && file_iter_.IsKeyPinned(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool IsValuePinned() const override { |
|
|
|
|
return pinned_iters_mgr_ && pinned_iters_mgr_->PinningEnabled() && |
|
|
|
|
file_iter_.iter() && file_iter_.IsValuePinned(); |
|
|
|
@ -955,6 +970,7 @@ class LevelIterator final : public InternalIterator { |
|
|
|
|
smallest_compaction_key = (*compaction_boundaries_)[file_index_].smallest; |
|
|
|
|
largest_compaction_key = (*compaction_boundaries_)[file_index_].largest; |
|
|
|
|
} |
|
|
|
|
CheckMayBeOutOfLowerBound(); |
|
|
|
|
return table_cache_->NewIterator( |
|
|
|
|
read_options_, env_options_, icomparator_, *file_meta.file_metadata, |
|
|
|
|
range_del_agg_, prefix_extractor_, |
|
|
|
@ -963,6 +979,19 @@ class LevelIterator final : public InternalIterator { |
|
|
|
|
largest_compaction_key); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Check if current file being fully within iterate_lower_bound.
|
|
|
|
|
//
|
|
|
|
|
// Note MyRocks may update iterate bounds between seek. To workaround it,
|
|
|
|
|
// we need to check and update may_be_out_of_lower_bound_ accordingly.
|
|
|
|
|
void CheckMayBeOutOfLowerBound() { |
|
|
|
|
if (Valid() && read_options_.iterate_lower_bound != nullptr) { |
|
|
|
|
may_be_out_of_lower_bound_ = |
|
|
|
|
user_comparator_.Compare( |
|
|
|
|
ExtractUserKey(file_smallest_key(file_index_)), |
|
|
|
|
*read_options_.iterate_lower_bound) < 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TableCache* table_cache_; |
|
|
|
|
const ReadOptions read_options_; |
|
|
|
|
const EnvOptions& env_options_; |
|
|
|
@ -976,6 +1005,7 @@ class LevelIterator final : public InternalIterator { |
|
|
|
|
bool should_sample_; |
|
|
|
|
TableReaderCaller caller_; |
|
|
|
|
bool skip_filters_; |
|
|
|
|
bool may_be_out_of_lower_bound_ = true; |
|
|
|
|
size_t file_index_; |
|
|
|
|
int level_; |
|
|
|
|
RangeDelAggregator* range_del_agg_; |
|
|
|
@ -1011,6 +1041,7 @@ void LevelIterator::Seek(const Slice& target) { |
|
|
|
|
file_iter_.Seek(target); |
|
|
|
|
} |
|
|
|
|
SkipEmptyFileForward(); |
|
|
|
|
CheckMayBeOutOfLowerBound(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void LevelIterator::SeekForPrev(const Slice& target) { |
|
|
|
@ -1024,6 +1055,7 @@ void LevelIterator::SeekForPrev(const Slice& target) { |
|
|
|
|
file_iter_.SeekForPrev(target); |
|
|
|
|
SkipEmptyFileBackward(); |
|
|
|
|
} |
|
|
|
|
CheckMayBeOutOfLowerBound(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void LevelIterator::SeekToFirst() { |
|
|
|
@ -1032,6 +1064,7 @@ void LevelIterator::SeekToFirst() { |
|
|
|
|
file_iter_.SeekToFirst(); |
|
|
|
|
} |
|
|
|
|
SkipEmptyFileForward(); |
|
|
|
|
CheckMayBeOutOfLowerBound(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void LevelIterator::SeekToLast() { |
|
|
|
@ -1040,15 +1073,17 @@ void LevelIterator::SeekToLast() { |
|
|
|
|
file_iter_.SeekToLast(); |
|
|
|
|
} |
|
|
|
|
SkipEmptyFileBackward(); |
|
|
|
|
CheckMayBeOutOfLowerBound(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void LevelIterator::Next() { NextImpl(); } |
|
|
|
|
|
|
|
|
|
bool LevelIterator::NextAndGetResult(Slice* ret_key) { |
|
|
|
|
bool LevelIterator::NextAndGetResult(IterateResult* result) { |
|
|
|
|
NextImpl(); |
|
|
|
|
bool is_valid = Valid(); |
|
|
|
|
if (is_valid) { |
|
|
|
|
*ret_key = key(); |
|
|
|
|
result->key = key(); |
|
|
|
|
result->may_be_out_of_upper_bound = MayBeOutOfUpperBound(); |
|
|
|
|
} |
|
|
|
|
return is_valid; |
|
|
|
|
} |
|
|
|
@ -4366,10 +4401,9 @@ Status VersionSet::Recover( |
|
|
|
|
", last_sequence is %" PRIu64 ", log_number is %" PRIu64 |
|
|
|
|
",prev_log_number is %" PRIu64 ",max_column_family is %" PRIu32 |
|
|
|
|
",min_log_number_to_keep is %" PRIu64 "\n", |
|
|
|
|
manifest_path.c_str(), manifest_file_number_, |
|
|
|
|
next_file_number_.load(), last_sequence_.load(), log_number, |
|
|
|
|
prev_log_number_, column_family_set_->GetMaxColumnFamily(), |
|
|
|
|
min_log_number_to_keep_2pc()); |
|
|
|
|
manifest_path.c_str(), manifest_file_number_, next_file_number_.load(), |
|
|
|
|
last_sequence_.load(), log_number, prev_log_number_, |
|
|
|
|
column_family_set_->GetMaxColumnFamily(), min_log_number_to_keep_2pc()); |
|
|
|
|
|
|
|
|
|
for (auto cfd : *column_family_set_) { |
|
|
|
|
if (cfd->IsDropped()) { |
|
|
|
|