1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #include "include/encoding.h"
4 #include "KeyValueDBMemory.h"
7 #include "include/memory.h"
13 * Iterate over the whole key space of the in-memory store
15 * @note Removing keys from the store while iterating over the store key-space
16 * may result in unspecified behavior.
17 * If one wants to safely iterate over the store while updating the
18 * store, one should instead use a snapshot iterator, which provides
19 * strong read-consistency.
21 class WholeSpaceMemIterator : public KeyValueDB::WholeSpaceIteratorImpl {
26 map<pair<string,string>, bufferlist>::iterator it;
29 explicit WholeSpaceMemIterator(KeyValueDBMemory *db) : db(db), ready(false) { }
30 ~WholeSpaceMemIterator() override { }
32 int seek_to_first() override {
43 int seek_to_first(const string &prefix) override {
44 it = db->db.lower_bound(make_pair(prefix, ""));
45 if (db->db.empty() || (it == db->db.end())) {
54 int seek_to_last() override {
61 assert(it != db->db.end());
66 int seek_to_last(const string &prefix) override {
68 tmp.append(1, (char) 0);
69 it = db->db.upper_bound(make_pair(tmp,""));
71 if (db->db.empty() || (it == db->db.end())) {
81 int lower_bound(const string &prefix, const string &to) override {
82 it = db->db.lower_bound(make_pair(prefix,to));
83 if ((db->db.empty()) || (it == db->db.end())) {
89 assert(it != db->db.end());
95 int upper_bound(const string &prefix, const string &after) override {
96 it = db->db.upper_bound(make_pair(prefix,after));
97 if ((db->db.empty()) || (it == db->db.end())) {
102 assert(it != db->db.end());
107 bool valid() override {
108 return ready && (it != db->db.end());
112 return ready && (it == db->db.begin());
115 int prev() override {
116 if (!begin() && ready)
123 int next() override {
129 string key() override {
131 return (*it).first.second;
136 pair<string,string> raw_key() override {
140 return make_pair("", "");
143 bool raw_key_is_prefixed(const string &prefix) override {
144 return prefix == (*it).first.first;
147 bufferlist value() override {
154 int status() override {
159 int KeyValueDBMemory::get(const string &prefix,
160 const std::set<string> &key,
161 map<string, bufferlist> *out) {
162 if (!exists_prefix(prefix))
165 for (std::set<string>::const_iterator i = key.begin();
168 pair<string,string> k(prefix, *i);
175 int KeyValueDBMemory::get_keys(const string &prefix,
176 const std::set<string> &key,
177 std::set<string> *out) {
178 if (!exists_prefix(prefix))
181 for (std::set<string>::const_iterator i = key.begin();
184 if (db.count(make_pair(prefix, *i)))
190 int KeyValueDBMemory::set(const string &prefix,
192 const bufferlist &bl) {
193 db[make_pair(prefix,key)] = bl;
197 int KeyValueDBMemory::rmkey(const string &prefix,
199 db.erase(make_pair(prefix,key));
203 int KeyValueDBMemory::rmkeys_by_prefix(const string &prefix) {
204 map<std::pair<string,string>,bufferlist>::iterator i;
205 i = db.lower_bound(make_pair(prefix, ""));
209 while (i != db.end()) {
210 std::pair<string,string> key = (*i).first;
211 if (key.first != prefix)
215 rmkey(key.first, key.second);
220 int KeyValueDBMemory::rm_range_keys(const string &prefix, const string &start, const string &end) {
221 map<std::pair<string,string>,bufferlist>::iterator i;
222 i = db.lower_bound(make_pair(prefix, start));
226 while (i != db.end()) {
227 std::pair<string,string> key = (*i).first;
228 if (key.first != prefix)
230 if (key.second >= end)
233 rmkey(key.first, key.second);
238 KeyValueDB::WholeSpaceIterator KeyValueDBMemory::_get_iterator() {
239 return ceph::shared_ptr<KeyValueDB::WholeSpaceIteratorImpl>(
240 new WholeSpaceMemIterator(this)
244 class WholeSpaceSnapshotMemIterator : public WholeSpaceMemIterator {
249 * We perform a copy of the db map, which is populated by bufferlists.
251 * These are designed as shallow containers, thus there is a chance that
252 * changing the underlying memory pages will lead to the iterator seeing
255 * Although we haven't verified this yet, there is this chance, so we should
259 explicit WholeSpaceSnapshotMemIterator(KeyValueDBMemory *db) :
260 WholeSpaceMemIterator(db) { }
261 ~WholeSpaceSnapshotMemIterator() override {