]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/db/merge_context.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rocksdb / db / merge_context.h
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).
5 //
6 #pragma once
7 #include <algorithm>
8 #include <memory>
9 #include <string>
10 #include <vector>
11 #include "rocksdb/slice.h"
12
13 namespace ROCKSDB_NAMESPACE {
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
78 // Same as GetOperandsDirectionForward
79 const std::vector<Slice>& GetOperands() {
80 return GetOperandsDirectionForward();
81 }
82
83 // Return all the operands in the order as they were merged (passed to
84 // FullMerge or FullMergeV2)
85 const std::vector<Slice>& GetOperandsDirectionForward() {
86 if (!operand_list_) {
87 return empty_operand_list;
88 }
89
90 SetDirectionForward();
91 return *operand_list_;
92 }
93
94 // Return all the operands in the reversed order relative to how they were
95 // merged (passed to FullMerge or FullMergeV2)
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
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
134 } // namespace ROCKSDB_NAMESPACE