Skip to content

Commit df2a8b6

Browse files
committed
Polish IterKey and use it in DBImpl::ProcessKeyValueCompaction()
Summary: 1. Polish IterKey a little bit. 2. Turn to use it in local parameter of current_user_key in DBImpl::ProcessKeyValueCompaction(). Our profile showing that DBImpl::ProcessKeyValueCompaction() has about 14% costs in std::string (the base including reading and writing data but excluding compaction filtering), which is higher than it should be. There are two std::string used in DBImpl::ProcessKeyValueCompaction(), compaction_filter_value and current_user_key and it's hard to distinguish the two. Test Plan: make all check Reviewers: haobo, ljin Reviewed By: haobo CC: igor, yhchiang, dhruba, leveldb Differential Revision: https://reviews.facebook.net/D17613
1 parent dc55903 commit df2a8b6

File tree

2 files changed

+39
-45
lines changed

2 files changed

+39
-45
lines changed

db/db_impl.cc

+9-11
Original file line numberDiff line numberDiff line change
@@ -2523,9 +2523,9 @@ Status DBImpl::ProcessKeyValueCompaction(
25232523
Status status;
25242524
std::string compaction_filter_value;
25252525
ParsedInternalKey ikey;
2526-
std::string current_user_key;
2526+
IterKey current_user_key;
25272527
bool has_current_user_key = false;
2528-
std::vector<char> delete_key; // for compaction filter
2528+
IterKey delete_key;
25292529
SequenceNumber last_sequence_for_key __attribute__((unused)) =
25302530
kMaxSequenceNumber;
25312531
SequenceNumber visible_in_snapshot = kMaxSequenceNumber;
@@ -2589,16 +2589,16 @@ Status DBImpl::ProcessKeyValueCompaction(
25892589
// Do not hide error keys
25902590
// TODO: error key stays in db forever? Figure out the intention/rationale
25912591
// v10 error v8 : we cannot hide v8 even though it's pretty obvious.
2592-
current_user_key.clear();
2592+
current_user_key.Clear();
25932593
has_current_user_key = false;
25942594
last_sequence_for_key = kMaxSequenceNumber;
25952595
visible_in_snapshot = kMaxSequenceNumber;
25962596
} else {
25972597
if (!has_current_user_key ||
25982598
cfd->user_comparator()->Compare(ikey.user_key,
2599-
Slice(current_user_key)) != 0) {
2599+
current_user_key.GetKey()) != 0) {
26002600
// First occurrence of this user key
2601-
current_user_key.assign(ikey.user_key.data(), ikey.user_key.size());
2601+
current_user_key.SetUserKey(ikey.user_key);
26022602
has_current_user_key = true;
26032603
last_sequence_for_key = kMaxSequenceNumber;
26042604
visible_in_snapshot = kMaxSequenceNumber;
@@ -2617,13 +2617,11 @@ Status DBImpl::ProcessKeyValueCompaction(
26172617
compact->compaction->level(), ikey.user_key, value,
26182618
&compaction_filter_value, &value_changed);
26192619
if (to_delete) {
2620-
// make a copy of the original key
2621-
delete_key.assign(key.data(), key.data() + key.size());
2622-
// convert it to a delete
2623-
UpdateInternalKey(&delete_key[0], delete_key.size(),
2624-
ikey.sequence, kTypeDeletion);
2620+
// make a copy of the original key and convert it to a delete
2621+
delete_key.SetInternalKey(ExtractUserKey(key), ikey.sequence,
2622+
kTypeDeletion);
26252623
// anchor the key again
2626-
key = Slice(&delete_key[0], delete_key.size());
2624+
key = delete_key.GetKey();
26272625
// needed because ikey is backed by key
26282626
ParseInternalKey(key, &ikey);
26292627
// no value associated with delete

db/dbformat.h

+30-34
Original file line numberDiff line numberDiff line change
@@ -242,47 +242,17 @@ class IterKey {
242242
public:
243243
IterKey() : key_(space_), buf_size_(sizeof(space_)), key_size_(0) {}
244244

245-
~IterKey() { Clear(); }
245+
~IterKey() { ResetBuffer(); }
246246

247-
Slice GetKey() const {
248-
if (key_ != nullptr) {
249-
return Slice(key_, key_size_);
250-
} else {
251-
return Slice();
252-
}
253-
}
254-
255-
bool Valid() const { return key_ != nullptr; }
256-
257-
void Clear() {
258-
if (key_ != nullptr && key_ != space_) {
259-
delete[] key_;
260-
}
261-
key_ = space_;
262-
buf_size_ = sizeof(buf_size_);
263-
}
247+
Slice GetKey() const { return Slice(key_, key_size_); }
264248

265-
// Enlarge the buffer size if needed based on key_size.
266-
// By default, static allocated buffer is used. Once there is a key
267-
// larger than the static allocated buffer, another buffer is dynamically
268-
// allocated, until a larger key buffer is requested. In that case, we
269-
// reallocate buffer and delete the old one.
270-
void EnlargeBufferIfNeeded(size_t key_size) {
271-
// If size is smaller than buffer size, continue using current buffer,
272-
// or the static allocated one, as default
273-
if (key_size > buf_size_) {
274-
// Need to enlarge the buffer.
275-
Clear();
276-
key_ = new char[key_size];
277-
buf_size_ = key_size;
278-
}
279-
key_size_ = key_size;
280-
}
249+
void Clear() { key_size_ = 0; }
281250

282251
void SetUserKey(const Slice& user_key) {
283252
size_t size = user_key.size();
284253
EnlargeBufferIfNeeded(size);
285254
memcpy(key_, user_key.data(), size);
255+
key_size_ = size;
286256
}
287257

288258
void SetInternalKey(const Slice& user_key, SequenceNumber s,
@@ -291,6 +261,7 @@ class IterKey {
291261
EnlargeBufferIfNeeded(usize + sizeof(uint64_t));
292262
memcpy(key_, user_key.data(), usize);
293263
EncodeFixed64(key_ + usize, PackSequenceAndType(s, value_type));
264+
key_size_ = usize + sizeof(uint64_t);
294265
}
295266

296267
void SetInternalKey(const ParsedInternalKey& parsed_key) {
@@ -303,6 +274,31 @@ class IterKey {
303274
size_t key_size_;
304275
char space_[32]; // Avoid allocation for short keys
305276

277+
void ResetBuffer() {
278+
if (key_ != nullptr && key_ != space_) {
279+
delete[] key_;
280+
}
281+
key_ = space_;
282+
buf_size_ = sizeof(buf_size_);
283+
key_size_ = 0;
284+
}
285+
286+
// Enlarge the buffer size if needed based on key_size.
287+
// By default, static allocated buffer is used. Once there is a key
288+
// larger than the static allocated buffer, another buffer is dynamically
289+
// allocated, until a larger key buffer is requested. In that case, we
290+
// reallocate buffer and delete the old one.
291+
void EnlargeBufferIfNeeded(size_t key_size) {
292+
// If size is smaller than buffer size, continue using current buffer,
293+
// or the static allocated one, as default
294+
if (key_size > buf_size_) {
295+
// Need to enlarge the buffer.
296+
ResetBuffer();
297+
key_ = new char[key_size];
298+
buf_size_ = key_size;
299+
}
300+
}
301+
306302
// No copying allowed
307303
IterKey(const IterKey&) = delete;
308304
void operator=(const IterKey&) = delete;

0 commit comments

Comments
 (0)