Summary: Introduce MaxOperator a simple merge operator that return the max of all operands. This merge operand help me in benchmarking Test Plan: Add new unitttests Reviewers: sdong, andrewkr, yhchiang Reviewed By: yhchiang Subscribers: andrewkr, dhruba Differential Revision: https://reviews.facebook.net/D57873main
parent
f6e404c20a
commit
1f2dca0eaa
@ -0,0 +1,77 @@ |
|||||||
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include "rocksdb/merge_operator.h" |
||||||
|
#include "rocksdb/slice.h" |
||||||
|
#include "utilities/merge_operators.h" |
||||||
|
|
||||||
|
using rocksdb::Slice; |
||||||
|
using rocksdb::Logger; |
||||||
|
using rocksdb::MergeOperator; |
||||||
|
|
||||||
|
namespace { // anonymous namespace
|
||||||
|
|
||||||
|
// Merge operator that picks the maximum operand, Comparison is based on
|
||||||
|
// Slice::compare
|
||||||
|
class MaxOperator : public MergeOperator { |
||||||
|
public: |
||||||
|
virtual bool FullMerge(const Slice& key, const Slice* existing_value, |
||||||
|
const std::deque<std::string>& operand_list, |
||||||
|
std::string* new_value, |
||||||
|
Logger* logger) const override { |
||||||
|
Slice max; |
||||||
|
if (existing_value) { |
||||||
|
max = Slice(existing_value->data(), existing_value->size()); |
||||||
|
} |
||||||
|
|
||||||
|
for (const auto& op : operand_list) { |
||||||
|
if (max.compare(op) < 0) { |
||||||
|
max = Slice(op.data(), op.size()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
new_value->assign(max.data(), max.size()); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
virtual bool PartialMerge(const Slice& key, const Slice& left_operand, |
||||||
|
const Slice& right_operand, std::string* new_value, |
||||||
|
Logger* logger) const override { |
||||||
|
if (left_operand.compare(right_operand) >= 0) { |
||||||
|
new_value->assign(left_operand.data(), left_operand.size()); |
||||||
|
} else { |
||||||
|
new_value->assign(right_operand.data(), right_operand.size()); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
virtual bool PartialMergeMulti(const Slice& key, |
||||||
|
const std::deque<Slice>& operand_list, |
||||||
|
std::string* new_value, |
||||||
|
Logger* logger) const override { |
||||||
|
Slice max; |
||||||
|
for (const auto& operand : operand_list) { |
||||||
|
if (max.compare(operand) < 0) { |
||||||
|
max = operand; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
new_value->assign(max.data(), max.size()); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
virtual const char* Name() const override { return "MaxOperator"; } |
||||||
|
}; |
||||||
|
|
||||||
|
} // end of anonymous namespace
|
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
std::shared_ptr<MergeOperator> MergeOperators::CreateMaxOperator() { |
||||||
|
return std::make_shared<MaxOperator>(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
#include "util/testharness.h" |
||||||
|
#include "util/testutil.h" |
||||||
|
#include "utilities/merge_operators.h" |
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
class UtilMergeOperatorTest : public testing::Test { |
||||||
|
public: |
||||||
|
UtilMergeOperatorTest() {} |
||||||
|
|
||||||
|
std::string FullMerge(std::string existing_value, |
||||||
|
std::deque<std::string> operands, |
||||||
|
std::string key = "") { |
||||||
|
Slice existing_value_slice(existing_value); |
||||||
|
std::string result; |
||||||
|
|
||||||
|
merge_operator_->FullMerge(key, &existing_value_slice, operands, &result, |
||||||
|
nullptr); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
std::string FullMerge(std::deque<std::string> operands, |
||||||
|
std::string key = "") { |
||||||
|
std::string result; |
||||||
|
|
||||||
|
merge_operator_->FullMerge(key, nullptr, operands, &result, nullptr); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
std::string PartialMerge(std::string left, std::string right, |
||||||
|
std::string key = "") { |
||||||
|
std::string result; |
||||||
|
|
||||||
|
merge_operator_->PartialMerge(key, left, right, &result, nullptr); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
std::string PartialMergeMulti(std::deque<std::string> operands, |
||||||
|
std::string key = "") { |
||||||
|
std::string result; |
||||||
|
std::deque<Slice> operands_slice(operands.begin(), operands.end()); |
||||||
|
|
||||||
|
merge_operator_->PartialMergeMulti(key, operands_slice, &result, nullptr); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
protected: |
||||||
|
std::shared_ptr<MergeOperator> merge_operator_; |
||||||
|
}; |
||||||
|
|
||||||
|
TEST_F(UtilMergeOperatorTest, MaxMergeOperator) { |
||||||
|
merge_operator_ = MergeOperators::CreateMaxOperator(); |
||||||
|
|
||||||
|
EXPECT_EQ("B", FullMerge("B", {"A"})); |
||||||
|
EXPECT_EQ("B", FullMerge("A", {"B"})); |
||||||
|
EXPECT_EQ("", FullMerge({"", "", ""})); |
||||||
|
EXPECT_EQ("A", FullMerge({"A"})); |
||||||
|
EXPECT_EQ("ABC", FullMerge({"ABC"})); |
||||||
|
EXPECT_EQ("Z", FullMerge({"ABC", "Z", "C", "AXX"})); |
||||||
|
EXPECT_EQ("ZZZ", FullMerge({"ABC", "CC", "Z", "ZZZ"})); |
||||||
|
EXPECT_EQ("a", FullMerge("a", {"ABC", "CC", "Z", "ZZZ"})); |
||||||
|
|
||||||
|
EXPECT_EQ("z", PartialMergeMulti({"a", "z", "efqfqwgwew", "aaz", "hhhhh"})); |
||||||
|
|
||||||
|
EXPECT_EQ("b", PartialMerge("a", "b")); |
||||||
|
EXPECT_EQ("z", PartialMerge("z", "azzz")); |
||||||
|
EXPECT_EQ("a", PartialMerge("a", "")); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace rocksdb
|
||||||
|
|
||||||
|
int main(int argc, char** argv) { |
||||||
|
::testing::InitGoogleTest(&argc, argv); |
||||||
|
return RUN_ALL_TESTS(); |
||||||
|
} |
Loading…
Reference in new issue