Line data Source code
1 : /* 2 : Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain 3 : Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany 4 : 5 : This software was partially supported by the 6 : EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). 7 : 8 : This software was partially supported by the 9 : ADA-FS project under the SPPEXA project funded by the DFG. 10 : 11 : This file is part of GekkoFS. 12 : 13 : GekkoFS is free software: you can redistribute it and/or modify 14 : it under the terms of the GNU General Public License as published by 15 : the Free Software Foundation, either version 3 of the License, or 16 : (at your option) any later version. 17 : 18 : GekkoFS is distributed in the hope that it will be useful, 19 : but WITHOUT ANY WARRANTY; without even the implied warranty of 20 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 : GNU General Public License for more details. 22 : 23 : You should have received a copy of the GNU General Public License 24 : along with GekkoFS. If not, see <https://www.gnu.org/licenses/>. 25 : 26 : SPDX-License-Identifier: GPL-3.0-or-later 27 : */ 28 : 29 : #ifndef DB_MERGE_HPP 30 : #define DB_MERGE_HPP 31 : 32 : #include <daemon/backend/metadata/metadata_module.hpp> 33 : #include <rocksdb/merge_operator.h> 34 : #include <common/metadata.hpp> 35 : 36 : namespace rdb = rocksdb; 37 : 38 : namespace gkfs::metadata { 39 : 40 : /** 41 : * @brief Merge operator classifiers 42 : */ 43 : enum class OperandID : char { 44 : increase_size = 'i', 45 : decrease_size = 'd', 46 : create = 'c' 47 : }; 48 : 49 : /** 50 : * @brief Base class for merge operands 51 : */ 52 1223 : class MergeOperand { 53 : public: 54 : constexpr static char operand_id_suffix = ':'; 55 : 56 : std::string 57 : serialize() const; 58 : 59 : static OperandID 60 : get_id(const rdb::Slice& serialized_op); 61 : 62 : static rdb::Slice 63 : get_params(const rdb::Slice& serialized_op); 64 : 65 : protected: 66 : std::string 67 : serialize_id() const; 68 : 69 : virtual std::string 70 : serialize_params() const = 0; 71 : 72 : virtual OperandID 73 : id() const = 0; 74 : }; 75 : /** 76 : * @brief Increase size operand 77 : */ 78 : class IncreaseSizeOperand : public MergeOperand { 79 : private: 80 : constexpr const static char serialize_sep = ','; 81 : constexpr const static char serialize_end = '\0'; 82 : 83 : size_t size_; 84 : /* 85 : * ID of the merge operation that this operand belongs to. 86 : * This ID is used only in append operations to communicate the starting 87 : * write offset from the asynchronous Merge operation back to the caller in 88 : * `increase_size_impl()`. 89 : */ 90 : uint16_t merge_id_; 91 : bool append_; 92 : 93 : public: 94 : IncreaseSizeOperand(size_t size); 95 : 96 : IncreaseSizeOperand(size_t size, uint16_t merge_id, bool append); 97 : 98 : explicit IncreaseSizeOperand(const rdb::Slice& serialized_op); 99 : 100 : OperandID 101 : id() const override; 102 : 103 : std::string 104 : serialize_params() const override; 105 : 106 : size_t 107 116 : size() const { 108 116 : return size_; 109 : } 110 : 111 : uint16_t 112 15 : merge_id() const { 113 15 : return merge_id_; 114 : } 115 : 116 : bool 117 116 : append() const { 118 116 : return append_; 119 : } 120 : }; 121 : /** 122 : * @brief Decrease size operand 123 : */ 124 : class DecreaseSizeOperand : public MergeOperand { 125 : private: 126 : size_t size_; 127 : 128 : public: 129 : explicit DecreaseSizeOperand(size_t size); 130 : 131 : explicit DecreaseSizeOperand(const rdb::Slice& serialized_op); 132 : 133 : OperandID 134 : id() const override; 135 : 136 : std::string 137 : serialize_params() const override; 138 : 139 : size_t 140 20 : size() const { 141 10 : return size_; 142 : } 143 : }; 144 : /** 145 : * @brief Create operand 146 : */ 147 1097 : class CreateOperand : public MergeOperand { 148 : public: 149 : std::string metadata; 150 : 151 : explicit CreateOperand(const std::string& metadata); 152 : 153 : OperandID 154 : id() const override; 155 : 156 : std::string 157 : serialize_params() const override; 158 : }; 159 : /** 160 : * @brief Merge operator class passed to RocksDB, used during merge operations 161 : */ 162 33 : class MetadataMergeOperator : public rocksdb::MergeOperator { 163 : public: 164 33 : ~MetadataMergeOperator() override = default; 165 : 166 : /** 167 : * @brief Merges all operands in chronological order for the same key 168 : * @param op1 Input operand 169 : * @param op2 Output operand 170 : * @return Result of the merge operation 171 : */ 172 : bool 173 : FullMergeV2(const MergeOperationInput& merge_in, 174 : MergeOperationOutput* merge_out) const override; 175 : 176 : /** 177 : * @brief TODO functionality unclear. Currently unused. 178 : * @param key 179 : * @param operand_list 180 : * @param new_value 181 : * @param logger 182 : * @return 183 : */ 184 : bool 185 : PartialMergeMulti(const rdb::Slice& key, 186 : const std::deque<rdb::Slice>& operand_list, 187 : std::string* new_value, 188 : rdb::Logger* logger) const override; 189 : 190 : /** 191 : * @brief Returns the name of this Merge operator 192 : * @return 193 : */ 194 : const char* 195 : Name() const override; 196 : 197 : /** 198 : * @brief Merge Operator configuration which allows merges with just a 199 : * single operand. 200 : * @return 201 : */ 202 : bool 203 : AllowSingleOperand() const override; 204 : }; 205 : 206 : } // namespace gkfs::metadata 207 : 208 : #endif // DB_MERGE_HPP