update IterKey that can get user key and internal key explicitly

Summary:
to void future bug that caused by the mix of userkey/internalkey
Closes https://github.com/facebook/rocksdb/pull/2084

Differential Revision: D4825889

Pulled By: lightmark

fbshipit-source-id: 28411db
This commit is contained in:
Aaron Gao 2017-04-04 14:17:16 -07:00 committed by Facebook Github Bot
parent e2c6c06366
commit 90cfd46458
15 changed files with 176 additions and 139 deletions

View file

@ -105,7 +105,7 @@ void CompactionIterator::Next() {
assert(valid_key);
// Keep current_key_ in sync.
current_key_.UpdateInternalKey(ikey_.sequence, ikey_.type);
key_ = current_key_.GetKey();
key_ = current_key_.GetInternalKey();
ikey_.user_key = current_key_.GetUserKey();
valid_ = true;
} else {
@ -151,7 +151,7 @@ void CompactionIterator::NextFromInput() {
status_ = Status::Corruption("Corrupted internal key not expected.");
break;
}
key_ = current_key_.SetKey(key_);
key_ = current_key_.SetInternalKey(key_);
has_current_user_key_ = false;
current_user_key_sequence_ = kMaxSequenceNumber;
current_user_key_snapshot_ = 0;
@ -181,7 +181,7 @@ void CompactionIterator::NextFromInput() {
!cmp_->Equal(ikey_.user_key, current_user_key_)) {
// First occurrence of this user key
// Copy key for output
key_ = current_key_.SetKey(key_, &ikey_);
key_ = current_key_.SetInternalKey(key_, &ikey_);
current_user_key_ = ikey_.user_key;
has_current_user_key_ = true;
has_outputted_key_ = false;
@ -241,7 +241,7 @@ void CompactionIterator::NextFromInput() {
// Need to have the compaction filter process multiple versions
// if we have versions on both sides of a snapshot
current_key_.UpdateInternalKey(ikey_.sequence, ikey_.type);
key_ = current_key_.GetKey();
key_ = current_key_.GetInternalKey();
ikey_.user_key = current_key_.GetUserKey();
}
@ -453,7 +453,7 @@ void CompactionIterator::NextFromInput() {
assert(valid_key);
// Keep current_key_ in sync.
current_key_.UpdateInternalKey(ikey_.sequence, ikey_.type);
key_ = current_key_.GetKey();
key_ = current_key_.GetInternalKey();
ikey_.user_key = current_key_.GetUserKey();
valid_ = true;
} else {

View file

@ -733,7 +733,7 @@ void CompactionJob::ProcessKeyValueCompaction(SubcompactionState* sub_compact) {
if (start != nullptr) {
IterKey start_iter;
start_iter.SetInternalKey(*start, kMaxSequenceNumber, kValueTypeForSeek);
input->Seek(start_iter.GetKey());
input->Seek(start_iter.GetInternalKey());
} else {
input->SeekToFirst();
}

View file

@ -162,7 +162,7 @@ class DBIter: public Iterator {
virtual bool Valid() const override { return valid_; }
virtual Slice key() const override {
assert(valid_);
return saved_key_.GetKey();
return saved_key_.GetUserKey();
}
virtual Slice value() const override {
assert(valid_);
@ -406,7 +406,8 @@ void DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check) {
if (ikey.sequence <= sequence_) {
if (skipping &&
user_comparator_->Compare(ikey.user_key, saved_key_.GetKey()) <= 0) {
user_comparator_->Compare(ikey.user_key, saved_key_.GetUserKey()) <=
0) {
num_skipped++; // skip this entry
PERF_COUNTER_ADD(internal_key_skipped_count, 1);
} else {
@ -416,14 +417,14 @@ void DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check) {
case kTypeSingleDeletion:
// Arrange to skip all upcoming entries for this key since
// they are hidden by this deletion.
saved_key_.SetKey(
saved_key_.SetUserKey(
ikey.user_key,
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
skipping = true;
PERF_COUNTER_ADD(internal_delete_skipped_count, 1);
break;
case kTypeValue:
saved_key_.SetKey(
saved_key_.SetUserKey(
ikey.user_key,
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
if (range_del_agg_.ShouldDelete(
@ -440,7 +441,7 @@ void DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check) {
}
break;
case kTypeMerge:
saved_key_.SetKey(
saved_key_.SetUserKey(
ikey.user_key,
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
if (range_del_agg_.ShouldDelete(
@ -471,12 +472,13 @@ void DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check) {
// Here saved_key_ may contain some old key, or the default empty key, or
// key assigned by some random other method. We don't care.
if (user_comparator_->Compare(ikey.user_key, saved_key_.GetKey()) <= 0) {
if (user_comparator_->Compare(ikey.user_key, saved_key_.GetUserKey()) <=
0) {
num_skipped++;
} else {
saved_key_.SetKey(
ikey.user_key,
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
saved_key_.SetUserKey(
ikey.user_key,
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
skipping = false;
num_skipped = 0;
}
@ -491,8 +493,8 @@ void DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check) {
// We're looking for the next user-key but all we see are the same
// user-key with decreasing sequence numbers. Fast forward to
// sequence number 0 and type deletion (the smallest type).
AppendInternalKey(&last_key, ParsedInternalKey(saved_key_.GetKey(), 0,
kTypeDeletion));
AppendInternalKey(&last_key, ParsedInternalKey(saved_key_.GetUserKey(),
0, kTypeDeletion));
// Don't set skipping = false because we may still see more user-keys
// equal to saved_key_.
} else {
@ -502,7 +504,7 @@ void DBIter::FindNextUserEntryInternal(bool skipping, bool prefix_check) {
// many times since our snapshot was taken, not the case when a lot of
// different keys were inserted after our snapshot was taken.
AppendInternalKey(&last_key,
ParsedInternalKey(saved_key_.GetKey(), sequence_,
ParsedInternalKey(saved_key_.GetUserKey(), sequence_,
kValueTypeForSeek));
}
iter_->Seek(last_key);
@ -543,7 +545,7 @@ void DBIter::MergeValuesNewToOld() {
continue;
}
if (!user_comparator_->Equal(ikey.user_key, saved_key_.GetKey())) {
if (!user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
// hit the next user key, stop right here
break;
} else if (kTypeDeletion == ikey.type || kTypeSingleDeletion == ikey.type ||
@ -583,9 +585,10 @@ void DBIter::MergeValuesNewToOld() {
// a deletion marker.
// feed null as the existing value to the merge operator, such that
// client can differentiate this scenario and do things accordingly.
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetKey(), nullptr,
merge_context_.GetOperands(), &saved_value_,
logger_, statistics_, env_, &pinned_value_);
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
nullptr, merge_context_.GetOperands(),
&saved_value_, logger_, statistics_, env_,
&pinned_value_);
if (!s.ok()) {
status_ = s;
}
@ -612,8 +615,8 @@ void DBIter::ReverseToForward() {
if (prefix_extractor_ != nullptr && !total_order_seek_) {
IterKey last_key;
last_key.SetInternalKey(ParsedInternalKey(
saved_key_.GetKey(), kMaxSequenceNumber, kValueTypeForSeek));
iter_->Seek(last_key.GetKey());
saved_key_.GetUserKey(), kMaxSequenceNumber, kValueTypeForSeek));
iter_->Seek(last_key.GetInternalKey());
}
FindNextUserKey();
direction_ = kForward;
@ -626,9 +629,9 @@ void DBIter::ReverseToForward() {
void DBIter::ReverseToBackward() {
if (prefix_extractor_ != nullptr && !total_order_seek_) {
IterKey last_key;
last_key.SetInternalKey(
ParsedInternalKey(saved_key_.GetKey(), 0, kValueTypeForSeekForPrev));
iter_->SeekForPrev(last_key.GetKey());
last_key.SetInternalKey(ParsedInternalKey(saved_key_.GetUserKey(), 0,
kValueTypeForSeekForPrev));
iter_->SeekForPrev(last_key.GetInternalKey());
}
if (current_entry_is_merged_) {
// Not placed in the same key. Need to call Prev() until finding the
@ -640,7 +643,8 @@ void DBIter::ReverseToBackward() {
ParsedInternalKey ikey;
FindParseableKey(&ikey, kReverse);
while (iter_->Valid() &&
user_comparator_->Compare(ikey.user_key, saved_key_.GetKey()) > 0) {
user_comparator_->Compare(ikey.user_key, saved_key_.GetUserKey()) >
0) {
if (ikey.sequence > sequence_) {
PERF_COUNTER_ADD(internal_recent_skipped_count, 1);
} else {
@ -654,7 +658,8 @@ void DBIter::ReverseToBackward() {
if (iter_->Valid()) {
ParsedInternalKey ikey;
assert(ParseKey(&ikey));
assert(user_comparator_->Compare(ikey.user_key, saved_key_.GetKey()) <= 0);
assert(user_comparator_->Compare(ikey.user_key, saved_key_.GetUserKey()) <=
0);
}
#endif
@ -671,8 +676,9 @@ void DBIter::PrevInternal() {
ParsedInternalKey ikey;
while (iter_->Valid()) {
saved_key_.SetKey(ExtractUserKey(iter_->key()),
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
saved_key_.SetUserKey(
ExtractUserKey(iter_->key()),
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
if (FindValueForCurrentKey()) {
valid_ = true;
@ -680,11 +686,11 @@ void DBIter::PrevInternal() {
return;
}
FindParseableKey(&ikey, kReverse);
if (user_comparator_->Equal(ikey.user_key, saved_key_.GetKey())) {
if (user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
FindPrevUserKey();
}
if (valid_ && prefix_extractor_ && prefix_same_as_start_ &&
prefix_extractor_->Transform(saved_key_.GetKey())
prefix_extractor_->Transform(saved_key_.GetUserKey())
.compare(prefix_start_key_) != 0) {
valid_ = false;
}
@ -699,7 +705,7 @@ void DBIter::PrevInternal() {
break;
}
FindParseableKey(&ikey, kReverse);
if (user_comparator_->Equal(ikey.user_key, saved_key_.GetKey())) {
if (user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
FindPrevUserKey();
}
}
@ -729,7 +735,7 @@ bool DBIter::FindValueForCurrentKey() {
TempPinData();
size_t num_skipped = 0;
while (iter_->Valid() && ikey.sequence <= sequence_ &&
user_comparator_->Equal(ikey.user_key, saved_key_.GetKey())) {
user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
if (TooManyInternalKeysSkipped()) {
return false;
}
@ -780,7 +786,7 @@ bool DBIter::FindValueForCurrentKey() {
}
PERF_COUNTER_ADD(internal_key_skipped_count, 1);
assert(user_comparator_->Equal(ikey.user_key, saved_key_.GetKey()));
assert(user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey()));
iter_->Prev();
++num_skipped;
FindParseableKey(&ikey, kReverse);
@ -798,14 +804,14 @@ bool DBIter::FindValueForCurrentKey() {
if (last_not_merge_type == kTypeDeletion ||
last_not_merge_type == kTypeSingleDeletion ||
last_not_merge_type == kTypeRangeDeletion) {
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetKey(),
nullptr, merge_context_.GetOperands(),
&saved_value_, logger_, statistics_,
env_, &pinned_value_);
s = MergeHelper::TimedFullMerge(
merge_operator_, saved_key_.GetUserKey(), nullptr,
merge_context_.GetOperands(), &saved_value_, logger_, statistics_,
env_, &pinned_value_);
} else {
assert(last_not_merge_type == kTypeValue);
s = MergeHelper::TimedFullMerge(
merge_operator_, saved_key_.GetKey(), &pinned_value_,
merge_operator_, saved_key_.GetUserKey(), &pinned_value_,
merge_context_.GetOperands(), &saved_value_, logger_, statistics_,
env_, &pinned_value_);
}
@ -831,8 +837,8 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
// FindValueForCurrentKeyUsingSeek()
assert(pinned_iters_mgr_.PinningEnabled());
std::string last_key;
AppendInternalKey(&last_key, ParsedInternalKey(saved_key_.GetKey(), sequence_,
kValueTypeForSeek));
AppendInternalKey(&last_key, ParsedInternalKey(saved_key_.GetUserKey(),
sequence_, kValueTypeForSeek));
iter_->Seek(last_key);
RecordTick(statistics_, NUMBER_OF_RESEEKS_IN_ITERATION);
@ -859,7 +865,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
merge_context_.Clear();
while (
iter_->Valid() &&
user_comparator_->Equal(ikey.user_key, saved_key_.GetKey()) &&
user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey()) &&
ikey.type == kTypeMerge &&
!range_del_agg_.ShouldDelete(
ikey, RangeDelAggregator::RangePositioningMode::kBackwardTraversal)) {
@ -872,17 +878,17 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
Status s;
if (!iter_->Valid() ||
!user_comparator_->Equal(ikey.user_key, saved_key_.GetKey()) ||
!user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey()) ||
ikey.type == kTypeDeletion || ikey.type == kTypeSingleDeletion ||
range_del_agg_.ShouldDelete(
ikey, RangeDelAggregator::RangePositioningMode::kBackwardTraversal)) {
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetKey(),
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
nullptr, merge_context_.GetOperands(),
&saved_value_, logger_, statistics_, env_,
&pinned_value_);
// Make iter_ valid and point to saved_key_
if (!iter_->Valid() ||
!user_comparator_->Equal(ikey.user_key, saved_key_.GetKey())) {
!user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
iter_->Seek(last_key);
RecordTick(statistics_, NUMBER_OF_RESEEKS_IN_ITERATION);
}
@ -894,9 +900,10 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
}
const Slice& val = iter_->value();
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetKey(), &val,
merge_context_.GetOperands(), &saved_value_,
logger_, statistics_, env_, &pinned_value_);
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
&val, merge_context_.GetOperands(),
&saved_value_, logger_, statistics_, env_,
&pinned_value_);
valid_ = true;
if (!s.ok()) {
status_ = s;
@ -915,7 +922,7 @@ void DBIter::FindNextUserKey() {
ParsedInternalKey ikey;
FindParseableKey(&ikey, kForward);
while (iter_->Valid() &&
!user_comparator_->Equal(ikey.user_key, saved_key_.GetKey())) {
!user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
iter_->Next();
FindParseableKey(&ikey, kForward);
}
@ -930,9 +937,10 @@ void DBIter::FindPrevUserKey() {
ParsedInternalKey ikey;
FindParseableKey(&ikey, kReverse);
int cmp;
while (iter_->Valid() && ((cmp = user_comparator_->Compare(
ikey.user_key, saved_key_.GetKey())) == 0 ||
(cmp > 0 && ikey.sequence > sequence_))) {
while (iter_->Valid() &&
((cmp = user_comparator_->Compare(ikey.user_key,
saved_key_.GetUserKey())) == 0 ||
(cmp > 0 && ikey.sequence > sequence_))) {
if (TooManyInternalKeysSkipped()) {
return;
}
@ -942,8 +950,8 @@ void DBIter::FindPrevUserKey() {
num_skipped = 0;
IterKey last_key;
last_key.SetInternalKey(ParsedInternalKey(
saved_key_.GetKey(), kMaxSequenceNumber, kValueTypeForSeek));
iter_->Seek(last_key.GetKey());
saved_key_.GetUserKey(), kMaxSequenceNumber, kValueTypeForSeek));
iter_->Seek(last_key.GetInternalKey());
RecordTick(statistics_, NUMBER_OF_RESEEKS_IN_ITERATION);
} else {
++num_skipped;
@ -991,7 +999,7 @@ void DBIter::Seek(const Slice& target) {
{
PERF_TIMER_GUARD(seek_internal_seek_time);
iter_->Seek(saved_key_.GetKey());
iter_->Seek(saved_key_.GetInternalKey());
range_del_agg_.InvalidateTombstoneMapPositions();
}
RecordTick(statistics_, NUMBER_DB_SEEK);
@ -1001,9 +1009,6 @@ void DBIter::Seek(const Slice& target) {
}
direction_ = kForward;
ClearSavedValue();
// convert the InternalKey to UserKey in saved_key_ before
// passed to FindNextUserEntry
saved_key_.Reserve(saved_key_.Size() - 8);
FindNextUserEntry(false /* not skipping */, prefix_same_as_start_);
if (!valid_) {
prefix_start_key_.clear();
@ -1019,8 +1024,8 @@ void DBIter::Seek(const Slice& target) {
}
if (valid_ && prefix_extractor_ && prefix_same_as_start_) {
prefix_start_buf_.SetKey(prefix_start_key_);
prefix_start_key_ = prefix_start_buf_.GetKey();
prefix_start_buf_.SetUserKey(prefix_start_key_);
prefix_start_key_ = prefix_start_buf_.GetUserKey();
}
}
@ -1035,7 +1040,7 @@ void DBIter::SeekForPrev(const Slice& target) {
{
PERF_TIMER_GUARD(seek_internal_seek_time);
iter_->SeekForPrev(saved_key_.GetKey());
iter_->SeekForPrev(saved_key_.GetInternalKey());
range_del_agg_.InvalidateTombstoneMapPositions();
}
@ -1060,8 +1065,8 @@ void DBIter::SeekForPrev(const Slice& target) {
valid_ = false;
}
if (valid_ && prefix_extractor_ && prefix_same_as_start_) {
prefix_start_buf_.SetKey(prefix_start_key_);
prefix_start_key_ = prefix_start_buf_.GetKey();
prefix_start_buf_.SetUserKey(prefix_start_key_);
prefix_start_key_ = prefix_start_buf_.GetUserKey();
}
}
@ -1084,8 +1089,9 @@ void DBIter::SeekToFirst() {
RecordTick(statistics_, NUMBER_DB_SEEK);
if (iter_->Valid()) {
saved_key_.SetKey(ExtractUserKey(iter_->key()),
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
saved_key_.SetUserKey(
ExtractUserKey(iter_->key()),
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
FindNextUserEntry(false /* not skipping */, false /* no prefix check */);
if (statistics_ != nullptr) {
if (valid_) {
@ -1097,8 +1103,9 @@ void DBIter::SeekToFirst() {
valid_ = false;
}
if (valid_ && prefix_extractor_ && prefix_same_as_start_) {
prefix_start_buf_.SetKey(prefix_extractor_->Transform(saved_key_.GetKey()));
prefix_start_key_ = prefix_start_buf_.GetKey();
prefix_start_buf_.SetUserKey(
prefix_extractor_->Transform(saved_key_.GetUserKey()));
prefix_start_key_ = prefix_start_buf_.GetUserKey();
}
}
@ -1140,8 +1147,9 @@ void DBIter::SeekToLast() {
}
}
if (valid_ && prefix_extractor_ && prefix_same_as_start_) {
prefix_start_buf_.SetKey(prefix_extractor_->Transform(saved_key_.GetKey()));
prefix_start_key_ = prefix_start_buf_.GetKey();
prefix_start_buf_.SetUserKey(
prefix_extractor_->Transform(saved_key_.GetUserKey()));
prefix_start_key_ = prefix_start_buf_.GetUserKey();
}
}

View file

@ -303,15 +303,26 @@ inline LookupKey::~LookupKey() {
class IterKey {
public:
IterKey()
: buf_(space_), buf_size_(sizeof(space_)), key_(buf_), key_size_(0) {}
: buf_(space_),
buf_size_(sizeof(space_)),
key_(buf_),
key_size_(0),
is_user_key_(true) {}
~IterKey() { ResetBuffer(); }
Slice GetKey() const { return Slice(key_, key_size_); }
Slice GetInternalKey() const {
assert(!IsUserKey());
return Slice(key_, key_size_);
}
Slice GetUserKey() const {
assert(key_size_ >= 8);
return Slice(key_, key_size_ - 8);
if (IsUserKey()) {
return Slice(key_, key_size_);
} else {
assert(key_size_ >= 8);
return Slice(key_, key_size_ - 8);
}
}
size_t Size() const { return key_size_; }
@ -349,27 +360,22 @@ class IterKey {
key_size_ = total_size;
}
Slice SetKey(const Slice& key, bool copy = true) {
size_t size = key.size();
if (copy) {
// Copy key to buf_
EnlargeBufferIfNeeded(size);
memcpy(buf_, key.data(), size);
key_ = buf_;
} else {
// Update key_ to point to external memory
key_ = key.data();
}
key_size_ = size;
return Slice(key_, key_size_);
Slice SetUserKey(const Slice& key, bool copy = true) {
is_user_key_ = true;
return SetKeyImpl(key, copy);
}
Slice SetInternalKey(const Slice& key, bool copy = true) {
is_user_key_ = false;
return SetKeyImpl(key, copy);
}
// Copies the content of key, updates the reference to the user key in ikey
// and returns a Slice referencing the new copy.
Slice SetKey(const Slice& key, ParsedInternalKey* ikey) {
Slice SetInternalKey(const Slice& key, ParsedInternalKey* ikey) {
size_t key_n = key.size();
assert(key_n >= 8);
SetKey(key);
SetInternalKey(key);
ikey->user_key = Slice(key_, key_n - 8);
return Slice(key_, key_n);
}
@ -408,6 +414,7 @@ class IterKey {
key_ = buf_;
key_size_ = psize + usize + sizeof(uint64_t);
is_user_key_ = false;
}
void SetInternalKey(const Slice& user_key, SequenceNumber s,
@ -436,14 +443,33 @@ class IterKey {
char* ptr = EncodeVarint32(buf_, static_cast<uint32_t>(size));
memcpy(ptr, key.data(), size);
key_ = buf_;
is_user_key_ = true;
}
bool IsUserKey() const { return is_user_key_; }
private:
char* buf_;
size_t buf_size_;
const char* key_;
size_t key_size_;
char space_[32]; // Avoid allocation for short keys
bool is_user_key_;
Slice SetKeyImpl(const Slice& key, bool copy) {
size_t size = key.size();
if (copy) {
// Copy key to buf_
EnlargeBufferIfNeeded(size);
memcpy(buf_, key.data(), size);
key_ = buf_;
} else {
// Update key_ to point to external memory
key_ = key.data();
}
key_size_ = size;
return Slice(key_, key_size_);
}
void ResetBuffer() {
if (buf_ != space_) {

View file

@ -139,38 +139,38 @@ TEST_F(FormatTest, IterKeyOperation) {
const char p[] = "abcdefghijklmnopqrstuvwxyz";
const char q[] = "0123456789";
ASSERT_EQ(std::string(k.GetKey().data(), k.GetKey().size()),
ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
std::string(""));
k.TrimAppend(0, p, 3);
ASSERT_EQ(std::string(k.GetKey().data(), k.GetKey().size()),
ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
std::string("abc"));
k.TrimAppend(1, p, 3);
ASSERT_EQ(std::string(k.GetKey().data(), k.GetKey().size()),
ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
std::string("aabc"));
k.TrimAppend(0, p, 26);
ASSERT_EQ(std::string(k.GetKey().data(), k.GetKey().size()),
ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
std::string("abcdefghijklmnopqrstuvwxyz"));
k.TrimAppend(26, q, 10);
ASSERT_EQ(std::string(k.GetKey().data(), k.GetKey().size()),
ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
std::string("abcdefghijklmnopqrstuvwxyz0123456789"));
k.TrimAppend(36, q, 1);
ASSERT_EQ(std::string(k.GetKey().data(), k.GetKey().size()),
ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
std::string("abcdefghijklmnopqrstuvwxyz01234567890"));
k.TrimAppend(26, q, 1);
ASSERT_EQ(std::string(k.GetKey().data(), k.GetKey().size()),
ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
std::string("abcdefghijklmnopqrstuvwxyz0"));
// Size going up, memory allocation is triggered
k.TrimAppend(27, p, 26);
ASSERT_EQ(std::string(k.GetKey().data(), k.GetKey().size()),
ASSERT_EQ(std::string(k.GetUserKey().data(), k.GetUserKey().size()),
std::string("abcdefghijklmnopqrstuvwxyz0"
"abcdefghijklmnopqrstuvwxyz"));
"abcdefghijklmnopqrstuvwxyz"));
}
TEST_F(FormatTest, UpdateInternalKey) {

View file

@ -310,7 +310,7 @@ void ForwardIterator::SeekInternal(const Slice& internal_key,
seek_to_first ||
// prev_key_ > internal_key
cfd_->internal_comparator().InternalKeyComparator::Compare(
prev_key_.GetKey(), internal_key) > 0)) {
prev_key_.GetInternalKey(), internal_key) > 0)) {
// Some iterators are trimmed. Need to rebuild.
RebuildIterators(true);
// Already seeked mutable iter, so seek again
@ -410,7 +410,7 @@ void ForwardIterator::SeekInternal(const Slice& internal_key,
if (seek_to_first) {
is_prev_set_ = false;
} else {
prev_key_.SetKey(internal_key);
prev_key_.SetInternalKey(internal_key);
is_prev_set_ = true;
is_prev_inclusive_ = true;
}
@ -449,15 +449,15 @@ void ForwardIterator::Next() {
if (is_prev_set_ && prefix_extractor_) {
// advance prev_key_ to current_ only if they share the same prefix
update_prev_key =
prefix_extractor_->Transform(prev_key_.GetKey()).compare(
prefix_extractor_->Transform(current_->key())) == 0;
prefix_extractor_->Transform(prev_key_.GetUserKey())
.compare(prefix_extractor_->Transform(current_->key())) == 0;
} else {
update_prev_key = true;
}
if (update_prev_key) {
prev_key_.SetKey(current_->key());
prev_key_.SetInternalKey(current_->key());
is_prev_set_ = true;
is_prev_inclusive_ = false;
}
@ -476,7 +476,7 @@ void ForwardIterator::Next() {
current_ = nullptr;
}
if (update_prev_key) {
mutable_iter_->Seek(prev_key_.GetKey());
mutable_iter_->Seek(prev_key_.GetInternalKey());
}
}
}
@ -776,7 +776,7 @@ bool ForwardIterator::NeedToSeekImmutable(const Slice& target) {
if (!valid_ || !current_ || !is_prev_set_ || !immutable_status_.ok()) {
return true;
}
Slice prev_key = prev_key_.GetKey();
Slice prev_key = prev_key_.GetInternalKey();
if (prefix_extractor_ && prefix_extractor_->Transform(target).compare(
prefix_extractor_->Transform(prev_key)) != 0) {
return true;

View file

@ -196,12 +196,12 @@ void ManagedIterator::Next() {
Slice ManagedIterator::key() const {
assert(valid_);
return cached_key_.GetKey();
return cached_key_.GetUserKey();
}
Slice ManagedIterator::value() const {
assert(valid_);
return cached_value_.GetKey();
return cached_value_.GetUserKey();
}
Status ManagedIterator::status() const { return status_; }
@ -221,8 +221,8 @@ void ManagedIterator::UpdateCurrent() {
}
status_ = Status::OK();
cached_key_.SetKey(mutable_iter_->key());
cached_value_.SetKey(mutable_iter_->value());
cached_key_.SetUserKey(mutable_iter_->key());
cached_value_.SetUserKey(mutable_iter_->value());
}
void ManagedIterator::ReleaseIter(bool only_old) {

View file

@ -286,7 +286,7 @@ Status TableCache::Get(const ReadOptions& options,
user_key.size());
if (auto row_handle =
ioptions_.row_cache->Lookup(row_cache_key.GetKey())) {
ioptions_.row_cache->Lookup(row_cache_key.GetUserKey())) {
auto found_row_cache_entry = static_cast<const std::string*>(
ioptions_.row_cache->Value(row_handle));
replayGetContextLog(*found_row_cache_entry, user_key, get_context);
@ -343,7 +343,7 @@ Status TableCache::Get(const ReadOptions& options,
size_t charge =
row_cache_key.Size() + row_cache_entry->size() + sizeof(std::string);
void* row_ptr = new std::string(std::move(*row_cache_entry));
ioptions_.row_cache->Insert(row_cache_key.GetKey(), row_ptr, charge,
ioptions_.row_cache->Insert(row_cache_key.GetUserKey(), row_ptr, charge,
&DeleteEntry<std::string>);
}
#endif // ROCKSDB_LITE

View file

@ -433,7 +433,7 @@ class HashLinkListRep : public MemTableRep {
} else {
IterKey encoded_key;
encoded_key.EncodeLengthPrefixedKey(k);
skip_list_iter_->Seek(encoded_key.GetKey().data());
skip_list_iter_->Seek(encoded_key.GetUserKey().data());
}
} else {
// The bucket is organized as a linked list

View file

@ -87,7 +87,7 @@ void BlockIter::Prev() {
const Slice current_key(key_ptr, current_prev_entry.key_size);
current_ = current_prev_entry.offset;
key_.SetKey(current_key, false /* copy */);
key_.SetInternalKey(current_key, false /* copy */);
value_ = current_prev_entry.value;
return;
@ -155,7 +155,7 @@ void BlockIter::Seek(const Slice& target) {
// Linear search (within restart block) for first key >= target
while (true) {
if (!ParseNextKey() || Compare(key_.GetKey(), target) >= 0) {
if (!ParseNextKey() || Compare(key_.GetInternalKey(), target) >= 0) {
return;
}
}
@ -176,12 +176,12 @@ void BlockIter::SeekForPrev(const Slice& target) {
SeekToRestartPoint(index);
// Linear search (within restart block) for first key >= target
while (ParseNextKey() && Compare(key_.GetKey(), target) < 0) {
while (ParseNextKey() && Compare(key_.GetInternalKey(), target) < 0) {
}
if (!Valid()) {
SeekToLast();
} else {
while (Valid() && Compare(key_.GetKey(), target) > 0) {
while (Valid() && Compare(key_.GetInternalKey(), target) > 0) {
Prev();
}
}
@ -234,7 +234,7 @@ bool BlockIter::ParseNextKey() {
if (shared == 0) {
// If this key dont share any bytes with prev key then we dont need
// to decode it and can use it's address in the block directly.
key_.SetKey(Slice(p, non_shared), false /* copy */);
key_.SetInternalKey(Slice(p, non_shared), false /* copy */);
key_pinned_ = true;
} else {
// This key share `shared` bytes with prev key, we need to decode it
@ -246,8 +246,8 @@ bool BlockIter::ParseNextKey() {
// If we are reading a file with a global sequence number we should
// expect that all encoded sequence numbers are zeros and all value
// types are kTypeValue
assert(GetInternalKeySeqno(key_.GetKey()) == 0);
assert(ExtractValueType(key_.GetKey()) == ValueType::kTypeValue);
assert(GetInternalKeySeqno(key_.GetInternalKey()) == 0);
assert(ExtractValueType(key_.GetInternalKey()) == ValueType::kTypeValue);
if (key_pinned_) {
// TODO(tec): Investigate updating the seqno in the loaded block

View file

@ -264,7 +264,7 @@ class BlockIter : public InternalIterator {
virtual Status status() const override { return status_; }
virtual Slice key() const override {
assert(Valid());
return key_.GetKey();
return key_.GetInternalKey();
}
virtual Slice value() const override {
assert(Valid());

View file

@ -124,7 +124,7 @@ class CuckooBuilderTest : public testing::Test {
std::string GetInternalKey(Slice user_key, bool zero_seqno) {
IterKey ikey;
ikey.SetInternalKey(user_key, zero_seqno ? 0 : 1000, kTypeValue);
return ikey.GetKey().ToString();
return ikey.GetInternalKey().ToString();
}
uint64_t NextPowOf2(uint64_t num) {

View file

@ -322,7 +322,7 @@ void CuckooTableIterator::PrepareKVAtCurrIdx() {
curr_key_.SetInternalKey(Slice(offset, reader_->user_key_length_),
0, kTypeValue);
} else {
curr_key_.SetKey(Slice(offset, reader_->key_length_));
curr_key_.SetInternalKey(Slice(offset, reader_->key_length_));
}
curr_value_ = Slice(offset + reader_->key_length_, reader_->value_length_);
}
@ -352,7 +352,7 @@ void CuckooTableIterator::Prev() {
Slice CuckooTableIterator::key() const {
assert(Valid());
return curr_key_.GetKey();
return curr_key_.GetInternalKey();
}
Slice CuckooTableIterator::value() const {

View file

@ -376,7 +376,7 @@ void GetKeys(uint64_t num, std::vector<std::string>* keys) {
keys->clear();
IterKey k;
k.SetInternalKey("", 0, kTypeValue);
std::string internal_key_suffix = k.GetKey().ToString();
std::string internal_key_suffix = k.GetInternalKey().ToString();
ASSERT_EQ(static_cast<size_t>(8), internal_key_suffix.size());
for (uint64_t key_idx = 0; key_idx < num; ++key_idx) {
uint64_t value = 2 * key_idx;

View file

@ -112,10 +112,10 @@ Status PlainTableKeyEncoder::AppendKey(const Slice& key,
Slice prefix =
prefix_extractor_->Transform(Slice(key.data(), user_key_size));
if (key_count_for_prefix_ == 0 || prefix != pre_prefix_.GetKey() ||
if (key_count_for_prefix_ == 0 || prefix != pre_prefix_.GetUserKey() ||
key_count_for_prefix_ % index_sparseness_ == 0) {
key_count_for_prefix_ = 1;
pre_prefix_.SetKey(prefix);
pre_prefix_.SetUserKey(prefix);
size_bytes_pos += EncodeSize(kFullKey, user_key_size, size_bytes);
Status s = file->Append(Slice(size_bytes, size_bytes_pos));
if (!s.ok()) {
@ -128,10 +128,11 @@ Status PlainTableKeyEncoder::AppendKey(const Slice& key,
// For second key within a prefix, need to encode prefix length
size_bytes_pos +=
EncodeSize(kPrefixFromPreviousKey,
static_cast<uint32_t>(pre_prefix_.GetKey().size()),
static_cast<uint32_t>(pre_prefix_.GetUserKey().size()),
size_bytes + size_bytes_pos);
}
uint32_t prefix_len = static_cast<uint32_t>(pre_prefix_.GetKey().size());
uint32_t prefix_len =
static_cast<uint32_t>(pre_prefix_.GetUserKey().size());
size_bytes_pos += EncodeSize(kKeySuffix, user_key_size - prefix_len,
size_bytes + size_bytes_pos);
Status s = file->Append(Slice(size_bytes, size_bytes_pos));
@ -315,9 +316,10 @@ Status PlainTableKeyDecoder::NextPlainEncodingKey(uint32_t start_offset,
}
if (!file_reader_.file_info()->is_mmap_mode) {
cur_key_.SetInternalKey(*parsed_key);
parsed_key->user_key = Slice(cur_key_.GetKey().data(), user_key_size);
parsed_key->user_key =
Slice(cur_key_.GetInternalKey().data(), user_key_size);
if (internal_key != nullptr) {
*internal_key = cur_key_.GetKey();
*internal_key = cur_key_.GetInternalKey();
}
} else if (internal_key != nullptr) {
if (decoded_internal_key_valid) {
@ -325,7 +327,7 @@ Status PlainTableKeyDecoder::NextPlainEncodingKey(uint32_t start_offset,
} else {
// Need to copy out the internal key
cur_key_.SetInternalKey(*parsed_key);
*internal_key = cur_key_.GetKey();
*internal_key = cur_key_.GetInternalKey();
}
}
return Status::OK();
@ -369,12 +371,13 @@ Status PlainTableKeyDecoder::NextPrefixEncodingKey(
// users, because after reading value for the key, the key might
// be invalid.
cur_key_.SetInternalKey(*parsed_key);
saved_user_key_ = cur_key_.GetKey();
saved_user_key_ = cur_key_.GetUserKey();
if (!file_reader_.file_info()->is_mmap_mode) {
parsed_key->user_key = Slice(cur_key_.GetKey().data(), size);
parsed_key->user_key =
Slice(cur_key_.GetInternalKey().data(), size);
}
if (internal_key != nullptr) {
*internal_key = cur_key_.GetKey();
*internal_key = cur_key_.GetInternalKey();
}
} else {
if (internal_key != nullptr) {
@ -421,16 +424,16 @@ Status PlainTableKeyDecoder::NextPrefixEncodingKey(
cur_key_.Reserve(prefix_len_ + size);
cur_key_.SetInternalKey(tmp, *parsed_key);
parsed_key->user_key =
Slice(cur_key_.GetKey().data(), prefix_len_ + size);
saved_user_key_ = cur_key_.GetKey();
Slice(cur_key_.GetInternalKey().data(), prefix_len_ + size);
saved_user_key_ = cur_key_.GetUserKey();
} else {
cur_key_.Reserve(prefix_len_ + size);
cur_key_.SetInternalKey(Slice(saved_user_key_.data(), prefix_len_),
*parsed_key);
}
parsed_key->user_key = ExtractUserKey(cur_key_.GetKey());
parsed_key->user_key = cur_key_.GetUserKey();
if (internal_key != nullptr) {
*internal_key = cur_key_.GetKey();
*internal_key = cur_key_.GetInternalKey();
}
break;
}