]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae FG |
5 | |
6 | #include <rocksdb/compaction_filter.h> | |
7 | #include <rocksdb/db.h> | |
8 | #include <rocksdb/merge_operator.h> | |
9 | #include <rocksdb/options.h> | |
10 | ||
11 | class MyMerge : public rocksdb::MergeOperator { | |
12 | public: | |
13 | virtual bool FullMergeV2(const MergeOperationInput& merge_in, | |
14 | MergeOperationOutput* merge_out) const override { | |
15 | merge_out->new_value.clear(); | |
16 | if (merge_in.existing_value != nullptr) { | |
17 | merge_out->new_value.assign(merge_in.existing_value->data(), | |
18 | merge_in.existing_value->size()); | |
19 | } | |
20 | for (const rocksdb::Slice& m : merge_in.operand_list) { | |
21 | fprintf(stderr, "Merge(%s)\n", m.ToString().c_str()); | |
22 | // the compaction filter filters out bad values | |
23 | assert(m.ToString() != "bad"); | |
24 | merge_out->new_value.assign(m.data(), m.size()); | |
25 | } | |
26 | return true; | |
27 | } | |
28 | ||
29 | const char* Name() const override { return "MyMerge"; } | |
30 | }; | |
31 | ||
32 | class MyFilter : public rocksdb::CompactionFilter { | |
33 | public: | |
34 | bool Filter(int level, const rocksdb::Slice& key, | |
35 | const rocksdb::Slice& existing_value, std::string* new_value, | |
36 | bool* value_changed) const override { | |
37 | fprintf(stderr, "Filter(%s)\n", key.ToString().c_str()); | |
38 | ++count_; | |
39 | assert(*value_changed == false); | |
40 | return false; | |
41 | } | |
42 | ||
43 | bool FilterMergeOperand(int level, const rocksdb::Slice& key, | |
44 | const rocksdb::Slice& existing_value) const override { | |
45 | fprintf(stderr, "FilterMerge(%s)\n", key.ToString().c_str()); | |
46 | ++merge_count_; | |
47 | return existing_value == "bad"; | |
48 | } | |
49 | ||
50 | const char* Name() const override { return "MyFilter"; } | |
51 | ||
52 | mutable int count_ = 0; | |
53 | mutable int merge_count_ = 0; | |
54 | }; | |
55 | ||
56 | int main() { | |
57 | rocksdb::DB* raw_db; | |
58 | rocksdb::Status status; | |
59 | ||
60 | MyFilter filter; | |
61 | ||
11fdf7f2 TL |
62 | int ret = system("rm -rf /tmp/rocksmergetest"); |
63 | if (ret != 0) { | |
64 | fprintf(stderr, "Error deleting /tmp/rocksmergetest, code: %d\n", ret); | |
65 | return ret; | |
66 | } | |
7c673cae FG |
67 | rocksdb::Options options; |
68 | options.create_if_missing = true; | |
69 | options.merge_operator.reset(new MyMerge); | |
70 | options.compaction_filter = &filter; | |
71 | status = rocksdb::DB::Open(options, "/tmp/rocksmergetest", &raw_db); | |
72 | assert(status.ok()); | |
73 | std::unique_ptr<rocksdb::DB> db(raw_db); | |
74 | ||
75 | rocksdb::WriteOptions wopts; | |
76 | db->Merge(wopts, "0", "bad"); // This is filtered out | |
77 | db->Merge(wopts, "1", "data1"); | |
78 | db->Merge(wopts, "1", "bad"); | |
79 | db->Merge(wopts, "1", "data2"); | |
80 | db->Merge(wopts, "1", "bad"); | |
81 | db->Merge(wopts, "3", "data3"); | |
82 | db->CompactRange(rocksdb::CompactRangeOptions(), nullptr, nullptr); | |
83 | fprintf(stderr, "filter.count_ = %d\n", filter.count_); | |
84 | assert(filter.count_ == 0); | |
85 | fprintf(stderr, "filter.merge_count_ = %d\n", filter.merge_count_); | |
86 | assert(filter.merge_count_ == 6); | |
87 | } |