-
Notifications
You must be signed in to change notification settings - Fork 6.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add insert hints for each writebatch #5728
Changes from 5 commits
22ced1d
0edc4bf
4b0990d
a3d876a
a8bc7ae
988c49f
a23314a
e0f8420
6416eb7
284b485
a0cc31e
a8d9ea4
5c907d8
5933652
54536d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,6 +120,20 @@ class MemTableRep { | |
return true; | ||
} | ||
|
||
// Same as ::InsertWithHint, but allow concurrnet write | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to document the ownership of hint. In my understanding, the caller will own the object hint, correct? Or, if that is the case, an even better idea is to change the argument to |
||
virtual void InsertWithHintConcurrently(KeyHandle handle, void** /*hint*/) { | ||
// Ignore the hint by default. | ||
InsertConcurrently(handle); | ||
} | ||
|
||
// Same as ::InsertWithHintConcurrently | ||
// Returns false if MemTableRepFactory::CanHandleDuplicatedKey() is true and | ||
// the <key, seq> already exists. | ||
virtual bool InsertKeyWithHintConcurrently(KeyHandle handle, void** hint) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as here. |
||
InsertWithHintConcurrently(handle, hint); | ||
return true; | ||
} | ||
|
||
// Like Insert(handle), but may be called concurrent with other calls | ||
// to InsertConcurrently for other handles. | ||
// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1338,6 +1338,11 @@ struct WriteOptions { | |
// Default: false | ||
bool low_pri; | ||
|
||
// If true, this writebatch will use its own insert hints in concurrent write | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will be a better idea to improve the comments. |
||
// | ||
// Default: false | ||
bool hint_per_batch; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. which of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we by default enable it if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The two options are not compatible with each other. But I'm wondering whether There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now I only enable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After some discussion we think having an extra There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should call it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will change it to |
||
|
||
// Timestamp of write operation, e.g. Put. All timestamps of the same | ||
// database must share the same length and format. The user is also | ||
// responsible for providing a customized compare function via Comparator to | ||
|
@@ -1355,6 +1360,7 @@ struct WriteOptions { | |
ignore_missing_column_families(false), | ||
no_slowdown(false), | ||
low_pri(false), | ||
hint_per_batch(false), | ||
timestamp(nullptr) {} | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,6 +102,12 @@ class InlineSkipList { | |
// REQUIRES: no concurrent calls to any of inserts. | ||
bool InsertWithHint(const char* key, void** hint); | ||
|
||
// Like InsertConcurrently, but with a hint | ||
// | ||
// REQUIRES: nothing that compares equal to key is currently in the list. | ||
// REQUIRES: no concurrent calls that use same hint | ||
bool InsertWithHintConcurrently(const char* key, void** hint); | ||
|
||
// Like Insert, but external synchronization is not required. | ||
bool InsertConcurrently(const char* key); | ||
|
||
|
@@ -669,6 +675,24 @@ bool InlineSkipList<Comparator>::InsertWithHint(const char* key, void** hint) { | |
return Insert<false>(key, splice, true); | ||
} | ||
|
||
template <class Comparator> | ||
bool InlineSkipList<Comparator>::InsertWithHintConcurrently(const char* key, | ||
void** hint) { | ||
assert(hint != nullptr); | ||
Splice* splice = reinterpret_cast<Splice*>(*hint); | ||
if (splice == nullptr) { | ||
size_t array_size = sizeof(Node*) * (kMaxHeight_ + 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extract the logic to a |
||
char* raw = new char[sizeof(Splice) + array_size * 2]; | ||
splice = reinterpret_cast<Splice*>(raw); | ||
splice->height_ = 0; | ||
splice->prev_ = reinterpret_cast<Node**>(raw + sizeof(Splice)); | ||
splice->next_ = reinterpret_cast<Node**>(raw + sizeof(Splice) + array_size); | ||
|
||
*hint = reinterpret_cast<void*>(splice); | ||
} | ||
return Insert<true>(key, splice, true); | ||
} | ||
|
||
template <class Comparator> | ||
template <bool prefetch_before> | ||
void InlineSkipList<Comparator>::FindSpliceForLevel(const DecodedKey& key, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I'm not knowledgable enough to C++. If hint map doesn't have "mem", does the value inserted guarantees to be nullptr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the value will be value-initialized, so pointer will be initialized to nullptr.