]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae FG |
5 | // |
6 | /** | |
7 | * Back-end implementation details specific to the Merge Operator. | |
8 | */ | |
9 | ||
10 | #include "rocksdb/merge_operator.h" | |
11 | ||
f67539c2 | 12 | namespace ROCKSDB_NAMESPACE { |
7c673cae FG |
13 | |
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()); | |
21 | } | |
22 | return FullMerge(merge_in.key, merge_in.existing_value, operand_list_str, | |
23 | &merge_out->new_value, merge_in.logger); | |
24 | } | |
25 | ||
26 | // The default implementation of PartialMergeMulti, which invokes | |
27 | // PartialMerge multiple times internally and merges two operands at | |
28 | // a time. | |
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]); | |
36 | ||
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)) { | |
41 | return false; | |
42 | } | |
43 | swap(temp_value, *new_value); | |
44 | temp_slice = Slice(*new_value); | |
45 | } | |
46 | ||
47 | // The result will be in *new_value. All merges succeeded. | |
48 | return true; | |
49 | } | |
50 | ||
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 | |
58 | Slice temp_existing; | |
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, | |
63 | merge_in.logger)) { | |
64 | return false; | |
65 | } | |
66 | swap(temp_value, merge_out->new_value); | |
67 | temp_existing = Slice(merge_out->new_value); | |
68 | existing_value = &temp_existing; | |
69 | } | |
70 | ||
71 | // The result will be in *new_value. All merges succeeded. | |
72 | return true; | |
73 | } | |
74 | ||
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( | |
78 | const Slice& key, | |
79 | const Slice& left_operand, | |
80 | const Slice& right_operand, | |
81 | std::string* new_value, | |
82 | Logger* logger) const { | |
83 | return Merge(key, &left_operand, right_operand, new_value, logger); | |
84 | } | |
85 | ||
f67539c2 | 86 | } // namespace ROCKSDB_NAMESPACE |