]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kv: drop the MemDB backend.
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Fri, 24 Jul 2020 08:13:41 +0000 (08:13 +0000)
committerRadosław Zarzyński <rzarzyns@redhat.com>
Mon, 23 May 2022 12:45:31 +0000 (14:45 +0200)
It's an experimental feature since 2016. It doesn't seem to be
used anywhere nor actively maintained. However, it's the sole
major user of `ceph::buffer::ptr::clone()` which could have
been dropped otherwise.

Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/kv/CMakeLists.txt
src/kv/KeyValueDB.cc
src/kv/MemDB.cc [deleted file]
src/kv/MemDB.h [deleted file]

index f797aea11355c2dba621a568565db98cdc056d4e..9121a6257cc03ab214c91a844b6c4978572848aa 100644 (file)
@@ -1,6 +1,5 @@
 set(kv_srcs
   KeyValueDB.cc
-  MemDB.cc
   RocksDBStore.cc
   KeyValueHistogram.cc
   rocksdb_cache/ShardedCache.cc
index c42968bbe184ab713092edc05a064f528b797fcf..83040023dff3c2b6417a115a5b7369ec32a202f6 100644 (file)
@@ -2,7 +2,6 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "KeyValueDB.h"
-#include "MemDB.h"
 #include "RocksDBStore.h"
 
 using std::map;
@@ -16,10 +15,6 @@ KeyValueDB *KeyValueDB::create(CephContext *cct, const string& type,
   if (type == "rocksdb") {
     return new RocksDBStore(cct, dir, options, p);
   }
-  if ((type == "memdb") && 
-    cct->check_experimental_feature_enabled("memdb")) {
-    return new MemDB(cct, dir, p);
-  }
   return NULL;
 }
 
@@ -28,8 +23,5 @@ int KeyValueDB::test_init(const string& type, const string& dir)
   if (type == "rocksdb") {
     return RocksDBStore::_test_init(dir);
   }
-  if (type == "memdb") {
-    return MemDB::_test_init(dir);
-  }
   return -EINVAL;
 }
diff --git a/src/kv/MemDB.cc b/src/kv/MemDB.cc
deleted file mode 100644 (file)
index f69bf1e..0000000
+++ /dev/null
@@ -1,657 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * In-memory crash non-safe keyvalue db
- * Author: Ramesh Chander, Ramesh.Chander@sandisk.com
- */
-
-#include "include/compat.h"
-#include <filesystem>
-#include <set>
-#include <map>
-#include <string>
-#include <memory>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "common/perf_counters.h"
-#include "common/debug.h"
-#include "include/str_list.h"
-#include "include/str_map.h"
-#include "KeyValueDB.h"
-#include "MemDB.h"
-
-#include "include/ceph_assert.h"
-#include "common/debug.h"
-#include "common/errno.h"
-#include "include/buffer.h"
-#include "include/buffer_raw.h"
-#include "include/compat.h"
-
-#define dout_context g_ceph_context
-#define dout_subsys ceph_subsys_memdb
-#undef dout_prefix
-#define dout_prefix *_dout << "memdb: "
-#define dtrace dout(30)
-#define dwarn dout(0)
-#define dinfo dout(0)
-
-namespace fs = std::filesystem;
-
-using std::cerr;
-using std::ostream;
-using std::string;
-using std::vector;
-
-using ceph::bufferlist;
-using ceph::bufferptr;
-using ceph::decode;
-using ceph::encode;
-
-static void split_key(const string& raw_key, string *prefix, string *key)
-{
-  size_t pos = raw_key.find(KEY_DELIM, 0);
-  ceph_assert(pos != std::string::npos);
-  *prefix = raw_key.substr(0, pos);
-  *key = raw_key.substr(pos + 1, raw_key.length());
-}
-
-static string make_key(const string &prefix, const string &value)
-{
-  string out = prefix;
-  out.push_back(KEY_DELIM);
-  out.append(value);
-  return out;
-}
-
-void MemDB::_encode(mdb_iter_t iter, bufferlist &bl)
-{
-  encode(iter->first, bl);
-  encode(iter->second, bl);
-}
-
-std::string MemDB::_get_data_fn()
-{
-  string fn = m_db_path + "/" + "MemDB.db";
-  return fn;
-}
-
-void MemDB::_save()
-{
-  std::lock_guard<std::mutex> l(m_lock);
-  dout(10) << __func__ << " Saving MemDB to file: "<< _get_data_fn().c_str() << dendl;
-  int mode = 0644;
-  int fd = TEMP_FAILURE_RETRY(::open(_get_data_fn().c_str(),
-                                     O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode));
-  if (fd < 0) {
-    int err = errno;
-    cerr << "write_file(" << _get_data_fn().c_str() << "): failed to open file: "
-         << cpp_strerror(err) << std::endl;
-    return;
-  }
-  bufferlist bl;
-  mdb_iter_t iter = m_map.begin();
-  while (iter != m_map.end()) {
-    dout(10) << __func__ << " Key:"<< iter->first << dendl;
-    _encode(iter, bl);
-    ++iter;
-  }
-  bl.write_fd(fd);
-
-  VOID_TEMP_FAILURE_RETRY(::close(fd));
-}
-
-int MemDB::_load()
-{
-  std::lock_guard<std::mutex> l(m_lock);
-  dout(10) << __func__ << " Reading MemDB from file: "<< _get_data_fn().c_str() << dendl;
-  /*
-   * Open file and read it in single shot.
-   */
-  int fd = TEMP_FAILURE_RETRY(::open(_get_data_fn().c_str(), O_RDONLY|O_CLOEXEC));
-  if (fd < 0) {
-    int err = errno;
-    cerr << "can't open " << _get_data_fn().c_str() << ": "
-         << cpp_strerror(err) << std::endl;
-    return -err;
-  }
-
-  struct stat st;
-  memset(&st, 0, sizeof(st));
-  if (::fstat(fd, &st) < 0) {
-    int err = errno;
-    cerr << "can't stat file " << _get_data_fn().c_str() << ": "
-         << cpp_strerror(err) << std::endl;
-    VOID_TEMP_FAILURE_RETRY(::close(fd));
-    return -err;
-  }
-
-  ssize_t file_size = st.st_size;
-  ssize_t bytes_done = 0;
-  while (bytes_done < file_size) {
-    string key;
-    bufferptr datap;
-
-    bytes_done += ceph::decode_file(fd, key);
-    bytes_done += ceph::decode_file(fd, datap);
-
-    dout(10) << __func__ << " Key:"<< key << dendl;
-    m_map[key] = datap;
-    m_total_bytes += datap.length();
-  }
-  VOID_TEMP_FAILURE_RETRY(::close(fd));
-  return 0;
-}
-
-int MemDB::_init(bool create)
-{
-  int r = 0;
-  dout(1) << __func__ << dendl;
-  if (create) {
-    if (fs::exists(m_db_path)) {
-      r = 0; // ignore EEXIST
-    } else {
-      std::error_code ec;
-      if (!fs::create_directory(m_db_path, ec)) {
-       derr << __func__ << " mkdir failed: " << ec.message() << dendl;
-       return -ec.value();
-      }
-      fs::permissions(m_db_path, fs::perms::owner_all);
-    }
-  } else {
-    r = _load();
-  }
-
-  PerfCountersBuilder plb(g_ceph_context, "memdb", l_memdb_first, l_memdb_last);
-  plb.add_u64_counter(l_memdb_gets, "get", "Gets");
-  plb.add_u64_counter(l_memdb_txns, "submit_transaction", "Submit transactions");
-  plb.add_time_avg(l_memdb_get_latency, "get_latency", "Get latency");
-  plb.add_time_avg(l_memdb_submit_latency, "submit_latency", "Submit Latency");
-  logger = plb.create_perf_counters();
-  m_cct->get_perfcounters_collection()->add(logger);
-
-  return r;
-}
-
-int MemDB::set_merge_operator(
-  const string& prefix,
-  std::shared_ptr<KeyValueDB::MergeOperator> mop)
-{
-  merge_ops.push_back(std::make_pair(prefix, mop));
-  return 0;
-}
-
-int MemDB::do_open(ostream &out, bool create)
-{
-  m_total_bytes = 0;
-  m_allocated_bytes = 1;
-
-  return _init(create);
-}
-
-int MemDB::open(ostream &out, const std::string& cfs) {
-  if (!cfs.empty()) {
-    ceph_abort_msg("Not implemented");
-  }
-  return do_open(out, false);
-}
-
-int MemDB::create_and_open(ostream &out, const std::string& cfs) {
-  if (!cfs.empty()) {
-    ceph_abort_msg("Not implemented");
-  }
-  return do_open(out, true);
-}
-
-MemDB::~MemDB()
-{
-  close();
-  dout(10) << __func__ << " Destroying MemDB instance: "<< dendl;
-}
-
-void MemDB::close()
-{
-  /*
-   * Save whatever in memory btree.
-   */
-  _save();
-  if (logger)
-    m_cct->get_perfcounters_collection()->remove(logger);
-}
-
-int MemDB::submit_transaction(KeyValueDB::Transaction t)
-{
-  utime_t start = ceph_clock_now();
-
-  MDBTransactionImpl* mt =  static_cast<MDBTransactionImpl*>(t.get());
-
-  dtrace << __func__ << " " << mt->get_ops().size() << dendl;
-  for(auto& op : mt->get_ops()) {
-    if(op.first == MDBTransactionImpl::WRITE) {
-      ms_op_t set_op = op.second;
-      _setkey(set_op);
-    } else if (op.first == MDBTransactionImpl::MERGE) {
-      ms_op_t merge_op = op.second;
-      _merge(merge_op);
-    } else {
-      ms_op_t rm_op = op.second;
-      ceph_assert(op.first == MDBTransactionImpl::DELETE);
-      _rmkey(rm_op);
-    }
-  }
-
-  utime_t lat = ceph_clock_now() - start;
-  logger->inc(l_memdb_txns);
-  logger->tinc(l_memdb_submit_latency, lat);
-
-  return 0;
-}
-
-int MemDB::submit_transaction_sync(KeyValueDB::Transaction tsync)
-{
-  dtrace << __func__ << " " << dendl;
-  submit_transaction(tsync);
-  return 0;
-}
-
-int MemDB::transaction_rollback(KeyValueDB::Transaction t)
-{
-  MDBTransactionImpl* mt =  static_cast<MDBTransactionImpl*>(t.get());
-  mt->clear();
-  return 0;
-}
-
-void MemDB::MDBTransactionImpl::set(
-  const string &prefix, const string &k, const bufferlist &to_set_bl)
-{
-  dtrace << __func__ << " " << prefix << " " << k << dendl;
-  ops.push_back(make_pair(WRITE, std::make_pair(std::make_pair(prefix, k),
-                  to_set_bl)));
-}
-
-void MemDB::MDBTransactionImpl::rmkey(const string &prefix,
-    const string &k)
-{
-  dtrace << __func__ << " " << prefix << " " << k << dendl;
-  ops.push_back(make_pair(DELETE,
-                          std::make_pair(std::make_pair(prefix, k),
-                          bufferlist())));
-}
-
-void MemDB::MDBTransactionImpl::rmkeys_by_prefix(const string &prefix)
-{
-  KeyValueDB::Iterator it = m_db->get_iterator(prefix);
-  for (it->seek_to_first(); it->valid(); it->next()) {
-    rmkey(prefix, it->key());
-  }
-}
-
-void MemDB::MDBTransactionImpl::rm_range_keys(const string &prefix, const string &start, const string &end)
-{
-  KeyValueDB::Iterator it = m_db->get_iterator(prefix);
-  it->lower_bound(start);
-  while (it->valid()) {
-    if (it->key() >= end) {
-      break;
-    }
-    rmkey(prefix, it->key());
-    it->next();
-  }
-}
-
-void MemDB::MDBTransactionImpl::merge(
-  const std::string &prefix, const std::string &key, const bufferlist  &value)
-{
-
-  dtrace << __func__ << " " << prefix << " " << key << dendl;
-  ops.push_back(make_pair(MERGE, make_pair(std::make_pair(prefix, key), value)));
-  return;
-}
-
-int MemDB::_setkey(ms_op_t &op)
-{
-  std::lock_guard<std::mutex> l(m_lock);
-  std::string key = make_key(op.first.first, op.first.second);
-  bufferlist bl = op.second;
-
-  m_total_bytes += bl.length();
-
-  bufferlist bl_old;
-  if (_get(op.first.first, op.first.second, &bl_old)) {
-    /*
-     * delete and free existing key.
-     */
-    ceph_assert(m_total_bytes >= bl_old.length());
-    m_total_bytes -= bl_old.length();
-    m_map.erase(key);
-  }
-
-  m_map[key] = bufferptr((char *) bl.c_str(), bl.length());
-  iterator_seq_no++;
-  return 0;
-}
-
-int MemDB::_rmkey(ms_op_t &op)
-{
-  std::lock_guard<std::mutex> l(m_lock);
-  std::string key = make_key(op.first.first, op.first.second);
-
-  bufferlist bl_old;
-  if (_get(op.first.first, op.first.second, &bl_old)) {
-    ceph_assert(m_total_bytes >= bl_old.length());
-    m_total_bytes -= bl_old.length();
-  }
-  iterator_seq_no++;
-  /*
-   * Erase will call the destructor for bufferptr.
-   */
-  return m_map.erase(key);
-}
-
-std::shared_ptr<KeyValueDB::MergeOperator> MemDB::_find_merge_op(const std::string &prefix)
-{
-  for (const auto& i : merge_ops) {
-    if (i.first == prefix) {
-      return i.second;
-    }
-  }
-
-  dtrace << __func__ << " No merge op for " << prefix << dendl;
-  return NULL;
-}
-
-
-int MemDB::_merge(ms_op_t &op)
-{
-  std::lock_guard<std::mutex> l(m_lock);
-  std::string prefix = op.first.first;
-  std::string key = make_key(op.first.first, op.first.second);
-  bufferlist bl = op.second;
-  int64_t bytes_adjusted = bl.length();
-
-  /*
-   *  find the operator for this prefix
-   */
-  std::shared_ptr<MergeOperator> mop = _find_merge_op(prefix);
-  ceph_assert(mop);
-
-  /*
-   * call the merge operator with value and non value
-   */
-  bufferlist bl_old;
-  if (_get(op.first.first, op.first.second, &bl_old) == false) {
-    std::string new_val;
-    /*
-     * Merge non existent.
-     */
-    mop->merge_nonexistent(bl.c_str(), bl.length(), &new_val);
-    m_map[key] = bufferptr(new_val.c_str(), new_val.length());
-  } else {
-    /*
-     * Merge existing.
-     */
-    std::string new_val;
-    mop->merge(bl_old.c_str(), bl_old.length(), bl.c_str(), bl.length(), &new_val);
-    m_map[key] = bufferptr(new_val.c_str(), new_val.length());
-    bytes_adjusted -= bl_old.length();
-    bl_old.clear();
-  }
-
-  ceph_assert((int64_t)m_total_bytes + bytes_adjusted >= 0);
-  m_total_bytes += bytes_adjusted;
-  iterator_seq_no++;
-  return 0;
-}
-
-/*
- * Caller take btree lock.
- */
-bool MemDB::_get(const string &prefix, const string &k, bufferlist *out)
-{
-  string key = make_key(prefix, k);
-
-  mdb_iter_t iter = m_map.find(key);
-  if (iter == m_map.end()) {
-    return false;
-  }
-
-  out->push_back((m_map[key].clone()));
-  return true;
-}
-
-bool MemDB::_get_locked(const string &prefix, const string &k, bufferlist *out)
-{
-  std::lock_guard<std::mutex> l(m_lock);
-  return _get(prefix, k, out);
-}
-
-
-int MemDB::get(const string &prefix, const std::string& key,
-                 bufferlist *out)
-{
-  utime_t start = ceph_clock_now();
-  int ret;
-
-  if (_get_locked(prefix, key, out)) {
-    ret = 0;
-  } else {
-    ret = -ENOENT;
-  }
-
-  utime_t lat = ceph_clock_now() - start;
-  logger->inc(l_memdb_gets);
-  logger->tinc(l_memdb_get_latency, lat);
-
-  return ret;
-}
-
-int MemDB::get(const string &prefix, const std::set<string> &keys,
-    std::map<string, bufferlist> *out)
-{
-  utime_t start = ceph_clock_now();
-
-  for (const auto& i : keys) {
-    bufferlist bl;
-    if (_get_locked(prefix, i, &bl))
-      out->insert(make_pair(i, bl));
-  }
-
-  utime_t lat = ceph_clock_now() - start;
-  logger->inc(l_memdb_gets);
-  logger->tinc(l_memdb_get_latency, lat);
-
-  return 0;
-}
-
-void MemDB::MDBWholeSpaceIteratorImpl::fill_current()
-{
-  bufferlist bl;
-  bl.push_back(m_iter->second.clone());
-  m_key_value = std::make_pair(m_iter->first, bl);
-}
-
-bool MemDB::MDBWholeSpaceIteratorImpl::valid()
-{
-  if (m_key_value.first.empty()) {
-    return false;
-  }
-  return true;
-}
-
-bool MemDB::MDBWholeSpaceIteratorImpl::iterator_validate() {
-
-  if (this_seq_no != *global_seq_no) {
-    auto key = m_key_value.first;
-    ceph_assert(!key.empty());
-
-    bool restart_iter = false;
-    if (!m_using_btree) {
-      /*
-       * Map is modified and marker key does not exists, 
-       * restart the iterator from next key.
-       */
-      if (m_map_p->find(key) == m_map_p->end()) {
-        restart_iter = true;
-      }
-    } else {
-      restart_iter = true;
-    }
-
-    if (restart_iter) {
-      m_iter = m_map_p->lower_bound(key);
-      if (m_iter == m_map_p->end()) {
-        return false;
-      }
-    }
-
-    /*
-     * This iter is valid now.
-     */
-    this_seq_no = *global_seq_no;
-  }
-
-  return true;
-}
-
-void
-MemDB::MDBWholeSpaceIteratorImpl::free_last()
-{
-  m_key_value.first.clear();
-  m_key_value.second.clear();
-}
-
-string MemDB::MDBWholeSpaceIteratorImpl::key()
-{
-  dtrace << __func__ << " " << m_key_value.first << dendl;
-  string prefix, key;
-  split_key(m_key_value.first, &prefix, &key);
-  return key;
-}
-
-std::pair<string,string> MemDB::MDBWholeSpaceIteratorImpl::raw_key()
-{
-  string prefix, key;
-  split_key(m_key_value.first, &prefix, &key);
-  return { prefix, key };
-}
-
-bool MemDB::MDBWholeSpaceIteratorImpl::raw_key_is_prefixed(
-    const string &prefix)
-{
-  string p, k;
-  split_key(m_key_value.first, &p, &k);
-  return (p == prefix);
-}
-
-bufferlist MemDB::MDBWholeSpaceIteratorImpl::value()
-{
-  dtrace << __func__ << " " << m_key_value << dendl;
-  return m_key_value.second;
-}
-
-int MemDB::MDBWholeSpaceIteratorImpl::next()
-{
-  std::lock_guard<std::mutex> l(*m_map_lock_p);
-  if (!iterator_validate()) {
-    free_last();
-    return -1;
-  }
-  free_last();
-  ++m_iter;
-  if (m_iter != m_map_p->end()) {
-    fill_current();
-    return 0;
-  } else {
-    return -1;
-  }
-}
-
-int MemDB::MDBWholeSpaceIteratorImpl:: prev()
-{
-  std::lock_guard<std::mutex> l(*m_map_lock_p);
-  if (!iterator_validate()) {
-    free_last();
-    return -1;
-  }
-  free_last();
-  if (m_iter != m_map_p->begin()) {
-    --m_iter;
-    fill_current();
-    return 0;
-  } else {
-    return -1;
-  }
-}
-
-/*
- * First key >= to given key, if key is null then first key in btree.
- */
-int MemDB::MDBWholeSpaceIteratorImpl::seek_to_first(const std::string &k)
-{
-  std::lock_guard<std::mutex> l(*m_map_lock_p);
-  free_last();
-  if (k.empty()) {
-    m_iter = m_map_p->begin();
-  } else {
-    m_iter = m_map_p->lower_bound(k);
-  }
-  
-  if (m_iter == m_map_p->end()) {
-    return -1;
-  }
-  fill_current();
-  return 0;
-}
-
-int MemDB::MDBWholeSpaceIteratorImpl::seek_to_last(const std::string &k)
-{
-  std::lock_guard<std::mutex> l(*m_map_lock_p);
-  free_last();
-  if (k.empty()) {
-    m_iter = m_map_p->end();
-    --m_iter;
-  } else {
-    m_iter = m_map_p->lower_bound(k);
-  }
-
-  if (m_iter == m_map_p->end()) {
-    return -1;
-  }
-  fill_current();
-  return 0;
-}
-
-MemDB::MDBWholeSpaceIteratorImpl::~MDBWholeSpaceIteratorImpl()
-{
-  free_last();
-}
-
-int MemDB::MDBWholeSpaceIteratorImpl::upper_bound(const std::string &prefix,
-    const std::string &after) {
-
-  std::lock_guard<std::mutex> l(*m_map_lock_p);
-
-  dtrace << "upper_bound " << prefix.c_str() << after.c_str() << dendl;
-  string k = make_key(prefix, after);
-  m_iter = m_map_p->upper_bound(k);
-  if (m_iter != m_map_p->end()) {
-    fill_current();
-    return 0;
-  }
-  return -1;
-}
-
-int MemDB::MDBWholeSpaceIteratorImpl::lower_bound(const std::string &prefix,
-    const std::string &to) {
-  std::lock_guard<std::mutex> l(*m_map_lock_p);
-  dtrace << "lower_bound " << prefix.c_str() << to.c_str() << dendl;
-  string k = make_key(prefix, to);
-  m_iter = m_map_p->lower_bound(k);
-  if (m_iter != m_map_p->end()) {
-    fill_current();
-    return 0;
-  }
-  return -1;
-}
diff --git a/src/kv/MemDB.h b/src/kv/MemDB.h
deleted file mode 100644 (file)
index 32d81db..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * In-memory crash non-safe keyvalue db
- * Author: Ramesh Chander, Ramesh.Chander@sandisk.com
- */
-
-#ifndef CEPH_OS_BLUESTORE_MEMDB_H
-#define CEPH_OS_BLUESTORE_MEMDB_H
-
-#include "include/buffer.h"
-#include <ostream>
-#include <set>
-#include <map>
-#include <string>
-#include <memory>
-#include <boost/scoped_ptr.hpp>
-#include "include/common_fwd.h"
-#include "include/encoding.h"
-#include "include/btree_map.h"
-#include "KeyValueDB.h"
-#include "osd/osd_types.h"
-
-#define KEY_DELIM '\0' 
-
-
-enum {
-  l_memdb_first = 34440,
-  l_memdb_gets,
-  l_memdb_txns,
-  l_memdb_get_latency,
-  l_memdb_submit_latency,
-  l_memdb_last,
-};
-
-class MemDB : public KeyValueDB
-{
-  typedef std::pair<std::pair<std::string, std::string>, ceph::bufferlist> ms_op_t;
-  std::mutex m_lock;
-  uint64_t m_total_bytes;
-  uint64_t m_allocated_bytes;
-
-  typedef std::map<std::string, ceph::bufferptr> mdb_map_t;
-  typedef mdb_map_t::iterator mdb_iter_t;
-  bool m_using_btree;
-
-  mdb_map_t m_map;
-
-  CephContext *m_cct;
-  PerfCounters *logger;
-  void* m_priv;
-  std::string m_options;
-  std::string m_db_path;
-
-  int transaction_rollback(KeyValueDB::Transaction t);
-  int _open(std::ostream &out);
-  void close() override;
-  bool _get(const std::string &prefix, const std::string &k, ceph::bufferlist *out);
-  bool _get_locked(const std::string &prefix, const std::string &k, ceph::bufferlist *out);
-  std::string _get_data_fn();
-  void _encode(mdb_iter_t iter, ceph::bufferlist &bl);
-  void _save();
-  int _load();
-  uint64_t iterator_seq_no;
-
-public:
-  MemDB(CephContext *c, const std::string &path, void *p) :
-    m_total_bytes(0), m_allocated_bytes(0), m_using_btree(false),
-    m_cct(c), logger(NULL), m_priv(p), m_db_path(path), iterator_seq_no(1)
-  {
-    //Nothing as of now
-  }
-
-  ~MemDB() override;
-  int set_merge_operator(const std::string& prefix,
-         std::shared_ptr<MergeOperator> mop) override;
-
-  std::shared_ptr<MergeOperator> _find_merge_op(const std::string &prefix);
-
-  static
-  int _test_init(const std::string& dir) { return 0; };
-
-  class MDBTransactionImpl : public KeyValueDB::TransactionImpl {
-    public:
-      enum op_type { WRITE = 1, MERGE = 2, DELETE = 3};
-    private:
-
-      std::vector<std::pair<op_type, ms_op_t>> ops;
-      MemDB *m_db;
-
-    bool key_is_prefixed(const std::string &prefix, const std::string& full_key);
-    public:
-      const std::vector<std::pair<op_type, ms_op_t>>&
-        get_ops() { return ops; };
-
-    void set(const std::string &prefix, const std::string &key,
-            const ceph::bufferlist &val) override;
-    using KeyValueDB::TransactionImpl::set;
-    void rmkey(const std::string &prefix, const std::string &k) override;
-    using KeyValueDB::TransactionImpl::rmkey;
-    void rmkeys_by_prefix(const std::string &prefix) override;
-    void rm_range_keys(
-      const std::string &prefix,
-      const std::string &start,
-      const std::string &end) override;
-
-    void merge(const std::string &prefix, const std::string &key,
-              const ceph::bufferlist  &value) override;
-    void clear() {
-      ops.clear();
-    }
-    explicit MDBTransactionImpl(MemDB* _db) :m_db(_db)
-    {
-      ops.clear();
-    }
-    ~MDBTransactionImpl() override {};
-  };
-
-private:
-
-  /*
-   * Transaction states.
-   */
-  int _merge(const std::string &k, ceph::bufferptr &bl);
-  int _merge(ms_op_t &op);
-  int _setkey(ms_op_t &op);
-  int _rmkey(ms_op_t &op);
-
-public:
-
-  int init(std::string option_str="") override { m_options = option_str; return 0; }
-  int _init(bool format);
-
-  int do_open(std::ostream &out, bool create);
-  int open(std::ostream &out, const std::string& cfs="") override;
-  int create_and_open(std::ostream &out, const std::string& cfs="") override;
-  using KeyValueDB::create_and_open;
-
-  KeyValueDB::Transaction get_transaction() override {
-    return std::shared_ptr<MDBTransactionImpl>(new MDBTransactionImpl(this));
-  }
-
-  int submit_transaction(Transaction) override;
-  int submit_transaction_sync(Transaction) override;
-
-  int get(const std::string &prefix, const std::set<std::string> &key,
-         std::map<std::string, ceph::bufferlist> *out) override;
-
-  int get(const std::string &prefix, const std::string &key,
-          ceph::bufferlist *out) override;
-
-  using KeyValueDB::get;
-
-  class MDBWholeSpaceIteratorImpl : public KeyValueDB::WholeSpaceIteratorImpl {
-
-      mdb_iter_t m_iter;
-      std::pair<std::string, ceph::bufferlist> m_key_value;
-      mdb_map_t *m_map_p;
-      std::mutex *m_map_lock_p;
-      uint64_t *global_seq_no;
-      uint64_t this_seq_no;
-      bool m_using_btree;
-
-  public:
-    MDBWholeSpaceIteratorImpl(mdb_map_t *btree_p, std::mutex *btree_lock_p,
-                              uint64_t *iterator_seq_no, bool using_btree) {
-      m_map_p = btree_p;
-      m_map_lock_p = btree_lock_p;
-      std::lock_guard<std::mutex> l(*m_map_lock_p);
-      global_seq_no = iterator_seq_no;
-      this_seq_no = *iterator_seq_no;
-      m_using_btree = using_btree;
-    }
-
-    void fill_current();
-    void free_last();
-
-
-    int seek_to_first(const std::string &k) override;
-    int seek_to_last(const std::string &k) override;
-
-    int seek_to_first() override { return seek_to_first(std::string()); };
-    int seek_to_last() override { return seek_to_last(std::string()); };
-
-    int upper_bound(const std::string &prefix, const std::string &after) override;
-    int lower_bound(const std::string &prefix, const std::string &to) override;
-    bool valid() override;
-    bool iterator_validate();
-
-    int next() override;
-    int prev() override;
-    int status() override { return 0; };
-
-    std::string key() override;
-    std::pair<std::string,std::string> raw_key() override;
-    bool raw_key_is_prefixed(const std::string &prefix) override;
-    ceph::bufferlist value() override;
-    ~MDBWholeSpaceIteratorImpl() override;
-  };
-
-  uint64_t get_estimated_size(std::map<std::string,uint64_t> &extra) override {
-      std::lock_guard<std::mutex> l(m_lock);
-      return m_allocated_bytes;
-  };
-
-  int get_statfs(struct store_statfs_t *buf) override {
-    std::lock_guard<std::mutex> l(m_lock);
-    buf->reset();
-    buf->total = m_total_bytes;
-    buf->allocated = m_allocated_bytes;
-    buf->data_stored = m_total_bytes;
-    return 0;
-  }
-
-  WholeSpaceIterator get_wholespace_iterator(IteratorOpts opts = 0) override {
-    return std::shared_ptr<KeyValueDB::WholeSpaceIteratorImpl>(
-      new MDBWholeSpaceIteratorImpl(&m_map, &m_lock, &iterator_seq_no, m_using_btree));
-  }
-};
-
-#endif
-