]>
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 | #pragma once | |
f67539c2 TL |
7 | #include <algorithm> |
8 | #include <memory> | |
7c673cae FG |
9 | #include <string> |
10 | #include <vector> | |
7c673cae FG |
11 | #include "rocksdb/slice.h" |
12 | ||
f67539c2 | 13 | namespace ROCKSDB_NAMESPACE { |
7c673cae FG |
14 | |
15 | const std::vector<Slice> empty_operand_list; | |
16 | ||
17 | // The merge context for merging a user key. | |
18 | // When doing a Get(), DB will create such a class and pass it when | |
19 | // issuing Get() operation to memtables and version_set. The operands | |
20 | // will be fetched from the context when issuing partial of full merge. | |
21 | class MergeContext { | |
22 | public: | |
23 | // Clear all the operands | |
24 | void Clear() { | |
25 | if (operand_list_) { | |
26 | operand_list_->clear(); | |
27 | copied_operands_->clear(); | |
28 | } | |
29 | } | |
30 | ||
31 | // Push a merge operand | |
32 | void PushOperand(const Slice& operand_slice, bool operand_pinned = false) { | |
33 | Initialize(); | |
34 | SetDirectionBackward(); | |
35 | ||
36 | if (operand_pinned) { | |
37 | operand_list_->push_back(operand_slice); | |
38 | } else { | |
39 | // We need to have our own copy of the operand since it's not pinned | |
40 | copied_operands_->emplace_back( | |
41 | new std::string(operand_slice.data(), operand_slice.size())); | |
42 | operand_list_->push_back(*copied_operands_->back()); | |
43 | } | |
44 | } | |
45 | ||
46 | // Push back a merge operand | |
47 | void PushOperandBack(const Slice& operand_slice, | |
48 | bool operand_pinned = false) { | |
49 | Initialize(); | |
50 | SetDirectionForward(); | |
51 | ||
52 | if (operand_pinned) { | |
53 | operand_list_->push_back(operand_slice); | |
54 | } else { | |
55 | // We need to have our own copy of the operand since it's not pinned | |
56 | copied_operands_->emplace_back( | |
57 | new std::string(operand_slice.data(), operand_slice.size())); | |
58 | operand_list_->push_back(*copied_operands_->back()); | |
59 | } | |
60 | } | |
61 | ||
62 | // return total number of operands in the list | |
63 | size_t GetNumOperands() const { | |
64 | if (!operand_list_) { | |
65 | return 0; | |
66 | } | |
67 | return operand_list_->size(); | |
68 | } | |
69 | ||
70 | // Get the operand at the index. | |
71 | Slice GetOperand(int index) { | |
72 | assert(operand_list_); | |
73 | ||
74 | SetDirectionForward(); | |
75 | return (*operand_list_)[index]; | |
76 | } | |
77 | ||
11fdf7f2 | 78 | // Same as GetOperandsDirectionForward |
7c673cae | 79 | const std::vector<Slice>& GetOperands() { |
11fdf7f2 TL |
80 | return GetOperandsDirectionForward(); |
81 | } | |
82 | ||
494da23a TL |
83 | // Return all the operands in the order as they were merged (passed to |
84 | // FullMerge or FullMergeV2) | |
11fdf7f2 | 85 | const std::vector<Slice>& GetOperandsDirectionForward() { |
7c673cae FG |
86 | if (!operand_list_) { |
87 | return empty_operand_list; | |
88 | } | |
89 | ||
90 | SetDirectionForward(); | |
91 | return *operand_list_; | |
92 | } | |
93 | ||
494da23a TL |
94 | // Return all the operands in the reversed order relative to how they were |
95 | // merged (passed to FullMerge or FullMergeV2) | |
11fdf7f2 TL |
96 | const std::vector<Slice>& GetOperandsDirectionBackward() { |
97 | if (!operand_list_) { | |
98 | return empty_operand_list; | |
99 | } | |
100 | ||
101 | SetDirectionBackward(); | |
102 | return *operand_list_; | |
103 | } | |
104 | ||
7c673cae FG |
105 | private: |
106 | void Initialize() { | |
107 | if (!operand_list_) { | |
108 | operand_list_.reset(new std::vector<Slice>()); | |
109 | copied_operands_.reset(new std::vector<std::unique_ptr<std::string>>()); | |
110 | } | |
111 | } | |
112 | ||
113 | void SetDirectionForward() { | |
114 | if (operands_reversed_ == true) { | |
115 | std::reverse(operand_list_->begin(), operand_list_->end()); | |
116 | operands_reversed_ = false; | |
117 | } | |
118 | } | |
119 | ||
120 | void SetDirectionBackward() { | |
121 | if (operands_reversed_ == false) { | |
122 | std::reverse(operand_list_->begin(), operand_list_->end()); | |
123 | operands_reversed_ = true; | |
124 | } | |
125 | } | |
126 | ||
127 | // List of operands | |
128 | std::unique_ptr<std::vector<Slice>> operand_list_; | |
129 | // Copy of operands that are not pinned. | |
130 | std::unique_ptr<std::vector<std::unique_ptr<std::string>>> copied_operands_; | |
131 | bool operands_reversed_ = true; | |
132 | }; | |
133 | ||
f67539c2 | 134 | } // namespace ROCKSDB_NAMESPACE |