This PR addresses issue #3865 and implements the following approach to fix it:
- adds `MergeContext::GetOperandsDirectionForward` and `MergeContext::GetOperandsDirectionBackward` to query merge operands in a specific order
- `MergeContext::GetOperands` becomes a shortcut for `MergeContext::GetOperandsDirectionForward`
- pass `MergeContext::GetOperandsDirectionBackward` to `MergeOperator::ShouldMerge` and document the order
Pull Request resolved: https://github.com/facebook/rocksdb/pull/4266
Differential Revision:
D9360750
Pulled By: sagar0
fbshipit-source-id:
20cb73ff017760b062ecdcf4382560767086e092
# Rocksdb Change Log
+
+## 5.14.3 (8/21/2018)
+### Public API Change
+* The merge operands are passed to `MergeOperator::ShouldMerge` in the reversed order relative to how they were merged (passed to FullMerge or FullMergeV2) for performance reasons
+
## 5.14.2 (7/3/2018)
### Bug Fixes
* Change default value of `bytes_max_delete_chunk` to 0 in NewSstFileManager() as it doesn't work well with checkpoints.
*(s->merge_in_progress) = true;
merge_context->PushOperand(
v, s->inplace_update_support == false /* operand_pinned */);
- if (merge_operator->ShouldMerge(merge_context->GetOperands())) {
+ if (merge_operator->ShouldMerge(merge_context->GetOperandsDirectionBackward())) {
*(s->status) = MergeHelper::TimedFullMerge(
merge_operator, s->key->user_key(), nullptr,
merge_context->GetOperands(), s->value, s->logger, s->statistics,
return (*operand_list_)[index];
}
- // Return all the operands.
+ // Same as GetOperandsDirectionForward
const std::vector<Slice>& GetOperands() {
+ return GetOperandsDirectionForward();
+ }
+
+ // Return all the operands in the order as they were merged (passed to FullMerge or FullMergeV2)
+ const std::vector<Slice>& GetOperandsDirectionForward() {
if (!operand_list_) {
return empty_operand_list;
}
return *operand_list_;
}
+ // Return all the operands in the reversed order relative to how they were merged (passed to FullMerge or FullMergeV2)
+ const std::vector<Slice>& GetOperandsDirectionBackward() {
+ if (!operand_list_) {
+ return empty_operand_list;
+ }
+
+ SetDirectionBackward();
+ return *operand_list_;
+ }
+
private:
void Initialize() {
if (!operand_list_) {
// during a point lookup, thereby helping in limiting the number of levels to
// read from.
// Doesn't help with iterators.
+ //
+ // Note: the merge operands are passed to this function in the reversed order
+ // relative to how they were merged (passed to FullMerge or FullMergeV2)
+ // for performance reasons, see also:
+ // https://github.com/facebook/rocksdb/issues/3865
virtual bool ShouldMerge(const std::vector<Slice>& /*operands*/) const {
return false;
}