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