1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include <map>
#include <set>
#include <string>
#include <tr1/memory>
#include "include/buffer.h"
#include "include/Context.h"
#include "os/KeyValueDB.h"
using std::string;
class KeyValueDBMemory : public KeyValueDB {
public:
std::map<std::pair<string,string>,bufferlist> db;
KeyValueDBMemory() { }
KeyValueDBMemory(KeyValueDBMemory *db) : db(db->db) { }
virtual ~KeyValueDBMemory() { }
int get(
const string &prefix,
const std::set<string> &key,
std::map<string, bufferlist> *out
);
int get_keys(
const string &prefix,
const std::set<string> &key,
std::set<string> *out
);
int set(
const string &prefix,
const string &key,
const bufferlist &bl
);
int rmkey(
const string &prefix,
const string &key
);
int rmkeys_by_prefix(
const string &prefix
);
class TransactionImpl_ : public TransactionImpl {
public:
list<Context *> on_commit;
KeyValueDBMemory *db;
TransactionImpl_(KeyValueDBMemory *db) : db(db) {}
struct SetOp : public Context {
KeyValueDBMemory *db;
std::pair<string,string> key;
bufferlist value;
SetOp(KeyValueDBMemory *db,
const std::pair<string,string> &key,
const bufferlist &value)
: db(db), key(key), value(value) {}
void finish(int r) {
db->set(key.first, key.second, value);
}
};
void set(const string &prefix, const string &k, const bufferlist& bl) {
on_commit.push_back(new SetOp(db, std::make_pair(prefix, k), bl));
}
struct RmKeysOp : public Context {
KeyValueDBMemory *db;
std::pair<string,string> key;
RmKeysOp(KeyValueDBMemory *db,
const std::pair<string,string> &key)
: db(db), key(key) {}
void finish(int r) {
db->rmkey(key.first, key.second);
}
};
void rmkey(const string &prefix, const string &key) {
on_commit.push_back(new RmKeysOp(db, std::make_pair(prefix, key)));
}
struct RmKeysByPrefixOp : public Context {
KeyValueDBMemory *db;
string prefix;
RmKeysByPrefixOp(KeyValueDBMemory *db,
const string &prefix)
: db(db), prefix(prefix) {}
void finish(int r) {
db->rmkeys_by_prefix(prefix);
}
};
void rmkeys_by_prefix(const string &prefix) {
on_commit.push_back(new RmKeysByPrefixOp(db, prefix));
}
int complete() {
for (list<Context *>::iterator i = on_commit.begin();
i != on_commit.end();
on_commit.erase(i++)) {
(*i)->finish(0);
delete *i;
}
return 0;
}
~TransactionImpl_() {
for (list<Context *>::iterator i = on_commit.begin();
i != on_commit.end();
on_commit.erase(i++)) {
delete *i;
}
}
};
Transaction get_transaction() {
return Transaction(new TransactionImpl_(this));
}
int submit_transaction(Transaction trans) {
return static_cast<TransactionImpl_*>(trans.get())->complete();
}
private:
bool exists_prefix(const string &prefix) {
std::map<std::pair<string,string>,bufferlist>::iterator it;
it = db.lower_bound(std::make_pair(prefix, ""));
return ((it != db.end()) && ((*it).first.first == prefix));
}
friend class WholeSpaceMemIterator;
protected:
WholeSpaceIterator _get_iterator();
WholeSpaceIterator _get_snapshot_iterator();
};
|