@ -22,6 +22,7 @@
# include "rocksdb/merge_operator.h"
# include "rocksdb/merge_operator.h"
# include "rocksdb/options.h"
# include "rocksdb/options.h"
# include "table/internal_iterator.h"
# include "table/internal_iterator.h"
# include "table/iterator_wrapper.h"
# include "util/arena.h"
# include "util/arena.h"
# include "util/filename.h"
# include "util/filename.h"
# include "util/logging.h"
# include "util/logging.h"
@ -149,8 +150,8 @@ class DBIter final: public Iterator {
if ( pin_thru_lifetime_ ) {
if ( pin_thru_lifetime_ ) {
pinned_iters_mgr_ . StartPinning ( ) ;
pinned_iters_mgr_ . StartPinning ( ) ;
}
}
if ( iter_ ) {
if ( iter_ . iter ( ) ) {
iter_ - > SetPinnedItersMgr ( & pinned_iters_mgr_ ) ;
iter_ . iter ( ) - > SetPinnedItersMgr ( & pinned_iters_mgr_ ) ;
}
}
}
}
~ DBIter ( ) override {
~ DBIter ( ) override {
@ -161,16 +162,12 @@ class DBIter final: public Iterator {
RecordTick ( statistics_ , NO_ITERATOR_DELETED ) ;
RecordTick ( statistics_ , NO_ITERATOR_DELETED ) ;
ResetInternalKeysSkippedCounter ( ) ;
ResetInternalKeysSkippedCounter ( ) ;
local_stats_ . BumpGlobalStatistics ( statistics_ ) ;
local_stats_ . BumpGlobalStatistics ( statistics_ ) ;
if ( ! arena_mode_ ) {
iter_ . DeleteIter ( arena_mode_ ) ;
delete iter_ ;
} else {
iter_ - > ~ InternalIterator ( ) ;
}
}
}
virtual void SetIter ( InternalIterator * iter ) {
virtual void SetIter ( InternalIterator * iter ) {
assert ( iter_ = = nullptr ) ;
assert ( iter_ . iter ( ) = = nullptr ) ;
iter_ = iter ;
iter_ . Set ( iter ) ;
iter_ - > SetPinnedItersMgr ( & pinned_iters_mgr_ ) ;
iter_ . iter ( ) - > SetPinnedItersMgr ( & pinned_iters_mgr_ ) ;
}
}
virtual ReadRangeDelAggregator * GetRangeDelAggregator ( ) {
virtual ReadRangeDelAggregator * GetRangeDelAggregator ( ) {
return & range_del_agg_ ;
return & range_del_agg_ ;
@ -194,12 +191,12 @@ class DBIter final: public Iterator {
} else if ( direction_ = = kReverse ) {
} else if ( direction_ = = kReverse ) {
return pinned_value_ ;
return pinned_value_ ;
} else {
} else {
return iter_ - > value ( ) ;
return iter_ . value ( ) ;
}
}
}
}
Status status ( ) const override {
Status status ( ) const override {
if ( status_ . ok ( ) ) {
if ( status_ . ok ( ) ) {
return iter_ - > status ( ) ;
return iter_ . status ( ) ;
} else {
} else {
assert ( ! valid_ ) ;
assert ( ! valid_ ) ;
return status_ ;
return status_ ;
@ -216,7 +213,7 @@ class DBIter final: public Iterator {
}
}
if ( prop_name = = " rocksdb.iterator.super-version-number " ) {
if ( prop_name = = " rocksdb.iterator.super-version-number " ) {
// First try to pass the value returned from inner iterator.
// First try to pass the value returned from inner iterator.
return iter_ - > GetProperty ( prop_name , prop ) ;
return iter_ . iter ( ) - > GetProperty ( prop_name , prop ) ;
} else if ( prop_name = = " rocksdb.iterator.is-key-pinned " ) {
} else if ( prop_name = = " rocksdb.iterator.is-key-pinned " ) {
if ( valid_ ) {
if ( valid_ ) {
* prop = ( pin_thru_lifetime_ & & saved_key_ . IsKeyPinned ( ) ) ? " 1 " : " 0 " ;
* prop = ( pin_thru_lifetime_ & & saved_key_ . IsKeyPinned ( ) ) ? " 1 " : " 0 " ;
@ -308,7 +305,7 @@ class DBIter final: public Iterator {
Logger * logger_ ;
Logger * logger_ ;
UserComparatorWrapper user_comparator_ ;
UserComparatorWrapper user_comparator_ ;
const MergeOperator * const merge_operator_ ;
const MergeOperator * const merge_operator_ ;
InternalIterator * iter_ ;
IteratorWrapper iter_ ;
ReadCallback * read_callback_ ;
ReadCallback * read_callback_ ;
// Max visible sequence number. It is normally the snapshot seq unless we have
// Max visible sequence number. It is normally the snapshot seq unless we have
// uncommitted data in db as in WriteUnCommitted.
// uncommitted data in db as in WriteUnCommitted.
@ -361,11 +358,11 @@ class DBIter final: public Iterator {
} ;
} ;
inline bool DBIter : : ParseKey ( ParsedInternalKey * ikey ) {
inline bool DBIter : : ParseKey ( ParsedInternalKey * ikey ) {
if ( ! ParseInternalKey ( iter_ - > key ( ) , ikey ) ) {
if ( ! ParseInternalKey ( iter_ . key ( ) , ikey ) ) {
status_ = Status : : Corruption ( " corrupted internal key in DBIter " ) ;
status_ = Status : : Corruption ( " corrupted internal key in DBIter " ) ;
valid_ = false ;
valid_ = false ;
ROCKS_LOG_ERROR ( logger_ , " corrupted internal key in DBIter: %s " ,
ROCKS_LOG_ERROR ( logger_ , " corrupted internal key in DBIter: %s " ,
iter_ - > key ( ) . ToString ( true ) . c_str ( ) ) ;
iter_ . key ( ) . ToString ( true ) . c_str ( ) ) ;
return false ;
return false ;
} else {
} else {
return true ;
return true ;
@ -393,13 +390,13 @@ void DBIter::Next() {
// Next() without checking the current key.
// Next() without checking the current key.
// If the current key is a merge, very likely iter already points
// If the current key is a merge, very likely iter already points
// to the next internal position.
// to the next internal position.
assert ( iter_ - > Valid ( ) ) ;
assert ( iter_ . Valid ( ) ) ;
iter_ - > Next ( ) ;
iter_ . Next ( ) ;
PERF_COUNTER_ADD ( internal_key_skipped_count , 1 ) ;
PERF_COUNTER_ADD ( internal_key_skipped_count , 1 ) ;
}
}
local_stats_ . next_count_ + + ;
local_stats_ . next_count_ + + ;
if ( ok & & iter_ - > Valid ( ) ) {
if ( ok & & iter_ . Valid ( ) ) {
FindNextUserEntry ( true /* skipping the current user key */ ,
FindNextUserEntry ( true /* skipping the current user key */ ,
prefix_same_as_start_ ) ;
prefix_same_as_start_ ) ;
} else {
} else {
@ -433,7 +430,7 @@ inline bool DBIter::FindNextUserEntry(bool skipping, bool prefix_check) {
// Actual implementation of DBIter::FindNextUserEntry()
// Actual implementation of DBIter::FindNextUserEntry()
inline bool DBIter : : FindNextUserEntryInternal ( bool skipping , bool prefix_check ) {
inline bool DBIter : : FindNextUserEntryInternal ( bool skipping , bool prefix_check ) {
// Loop until we hit an acceptable entry to yield
// Loop until we hit an acceptable entry to yield
assert ( iter_ - > Valid ( ) ) ;
assert ( iter_ . Valid ( ) ) ;
assert ( status_ . ok ( ) ) ;
assert ( status_ . ok ( ) ) ;
assert ( direction_ = = kForward ) ;
assert ( direction_ = = kForward ) ;
current_entry_is_merged_ = false ;
current_entry_is_merged_ = false ;
@ -495,8 +492,8 @@ inline bool DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check)
return true ;
return true ;
} else {
} else {
saved_key_ . SetUserKey (
saved_key_ . SetUserKey (
ikey_ . user_key ,
ikey_ . user_key , ! pin_thru_lifetime_ | |
! pin_thru_lifetime_ | | ! iter_ - > IsKeyPinned ( ) /* copy */ ) ;
! iter_ . iter ( ) - > IsKeyPinned ( ) /* copy */ ) ;
skipping = true ;
skipping = true ;
PERF_COUNTER_ADD ( internal_delete_skipped_count , 1 ) ;
PERF_COUNTER_ADD ( internal_delete_skipped_count , 1 ) ;
}
}
@ -516,14 +513,16 @@ inline bool DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check)
} else {
} else {
// this key and all previous versions shouldn't be included,
// this key and all previous versions shouldn't be included,
// skipping
// skipping
saved_key_ . SetUserKey ( ikey_ . user_key ,
saved_key_ . SetUserKey (
! pin_thru_lifetime_ | | ! iter_ - > IsKeyPinned ( ) /* copy */ ) ;
ikey_ . user_key ,
! pin_thru_lifetime_ | |
! iter_ . iter ( ) - > IsKeyPinned ( ) /* copy */ ) ;
skipping = true ;
skipping = true ;
}
}
} else {
} else {
saved_key_ . SetUserKey (
saved_key_ . SetUserKey (
ikey_ . user_key ,
ikey_ . user_key , ! pin_thru_lifetime_ | |
! pin_thru_lifetime_ | | ! iter_ - > IsKeyPinned ( ) /* copy */ ) ;
! iter_ . iter ( ) - > IsKeyPinned ( ) /* copy */ ) ;
if ( range_del_agg_ . ShouldDelete (
if ( range_del_agg_ . ShouldDelete (
ikey_ , RangeDelPositioningMode : : kForwardTraversal ) ) {
ikey_ , RangeDelPositioningMode : : kForwardTraversal ) ) {
// Arrange to skip all upcoming entries for this key since
// Arrange to skip all upcoming entries for this key since
@ -553,7 +552,7 @@ inline bool DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check)
case kTypeMerge :
case kTypeMerge :
saved_key_ . SetUserKey (
saved_key_ . SetUserKey (
ikey_ . user_key ,
ikey_ . user_key ,
! pin_thru_lifetime_ | | ! iter_ - > IsKeyPinned ( ) /* copy */ ) ;
! pin_thru_lifetime_ | | ! iter_ . iter ( ) - > IsKeyPinned ( ) /* copy */ ) ;
if ( range_del_agg_ . ShouldDelete (
if ( range_del_agg_ . ShouldDelete (
ikey_ , RangeDelPositioningMode : : kForwardTraversal ) ) {
ikey_ , RangeDelPositioningMode : : kForwardTraversal ) ) {
// Arrange to skip all upcoming entries for this key since
// Arrange to skip all upcoming entries for this key since
@ -587,7 +586,7 @@ inline bool DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check)
} else {
} else {
saved_key_ . SetUserKey (
saved_key_ . SetUserKey (
ikey_ . user_key ,
ikey_ . user_key ,
! iter_ - > IsKeyPinned ( ) | | ! pin_thru_lifetime_ /* copy */ ) ;
! iter_ . iter ( ) - > IsKeyPinned ( ) | | ! pin_thru_lifetime_ /* copy */ ) ;
skipping = false ;
skipping = false ;
num_skipped = 0 ;
num_skipped = 0 ;
}
}
@ -616,20 +615,20 @@ inline bool DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check)
ParsedInternalKey ( saved_key_ . GetUserKey ( ) , sequence_ ,
ParsedInternalKey ( saved_key_ . GetUserKey ( ) , sequence_ ,
kValueTypeForSeek ) ) ;
kValueTypeForSeek ) ) ;
}
}
iter_ - > Seek ( last_key ) ;
iter_ . Seek ( last_key ) ;
RecordTick ( statistics_ , NUMBER_OF_RESEEKS_IN_ITERATION ) ;
RecordTick ( statistics_ , NUMBER_OF_RESEEKS_IN_ITERATION ) ;
} else {
} else {
iter_ - > Next ( ) ;
iter_ . Next ( ) ;
}
}
} while ( iter_ - > Valid ( ) ) ;
} while ( iter_ . Valid ( ) ) ;
valid_ = false ;
valid_ = false ;
return iter_ - > status ( ) . ok ( ) ;
return iter_ . status ( ) . ok ( ) ;
}
}
// Merge values of the same user key starting from the current iter_ position
// Merge values of the same user key starting from the current iter_ position
// Scan from the newer entries to older entries.
// Scan from the newer entries to older entries.
// PRE: iter_-> key() points to the first merge type entry
// PRE: iter_. key() points to the first merge type entry
// saved_key_ stores the user key
// saved_key_ stores the user key
// POST: saved_value_ has the merged value for the user key
// POST: saved_value_ has the merged value for the user key
// iter_ points to the next entry (or invalid)
// iter_ points to the next entry (or invalid)
@ -645,13 +644,13 @@ bool DBIter::MergeValuesNewToOld() {
TempPinData ( ) ;
TempPinData ( ) ;
merge_context_ . Clear ( ) ;
merge_context_ . Clear ( ) ;
// Start the merge process by pushing the first operand
// Start the merge process by pushing the first operand
merge_context_ . PushOperand ( iter_ - > value ( ) ,
merge_context_ . PushOperand (
iter_ - > IsValuePinned ( ) /* operand_pinned */ ) ;
iter_ . value ( ) , iter_ . iter ( ) - > IsValuePinned ( ) /* operand_pinned */ ) ;
TEST_SYNC_POINT ( " DBIter::MergeValuesNewToOld:PushedFirstOperand " ) ;
TEST_SYNC_POINT ( " DBIter::MergeValuesNewToOld:PushedFirstOperand " ) ;
ParsedInternalKey ikey ;
ParsedInternalKey ikey ;
Status s ;
Status s ;
for ( iter_ - > Next ( ) ; iter_ - > Valid ( ) ; iter_ - > Next ( ) ) {
for ( iter_ . Next ( ) ; iter_ . Valid ( ) ; iter_ . Next ( ) ) {
TEST_SYNC_POINT ( " DBIter::MergeValuesNewToOld:SteppedToNextOperand " ) ;
TEST_SYNC_POINT ( " DBIter::MergeValuesNewToOld:SteppedToNextOperand " ) ;
if ( ! ParseKey ( & ikey ) ) {
if ( ! ParseKey ( & ikey ) ) {
return false ;
return false ;
@ -665,12 +664,12 @@ bool DBIter::MergeValuesNewToOld() {
ikey , RangeDelPositioningMode : : kForwardTraversal ) ) {
ikey , RangeDelPositioningMode : : kForwardTraversal ) ) {
// hit a delete with the same user key, stop right here
// hit a delete with the same user key, stop right here
// iter_ is positioned after delete
// iter_ is positioned after delete
iter_ - > Next ( ) ;
iter_ . Next ( ) ;
break ;
break ;
} else if ( kTypeValue = = ikey . type ) {
} else if ( kTypeValue = = ikey . type ) {
// hit a put, merge the put value with operands and store the
// hit a put, merge the put value with operands and store the
// final result in saved_value_. We are done!
// final result in saved_value_. We are done!
const Slice val = iter_ - > value ( ) ;
const Slice val = iter_ . value ( ) ;
s = MergeHelper : : TimedFullMerge (
s = MergeHelper : : TimedFullMerge (
merge_operator_ , ikey . user_key , & val , merge_context_ . GetOperands ( ) ,
merge_operator_ , ikey . user_key , & val , merge_context_ . GetOperands ( ) ,
& saved_value_ , logger_ , statistics_ , env_ , & pinned_value_ , true ) ;
& saved_value_ , logger_ , statistics_ , env_ , & pinned_value_ , true ) ;
@ -680,8 +679,8 @@ bool DBIter::MergeValuesNewToOld() {
return false ;
return false ;
}
}
// iter_ is positioned after put
// iter_ is positioned after put
iter_ - > Next ( ) ;
iter_ . Next ( ) ;
if ( ! iter_ - > status ( ) . ok ( ) ) {
if ( ! iter_ . status ( ) . ok ( ) ) {
valid_ = false ;
valid_ = false ;
return false ;
return false ;
}
}
@ -689,8 +688,8 @@ bool DBIter::MergeValuesNewToOld() {
} else if ( kTypeMerge = = ikey . type ) {
} else if ( kTypeMerge = = ikey . type ) {
// hit a merge, add the value as an operand and run associative merge.
// hit a merge, add the value as an operand and run associative merge.
// when complete, add result to operands and continue.
// when complete, add result to operands and continue.
merge_context_ . PushOperand ( iter_ - > value ( ) ,
merge_context_ . PushOperand (
iter_ - > IsValuePinned ( ) /* operand_pinned */ ) ;
iter_ . value ( ) , iter_ . iter ( ) - > IsValuePinned ( ) /* operand_pinned */ ) ;
PERF_COUNTER_ADD ( internal_merge_count , 1 ) ;
PERF_COUNTER_ADD ( internal_merge_count , 1 ) ;
} else if ( kTypeBlobIndex = = ikey . type ) {
} else if ( kTypeBlobIndex = = ikey . type ) {
if ( ! allow_blob_ ) {
if ( ! allow_blob_ ) {
@ -709,7 +708,7 @@ bool DBIter::MergeValuesNewToOld() {
}
}
}
}
if ( ! iter_ - > status ( ) . ok ( ) ) {
if ( ! iter_ . status ( ) . ok ( ) ) {
valid_ = false ;
valid_ = false ;
return false ;
return false ;
}
}
@ -758,21 +757,21 @@ void DBIter::Prev() {
}
}
bool DBIter : : ReverseToForward ( ) {
bool DBIter : : ReverseToForward ( ) {
assert ( iter_ - > status ( ) . ok ( ) ) ;
assert ( iter_ . status ( ) . ok ( ) ) ;
// When moving backwards, iter_ is positioned on _previous_ key, which may
// When moving backwards, iter_ is positioned on _previous_ key, which may
// not exist or may have different prefix than the current key().
// not exist or may have different prefix than the current key().
// If that's the case, seek iter_ to current key.
// If that's the case, seek iter_ to current key.
if ( ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) | | ! iter_ - > Valid ( ) ) {
if ( ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) | | ! iter_ . Valid ( ) ) {
IterKey last_key ;
IterKey last_key ;
last_key . SetInternalKey ( ParsedInternalKey (
last_key . SetInternalKey ( ParsedInternalKey (
saved_key_ . GetUserKey ( ) , kMaxSequenceNumber , kValueTypeForSeek ) ) ;
saved_key_ . GetUserKey ( ) , kMaxSequenceNumber , kValueTypeForSeek ) ) ;
iter_ - > Seek ( last_key . GetInternalKey ( ) ) ;
iter_ . Seek ( last_key . GetInternalKey ( ) ) ;
}
}
direction_ = kForward ;
direction_ = kForward ;
// Skip keys less than the current key() (a.k.a. saved_key_).
// Skip keys less than the current key() (a.k.a. saved_key_).
while ( iter_ - > Valid ( ) ) {
while ( iter_ . Valid ( ) ) {
ParsedInternalKey ikey ;
ParsedInternalKey ikey ;
if ( ! ParseKey ( & ikey ) ) {
if ( ! ParseKey ( & ikey ) ) {
return false ;
return false ;
@ -780,10 +779,10 @@ bool DBIter::ReverseToForward() {
if ( user_comparator_ . Compare ( ikey . user_key , saved_key_ . GetUserKey ( ) ) > = 0 ) {
if ( user_comparator_ . Compare ( ikey . user_key , saved_key_ . GetUserKey ( ) ) > = 0 ) {
return true ;
return true ;
}
}
iter_ - > Next ( ) ;
iter_ . Next ( ) ;
}
}
if ( ! iter_ - > status ( ) . ok ( ) ) {
if ( ! iter_ . status ( ) . ok ( ) ) {
valid_ = false ;
valid_ = false ;
return false ;
return false ;
}
}
@ -793,14 +792,14 @@ bool DBIter::ReverseToForward() {
// Move iter_ to the key before saved_key_.
// Move iter_ to the key before saved_key_.
bool DBIter : : ReverseToBackward ( ) {
bool DBIter : : ReverseToBackward ( ) {
assert ( iter_ - > status ( ) . ok ( ) ) ;
assert ( iter_ . status ( ) . ok ( ) ) ;
// When current_entry_is_merged_ is true, iter_ may be positioned on the next
// When current_entry_is_merged_ is true, iter_ may be positioned on the next
// key, which may not exist or may have prefix different from current.
// key, which may not exist or may have prefix different from current.
// If that's the case, seek to saved_key_.
// If that's the case, seek to saved_key_.
if ( current_entry_is_merged_ & &
if ( current_entry_is_merged_ & &
( ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) | |
( ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) | |
! iter_ - > Valid ( ) ) ) {
! iter_ . Valid ( ) ) ) {
IterKey last_key ;
IterKey last_key ;
// Using kMaxSequenceNumber and kValueTypeForSeek
// Using kMaxSequenceNumber and kValueTypeForSeek
// (not kValueTypeForSeekForPrev) to seek to a key strictly smaller
// (not kValueTypeForSeekForPrev) to seek to a key strictly smaller
@ -808,15 +807,15 @@ bool DBIter::ReverseToBackward() {
last_key . SetInternalKey ( ParsedInternalKey (
last_key . SetInternalKey ( ParsedInternalKey (
saved_key_ . GetUserKey ( ) , kMaxSequenceNumber , kValueTypeForSeek ) ) ;
saved_key_ . GetUserKey ( ) , kMaxSequenceNumber , kValueTypeForSeek ) ) ;
if ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) {
if ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) {
iter_ - > SeekForPrev ( last_key . GetInternalKey ( ) ) ;
iter_ . SeekForPrev ( last_key . GetInternalKey ( ) ) ;
} else {
} else {
// Some iterators may not support SeekForPrev(), so we avoid using it
// Some iterators may not support SeekForPrev(), so we avoid using it
// when prefix seek mode is disabled. This is somewhat expensive
// when prefix seek mode is disabled. This is somewhat expensive
// (an extra Prev(), as well as an extra change of direction of iter_),
// (an extra Prev(), as well as an extra change of direction of iter_),
// so we may need to reconsider it later.
// so we may need to reconsider it later.
iter_ - > Seek ( last_key . GetInternalKey ( ) ) ;
iter_ . Seek ( last_key . GetInternalKey ( ) ) ;
if ( ! iter_ - > Valid ( ) & & iter_ - > status ( ) . ok ( ) ) {
if ( ! iter_ . Valid ( ) & & iter_ . status ( ) . ok ( ) ) {
iter_ - > SeekToLast ( ) ;
iter_ . SeekToLast ( ) ;
}
}
}
}
}
}
@ -826,10 +825,10 @@ bool DBIter::ReverseToBackward() {
}
}
void DBIter : : PrevInternal ( ) {
void DBIter : : PrevInternal ( ) {
while ( iter_ - > Valid ( ) ) {
while ( iter_ . Valid ( ) ) {
saved_key_ . SetUserKey (
saved_key_ . SetUserKey (
ExtractUserKey ( iter_ - > key ( ) ) ,
ExtractUserKey ( iter_ . key ( ) ) ,
! iter_ - > IsKeyPinned ( ) | | ! pin_thru_lifetime_ /* copy */ ) ;
! iter_ . iter ( ) - > IsKeyPinned ( ) | | ! pin_thru_lifetime_ /* copy */ ) ;
if ( prefix_extractor_ & & prefix_same_as_start_ & &
if ( prefix_extractor_ & & prefix_same_as_start_ & &
prefix_extractor_ - > Transform ( saved_key_ . GetUserKey ( ) )
prefix_extractor_ - > Transform ( saved_key_ . GetUserKey ( ) )
@ -883,7 +882,7 @@ void DBIter::PrevInternal() {
// POST: iter_ is positioned on one of the entries equal to saved_key_, or on
// POST: iter_ is positioned on one of the entries equal to saved_key_, or on
// the entry just before them, or on the entry just after them.
// the entry just before them, or on the entry just after them.
bool DBIter : : FindValueForCurrentKey ( ) {
bool DBIter : : FindValueForCurrentKey ( ) {
assert ( iter_ - > Valid ( ) ) ;
assert ( iter_ . Valid ( ) ) ;
merge_context_ . Clear ( ) ;
merge_context_ . Clear ( ) ;
current_entry_is_merged_ = false ;
current_entry_is_merged_ = false ;
// last entry before merge (could be kTypeDeletion, kTypeSingleDeletion or
// last entry before merge (could be kTypeDeletion, kTypeSingleDeletion or
@ -895,7 +894,7 @@ bool DBIter::FindValueForCurrentKey() {
ReleaseTempPinnedData ( ) ;
ReleaseTempPinnedData ( ) ;
TempPinData ( ) ;
TempPinData ( ) ;
size_t num_skipped = 0 ;
size_t num_skipped = 0 ;
while ( iter_ - > Valid ( ) ) {
while ( iter_ . Valid ( ) ) {
ParsedInternalKey ikey ;
ParsedInternalKey ikey ;
if ( ! ParseKey ( & ikey ) ) {
if ( ! ParseKey ( & ikey ) ) {
return false ;
return false ;
@ -925,8 +924,8 @@ bool DBIter::FindValueForCurrentKey() {
last_key_entry_type = kTypeRangeDeletion ;
last_key_entry_type = kTypeRangeDeletion ;
PERF_COUNTER_ADD ( internal_delete_skipped_count , 1 ) ;
PERF_COUNTER_ADD ( internal_delete_skipped_count , 1 ) ;
} else {
} else {
assert ( iter_ - > IsValuePinned ( ) ) ;
assert ( iter_ . iter ( ) - > IsValuePinned ( ) ) ;
pinned_value_ = iter_ - > value ( ) ;
pinned_value_ = iter_ . value ( ) ;
}
}
merge_context_ . Clear ( ) ;
merge_context_ . Clear ( ) ;
last_not_merge_type = last_key_entry_type ;
last_not_merge_type = last_key_entry_type ;
@ -947,7 +946,8 @@ bool DBIter::FindValueForCurrentKey() {
} else {
} else {
assert ( merge_operator_ ! = nullptr ) ;
assert ( merge_operator_ ! = nullptr ) ;
merge_context_ . PushOperandBack (
merge_context_ . PushOperandBack (
iter_ - > value ( ) , iter_ - > IsValuePinned ( ) /* operand_pinned */ ) ;
iter_ . value ( ) ,
iter_ . iter ( ) - > IsValuePinned ( ) /* operand_pinned */ ) ;
PERF_COUNTER_ADD ( internal_merge_count , 1 ) ;
PERF_COUNTER_ADD ( internal_merge_count , 1 ) ;
}
}
break ;
break ;
@ -956,11 +956,11 @@ bool DBIter::FindValueForCurrentKey() {
}
}
PERF_COUNTER_ADD ( internal_key_skipped_count , 1 ) ;
PERF_COUNTER_ADD ( internal_key_skipped_count , 1 ) ;
iter_ - > Prev ( ) ;
iter_ . Prev ( ) ;
+ + num_skipped ;
+ + num_skipped ;
}
}
if ( ! iter_ - > status ( ) . ok ( ) ) {
if ( ! iter_ . status ( ) . ok ( ) ) {
valid_ = false ;
valid_ = false ;
return false ;
return false ;
}
}
@ -1040,16 +1040,16 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
std : : string last_key ;
std : : string last_key ;
AppendInternalKey ( & last_key , ParsedInternalKey ( saved_key_ . GetUserKey ( ) ,
AppendInternalKey ( & last_key , ParsedInternalKey ( saved_key_ . GetUserKey ( ) ,
sequence_ , kValueTypeForSeek ) ) ;
sequence_ , kValueTypeForSeek ) ) ;
iter_ - > Seek ( last_key ) ;
iter_ . Seek ( last_key ) ;
RecordTick ( statistics_ , NUMBER_OF_RESEEKS_IN_ITERATION ) ;
RecordTick ( statistics_ , NUMBER_OF_RESEEKS_IN_ITERATION ) ;
// In case read_callback presents, the value we seek to may not be visible.
// In case read_callback presents, the value we seek to may not be visible.
// Find the next value that's visible.
// Find the next value that's visible.
ParsedInternalKey ikey ;
ParsedInternalKey ikey ;
while ( true ) {
while ( true ) {
if ( ! iter_ - > Valid ( ) ) {
if ( ! iter_ . Valid ( ) ) {
valid_ = false ;
valid_ = false ;
return iter_ - > status ( ) . ok ( ) ;
return iter_ . status ( ) . ok ( ) ;
}
}
if ( ! ParseKey ( & ikey ) ) {
if ( ! ParseKey ( & ikey ) ) {
@ -1067,7 +1067,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
break ;
break ;
}
}
iter_ - > Next ( ) ;
iter_ . Next ( ) ;
}
}
if ( ikey . type = = kTypeDeletion | | ikey . type = = kTypeSingleDeletion | |
if ( ikey . type = = kTypeDeletion | | ikey . type = = kTypeSingleDeletion | |
@ -1085,8 +1085,8 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
return false ;
return false ;
}
}
if ( ikey . type = = kTypeValue | | ikey . type = = kTypeBlobIndex ) {
if ( ikey . type = = kTypeValue | | ikey . type = = kTypeBlobIndex ) {
assert ( iter_ - > IsValuePinned ( ) ) ;
assert ( iter_ . iter ( ) - > IsValuePinned ( ) ) ;
pinned_value_ = iter_ - > value ( ) ;
pinned_value_ = iter_ . value ( ) ;
valid_ = true ;
valid_ = true ;
return true ;
return true ;
}
}
@ -1096,13 +1096,13 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
assert ( ikey . type = = kTypeMerge ) ;
assert ( ikey . type = = kTypeMerge ) ;
current_entry_is_merged_ = true ;
current_entry_is_merged_ = true ;
merge_context_ . Clear ( ) ;
merge_context_ . Clear ( ) ;
merge_context_ . PushOperand ( iter_ - > value ( ) ,
merge_context_ . PushOperand (
iter_ - > IsValuePinned ( ) /* operand_pinned */ ) ;
iter_ . value ( ) , iter_ . iter ( ) - > IsValuePinned ( ) /* operand_pinned */ ) ;
while ( true ) {
while ( true ) {
iter_ - > Next ( ) ;
iter_ . Next ( ) ;
if ( ! iter_ - > Valid ( ) ) {
if ( ! iter_ . Valid ( ) ) {
if ( ! iter_ - > status ( ) . ok ( ) ) {
if ( ! iter_ . status ( ) . ok ( ) ) {
valid_ = false ;
valid_ = false ;
return false ;
return false ;
}
}
@ -1120,7 +1120,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
ikey , RangeDelPositioningMode : : kForwardTraversal ) ) {
ikey , RangeDelPositioningMode : : kForwardTraversal ) ) {
break ;
break ;
} else if ( ikey . type = = kTypeValue ) {
} else if ( ikey . type = = kTypeValue ) {
const Slice val = iter_ - > value ( ) ;
const Slice val = iter_ . value ( ) ;
Status s = MergeHelper : : TimedFullMerge (
Status s = MergeHelper : : TimedFullMerge (
merge_operator_ , saved_key_ . GetUserKey ( ) , & val ,
merge_operator_ , saved_key_ . GetUserKey ( ) , & val ,
merge_context_ . GetOperands ( ) , & saved_value_ , logger_ , statistics_ ,
merge_context_ . GetOperands ( ) , & saved_value_ , logger_ , statistics_ ,
@ -1133,8 +1133,8 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
valid_ = true ;
valid_ = true ;
return true ;
return true ;
} else if ( ikey . type = = kTypeMerge ) {
} else if ( ikey . type = = kTypeMerge ) {
merge_context_ . PushOperand ( iter_ - > value ( ) ,
merge_context_ . PushOperand (
iter_ - > IsValuePinned ( ) /* operand_pinned */ ) ;
iter_ . value ( ) , iter_ . iter ( ) - > IsValuePinned ( ) /* operand_pinned */ ) ;
PERF_COUNTER_ADD ( internal_merge_count , 1 ) ;
PERF_COUNTER_ADD ( internal_merge_count , 1 ) ;
} else if ( ikey . type = = kTypeBlobIndex ) {
} else if ( ikey . type = = kTypeBlobIndex ) {
if ( ! allow_blob_ ) {
if ( ! allow_blob_ ) {
@ -1166,13 +1166,13 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
// Make sure we leave iter_ in a good state. If it's valid and we don't care
// Make sure we leave iter_ in a good state. If it's valid and we don't care
// about prefixes, that's already good enough. Otherwise it needs to be
// about prefixes, that's already good enough. Otherwise it needs to be
// seeked to the current key.
// seeked to the current key.
if ( ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) | | ! iter_ - > Valid ( ) ) {
if ( ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) | | ! iter_ . Valid ( ) ) {
if ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) {
if ( prefix_extractor_ ! = nullptr & & ! total_order_seek_ ) {
iter_ - > SeekForPrev ( last_key ) ;
iter_ . SeekForPrev ( last_key ) ;
} else {
} else {
iter_ - > Seek ( last_key ) ;
iter_ . Seek ( last_key ) ;
if ( ! iter_ - > Valid ( ) & & iter_ - > status ( ) . ok ( ) ) {
if ( ! iter_ . Valid ( ) & & iter_ . status ( ) . ok ( ) ) {
iter_ - > SeekToLast ( ) ;
iter_ . SeekToLast ( ) ;
}
}
}
}
RecordTick ( statistics_ , NUMBER_OF_RESEEKS_IN_ITERATION ) ;
RecordTick ( statistics_ , NUMBER_OF_RESEEKS_IN_ITERATION ) ;
@ -1187,7 +1187,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
bool DBIter : : FindUserKeyBeforeSavedKey ( ) {
bool DBIter : : FindUserKeyBeforeSavedKey ( ) {
assert ( status_ . ok ( ) ) ;
assert ( status_ . ok ( ) ) ;
size_t num_skipped = 0 ;
size_t num_skipped = 0 ;
while ( iter_ - > Valid ( ) ) {
while ( iter_ . Valid ( ) ) {
ParsedInternalKey ikey ;
ParsedInternalKey ikey ;
if ( ! ParseKey ( & ikey ) ) {
if ( ! ParseKey ( & ikey ) ) {
return false ;
return false ;
@ -1215,19 +1215,19 @@ bool DBIter::FindUserKeyBeforeSavedKey() {
saved_key_ . GetUserKey ( ) , kMaxSequenceNumber , kValueTypeForSeek ) ) ;
saved_key_ . GetUserKey ( ) , kMaxSequenceNumber , kValueTypeForSeek ) ) ;
// It would be more efficient to use SeekForPrev() here, but some
// It would be more efficient to use SeekForPrev() here, but some
// iterators may not support it.
// iterators may not support it.
iter_ - > Seek ( last_key . GetInternalKey ( ) ) ;
iter_ . Seek ( last_key . GetInternalKey ( ) ) ;
RecordTick ( statistics_ , NUMBER_OF_RESEEKS_IN_ITERATION ) ;
RecordTick ( statistics_ , NUMBER_OF_RESEEKS_IN_ITERATION ) ;
if ( ! iter_ - > Valid ( ) ) {
if ( ! iter_ . Valid ( ) ) {
break ;
break ;
}
}
} else {
} else {
+ + num_skipped ;
+ + num_skipped ;
}
}
iter_ - > Prev ( ) ;
iter_ . Prev ( ) ;
}
}
if ( ! iter_ - > status ( ) . ok ( ) ) {
if ( ! iter_ . status ( ) . ok ( ) ) {
valid_ = false ;
valid_ = false ;
return false ;
return false ;
}
}
@ -1285,11 +1285,11 @@ void DBIter::Seek(const Slice& target) {
{
{
PERF_TIMER_GUARD ( seek_internal_seek_time ) ;
PERF_TIMER_GUARD ( seek_internal_seek_time ) ;
iter_ - > Seek ( saved_key_ . GetInternalKey ( ) ) ;
iter_ . Seek ( saved_key_ . GetInternalKey ( ) ) ;
range_del_agg_ . InvalidateRangeDelMapPositions ( ) ;
range_del_agg_ . InvalidateRangeDelMapPositions ( ) ;
}
}
RecordTick ( statistics_ , NUMBER_DB_SEEK ) ;
RecordTick ( statistics_ , NUMBER_DB_SEEK ) ;
if ( iter_ - > Valid ( ) ) {
if ( iter_ . Valid ( ) ) {
if ( prefix_extractor_ & & prefix_same_as_start_ ) {
if ( prefix_extractor_ & & prefix_same_as_start_ ) {
prefix_start_key_ = prefix_extractor_ - > Transform ( target ) ;
prefix_start_key_ = prefix_extractor_ - > Transform ( target ) ;
}
}
@ -1337,7 +1337,7 @@ void DBIter::SeekForPrev(const Slice& target) {
{
{
PERF_TIMER_GUARD ( seek_internal_seek_time ) ;
PERF_TIMER_GUARD ( seek_internal_seek_time ) ;
iter_ - > SeekForPrev ( saved_key_ . GetInternalKey ( ) ) ;
iter_ . SeekForPrev ( saved_key_ . GetInternalKey ( ) ) ;
range_del_agg_ . InvalidateRangeDelMapPositions ( ) ;
range_del_agg_ . InvalidateRangeDelMapPositions ( ) ;
}
}
@ -1348,7 +1348,7 @@ void DBIter::SeekForPrev(const Slice& target) {
# endif // ROCKSDB_LITE
# endif // ROCKSDB_LITE
RecordTick ( statistics_ , NUMBER_DB_SEEK ) ;
RecordTick ( statistics_ , NUMBER_DB_SEEK ) ;
if ( iter_ - > Valid ( ) ) {
if ( iter_ . Valid ( ) ) {
if ( prefix_extractor_ & & prefix_same_as_start_ ) {
if ( prefix_extractor_ & & prefix_same_as_start_ ) {
prefix_start_key_ = prefix_extractor_ - > Transform ( target ) ;
prefix_start_key_ = prefix_extractor_ - > Transform ( target ) ;
}
}
@ -1393,15 +1393,15 @@ void DBIter::SeekToFirst() {
{
{
PERF_TIMER_GUARD ( seek_internal_seek_time ) ;
PERF_TIMER_GUARD ( seek_internal_seek_time ) ;
iter_ - > SeekToFirst ( ) ;
iter_ . SeekToFirst ( ) ;
range_del_agg_ . InvalidateRangeDelMapPositions ( ) ;
range_del_agg_ . InvalidateRangeDelMapPositions ( ) ;
}
}
RecordTick ( statistics_ , NUMBER_DB_SEEK ) ;
RecordTick ( statistics_ , NUMBER_DB_SEEK ) ;
if ( iter_ - > Valid ( ) ) {
if ( iter_ . Valid ( ) ) {
saved_key_ . SetUserKey (
saved_key_ . SetUserKey (
ExtractUserKey ( iter_ - > key ( ) ) ,
ExtractUserKey ( iter_ . key ( ) ) ,
! iter_ - > IsKeyPinned ( ) | | ! pin_thru_lifetime_ /* copy */ ) ;
! iter_ . iter ( ) - > IsKeyPinned ( ) | | ! pin_thru_lifetime_ /* copy */ ) ;
FindNextUserEntry ( false /* not skipping */ , false /* no prefix check */ ) ;
FindNextUserEntry ( false /* not skipping */ , false /* no prefix check */ ) ;
if ( statistics_ ! = nullptr ) {
if ( statistics_ ! = nullptr ) {
if ( valid_ ) {
if ( valid_ ) {
@ -1445,7 +1445,7 @@ void DBIter::SeekToLast() {
{
{
PERF_TIMER_GUARD ( seek_internal_seek_time ) ;
PERF_TIMER_GUARD ( seek_internal_seek_time ) ;
iter_ - > SeekToLast ( ) ;
iter_ . SeekToLast ( ) ;
range_del_agg_ . InvalidateRangeDelMapPositions ( ) ;
range_del_agg_ . InvalidateRangeDelMapPositions ( ) ;
}
}
PrevInternal ( ) ;
PrevInternal ( ) ;