mirror of
https://github.com/facebook/rocksdb.git
synced 2024-11-29 09:36:17 +00:00
64 lines
1.6 KiB
C++
64 lines
1.6 KiB
C++
|
#include <memory>
|
||
|
#include "leveldb/env.h"
|
||
|
#include "leveldb/merge_operator.h"
|
||
|
#include "leveldb/slice.h"
|
||
|
#include "util/coding.h"
|
||
|
#include "utilities/merge_operators.h"
|
||
|
|
||
|
|
||
|
using namespace leveldb;
|
||
|
|
||
|
namespace { // anonymous namespace
|
||
|
|
||
|
// A 'model' merge operator with uint64 addition semantics
|
||
|
class UInt64AddOperator : public MergeOperator {
|
||
|
public:
|
||
|
virtual void Merge(const Slice& key,
|
||
|
const Slice* existing_value,
|
||
|
const Slice& value,
|
||
|
std::string* new_value,
|
||
|
Logger* logger) const override {
|
||
|
// assuming 0 if no existing value
|
||
|
uint64_t existing = 0;
|
||
|
if (existing_value) {
|
||
|
if (existing_value->size() == sizeof(uint64_t)) {
|
||
|
existing = DecodeFixed64(existing_value->data());
|
||
|
} else {
|
||
|
// if existing_value is corrupted, treat it as 0
|
||
|
Log(logger, "existing value corruption, size: %zu > %zu",
|
||
|
existing_value->size(), sizeof(uint64_t));
|
||
|
existing = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint64_t operand;
|
||
|
if (value.size() == sizeof(uint64_t)) {
|
||
|
operand = DecodeFixed64(value.data());
|
||
|
} else {
|
||
|
// if operand is corrupted, treat it as 0
|
||
|
Log(logger, "operand value corruption, size: %zu > %zu",
|
||
|
value.size(), sizeof(uint64_t));
|
||
|
operand = 0;
|
||
|
}
|
||
|
|
||
|
new_value->resize(sizeof(uint64_t));
|
||
|
EncodeFixed64(&(*new_value)[0], existing + operand);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
virtual const char* Name() const override {
|
||
|
return "UInt64AddOperator";
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
namespace leveldb {
|
||
|
|
||
|
std::shared_ptr<MergeOperator> MergeOperators::CreateUInt64AddOperator() {
|
||
|
return std::make_shared<UInt64AddOperator>();
|
||
|
}
|
||
|
|
||
|
}
|