]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/db/merge_operator.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
7 * Back-end implementation details specific to the Merge Operator.
10 #include "rocksdb/merge_operator.h"
12 namespace ROCKSDB_NAMESPACE
{
14 bool MergeOperator::FullMergeV2(const MergeOperationInput
& merge_in
,
15 MergeOperationOutput
* merge_out
) const {
16 // If FullMergeV2 is not implemented, we convert the operand_list to
17 // std::deque<std::string> and pass it to FullMerge
18 std::deque
<std::string
> operand_list_str
;
19 for (auto& op
: merge_in
.operand_list
) {
20 operand_list_str
.emplace_back(op
.data(), op
.size());
22 return FullMerge(merge_in
.key
, merge_in
.existing_value
, operand_list_str
,
23 &merge_out
->new_value
, merge_in
.logger
);
26 // The default implementation of PartialMergeMulti, which invokes
27 // PartialMerge multiple times internally and merges two operands at
29 bool MergeOperator::PartialMergeMulti(const Slice
& key
,
30 const std::deque
<Slice
>& operand_list
,
31 std::string
* new_value
,
32 Logger
* logger
) const {
33 assert(operand_list
.size() >= 2);
34 // Simply loop through the operands
35 Slice
temp_slice(operand_list
[0]);
37 for (size_t i
= 1; i
< operand_list
.size(); ++i
) {
38 auto& operand
= operand_list
[i
];
39 std::string temp_value
;
40 if (!PartialMerge(key
, temp_slice
, operand
, &temp_value
, logger
)) {
43 swap(temp_value
, *new_value
);
44 temp_slice
= Slice(*new_value
);
47 // The result will be in *new_value. All merges succeeded.
51 // Given a "real" merge from the library, call the user's
52 // associative merge function one-by-one on each of the operands.
53 // NOTE: It is assumed that the client's merge-operator will handle any errors.
54 bool AssociativeMergeOperator::FullMergeV2(
55 const MergeOperationInput
& merge_in
,
56 MergeOperationOutput
* merge_out
) const {
57 // Simply loop through the operands
59 const Slice
* existing_value
= merge_in
.existing_value
;
60 for (const auto& operand
: merge_in
.operand_list
) {
61 std::string temp_value
;
62 if (!Merge(merge_in
.key
, existing_value
, operand
, &temp_value
,
66 swap(temp_value
, merge_out
->new_value
);
67 temp_existing
= Slice(merge_out
->new_value
);
68 existing_value
= &temp_existing
;
71 // The result will be in *new_value. All merges succeeded.
75 // Call the user defined simple merge on the operands;
76 // NOTE: It is assumed that the client's merge-operator will handle any errors.
77 bool AssociativeMergeOperator::PartialMerge(const Slice
& key
,
78 const Slice
& left_operand
,
79 const Slice
& right_operand
,
80 std::string
* new_value
,
81 Logger
* logger
) const {
82 return Merge(key
, &left_operand
, right_operand
, new_value
, logger
);
85 } // namespace ROCKSDB_NAMESPACE