Loading ifs/include/daemon/db/merge.hpp +22 −6 Original line number Diff line number Diff line Loading @@ -7,20 +7,36 @@ namespace rdb = rocksdb; enum class OperandID: char { increase_size = 's', create = 'c' }; class IncreaseSizeOperand { class MergeOperand { public: const static char separator; const static char true_char; const static char false_char; constexpr static char operand_id_suffix = ':'; std::string serialize() const; protected: std::string serialize_id() const; virtual std::string serialize_params() const = 0; virtual const OperandID id() const = 0; }; class IncreaseSizeOperand: public MergeOperand { public: constexpr const static char separator = ','; constexpr const static char true_char = 't'; constexpr const static char false_char = 'f'; size_t size; bool append; IncreaseSizeOperand(const size_t size, const bool append); IncreaseSizeOperand(const std::string& serialized_op); IncreaseSizeOperand(const rdb::Slice& serialized_op); std::string serialize() const; virtual const OperandID id() const override; virtual std::string serialize_params() const override; }; class MetadataMergeOperator: public rocksdb::MergeOperator { Loading ifs/src/daemon/db/merge.cpp +42 −17 Original line number Diff line number Diff line #include <daemon/db/merge.hpp> const char IncreaseSizeOperand::separator = ','; const char IncreaseSizeOperand::true_char = 't'; const char IncreaseSizeOperand::false_char = 'f'; std::string MergeOperand::serialize_id() const { std::string s; s.reserve(2); s += (char)id(); s += operand_id_suffix; return s; } std::string MergeOperand::serialize() const { std::string s = serialize_id(); s += serialize_params(); return s; } IncreaseSizeOperand::IncreaseSizeOperand(const size_t size, const bool append): size(size), append(append) {} IncreaseSizeOperand::IncreaseSizeOperand(const std::string& serialized_op){ IncreaseSizeOperand::IncreaseSizeOperand(const rdb::Slice& serialized_op){ size_t chrs_parsed = 0; size_t read = 0; //Parse size size = std::stoul(&serialized_op.at(chrs_parsed), &read); size = std::stoul(serialized_op.data() + chrs_parsed, &read); chrs_parsed += read + 1; assert(serialized_op.at(chrs_parsed - 1) == separator); assert(serialized_op[chrs_parsed - 1] == separator); //Parse append flag assert(serialized_op.at(chrs_parsed) == false_char || serialized_op.at(chrs_parsed) == true_char); append = (serialized_op.at(chrs_parsed) == false_char) ? false : true; assert(serialized_op[chrs_parsed] == false_char || serialized_op[chrs_parsed] == true_char); append = (serialized_op[chrs_parsed] == false_char) ? false : true; //check that we consumed all the input string assert(chrs_parsed + 1 == serialized_op.size()); } std::string IncreaseSizeOperand::serialize() const { const OperandID IncreaseSizeOperand::id() const { return OperandID::increase_size; } std::string IncreaseSizeOperand::serialize_params() const { std::string s; s.reserve(3); s += std::to_string(size); s += this->separator; s += (append == false)? false_char : true_char; return s; } bool MetadataMergeOperator::FullMergeV2( const MergeOperationInput& merge_in, MergeOperationOutput* merge_out) const { Loading @@ -49,14 +66,22 @@ bool MetadataMergeOperator::FullMergeV2( Metadata md{merge_in.key.ToString(), merge_in.existing_value->ToString()}; size_t fsize = md.size(); for(const auto& operand: merge_in.operand_list){ auto op = IncreaseSizeOperand(operand.ToString()); for(const auto& serialized_op: merge_in.operand_list){ assert(serialized_op.size() >= 2); auto operand_id = static_cast<OperandID>(serialized_op[0]); auto parameters = rdb::Slice(serialized_op.data() + 2, serialized_op.size() - 2); if(operand_id == OperandID::increase_size){ auto op = IncreaseSizeOperand(parameters); if(op.append){ //append mode, just increment file fsize += op.size; } else { fsize = std::max(op.size, fsize); } } else { throw std::runtime_error(fmt::format("Unrecognized merge operand ID: {}", (char)operand_id)); } } md.size(fsize); Loading Loading
ifs/include/daemon/db/merge.hpp +22 −6 Original line number Diff line number Diff line Loading @@ -7,20 +7,36 @@ namespace rdb = rocksdb; enum class OperandID: char { increase_size = 's', create = 'c' }; class IncreaseSizeOperand { class MergeOperand { public: const static char separator; const static char true_char; const static char false_char; constexpr static char operand_id_suffix = ':'; std::string serialize() const; protected: std::string serialize_id() const; virtual std::string serialize_params() const = 0; virtual const OperandID id() const = 0; }; class IncreaseSizeOperand: public MergeOperand { public: constexpr const static char separator = ','; constexpr const static char true_char = 't'; constexpr const static char false_char = 'f'; size_t size; bool append; IncreaseSizeOperand(const size_t size, const bool append); IncreaseSizeOperand(const std::string& serialized_op); IncreaseSizeOperand(const rdb::Slice& serialized_op); std::string serialize() const; virtual const OperandID id() const override; virtual std::string serialize_params() const override; }; class MetadataMergeOperator: public rocksdb::MergeOperator { Loading
ifs/src/daemon/db/merge.cpp +42 −17 Original line number Diff line number Diff line #include <daemon/db/merge.hpp> const char IncreaseSizeOperand::separator = ','; const char IncreaseSizeOperand::true_char = 't'; const char IncreaseSizeOperand::false_char = 'f'; std::string MergeOperand::serialize_id() const { std::string s; s.reserve(2); s += (char)id(); s += operand_id_suffix; return s; } std::string MergeOperand::serialize() const { std::string s = serialize_id(); s += serialize_params(); return s; } IncreaseSizeOperand::IncreaseSizeOperand(const size_t size, const bool append): size(size), append(append) {} IncreaseSizeOperand::IncreaseSizeOperand(const std::string& serialized_op){ IncreaseSizeOperand::IncreaseSizeOperand(const rdb::Slice& serialized_op){ size_t chrs_parsed = 0; size_t read = 0; //Parse size size = std::stoul(&serialized_op.at(chrs_parsed), &read); size = std::stoul(serialized_op.data() + chrs_parsed, &read); chrs_parsed += read + 1; assert(serialized_op.at(chrs_parsed - 1) == separator); assert(serialized_op[chrs_parsed - 1] == separator); //Parse append flag assert(serialized_op.at(chrs_parsed) == false_char || serialized_op.at(chrs_parsed) == true_char); append = (serialized_op.at(chrs_parsed) == false_char) ? false : true; assert(serialized_op[chrs_parsed] == false_char || serialized_op[chrs_parsed] == true_char); append = (serialized_op[chrs_parsed] == false_char) ? false : true; //check that we consumed all the input string assert(chrs_parsed + 1 == serialized_op.size()); } std::string IncreaseSizeOperand::serialize() const { const OperandID IncreaseSizeOperand::id() const { return OperandID::increase_size; } std::string IncreaseSizeOperand::serialize_params() const { std::string s; s.reserve(3); s += std::to_string(size); s += this->separator; s += (append == false)? false_char : true_char; return s; } bool MetadataMergeOperator::FullMergeV2( const MergeOperationInput& merge_in, MergeOperationOutput* merge_out) const { Loading @@ -49,14 +66,22 @@ bool MetadataMergeOperator::FullMergeV2( Metadata md{merge_in.key.ToString(), merge_in.existing_value->ToString()}; size_t fsize = md.size(); for(const auto& operand: merge_in.operand_list){ auto op = IncreaseSizeOperand(operand.ToString()); for(const auto& serialized_op: merge_in.operand_list){ assert(serialized_op.size() >= 2); auto operand_id = static_cast<OperandID>(serialized_op[0]); auto parameters = rdb::Slice(serialized_op.data() + 2, serialized_op.size() - 2); if(operand_id == OperandID::increase_size){ auto op = IncreaseSizeOperand(parameters); if(op.append){ //append mode, just increment file fsize += op.size; } else { fsize = std::max(op.size, fsize); } } else { throw std::runtime_error(fmt::format("Unrecognized merge operand ID: {}", (char)operand_id)); } } md.size(fsize); Loading