/Users/deen/code/yugabyte-db/src/yb/rocksdb/utilities/merge_operators/string_append/stringappend2.cc
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * @author Deon Nicholas (dnicholas@fb.com) |
3 | | * Copyright 2013 Facebook |
4 | | * |
5 | | * The following only applies to changes made to this file as part of YugaByte development. |
6 | | * |
7 | | * Portions Copyright (c) YugaByte, Inc. |
8 | | * |
9 | | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
10 | | * in compliance with the License. You may obtain a copy of the License at |
11 | | * |
12 | | * http://www.apache.org/licenses/LICENSE-2.0 |
13 | | * |
14 | | * Unless required by applicable law or agreed to in writing, software distributed under the License |
15 | | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
16 | | * or implied. See the License for the specific language governing permissions and limitations |
17 | | * under the License. |
18 | | * |
19 | | */ |
20 | | |
21 | | #include "yb/rocksdb/utilities/merge_operators/string_append/stringappend2.h" |
22 | | |
23 | | #include <assert.h> |
24 | | |
25 | | #include <memory> |
26 | | #include <string> |
27 | | |
28 | | #include "yb/util/slice.h" |
29 | | #include "yb/rocksdb/merge_operator.h" |
30 | | #include "yb/rocksdb/utilities/merge_operators.h" |
31 | | |
32 | | namespace rocksdb { |
33 | | |
34 | | // Constructor: also specify the delimiter character. |
35 | | StringAppendTESTOperator::StringAppendTESTOperator(char delim_char) |
36 | 14 | : delim_(delim_char) { |
37 | 14 | } |
38 | | |
39 | | // Implementation for the merge operation (concatenates two strings) |
40 | | bool StringAppendTESTOperator::FullMerge( |
41 | | const Slice& key, |
42 | | const Slice* existing_value, |
43 | | const std::deque<std::string>& operands, |
44 | | std::string* new_value, |
45 | 547 | Logger* logger) const { |
46 | | |
47 | | // Clear the *new_value for writing. |
48 | 547 | assert(new_value); |
49 | 547 | new_value->clear(); |
50 | | |
51 | | // Compute the space needed for the final result. |
52 | 547 | size_t numBytes = 0; |
53 | 22.4k | for(auto it = operands.begin(); it != operands.end(); ++it) { |
54 | 21.8k | numBytes += it->size() + 1; // Plus 1 for the delimiter |
55 | 21.8k | } |
56 | | |
57 | | // Only print the delimiter after the first entry has been printed |
58 | 547 | bool printDelim = false; |
59 | | |
60 | | // Prepend the *existing_value if one exists. |
61 | 547 | if (existing_value) { |
62 | 5 | new_value->reserve(numBytes + existing_value->size()); |
63 | 5 | new_value->append(existing_value->cdata(), existing_value->size()); |
64 | 5 | printDelim = true; |
65 | 542 | } else if (numBytes) { |
66 | 542 | new_value->reserve(numBytes-1); // Minus 1 since we have one less delimiter |
67 | 542 | } |
68 | | |
69 | | // Concatenate the sequence of strings (and add a delimiter between each) |
70 | 22.4k | for(auto it = operands.begin(); it != operands.end(); ++it) { |
71 | 21.8k | if (printDelim) { |
72 | 21.3k | new_value->append(1, delim_); |
73 | 21.3k | } |
74 | 21.8k | new_value->append(*it); |
75 | 21.8k | printDelim = true; |
76 | 21.8k | } |
77 | | |
78 | 547 | return true; |
79 | 547 | } |
80 | | |
81 | | bool StringAppendTESTOperator::PartialMergeMulti( |
82 | | const Slice& key, const std::deque<Slice>& operand_list, |
83 | 15 | std::string* new_value, Logger* logger) const { |
84 | 15 | return false; |
85 | 15 | } |
86 | | |
87 | | // A version of PartialMerge that actually performs "partial merging". |
88 | | // Use this to simulate the exact behaviour of the StringAppendOperator. |
89 | | bool StringAppendTESTOperator::_AssocPartialMergeMulti( |
90 | | const Slice& key, const std::deque<Slice>& operand_list, |
91 | 0 | std::string* new_value, Logger* logger) const { |
92 | | // Clear the *new_value for writing |
93 | 0 | assert(new_value); |
94 | 0 | new_value->clear(); |
95 | 0 | assert(operand_list.size() >= 2); |
96 | | |
97 | | // Generic append |
98 | | // Determine and reserve correct size for *new_value. |
99 | 0 | size_t size = 0; |
100 | 0 | for (const auto& operand : operand_list) { |
101 | 0 | size += operand.size(); |
102 | 0 | } |
103 | 0 | size += operand_list.size() - 1; // Delimiters |
104 | 0 | new_value->reserve(size); |
105 | | |
106 | | // Apply concatenation |
107 | 0 | new_value->assign(operand_list.front().cdata(), operand_list.front().size()); |
108 | |
|
109 | 0 | for (std::deque<Slice>::const_iterator it = operand_list.begin() + 1; |
110 | 0 | it != operand_list.end(); ++it) { |
111 | 0 | new_value->append(1, delim_); |
112 | 0 | new_value->append(it->cdata(), it->size()); |
113 | 0 | } |
114 | |
|
115 | 0 | return true; |
116 | 0 | } |
117 | | |
118 | 0 | const char* StringAppendTESTOperator::Name() const { |
119 | 0 | return "StringAppendTESTOperator"; |
120 | 0 | } |
121 | | |
122 | | |
123 | | std::shared_ptr<MergeOperator> |
124 | 1 | MergeOperators::CreateStringAppendTESTOperator() { |
125 | 1 | return std::make_shared<StringAppendTESTOperator>(','); |
126 | 1 | } |
127 | | |
128 | | } // namespace rocksdb |