// Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. #ifndef STORAGE_LEVELDB_INCLUDE_MERGE_OPERATOR_H_ #define STORAGE_LEVELDB_INCLUDE_MERGE_OPERATOR_H_ #include namespace leveldb { class Slice; class Logger; // The Merge Operator interface. // Client needs to provide an object implementing this interface if Merge // operation is accessed. // Essentially, MergeOperator specifies the SEMANTICS of a merge, which only // client knows. It could be numeric addition, list append, string // concatenation, ... , anything. // The library, on the other hand, is concerned with the exercise of this // interface, at the right time (during get, iteration, compaction...) // Note that, even though in principle we don't require any special property // of the merge operator, the current rocksdb compaction order does imply that // an associative operator could be exercised more naturally (and more // efficiently). // // Refer to my_test.cc for an example of implementation // class MergeOperator { public: virtual ~MergeOperator() {} // Gives the client a way to express the read -> modify -> write semantics // key: (IN) The key that's associated with this merge operation. // Client could multiplex the merge operator based on it // if the key space is partitioned and different subspaces // refer to different types of data which have different // merge operation semantics // existing: (IN) null indicates that the key does not exist before this op // value: (IN) The passed-in merge operand value (when Merge is issued) // new_value:(OUT) Client is responsible for filling the merge result here // logger: (IN) Client could use this to log errors during merge. // // Note: Merge does not return anything to indicate if a merge is successful // or not. // Rationale: If a merge failed due to, say de-serialization error, we still // need to define a consistent merge result. Should we throw away // the existing value? the merge operand? Or reset the merged value // to sth? The rocksdb library is not in a position to make the // right choice. On the other hand, client knows exactly what // happened during Merge, thus is able to make the best decision. // Just save the final decision in new_value. logger is passed in, // in case client wants to leave a trace of what went wrong. virtual void Merge(const Slice& key, const Slice* existing_value, const Slice& value, std::string* new_value, Logger* logger) const = 0; // The name of the MergeOperator. Used to check for MergeOperator // mismatches (i.e., a DB created with one MergeOperator is // accessed using a different MergeOperator) // TODO: the name is currently not stored persistently and thus // no checking is enforced. Client is responsible for providing // consistent MergeOperator between DB opens. virtual const char* Name() const = 0; }; } // namespace leveldb #endif // STORAGE_LEVELDB_INCLUDE_MERGE_OPERATOR_H_