diff --git a/src/kv/MemDB.cc b/src/kv/MemDB.cc index b6a8165f9c25ae..1ef14e105c8500 100644 --- a/src/kv/MemDB.cc +++ b/src/kv/MemDB.cc @@ -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; } @@ -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. */ @@ -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; } @@ -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() { @@ -442,6 +456,10 @@ bufferlist MemDB::MDBWholeSpaceIteratorImpl::value() int MemDB::MDBWholeSpaceIteratorImpl::next() { std::lock_guard l(*m_btree_lock_p); + if (!iterator_validate()) { + free_last(); + return -1; + } free_last(); m_iter++; if (m_iter != m_btree_p->end()) { @@ -455,6 +473,10 @@ int MemDB::MDBWholeSpaceIteratorImpl::next() int MemDB::MDBWholeSpaceIteratorImpl:: prev() { std::lock_guard l(*m_btree_lock_p); + if (!iterator_validate()) { + free_last(); + return -1; + } free_last(); m_iter--; if (m_iter != m_btree_p->end()) { @@ -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 l(*m_btree_lock_p); - free_last(); if (k.empty()) { m_iter = m_btree_p->end(); @@ -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; } diff --git a/src/kv/MemDB.h b/src/kv/MemDB.h index ee276431fc2403..020ca0ef6c6538 100644 --- a/src/kv/MemDB.h +++ b/src/kv/MemDB.h @@ -48,10 +48,11 @@ class MemDB : public KeyValueDB void _encode(btree::btree_map:: 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 } @@ -132,12 +133,16 @@ class MemDB : public KeyValueDB std::pair m_key_value; btree::btree_map *m_btree_p; std::mutex *m_btree_lock_p; + uint64_t *btree_seq; + uint64_t current_seq; public: MDBWholeSpaceIteratorImpl(btree::btree_map *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(); @@ -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(); @@ -183,7 +189,7 @@ class MemDB : public KeyValueDB WholeSpaceIterator _get_iterator() { return std::shared_ptr( - new MDBWholeSpaceIteratorImpl(&m_btree, &m_lock)); + new MDBWholeSpaceIteratorImpl(&m_btree, &m_lock, &btree_iterator_seq)); } WholeSpaceIterator _get_snapshot_iterator();