c2d7826ced
Summary: Here are the major changes to the Merge Interface. It has been expanded to handle cases where the MergeOperator is not associative. It does so by stacking up merge operations while scanning through the key history (i.e.: during Get() or Compaction), until a valid Put/Delete/end-of-history is encountered; it then applies all of the merge operations in the correct sequence starting with the base/sentinel value. I have also introduced an "AssociativeMerge" function which allows the user to take advantage of associative merge operations (such as in the case of counters). The implementation will always attempt to merge the operations/operands themselves together when they are encountered, and will resort to the "stacking" method if and only if the "associative-merge" fails. This implementation is conjectured to allow MergeOperator to handle the general case, while still providing the user with the ability to take advantage of certain efficiencies in their own merge-operator / data-structure. NOTE: This is a preliminary diff. This must still go through a lot of review, revision, and testing. Feedback welcome! Test Plan: -This is a preliminary diff. I have only just begun testing/debugging it. -I will be testing this with the existing MergeOperator use-cases and unit-tests (counters, string-append, and redis-lists) -I will be "desk-checking" and walking through the code with the help gdb. -I will find a way of stress-testing the new interface / implementation using db_bench, db_test, merge_test, and/or db_stress. -I will ensure that my tests cover all cases: Get-Memtable, Get-Immutable-Memtable, Get-from-Disk, Iterator-Range-Scan, Flush-Memtable-to-L0, Compaction-L0-L1, Compaction-Ln-L(n+1), Put/Delete found, Put/Delete not-found, end-of-history, end-of-file, etc. -A lot of feedback from the reviewers. Reviewers: haobo, dhruba, zshao, emayanke Reviewed By: haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D11499
81 lines
2.4 KiB
C++
81 lines
2.4 KiB
C++
// Copyright (c) 2012 Facebook. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef STORAGE_LEVELDB_DB_DB_IMPL_READONLY_H_
|
|
#define STORAGE_LEVELDB_DB_DB_IMPL_READONLY_H_
|
|
|
|
#include "db/db_impl.h"
|
|
|
|
#include <deque>
|
|
#include <set>
|
|
#include "db/dbformat.h"
|
|
#include "db/log_writer.h"
|
|
#include "db/snapshot.h"
|
|
#include "leveldb/db.h"
|
|
#include "leveldb/env.h"
|
|
#include "port/port.h"
|
|
#include "util/stats_logger.h"
|
|
|
|
#ifdef USE_SCRIBE
|
|
#include "scribe/scribe_logger.h"
|
|
#endif
|
|
|
|
namespace leveldb {
|
|
|
|
class DBImplReadOnly : public DBImpl {
|
|
public:
|
|
DBImplReadOnly(const Options& options, const std::string& dbname);
|
|
virtual ~DBImplReadOnly();
|
|
|
|
// Implementations of the DB interface
|
|
virtual Status Get(const ReadOptions& options,
|
|
const Slice& key,
|
|
std::string* value);
|
|
|
|
// TODO: Implement ReadOnly MultiGet?
|
|
|
|
virtual Iterator* NewIterator(const ReadOptions&);
|
|
|
|
virtual Status Put(const WriteOptions&, const Slice& key, const Slice& value) {
|
|
return Status::NotSupported("Not supported operation in read only mode.");
|
|
}
|
|
virtual Status Merge(const WriteOptions&, const Slice& key,
|
|
const Slice& value) {
|
|
return Status::NotSupported("Not supported operation in read only mode.");
|
|
}
|
|
virtual Status Delete(const WriteOptions&, const Slice& key) {
|
|
return Status::NotSupported("Not supported operation in read only mode.");
|
|
}
|
|
virtual Status Write(const WriteOptions& options, WriteBatch* updates) {
|
|
return Status::NotSupported("Not supported operation in read only mode.");
|
|
}
|
|
virtual void CompactRange(const Slice* begin, const Slice* end,
|
|
bool reduce_level = false) {
|
|
}
|
|
virtual Status DisableFileDeletions() {
|
|
return Status::NotSupported("Not supported operation in read only mode.");
|
|
}
|
|
virtual Status EnableFileDeletions() {
|
|
return Status::NotSupported("Not supported operation in read only mode.");
|
|
}
|
|
virtual Status GetLiveFiles(std::vector<std::string>&,
|
|
uint64_t* manifest_file_size) {
|
|
return Status::NotSupported("Not supported operation in read only mode.");
|
|
}
|
|
virtual Status Flush(const FlushOptions& options) {
|
|
return Status::NotSupported("Not supported operation in read only mode.");
|
|
}
|
|
|
|
private:
|
|
friend class DB;
|
|
|
|
// No copying allowed
|
|
DBImplReadOnly(const DBImplReadOnly&);
|
|
void operator=(const DBImplReadOnly&);
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|