You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
rocksdb/examples/compaction_filter_example.cc

96 lines
3.3 KiB

// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
#include "rocksdb/compaction_filter.h"
#include "rocksdb/db.h"
#include "rocksdb/merge_operator.h"
#include "rocksdb/options.h"
class MyMerge : public ROCKSDB_NAMESPACE::MergeOperator {
public:
virtual bool FullMergeV2(const MergeOperationInput& merge_in,
MergeOperationOutput* merge_out) const override {
merge_out->new_value.clear();
if (merge_in.existing_value != nullptr) {
merge_out->new_value.assign(merge_in.existing_value->data(),
merge_in.existing_value->size());
}
for (const ROCKSDB_NAMESPACE::Slice& m : merge_in.operand_list) {
fprintf(stderr, "Merge(%s)\n", m.ToString().c_str());
// the compaction filter filters out bad values
assert(m.ToString() != "bad");
merge_out->new_value.assign(m.data(), m.size());
}
return true;
}
const char* Name() const override { return "MyMerge"; }
};
class MyFilter : public ROCKSDB_NAMESPACE::CompactionFilter {
public:
bool Filter(int level, const ROCKSDB_NAMESPACE::Slice& key,
const ROCKSDB_NAMESPACE::Slice& existing_value,
std::string* new_value, bool* value_changed) const override {
fprintf(stderr, "Filter(%s)\n", key.ToString().c_str());
++count_;
assert(*value_changed == false);
return false;
}
bool FilterMergeOperand(
int level, const ROCKSDB_NAMESPACE::Slice& key,
const ROCKSDB_NAMESPACE::Slice& existing_value) const override {
fprintf(stderr, "FilterMerge(%s)\n", key.ToString().c_str());
++merge_count_;
return existing_value == "bad";
}
const char* Name() const override { return "MyFilter"; }
mutable int count_ = 0;
mutable int merge_count_ = 0;
};
#if defined(OS_WIN)
std::string kDBPath = "C:\\Windows\\TEMP\\rocksmergetest";
std::string kRemoveDirCommand = "rmdir /Q /S ";
#else
std::string kDBPath = "/tmp/rocksmergetest";
std::string kRemoveDirCommand = "rm -rf ";
#endif
int main() {
ROCKSDB_NAMESPACE::DB* raw_db;
ROCKSDB_NAMESPACE::Status status;
MyFilter filter;
std::string rm_cmd = kRemoveDirCommand + kDBPath;
int ret = system(rm_cmd.c_str());
if (ret != 0) {
fprintf(stderr, "Error deleting %s, code: %d\n", kDBPath.c_str(), ret);
}
ROCKSDB_NAMESPACE::Options options;
options.create_if_missing = true;
options.merge_operator.reset(new MyMerge);
options.compaction_filter = &filter;
status = ROCKSDB_NAMESPACE::DB::Open(options, kDBPath, &raw_db);
assert(status.ok());
std::unique_ptr<ROCKSDB_NAMESPACE::DB> db(raw_db);
ROCKSDB_NAMESPACE::WriteOptions wopts;
db->Merge(wopts, "0", "bad"); // This is filtered out
db->Merge(wopts, "1", "data1");
db->Merge(wopts, "1", "bad");
db->Merge(wopts, "1", "data2");
db->Merge(wopts, "1", "bad");
db->Merge(wopts, "3", "data3");
db->CompactRange(ROCKSDB_NAMESPACE::CompactRangeOptions(), nullptr, nullptr);
fprintf(stderr, "filter.count_ = %d\n", filter.count_);
assert(filter.count_ == 0);
fprintf(stderr, "filter.merge_count_ = %d\n", filter.merge_count_);
assert(filter.merge_count_ == 6);
}