]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/merge_operators/string_append/stringappend2.cc
2 * @author Deon Nicholas (dnicholas@fb.com)
3 * Copyright 2013 Facebook
6 #include "stringappend2.h"
12 #include "rocksdb/slice.h"
13 #include "rocksdb/merge_operator.h"
14 #include "utilities/merge_operators.h"
16 namespace ROCKSDB_NAMESPACE
{
18 // Constructor: also specify the delimiter character.
19 StringAppendTESTOperator::StringAppendTESTOperator(char delim_char
)
20 : delim_(delim_char
) {
23 // Implementation for the merge operation (concatenates two strings)
24 bool StringAppendTESTOperator::FullMergeV2(
25 const MergeOperationInput
& merge_in
,
26 MergeOperationOutput
* merge_out
) const {
27 // Clear the *new_value for writing.
28 merge_out
->new_value
.clear();
30 if (merge_in
.existing_value
== nullptr && merge_in
.operand_list
.size() == 1) {
32 merge_out
->existing_operand
= merge_in
.operand_list
.back();
36 // Compute the space needed for the final result.
38 for (auto it
= merge_in
.operand_list
.begin();
39 it
!= merge_in
.operand_list
.end(); ++it
) {
40 numBytes
+= it
->size() + 1; // Plus 1 for the delimiter
43 // Only print the delimiter after the first entry has been printed
44 bool printDelim
= false;
46 // Prepend the *existing_value if one exists.
47 if (merge_in
.existing_value
) {
48 merge_out
->new_value
.reserve(numBytes
+ merge_in
.existing_value
->size());
49 merge_out
->new_value
.append(merge_in
.existing_value
->data(),
50 merge_in
.existing_value
->size());
52 } else if (numBytes
) {
53 merge_out
->new_value
.reserve(
54 numBytes
- 1); // Minus 1 since we have one less delimiter
57 // Concatenate the sequence of strings (and add a delimiter between each)
58 for (auto it
= merge_in
.operand_list
.begin();
59 it
!= merge_in
.operand_list
.end(); ++it
) {
61 merge_out
->new_value
.append(1, delim_
);
63 merge_out
->new_value
.append(it
->data(), it
->size());
70 bool StringAppendTESTOperator::PartialMergeMulti(
71 const Slice
& /*key*/, const std::deque
<Slice
>& /*operand_list*/,
72 std::string
* /*new_value*/, Logger
* /*logger*/) const {
76 // A version of PartialMerge that actually performs "partial merging".
77 // Use this to simulate the exact behaviour of the StringAppendOperator.
78 bool StringAppendTESTOperator::_AssocPartialMergeMulti(
79 const Slice
& /*key*/, const std::deque
<Slice
>& operand_list
,
80 std::string
* new_value
, Logger
* /*logger*/) const {
81 // Clear the *new_value for writing
84 assert(operand_list
.size() >= 2);
87 // Determine and reserve correct size for *new_value.
89 for (const auto& operand
: operand_list
) {
90 size
+= operand
.size();
92 size
+= operand_list
.size() - 1; // Delimiters
93 new_value
->reserve(size
);
95 // Apply concatenation
96 new_value
->assign(operand_list
.front().data(), operand_list
.front().size());
98 for (std::deque
<Slice
>::const_iterator it
= operand_list
.begin() + 1;
99 it
!= operand_list
.end(); ++it
) {
100 new_value
->append(1, delim_
);
101 new_value
->append(it
->data(), it
->size());
107 const char* StringAppendTESTOperator::Name() const {
108 return "StringAppendTESTOperator";
112 std::shared_ptr
<MergeOperator
>
113 MergeOperators::CreateStringAppendTESTOperator() {
114 return std::make_shared
<StringAppendTESTOperator
>(',');
117 } // namespace ROCKSDB_NAMESPACE