]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kv/RocksDBStore: implement rm_range_keys operator interface and test
authorHaomai Wang <haomai@xsky.com>
Wed, 21 Sep 2016 09:09:12 +0000 (17:09 +0800)
committerHaomai Wang <haomai@xsky.com>
Sun, 26 Mar 2017 18:56:35 +0000 (14:56 -0400)
Signed-off-by: Haomai Wang <haomai@xsky.com>
12 files changed:
src/kv/KeyValueDB.h
src/kv/KineticStore.cc
src/kv/KineticStore.h
src/kv/LevelDBStore.cc
src/kv/LevelDBStore.h
src/kv/MemDB.cc
src/kv/MemDB.h
src/kv/RocksDBStore.cc
src/kv/RocksDBStore.h
src/test/ObjectMap/KeyValueDBMemory.cc
src/test/ObjectMap/KeyValueDBMemory.h
src/test/objectstore/test_kv.cc

index 52d434e2bd38ca01da99d84c14504ad62066be44..9f454ac973aeeb2459cbd7993a660db3df39183c 100644 (file)
@@ -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
index 7a23714d4d5212f10f498d3a3414713b91b17d06..ddbd48720f8ae25f944ec61f7532e5d5ec090ee9 100644 (file)
@@ -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<string> &keys,
index f52df90c2b4e163c518c9b5a8968c9095fb9f900..8496b76144ece7288f2aac6918e942917637cece 100644 (file)
@@ -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() {
index b9951e15dd8b46c9bcb89f2dad280c8b50fa9c17..53840319cf50adca583da51b8f30d68e94127840 100644 (file)
@@ -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();
   }
 }
 
index c4abbf63b3fc1925c0bd16ad428ebc0907c371b6..7ce87ecc4812091583ecd8e976c1eee829763810 100644 (file)
@@ -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;
   };
 
index e9377ed1bb51134667d446d3552581f133da08db..d6af78b182706e1a5ad191d9750b2373c0817f09 100644 (file)
@@ -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)
 {
index d3c8268cc43ce34bd1fe185d311d556c5b36ecdf..cb2a16b9ba9d98ffb9b30ecd72d4b6b6ca59981d 100644 (file)
@@ -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() {
index 3fcc14a209cd5640f1af2b5f495a34da34294d3f..0d102c6e6d04dd59f02d8f6c397ddecd618111e4 100644 (file)
@@ -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,
index 0d15ca4818b979c55a0883571c01c05b994cabcd..ef81df324961bd2125e2102e2dba27827349e430 100644 (file)
@@ -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,
index f4b3719eff5f747d48cce16b46f430b378c0116f..1a095e3e1a149f7bd37105ab9280ee2d787d723c 100644 (file)
@@ -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<std::pair<string,string>,bufferlist>::iterator i;
+  i = db.lower_bound(make_pair(prefix, start));
+  if (i == db.end())
+    return 0;
+
+  while (i != db.end()) {
+    std::pair<string,string> 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<KeyValueDB::WholeSpaceIteratorImpl>(
     new WholeSpaceMemIterator(this)
index 767d56f1be4ea31eeed2b2e0b82daa616f5a2d58..089fb038f79fe8e23a308304dc453f55ad70dcd0 100644 (file)
@@ -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<Context *> 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<Context *>::iterator i = on_commit.begin();
           i != on_commit.end();
index 87bd62b9a4426201330f85c22b62aa3123452a56..46a8a8be32d90625366e35f2a72b512467718419 100644 (file)
@@ -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,