txn->set(prefix, newkey, newvalue);
dout(20) << __func__ << " set " << newoff << "~" << newlen
<< " (remaining tail)" << dendl;
+ kv_free.erase(p);
kv_free[newoff] = newlen;
+ } else {
+ kv_free.erase(p);
}
- kv_free.erase(p);
} else {
assert(p->first < offset);
// shorten
dout(20) << __func__ << " set " << tailoff << "~" << taillen
<< " (remaining tail from " << p->first << "~" << p->second << ")"
<< dendl;
+ p->second = newlen;
kv_free[tailoff] = taillen;
+ } else {
+ p->second = newlen;
}
- p->second = newlen;
}
if (g_conf->bluestore_debug_freelist)
_audit();
<< " (merge with previous)" << dendl;
length += p->second;
offset = p->first;
- kv_free.erase(p++);
+ if (map_t_has_stable_iterators) {
+ kv_free.erase(p++);
+ } else {
+ uint64_t next = 0;
+ ++p;
+ if (p != kv_free.end())
+ next = p->first;
+ --p;
+ kv_free.erase(p);
+ if (next)
+ p = kv_free.find(next);
+ else
+ p = kv_free.end();
+ }
} else if (p->first + p->second > offset) {
derr << __func__ << " bad release " << offset << "~" << length
<< " overlaps with " << p->first << "~" << p->second << dendl;
#include <ostream>
#include "kv/KeyValueDB.h"
+#include "include/cpp-btree/btree_map.h"
+
class FreelistManager {
std::string prefix;
std::mutex lock;
uint64_t total_free;
- std::map<uint64_t, uint64_t> kv_free; ///< mirrors our kv values in the db
+ typedef btree::btree_map<uint64_t,uint64_t> map_t;
+ static const bool map_t_has_stable_iterators = false;
+
+ map_t kv_free; ///< mirrors our kv values in the db
void _audit();
void _dump();
return total_free;
}
- const std::map<uint64_t,uint64_t>& get_freelist() {
+ const map_t& get_freelist() {
return kv_free;
}