Skip to content

Commit 587d77a

Browse files
committed
Fix merge errors
1 parent 2f2aa29 commit 587d77a

File tree

5 files changed

+78
-15
lines changed

5 files changed

+78
-15
lines changed

file/sst_file_manager_impl.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ class SstFileManagerImpl : public SstFileManager {
4444
Status OnAddFile(const std::string& file_path, uint64_t file_size,
4545
bool compaction);
4646

47-
// Overload where size of the file is provided by the caller rather than
48-
// queried from the filesystem. This is an optimization.
49-
Status OnAddFile(const std::string& file_path, uint64_t file_size,
50-
bool compaction);
51-
5247
// DB will call OnDeleteFile whenever an sst file is deleted.
5348
Status OnDeleteFile(const std::string& file_path);
5449

table/block_based/block.cc

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,19 @@ void IndexBlockIter::Seek(const Slice& target) {
384384
if (data_ == nullptr) { // Not init yet
385385
return;
386386
}
387+
status_ = Status::OK();
387388
uint32_t index = 0;
388389
bool ok = false;
389390
if (prefix_index_) {
390-
ok = PrefixSeek(target, &index);
391+
bool prefix_may_exist = true;
392+
ok = PrefixSeek(target, &index, &prefix_may_exist);
393+
if (!prefix_may_exist) {
394+
// This is to let the caller to distinguish between non-existing prefix,
395+
// and when key is larger than the last key, which both set Valid() to
396+
// false.
397+
current_ = restarts_;
398+
status_ = Status::NotFound();
399+
}
391400
} else if (value_delta_encoded_) {
392401
ok = BinarySeek<DecodeKeyV4>(seek_key, 0, num_restarts_ - 1, &index,
393402
comparator_);
@@ -453,6 +462,7 @@ void IndexBlockIter::SeekToFirst() {
453462
if (data_ == nullptr) { // Not init yet
454463
return;
455464
}
465+
status_ = Status::OK();
456466
SeekToRestartPoint(0);
457467
ParseNextIndexKey();
458468
}
@@ -471,6 +481,7 @@ void IndexBlockIter::SeekToLast() {
471481
if (data_ == nullptr) { // Not init yet
472482
return;
473483
}
484+
status_ = Status::OK();
474485
SeekToRestartPoint(num_restarts_ - 1);
475486
while (ParseNextIndexKey() && NextEntryOffset() < restarts_) {
476487
// Keep skipping
@@ -709,8 +720,12 @@ int IndexBlockIter::CompareBlockKey(uint32_t block_index, const Slice& target) {
709720
// with a key >= target
710721
bool IndexBlockIter::BinaryBlockIndexSeek(const Slice& target,
711722
uint32_t* block_ids, uint32_t left,
712-
uint32_t right, uint32_t* index) {
723+
uint32_t right, uint32_t* index,
724+
bool* prefix_may_exist) {
713725
assert(left <= right);
726+
assert(index);
727+
assert(prefix_may_exist);
728+
*prefix_may_exist = true;
714729
uint32_t left_bound = left;
715730

716731
while (left <= right) {
@@ -744,21 +759,53 @@ bool IndexBlockIter::BinaryBlockIndexSeek(const Slice& target,
744759
(left == left_bound || block_ids[left - 1] != block_ids[left] - 1) &&
745760
CompareBlockKey(block_ids[left] - 1, target) > 0) {
746761
current_ = restarts_;
762+
*prefix_may_exist = false;
747763
return false;
748764
}
749765

750766
*index = block_ids[left];
751767
return true;
752768
} else {
753769
assert(left > right);
770+
771+
// If the next block key is larger than seek key, it is possible that
772+
// no key shares the prefix with `target`, or all keys with the same
773+
// prefix as `target` are smaller than prefix. In the latter case,
774+
// we are mandated to set the position the same as the total order.
775+
// In the latter case, either:
776+
// (1) `target` falls into the range of the next block. In this case,
777+
// we can place the iterator to the next block, or
778+
// (2) `target` is larger than all block keys. In this case we can
779+
// keep the iterator invalidate without setting `prefix_may_exist`
780+
// to false.
781+
// We might sometimes end up with setting the total order position
782+
// while there is no key sharing the prefix as `target`, but it
783+
// still follows the contract.
784+
uint32_t right_index = block_ids[right];
785+
assert(right_index + 1 <= num_restarts_);
786+
if (right_index + 1 < num_restarts_) {
787+
if (CompareBlockKey(right_index + 1, target) >= 0) {
788+
*index = right_index + 1;
789+
return true;
790+
} else {
791+
// We have to set the flag here because we are not positioning
792+
// the iterator to the total order position.
793+
*prefix_may_exist = false;
794+
}
795+
}
796+
754797
// Mark iterator invalid
755798
current_ = restarts_;
756799
return false;
757800
}
758801
}
759802

760-
bool IndexBlockIter::PrefixSeek(const Slice& target, uint32_t* index) {
803+
bool IndexBlockIter::PrefixSeek(const Slice& target, uint32_t* index,
804+
bool* prefix_may_exist) {
805+
assert(index);
806+
assert(prefix_may_exist);
761807
assert(prefix_index_);
808+
*prefix_may_exist = true;
762809
Slice seek_key = target;
763810
if (!key_includes_seq_) {
764811
seek_key = ExtractUserKey(target);
@@ -768,9 +815,12 @@ bool IndexBlockIter::PrefixSeek(const Slice& target, uint32_t* index) {
768815

769816
if (num_blocks == 0) {
770817
current_ = restarts_;
818+
*prefix_may_exist = false;
771819
return false;
772820
} else {
773-
return BinaryBlockIndexSeek(seek_key, block_ids, 0, num_blocks - 1, index);
821+
assert(block_ids);
822+
return BinaryBlockIndexSeek(seek_key, block_ids, 0, num_blocks - 1, index,
823+
prefix_may_exist);
774824
}
775825
}
776826

table/block_based/block.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,16 @@ class IndexBlockIter final : public BlockIter<IndexValue> {
601601

602602
std::unique_ptr<GlobalSeqnoState> global_seqno_state_;
603603

604-
bool PrefixSeek(const Slice& target, uint32_t* index);
604+
// Set *prefix_may_exist to false if no key possibly share the same prefix
605+
// as `target`. If not set, the result position should be the same as total
606+
// order Seek.
607+
bool PrefixSeek(const Slice& target, uint32_t* index, bool* prefix_may_exist);
608+
// Set *prefix_may_exist to false if no key can possibly share the same
609+
// prefix as `target`. If not set, the result position should be the same
610+
// as total order seek.
605611
bool BinaryBlockIndexSeek(const Slice& target, uint32_t* block_ids,
606-
uint32_t left, uint32_t right, uint32_t* index);
612+
uint32_t left, uint32_t right, uint32_t* index,
613+
bool* prefix_may_exist);
607614
inline int CompareBlockKey(uint32_t block_index, const Slice& target);
608615

609616
inline int Compare(const Slice& a, const Slice& b) const {

table/block_based/block_based_table_reader.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2908,12 +2908,22 @@ void BlockBasedTableIterator<TBlockIter, TValue>::SeekForPrev(
29082908
index_iter_->Seek(target);
29092909

29102910
if (!index_iter_->Valid()) {
2911-
if (!index_iter_->status().ok()) {
2911+
auto seek_status = index_iter_->status();
2912+
// Check for IO error
2913+
if (!seek_status.IsNotFound() && !seek_status.ok()) {
29122914
ResetDataIter();
29132915
return;
29142916
}
29152917

2916-
index_iter_->SeekToLast();
2918+
// With prefix index, Seek() returns NotFound if the prefix doesn't exist
2919+
if (seek_status.IsNotFound()) {
2920+
// Any key less than the target is fine for prefix seek
2921+
ResetDataIter();
2922+
return;
2923+
} else {
2924+
index_iter_->SeekToLast();
2925+
}
2926+
// Check for IO error
29172927
if (!index_iter_->Valid()) {
29182928
ResetDataIter();
29192929
return;
@@ -3465,7 +3475,7 @@ Status BlockBasedTable::Get(const ReadOptions& read_options, const Slice& key,
34653475
PERF_COUNTER_BY_LEVEL_ADD(bloom_filter_full_true_positive, 1,
34663476
rep_->level);
34673477
}
3468-
if (s.ok()) {
3478+
if (s.ok() && !iiter->status().IsNotFound()) {
34693479
s = iiter->status();
34703480
}
34713481
}

table/block_based/block_based_table_reader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,8 @@ class BlockBasedTableIterator : public InternalIteratorBase<TValue> {
688688
return block_iter_.value();
689689
}
690690
Status status() const override {
691-
if (!index_iter_->status().ok()) {
691+
// Prefix index set status to NotFound when the prefix does not exist
692+
if (!index_iter_->status().ok() && !index_iter_->status().IsNotFound()) {
692693
return index_iter_->status();
693694
} else if (block_iter_points_to_real_block_) {
694695
return block_iter_.status();

0 commit comments

Comments
 (0)