1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
6 #include "include/memory.h"
8 #include "kv/KeyValueDB.h"
9 #include "include/buffer.h"
10 #include "include/Context.h"
14 class KeyValueDBMemory : public KeyValueDB {
16 std::map<std::pair<string,string>,bufferlist> db;
18 KeyValueDBMemory() { }
19 explicit KeyValueDBMemory(KeyValueDBMemory *db) : db(db->db) { }
20 ~KeyValueDBMemory() override { }
22 int init(string _opt) override {
25 int open(ostream &out) override {
28 int create_and_open(ostream &out) override {
34 const std::set<string> &key,
35 std::map<string, bufferlist> *out
37 using KeyValueDB::get;
41 const std::set<string> &key,
66 class TransactionImpl_ : public TransactionImpl {
68 list<Context *> on_commit;
71 explicit TransactionImpl_(KeyValueDBMemory *db) : db(db) {}
74 struct SetOp : public Context {
76 std::pair<string,string> key;
78 SetOp(KeyValueDBMemory *db,
79 const std::pair<string,string> &key,
80 const bufferlist &value)
81 : db(db), key(key), value(value) {}
82 void finish(int r) override {
83 db->set(key.first, key.second, value);
87 void set(const string &prefix, const string &k, const bufferlist& bl) override {
88 on_commit.push_back(new SetOp(db, std::make_pair(prefix, k), bl));
91 struct RmKeysOp : public Context {
93 std::pair<string,string> key;
94 RmKeysOp(KeyValueDBMemory *db,
95 const std::pair<string,string> &key)
97 void finish(int r) override {
98 db->rmkey(key.first, key.second);
102 void rmkey(const string &prefix, const string &key) override {
103 on_commit.push_back(new RmKeysOp(db, std::make_pair(prefix, key)));
106 struct RmKeysByPrefixOp : public Context {
107 KeyValueDBMemory *db;
109 RmKeysByPrefixOp(KeyValueDBMemory *db,
110 const string &prefix)
111 : db(db), prefix(prefix) {}
112 void finish(int r) override {
113 db->rmkeys_by_prefix(prefix);
116 void rmkeys_by_prefix(const string &prefix) override {
117 on_commit.push_back(new RmKeysByPrefixOp(db, prefix));
120 struct RmRangeKeys: public Context {
121 KeyValueDBMemory *db;
122 string prefix, start, end;
123 RmRangeKeys(KeyValueDBMemory *db, const string &prefix, const string &s, const string &e)
124 : db(db), prefix(prefix), start(s), end(e) {}
126 db->rm_range_keys(prefix, start, end);
130 void rm_range_keys(const string &prefix, const string &start, const string &end) {
131 on_commit.push_back(new RmRangeKeys(db, prefix, start, end));
135 for (list<Context *>::iterator i = on_commit.begin();
136 i != on_commit.end();
137 on_commit.erase(i++)) {
143 ~TransactionImpl_() override {
144 for (list<Context *>::iterator i = on_commit.begin();
145 i != on_commit.end();
146 on_commit.erase(i++)) {
152 Transaction get_transaction() override {
153 return Transaction(new TransactionImpl_(this));
156 int submit_transaction(Transaction trans) override {
157 return static_cast<TransactionImpl_*>(trans.get())->complete();
160 uint64_t get_estimated_size(map<string,uint64_t> &extras) override {
161 uint64_t total_size = 0;
163 for (map<pair<string,string>,bufferlist>::iterator p = db.begin();
164 p != db.end(); ++p) {
165 string prefix = p->first.first;
166 bufferlist &bl = p->second;
168 uint64_t sz = bl.length();
170 if (extras.count(prefix) == 0)
172 extras[prefix] += sz;
179 bool exists_prefix(const string &prefix) {
180 std::map<std::pair<string,string>,bufferlist>::iterator it;
181 it = db.lower_bound(std::make_pair(prefix, ""));
182 return ((it != db.end()) && ((*it).first.first == prefix));
185 friend class WholeSpaceMemIterator;
188 WholeSpaceIterator _get_iterator() override;