2011-03-18 23:37:00 +01:00
|
|
|
// 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_DB_MEMTABLE_H_
|
|
|
|
#define STORAGE_LEVELDB_DB_MEMTABLE_H_
|
|
|
|
|
|
|
|
#include <string>
|
2013-07-23 23:42:27 +02:00
|
|
|
#include <memory>
|
2011-03-30 20:35:40 +02:00
|
|
|
#include "leveldb/db.h"
|
2011-03-18 23:37:00 +01:00
|
|
|
#include "db/dbformat.h"
|
|
|
|
#include "db/skiplist.h"
|
2012-10-19 23:00:53 +02:00
|
|
|
#include "db/version_set.h"
|
2013-07-23 23:42:27 +02:00
|
|
|
#include "leveldb/memtablerep.h"
|
Make arena block size configurable
Summary:
Add an option for arena block size, default value 4096 bytes. Arena will allocate blocks with such size.
I am not sure about passing parameter to skiplist in the new virtualized framework, though I talked to Jim a bit. So add Jim as reviewer.
Test Plan:
new unit test, I am running db_test.
For passing paramter from configured option to Arena, I tried tests like:
TEST(DBTest, Arena_Option) {
std::string dbname = test::TmpDir() + "/db_arena_option_test";
DestroyDB(dbname, Options());
DB* db = nullptr;
Options opts;
opts.create_if_missing = true;
opts.arena_block_size = 1000000; // tested 99, 999999
Status s = DB::Open(opts, dbname, &db);
db->Put(WriteOptions(), "a", "123");
}
and printed some debug info. The results look good. Any suggestion for such a unit-test?
Reviewers: haobo, dhruba, emayanke, jpaton
Reviewed By: dhruba
CC: leveldb, zshao
Differential Revision: https://reviews.facebook.net/D11799
2013-07-31 21:42:23 +02:00
|
|
|
#include "util/arena_impl.h"
|
2011-03-18 23:37:00 +01:00
|
|
|
|
|
|
|
namespace leveldb {
|
|
|
|
|
|
|
|
class Mutex;
|
|
|
|
class MemTableIterator;
|
|
|
|
|
|
|
|
class MemTable {
|
|
|
|
public:
|
2013-07-23 23:42:27 +02:00
|
|
|
struct KeyComparator : public MemTableRep::KeyComparator {
|
|
|
|
const InternalKeyComparator comparator;
|
|
|
|
explicit KeyComparator(const InternalKeyComparator& c) : comparator(c) { }
|
|
|
|
virtual int operator()(const char* a, const char* b) const;
|
|
|
|
};
|
|
|
|
|
2011-05-21 04:17:43 +02:00
|
|
|
// MemTables are reference counted. The initial reference count
|
|
|
|
// is zero and the caller must call Ref() at least once.
|
Make arena block size configurable
Summary:
Add an option for arena block size, default value 4096 bytes. Arena will allocate blocks with such size.
I am not sure about passing parameter to skiplist in the new virtualized framework, though I talked to Jim a bit. So add Jim as reviewer.
Test Plan:
new unit test, I am running db_test.
For passing paramter from configured option to Arena, I tried tests like:
TEST(DBTest, Arena_Option) {
std::string dbname = test::TmpDir() + "/db_arena_option_test";
DestroyDB(dbname, Options());
DB* db = nullptr;
Options opts;
opts.create_if_missing = true;
opts.arena_block_size = 1000000; // tested 99, 999999
Status s = DB::Open(opts, dbname, &db);
db->Put(WriteOptions(), "a", "123");
}
and printed some debug info. The results look good. Any suggestion for such a unit-test?
Reviewers: haobo, dhruba, emayanke, jpaton
Reviewed By: dhruba
CC: leveldb, zshao
Differential Revision: https://reviews.facebook.net/D11799
2013-07-31 21:42:23 +02:00
|
|
|
explicit MemTable(
|
|
|
|
const InternalKeyComparator& comparator,
|
|
|
|
std::shared_ptr<MemTableRepFactory> table_factory,
|
|
|
|
int numlevel = 7,
|
|
|
|
const Options& options = Options());
|
2011-05-21 04:17:43 +02:00
|
|
|
|
|
|
|
// Increase reference count.
|
|
|
|
void Ref() { ++refs_; }
|
|
|
|
|
|
|
|
// Drop reference count. Delete if no more references exist.
|
|
|
|
void Unref() {
|
|
|
|
--refs_;
|
|
|
|
assert(refs_ >= 0);
|
|
|
|
if (refs_ <= 0) {
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
}
|
2011-03-18 23:37:00 +01:00
|
|
|
|
|
|
|
// Returns an estimate of the number of bytes of data in use by this
|
|
|
|
// data structure.
|
|
|
|
//
|
|
|
|
// REQUIRES: external synchronization to prevent simultaneous
|
|
|
|
// operations on the same MemTable.
|
|
|
|
size_t ApproximateMemoryUsage();
|
|
|
|
|
|
|
|
// Return an iterator that yields the contents of the memtable.
|
|
|
|
//
|
|
|
|
// The caller must ensure that the underlying MemTable remains live
|
|
|
|
// while the returned iterator is live. The keys returned by this
|
|
|
|
// iterator are internal keys encoded by AppendInternalKey in the
|
2013-01-04 02:13:56 +01:00
|
|
|
// db/dbformat.{h,cc} module.
|
2011-03-18 23:37:00 +01:00
|
|
|
Iterator* NewIterator();
|
|
|
|
|
|
|
|
// Add an entry into memtable that maps key to value at the
|
|
|
|
// specified sequence number and with the specified type.
|
|
|
|
// Typically value will be empty if type==kTypeDeletion.
|
|
|
|
void Add(SequenceNumber seq, ValueType type,
|
|
|
|
const Slice& key,
|
|
|
|
const Slice& value);
|
|
|
|
|
2011-06-22 04:36:45 +02:00
|
|
|
// If memtable contains a value for key, store it in *value and return true.
|
|
|
|
// If memtable contains a deletion for key, store a NotFound() error
|
|
|
|
// in *status and return true.
|
2013-03-21 23:59:47 +01:00
|
|
|
// If memtable contains Merge operation as the most recent entry for a key,
|
2013-07-26 21:57:01 +02:00
|
|
|
// and the merge process does not stop (not reaching a value or delete),
|
2013-03-21 23:59:47 +01:00
|
|
|
// store the current merged result in value and MergeInProgress in s.
|
|
|
|
// return false
|
2011-06-22 04:36:45 +02:00
|
|
|
// Else, return false.
|
2013-03-21 23:59:47 +01:00
|
|
|
bool Get(const LookupKey& key, std::string* value, Status* s,
|
2013-07-26 21:57:01 +02:00
|
|
|
const Options& options);
|
2011-06-22 04:36:45 +02:00
|
|
|
|
2012-10-19 23:00:53 +02:00
|
|
|
// Returns the edits area that is needed for flushing the memtable
|
|
|
|
VersionEdit* GetEdits() { return &edit_; }
|
|
|
|
|
2013-02-28 23:09:30 +01:00
|
|
|
// Returns the sequence number of the first element that was inserted
|
|
|
|
// into the memtable
|
|
|
|
SequenceNumber GetFirstSequenceNumber() { return first_seqno_; }
|
|
|
|
|
2013-06-11 23:23:58 +02:00
|
|
|
// Returns the logfile number that can be safely deleted when this
|
|
|
|
// memstore is flushed to storage
|
|
|
|
uint64_t GetLogNumber() { return mem_logfile_number_; }
|
|
|
|
|
|
|
|
// Sets the logfile number that can be safely deleted when this
|
|
|
|
// memstore is flushed to storage
|
|
|
|
void SetLogNumber(uint64_t num) { mem_logfile_number_ = num; }
|
|
|
|
|
2011-03-18 23:37:00 +01:00
|
|
|
private:
|
2011-05-21 04:17:43 +02:00
|
|
|
~MemTable(); // Private since only Unref() should be used to delete it
|
2011-03-18 23:37:00 +01:00
|
|
|
friend class MemTableIterator;
|
|
|
|
friend class MemTableBackwardIterator;
|
2012-10-19 23:00:53 +02:00
|
|
|
friend class MemTableList;
|
2011-03-18 23:37:00 +01:00
|
|
|
|
|
|
|
KeyComparator comparator_;
|
2011-05-21 04:17:43 +02:00
|
|
|
int refs_;
|
Make arena block size configurable
Summary:
Add an option for arena block size, default value 4096 bytes. Arena will allocate blocks with such size.
I am not sure about passing parameter to skiplist in the new virtualized framework, though I talked to Jim a bit. So add Jim as reviewer.
Test Plan:
new unit test, I am running db_test.
For passing paramter from configured option to Arena, I tried tests like:
TEST(DBTest, Arena_Option) {
std::string dbname = test::TmpDir() + "/db_arena_option_test";
DestroyDB(dbname, Options());
DB* db = nullptr;
Options opts;
opts.create_if_missing = true;
opts.arena_block_size = 1000000; // tested 99, 999999
Status s = DB::Open(opts, dbname, &db);
db->Put(WriteOptions(), "a", "123");
}
and printed some debug info. The results look good. Any suggestion for such a unit-test?
Reviewers: haobo, dhruba, emayanke, jpaton
Reviewed By: dhruba
CC: leveldb, zshao
Differential Revision: https://reviews.facebook.net/D11799
2013-07-31 21:42:23 +02:00
|
|
|
ArenaImpl arena_impl_;
|
2013-07-23 23:42:27 +02:00
|
|
|
shared_ptr<MemTableRep> table_;
|
2011-03-18 23:37:00 +01:00
|
|
|
|
2012-10-19 23:00:53 +02:00
|
|
|
// These are used to manage memtable flushes to storage
|
2012-11-29 01:42:36 +01:00
|
|
|
bool flush_in_progress_; // started the flush
|
2012-10-19 23:00:53 +02:00
|
|
|
bool flush_completed_; // finished the flush
|
|
|
|
uint64_t file_number_; // filled up after flush is complete
|
|
|
|
|
|
|
|
// The udpates to be applied to the transaction log when this
|
|
|
|
// memtable is flushed to storage.
|
|
|
|
VersionEdit edit_;
|
|
|
|
|
2013-02-28 23:09:30 +01:00
|
|
|
// The sequence number of the kv that was inserted first
|
|
|
|
SequenceNumber first_seqno_;
|
|
|
|
|
2013-06-11 23:23:58 +02:00
|
|
|
// The log files earlier than this number can be deleted.
|
|
|
|
uint64_t mem_logfile_number_;
|
|
|
|
|
2011-03-18 23:37:00 +01:00
|
|
|
// No copying allowed
|
|
|
|
MemTable(const MemTable&);
|
|
|
|
void operator=(const MemTable&);
|
|
|
|
};
|
|
|
|
|
2011-10-31 18:22:06 +01:00
|
|
|
} // namespace leveldb
|
2011-03-18 23:37:00 +01:00
|
|
|
|
|
|
|
#endif // STORAGE_LEVELDB_DB_MEMTABLE_H_
|