KeyValueStore: Fix incorrect rm_keys behaviors

GenericObjectMap will copyup parents keys when rm keys, but if
caller(KeyValueStore) already buffer "set keys", it shouldn't
copyup reset keys.

Signed-off-by: Haomai Wang <haomaiwang@gmail.com>
This commit is contained in:
Haomai Wang 2015-07-31 16:05:41 +08:00 committed by Kefu Chai
parent f008440765
commit 5760655554
3 changed files with 14 additions and 2 deletions

View File

@ -534,6 +534,7 @@ int GenericObjectMap::clear(const Header header,
int GenericObjectMap::rm_keys(const Header header,
const string &prefix,
const set<string> &buffered_keys,
const set<string> &to_clear,
KeyValueDB::Transaction t)
{
@ -563,7 +564,7 @@ int GenericObjectMap::rm_keys(const Header header,
begin = new_complete.rbegin()->first;
}
while (iter->valid() && copied < 20) {
if (!to_clear.count(iter->key()))
if (!to_clear.count(iter->key()) && !buffered_keys.count(iter->key()))
to_write[iter->key()].append(iter->value());
if (i != to_clear.end() && *i <= iter->key()) {
++i;
@ -692,6 +693,7 @@ void GenericObjectMap::clone(const Header parent, const coll_t &cid,
// to find parent header. So it will let lookup_parent fail when "clone" and
// "rm_keys" in one transaction. Here have to sync transaction to make
// visiable for lookup_parent
// FIXME: Clear transaction operations here
int r = submit_transaction_sync(t);
assert(r == 0);
}

View File

@ -240,6 +240,7 @@ class GenericObjectMap {
int rm_keys(
const Header header,
const string &prefix,
const set<string> &buffered_keys,
const set<string> &to_clear,
KeyValueDB::Transaction t
);

View File

@ -389,13 +389,22 @@ int KeyValueStore::BufferTransaction::remove_buffer_keys(
{
uniq_id uid = make_pair(strip_header->cid, strip_header->oid);
map< uniq_id, map<pair<string, string>, bufferlist> >::iterator obj_it = buffers.find(uid);
set<string> buffered_keys;
if ( obj_it != buffers.end() ) {
// TODO: Avoid use empty bufferlist to indicate the key is removed
for (set<string>::iterator iter = keys.begin(); iter != keys.end(); ++iter) {
obj_it->second[make_pair(prefix, *iter)] = bufferlist();
}
// TODO: Avoid collect all buffered keys when remove keys
if (strip_header->header->parent) {
for (map<pair<string, string>, bufferlist>::iterator iter = obj_it->second.begin();
iter != obj_it->second.end(); ++iter) {
buffered_keys.insert(iter->first.second);
}
}
}
return store->backend->rm_keys(strip_header->header, prefix, keys, t);
return store->backend->rm_keys(strip_header->header, prefix, buffered_keys, keys, t);
}
void KeyValueStore::BufferTransaction::clear_buffer_keys(