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"
12 * Iterate over the whole key space of the in-memory store
14 * @note Removing keys from the store while iterating over the store key-space
15 * may result in unspecified behavior.
16 * If one wants to safely iterate over the store while updating the
17 * store, one should instead use a snapshot iterator, which provides
18 * strong read-consistency.
20 class WholeSpaceMemIterator
: public KeyValueDB::WholeSpaceIteratorImpl
{
25 map
<pair
<string
,string
>, bufferlist
>::iterator it
;
28 explicit WholeSpaceMemIterator(KeyValueDBMemory
*db
) : db(db
), ready(false) { }
29 ~WholeSpaceMemIterator() override
{ }
31 int seek_to_first() override
{
42 int seek_to_first(const string
&prefix
) override
{
43 it
= db
->db
.lower_bound(make_pair(prefix
, ""));
44 if (db
->db
.empty() || (it
== db
->db
.end())) {
53 int seek_to_last() override
{
60 ceph_assert(it
!= db
->db
.end());
65 int seek_to_last(const string
&prefix
) override
{
67 tmp
.append(1, (char) 0);
68 it
= db
->db
.upper_bound(make_pair(tmp
,""));
70 if (db
->db
.empty() || (it
== db
->db
.end())) {
80 int lower_bound(const string
&prefix
, const string
&to
) override
{
81 it
= db
->db
.lower_bound(make_pair(prefix
,to
));
82 if ((db
->db
.empty()) || (it
== db
->db
.end())) {
88 ceph_assert(it
!= db
->db
.end());
94 int upper_bound(const string
&prefix
, const string
&after
) override
{
95 it
= db
->db
.upper_bound(make_pair(prefix
,after
));
96 if ((db
->db
.empty()) || (it
== db
->db
.end())) {
101 ceph_assert(it
!= db
->db
.end());
106 bool valid() override
{
107 return ready
&& (it
!= db
->db
.end());
111 return ready
&& (it
== db
->db
.begin());
114 int prev() override
{
115 if (!begin() && ready
)
122 int next() override
{
128 string
key() override
{
130 return (*it
).first
.second
;
135 pair
<string
,string
> raw_key() override
{
139 return make_pair("", "");
142 bool raw_key_is_prefixed(const string
&prefix
) override
{
143 return prefix
== (*it
).first
.first
;
146 bufferlist
value() override
{
153 int status() override
{
158 int KeyValueDBMemory::get(const string
&prefix
,
159 const std::set
<string
> &key
,
160 map
<string
, bufferlist
> *out
) {
161 if (!exists_prefix(prefix
))
164 for (std::set
<string
>::const_iterator i
= key
.begin();
167 pair
<string
,string
> k(prefix
, *i
);
174 int KeyValueDBMemory::get_keys(const string
&prefix
,
175 const std::set
<string
> &key
,
176 std::set
<string
> *out
) {
177 if (!exists_prefix(prefix
))
180 for (std::set
<string
>::const_iterator i
= key
.begin();
183 if (db
.count(make_pair(prefix
, *i
)))
189 int KeyValueDBMemory::set(const string
&prefix
,
191 const bufferlist
&bl
) {
192 db
[make_pair(prefix
,key
)] = bl
;
196 int KeyValueDBMemory::rmkey(const string
&prefix
,
198 db
.erase(make_pair(prefix
,key
));
202 int KeyValueDBMemory::rmkeys_by_prefix(const string
&prefix
) {
203 map
<std::pair
<string
,string
>,bufferlist
>::iterator i
;
204 i
= db
.lower_bound(make_pair(prefix
, ""));
208 while (i
!= db
.end()) {
209 std::pair
<string
,string
> key
= (*i
).first
;
210 if (key
.first
!= prefix
)
214 rmkey(key
.first
, key
.second
);
219 int KeyValueDBMemory::rm_range_keys(const string
&prefix
, const string
&start
, const string
&end
) {
220 map
<std::pair
<string
,string
>,bufferlist
>::iterator i
;
221 i
= db
.lower_bound(make_pair(prefix
, start
));
225 while (i
!= db
.end()) {
226 std::pair
<string
,string
> key
= (*i
).first
;
227 if (key
.first
!= prefix
)
229 if (key
.second
>= end
)
232 rmkey(key
.first
, key
.second
);
237 KeyValueDB::WholeSpaceIterator
KeyValueDBMemory::get_wholespace_iterator(IteratorOpts opts
) {
238 return std::shared_ptr
<KeyValueDB::WholeSpaceIteratorImpl
>(
239 new WholeSpaceMemIterator(this)
243 class WholeSpaceSnapshotMemIterator
: public WholeSpaceMemIterator
{
248 * We perform a copy of the db map, which is populated by bufferlists.
250 * These are designed as shallow containers, thus there is a chance that
251 * changing the underlying memory pages will lead to the iterator seeing
254 * Although we haven't verified this yet, there is this chance, so we should
258 explicit WholeSpaceSnapshotMemIterator(KeyValueDBMemory
*db
) :
259 WholeSpaceMemIterator(db
) { }
260 ~WholeSpaceSnapshotMemIterator() override
{