Skip to content

Commit

Permalink
kv: fix iterator invalidation in memdb
Browse files Browse the repository at this point in the history
Signed-off-by: Haodong Tang <haodong.tang@intel.com>
  • Loading branch information
haodong committed Aug 12, 2016
1 parent 1274427 commit 619736c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
29 changes: 26 additions & 3 deletions src/kv/MemDB.cc
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ int MemDB::_setkey(ms_op_t &op)
}

m_btree[key] = bufferptr((char *) bl.c_str(), bl.length());

btree_iterator_seq++;
return 0;
}

Expand All @@ -284,6 +284,7 @@ int MemDB::_rmkey(ms_op_t &op)
assert(m_total_bytes >= bl_old.length());
m_total_bytes -= bl_old.length();
}
btree_iterator_seq++;
/*
* Erase will call the destructor for bufferptr.
*/
Expand Down Expand Up @@ -341,6 +342,7 @@ int MemDB::_merge(ms_op_t &op)

assert((int64_t)m_total_bytes + bytes_adjusted >= 0);
m_total_bytes += bytes_adjusted;
btree_iterator_seq++;
return 0;
}

Expand Down Expand Up @@ -403,6 +405,18 @@ bool MemDB::MDBWholeSpaceIteratorImpl::valid()
return true;
}

bool MemDB::MDBWholeSpaceIteratorImpl::iterator_validate() {
if (current_seq != *btree_seq) {
auto key = m_key_value.first;
assert(!key.empty());
m_iter = m_btree_p->lower_bound(key);
if (m_iter == m_btree_p->end()) {
return false;
}
}
return true;
}

void
MemDB::MDBWholeSpaceIteratorImpl::free_last()
{
Expand Down Expand Up @@ -442,6 +456,10 @@ bufferlist MemDB::MDBWholeSpaceIteratorImpl::value()
int MemDB::MDBWholeSpaceIteratorImpl::next()
{
std::lock_guard<std::mutex> l(*m_btree_lock_p);
if (!iterator_validate()) {
free_last();
return -1;
}
free_last();
m_iter++;
if (m_iter != m_btree_p->end()) {
Expand All @@ -455,6 +473,10 @@ int MemDB::MDBWholeSpaceIteratorImpl::next()
int MemDB::MDBWholeSpaceIteratorImpl:: prev()
{
std::lock_guard<std::mutex> l(*m_btree_lock_p);
if (!iterator_validate()) {
free_last();
return -1;
}
free_last();
m_iter--;
if (m_iter != m_btree_p->end()) {
Expand All @@ -477,17 +499,17 @@ int MemDB::MDBWholeSpaceIteratorImpl::seek_to_first(const std::string &k)
} else {
m_iter = m_btree_p->lower_bound(k);
}

if (m_iter == m_btree_p->end()) {
return -1;
}
fill_current();
return 0;
}

int MemDB::MDBWholeSpaceIteratorImpl::seek_to_last(const std::string &k)
{
std::lock_guard<std::mutex> l(*m_btree_lock_p);

free_last();
if (k.empty()) {
m_iter = m_btree_p->end();
Expand All @@ -499,6 +521,7 @@ int MemDB::MDBWholeSpaceIteratorImpl::seek_to_last(const std::string &k)
if (m_iter == m_btree_p->end()) {
return -1;
}
fill_current();
return 0;
}

Expand Down
16 changes: 11 additions & 5 deletions src/kv/MemDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ class MemDB : public KeyValueDB
void _encode(btree::btree_map<string, bufferptr>:: iterator iter, bufferlist &bl);
void _save();
int _load();
uint64_t btree_iterator_seq;

public:
MemDB(CephContext *c, const string &path, void *p) :
m_cct(c), m_priv(p), m_db_path(path)
m_cct(c), m_priv(p), m_db_path(path), btree_iterator_seq(1)
{
//Nothing as of now
}
Expand Down Expand Up @@ -132,12 +133,16 @@ class MemDB : public KeyValueDB
std::pair<string, bufferlist> m_key_value;
btree::btree_map<std::string, bufferptr> *m_btree_p;
std::mutex *m_btree_lock_p;
uint64_t *btree_seq;
uint64_t current_seq;

public:
MDBWholeSpaceIteratorImpl(btree::btree_map<std::string, bufferptr> *btree_p,
std::mutex *btree_lock_p) {
std::mutex *btree_lock_p, uint64_t *btree_seq_) {
m_btree_p = btree_p;
m_btree_lock_p = btree_lock_p;
btree_seq = btree_seq_;
current_seq = *btree_seq_;
}

void fill_current();
Expand All @@ -147,12 +152,13 @@ class MemDB : public KeyValueDB
int seek_to_first(const std::string &k);
int seek_to_last(const std::string &k);

int seek_to_first() { return seek_to_first(NULL); };
int seek_to_last() { return seek_to_last(NULL); };
int seek_to_first() { return seek_to_first(""); };
int seek_to_last() { return seek_to_last(""); };

int upper_bound(const std::string &prefix, const std::string &after);
int lower_bound(const std::string &prefix, const std::string &to);
bool valid();
bool iterator_validate();

int next();
int prev();
Expand Down Expand Up @@ -183,7 +189,7 @@ class MemDB : public KeyValueDB

WholeSpaceIterator _get_iterator() {
return std::shared_ptr<KeyValueDB::WholeSpaceIteratorImpl>(
new MDBWholeSpaceIteratorImpl(&m_btree, &m_lock));
new MDBWholeSpaceIteratorImpl(&m_btree, &m_lock, &btree_iterator_seq));
}

WholeSpaceIterator _get_snapshot_iterator();
Expand Down

0 comments on commit 619736c

Please sign in to comment.