Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / ObjectMap / KeyValueDBMemory.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #include <map>
4 #include <set>
5 #include <string>
6 #include "include/memory.h"
7
8 #include "kv/KeyValueDB.h"
9 #include "include/buffer.h"
10 #include "include/Context.h"
11
12 using std::string;
13
14 class KeyValueDBMemory : public KeyValueDB {
15 public:
16   std::map<std::pair<string,string>,bufferlist> db;
17
18   KeyValueDBMemory() { }
19   explicit KeyValueDBMemory(KeyValueDBMemory *db) : db(db->db) { }
20   ~KeyValueDBMemory() override { }
21
22   int init(string _opt) override {
23     return 0;
24   }
25   int open(ostream &out) override {
26     return 0;
27   }
28   int create_and_open(ostream &out) override {
29     return 0;
30   }
31
32   int get(
33     const string &prefix,
34     const std::set<string> &key,
35     std::map<string, bufferlist> *out
36     ) override;
37   using KeyValueDB::get;
38
39   int get_keys(
40     const string &prefix,
41     const std::set<string> &key,
42     std::set<string> *out
43     );
44
45   int set(
46     const string &prefix,
47     const string &key,
48     const bufferlist &bl
49     );
50
51   int rmkey(
52     const string &prefix,
53     const string &key
54     );
55
56   int rmkeys_by_prefix(
57     const string &prefix
58     );
59
60   int rm_range_keys(
61       const string &prefix,
62       const string &start,
63       const string &end
64       );
65
66   class TransactionImpl_ : public TransactionImpl {
67   public:
68     list<Context *> on_commit;
69     KeyValueDBMemory *db;
70
71     explicit TransactionImpl_(KeyValueDBMemory *db) : db(db) {}
72
73
74     struct SetOp : public Context {
75       KeyValueDBMemory *db;
76       std::pair<string,string> key;
77       bufferlist value;
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);
84       }
85     };
86
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));
89     }
90
91     struct RmKeysOp : public Context {
92       KeyValueDBMemory *db;
93       std::pair<string,string> key;
94       RmKeysOp(KeyValueDBMemory *db,
95                const std::pair<string,string> &key)
96         : db(db), key(key) {}
97       void finish(int r) override {
98         db->rmkey(key.first, key.second);
99       }
100     };
101
102     void rmkey(const string &prefix, const string &key) override {
103       on_commit.push_back(new RmKeysOp(db, std::make_pair(prefix, key)));
104     }
105
106     struct RmKeysByPrefixOp : public Context {
107       KeyValueDBMemory *db;
108       string prefix;
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);
114       }
115     };
116     void rmkeys_by_prefix(const string &prefix) override {
117       on_commit.push_back(new RmKeysByPrefixOp(db, prefix));
118     }
119
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) {}
125       void finish(int r) {
126         db->rm_range_keys(prefix, start, end);
127       }
128     };
129
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));
132     }
133
134     int complete() {
135       for (list<Context *>::iterator i = on_commit.begin();
136            i != on_commit.end();
137            on_commit.erase(i++)) {
138         (*i)->complete(0);
139       }
140       return 0;
141     }
142
143     ~TransactionImpl_() override {
144       for (list<Context *>::iterator i = on_commit.begin();
145            i != on_commit.end();
146            on_commit.erase(i++)) {
147         delete *i;
148       }
149     }
150   };
151
152   Transaction get_transaction() override {
153     return Transaction(new TransactionImpl_(this));
154   }
155
156   int submit_transaction(Transaction trans) override {
157     return static_cast<TransactionImpl_*>(trans.get())->complete();
158   }
159
160   uint64_t get_estimated_size(map<string,uint64_t> &extras) override {
161     uint64_t total_size = 0;
162
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;
167
168       uint64_t sz = bl.length();
169       total_size += sz;
170       if (extras.count(prefix) == 0)
171         extras[prefix] = 0;
172       extras[prefix] += sz;
173     }
174
175     return total_size;
176   }
177
178 private:
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));
183   }
184
185   friend class WholeSpaceMemIterator;
186
187 protected:
188   WholeSpaceIterator _get_iterator() override;
189 };