From: Haomai Wang Date: Wed, 21 Sep 2016 09:09:12 +0000 (+0800) Subject: kv/RocksDBStore: implement rm_range_keys operator interface and test X-Git-Tag: v12.0.2~282^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9e092fcc534f3de4616e852306b27ac01b2d37c7;p=ceph.git kv/RocksDBStore: implement rm_range_keys operator interface and test Signed-off-by: Haomai Wang --- diff --git a/src/kv/KeyValueDB.h b/src/kv/KeyValueDB.h index 52d434e2bd38..9f454ac973ae 100644 --- a/src/kv/KeyValueDB.h +++ b/src/kv/KeyValueDB.h @@ -117,6 +117,12 @@ public: const std::string &prefix ///< [in] Prefix by which to remove keys ) = 0; + virtual void rm_range_keys( + const string &prefix, ///< [in] Prefix by which to remove keys + const string &start, ///< [in] The start bound of remove keys + const string &end ///< [in] The start bound of remove keys + ) = 0; + /// Merge value into key virtual void merge( const std::string &prefix, ///< [in] Prefix ==> MUST match some established merge operator diff --git a/src/kv/KineticStore.cc b/src/kv/KineticStore.cc index 7a23714d4d52..ddbd48720f8a 100644 --- a/src/kv/KineticStore.cc +++ b/src/kv/KineticStore.cc @@ -166,6 +166,20 @@ void KineticStore::KineticTransactionImpl::rmkeys_by_prefix(const string &prefix } } +void KineticStore::KineticTransactionImpl::rm_range_keys(const string &prefix, const string &start, const string &end) +{ + KeyValueDB::Iterator it = db->get_iterator(prefix); + it->lower_bound(start); + while (it->valid()) { + if (it->key() >= end) { + break; + } + ops.push_back( + KineticOp(KINETIC_OP_DELETE, combine_strings(prefix, it->key()))); + it->next(); + } +} + int KineticStore::get( const string &prefix, const std::set &keys, diff --git a/src/kv/KineticStore.h b/src/kv/KineticStore.h index f52df90c2b4e..8496b76144ec 100644 --- a/src/kv/KineticStore.h +++ b/src/kv/KineticStore.h @@ -92,6 +92,10 @@ public: void rmkeys_by_prefix( const string &prefix ); + void rm_range_keys( + const string &prefix, + const string &start, + const string &end); }; KeyValueDB::Transaction get_transaction() { diff --git a/src/kv/LevelDBStore.cc b/src/kv/LevelDBStore.cc index b9951e15dd8b..53840319cf50 100644 --- a/src/kv/LevelDBStore.cc +++ b/src/kv/LevelDBStore.cc @@ -237,8 +237,20 @@ void LevelDBStore::LevelDBTransactionImpl::rmkeys_by_prefix(const string &prefix for (it->seek_to_first(); it->valid(); it->next()) { - string key = combine_strings(prefix, it->key()); - bat.Delete(key); + bat.Delete(leveldb::Slice(combine_strings(prefix, it->key()))); + } +} + +void LevelDBStore::LevelDBTransactionImpl::rm_range_keys(const string &prefix, const string &start, const string &end) +{ + KeyValueDB::Iterator it = db->get_iterator(prefix); + it->lower_bound(start); + while (it->valid()) { + if (it->key() >= end) { + break; + } + bat.Delete(combine_strings(prefix, it->key())); + it->next(); } } diff --git a/src/kv/LevelDBStore.h b/src/kv/LevelDBStore.h index c4abbf63b3fc..7ce87ecc4812 100644 --- a/src/kv/LevelDBStore.h +++ b/src/kv/LevelDBStore.h @@ -197,6 +197,11 @@ public: void rmkeys_by_prefix( const string &prefix ) override; + virtual void rm_range_keys( + const string &prefix, + const string &start, + const string &end) override; + using KeyValueDB::TransactionImpl::rmkey; }; diff --git a/src/kv/MemDB.cc b/src/kv/MemDB.cc index e9377ed1bb51..d6af78b18270 100644 --- a/src/kv/MemDB.cc +++ b/src/kv/MemDB.cc @@ -242,6 +242,19 @@ void MemDB::MDBTransactionImpl::rmkeys_by_prefix(const string &prefix) } } +void MemDB::MDBTransactionImpl::rm_range_keys(const string &prefix, const string &start, const string &end) +{ + KeyValueDB::Iterator it = m_db->get_iterator(prefix); + it->lower_bound(start); + while (it->valid()) { + if (it->key() >= end) { + break; + } + rmkey(prefix, it->key()); + it->next(); + } +} + void MemDB::MDBTransactionImpl::merge( const std::string &prefix, const std::string &key, const bufferlist &value) { diff --git a/src/kv/MemDB.h b/src/kv/MemDB.h index d3c8268cc43c..cb2a16b9ba9d 100644 --- a/src/kv/MemDB.h +++ b/src/kv/MemDB.h @@ -90,6 +90,10 @@ public: void rmkey(const std::string &prefix, const std::string &k) override; using KeyValueDB::TransactionImpl::rmkey; void rmkeys_by_prefix(const std::string &prefix) override; + void rm_range_keys( + const string &prefix, + const string &start, + const string &end) override; void merge(const std::string &prefix, const std::string &key, const bufferlist &value) override; void clear() { diff --git a/src/kv/RocksDBStore.cc b/src/kv/RocksDBStore.cc index 3fcc14a209cd..0d102c6e6d04 100644 --- a/src/kv/RocksDBStore.cc +++ b/src/kv/RocksDBStore.cc @@ -615,6 +615,13 @@ void RocksDBStore::RocksDBTransactionImpl::rmkeys_by_prefix(const string &prefix } } +void RocksDBStore::RocksDBTransactionImpl::rm_range_keys(const string &prefix, + const string &start, + const string &end) +{ + bat.DeleteRange(combine_strings(prefix, start), combine_strings(prefix, end)); +} + void RocksDBStore::RocksDBTransactionImpl::merge( const string &prefix, const string &k, diff --git a/src/kv/RocksDBStore.h b/src/kv/RocksDBStore.h index 0d15ca4818b9..ef81df324961 100644 --- a/src/kv/RocksDBStore.h +++ b/src/kv/RocksDBStore.h @@ -273,6 +273,10 @@ public: void rmkeys_by_prefix( const string &prefix ) override; + void rm_range_keys( + const string &prefix, + const string &start, + const string &end) override; void merge( const string& prefix, const string& k, diff --git a/src/test/ObjectMap/KeyValueDBMemory.cc b/src/test/ObjectMap/KeyValueDBMemory.cc index f4b3719eff5f..1a095e3e1a14 100644 --- a/src/test/ObjectMap/KeyValueDBMemory.cc +++ b/src/test/ObjectMap/KeyValueDBMemory.cc @@ -217,6 +217,24 @@ int KeyValueDBMemory::rmkeys_by_prefix(const string &prefix) { return 0; } +int KeyValueDBMemory::rm_range_keys(const string &prefix, const string &start, const string &end) { + map,bufferlist>::iterator i; + i = db.lower_bound(make_pair(prefix, start)); + if (i == db.end()) + return 0; + + while (i != db.end()) { + std::pair key = (*i).first; + if (key.first != prefix) + break; + if (key.second >= end) + break; + ++i; + rmkey(key.first, key.second); + } + return 0; +} + KeyValueDB::WholeSpaceIterator KeyValueDBMemory::_get_iterator() { return ceph::shared_ptr( new WholeSpaceMemIterator(this) diff --git a/src/test/ObjectMap/KeyValueDBMemory.h b/src/test/ObjectMap/KeyValueDBMemory.h index 767d56f1be4e..089fb038f79f 100644 --- a/src/test/ObjectMap/KeyValueDBMemory.h +++ b/src/test/ObjectMap/KeyValueDBMemory.h @@ -57,6 +57,12 @@ public: const string &prefix ); + int rm_range_keys( + const string &prefix, + const string &start, + const string &end + ); + class TransactionImpl_ : public TransactionImpl { public: list on_commit; @@ -111,6 +117,20 @@ public: on_commit.push_back(new RmKeysByPrefixOp(db, prefix)); } + struct RmRangeKeys: public Context { + KeyValueDBMemory *db; + string prefix, start, end; + RmRangeKeys(KeyValueDBMemory *db, const string &prefix, const string &s, const string &e) + : db(db), prefix(prefix), start(s), end(e) {} + void finish(int r) { + db->rm_range_keys(prefix, start, end); + } + }; + + void rm_range_keys(const string &prefix, const string &start, const string &end) { + on_commit.push_back(new RmRangeKeys(db, prefix, start, end)); + } + int complete() { for (list::iterator i = on_commit.begin(); i != on_commit.end(); diff --git a/src/test/objectstore/test_kv.cc b/src/test/objectstore/test_kv.cc index 87bd62b9a442..46a8a8be32d9 100644 --- a/src/test/objectstore/test_kv.cc +++ b/src/test/objectstore/test_kv.cc @@ -255,6 +255,59 @@ TEST_P(KVTest, Merge) { fini(); } +TEST_P(KVTest, RMRange) { + ASSERT_EQ(0, db->create_and_open(cout)); + bufferlist value; + value.append("value"); + { + KeyValueDB::Transaction t = db->get_transaction(); + t->set("prefix", "key1", value); + t->set("prefix", "key2", value); + t->set("prefix", "key3", value); + t->set("prefix", "key4", value); + t->set("prefix", "key45", value); + t->set("prefix", "key5", value); + t->set("prefix", "key6", value); + db->submit_transaction_sync(t); + } + + { + KeyValueDB::Transaction t = db->get_transaction(); + t->set("prefix", "key7", value); + t->set("prefix", "key8", value); + t->rm_range_keys("prefix", "key2", "key7"); + db->submit_transaction_sync(t); + bufferlist v1, v2; + ASSERT_EQ(0, db->get("prefix", "key1", &v1)); + v1.clear(); + ASSERT_EQ(-ENOENT, db->get("prefix", "key45", &v1)); + ASSERT_EQ(0, db->get("prefix", "key8", &v1)); + v1.clear(); + ASSERT_EQ(-ENOENT, db->get("prefix", "key2", &v1)); + ASSERT_EQ(0, db->get("prefix", "key7", &v2)); + } + + { + KeyValueDB::Transaction t = db->get_transaction(); + t->rm_range_keys("prefix", "key", "key"); + db->submit_transaction_sync(t); + bufferlist v1, v2; + ASSERT_EQ(0, db->get("prefix", "key1", &v1)); + ASSERT_EQ(0, db->get("prefix", "key8", &v2)); + } + + { + KeyValueDB::Transaction t = db->get_transaction(); + t->rm_range_keys("prefix", "key-", "key~"); + db->submit_transaction_sync(t); + bufferlist v1, v2; + ASSERT_EQ(-ENOENT, db->get("prefix", "key1", &v1)); + ASSERT_EQ(-ENOENT, db->get("prefix", "key8", &v2)); + } + + fini(); +} + INSTANTIATE_TEST_CASE_P( KeyValueDB,