]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: refactor _collection_list
authorMykola Golub <mgolub@suse.com>
Wed, 19 Aug 2020 08:33:38 +0000 (09:33 +0100)
committerMykola Golub <mgolub@suse.com>
Wed, 9 Sep 2020 09:26:38 +0000 (12:26 +0300)
Make it operate with oids only hiding keys in CollectionListIterator.

Signed-off-by: Mykola Golub <mgolub@suse.com>
(cherry picked from commit f2ccd547d8d0b1518f77a08b61f3c7f509af65d3)

src/os/bluestore/BlueStore.cc

index 557e7fea4af554ce8ae2b78e9c7b15e0eab0f051..9c347b41a58c9788099d55a759b35a65a937ba6c 100644 (file)
@@ -282,47 +282,48 @@ static const char *_key_decode_shard(const char *key, shard_id_t *pshard)
   return key + 1;
 }
 
-static void get_coll_key_range(const coll_t& cid, int bits,
-                              string *temp_start, string *temp_end,
-                              string *start, string *end)
+static void get_coll_range(const coll_t& cid, int bits,
+                           ghobject_t *temp_start, ghobject_t *temp_end,
+                           ghobject_t *start, ghobject_t *end)
 {
-  temp_start->clear();
-  temp_end->clear();
-  start->clear();
-  end->clear();
-
   spg_t pgid;
   if (cid.is_pg(&pgid)) {
-    _key_encode_shard(pgid.shard, start);
+    start->shard_id = pgid.shard;
     *temp_start = *start;
 
-    _key_encode_u64(pgid.pool() + 0x8000000000000000ull, start);
-    _key_encode_u64((-2ll - pgid.pool()) + 0x8000000000000000ull, temp_start);
+    start->hobj.pool = pgid.pool();
+    temp_start->hobj.pool = -2ll - pgid.pool();
 
     *end = *start;
     *temp_end = *temp_start;
 
     uint32_t reverse_hash = hobject_t::_reverse_bits(pgid.ps());
-    _key_encode_u32(reverse_hash, start);
-    _key_encode_u32(reverse_hash, temp_start);
+    start->hobj.set_bitwise_key_u32(reverse_hash);
+    temp_start->hobj.set_bitwise_key_u32(reverse_hash);
 
     uint64_t end_hash = reverse_hash  + (1ull << (32 - bits));
     if (end_hash > 0xffffffffull)
       end_hash = 0xffffffffull;
 
-    _key_encode_u32(end_hash, end);
-    _key_encode_u32(end_hash, temp_end);
+    end->hobj.set_bitwise_key_u32(end_hash);
+    temp_end->hobj.set_bitwise_key_u32(end_hash);
   } else {
-    _key_encode_shard(shard_id_t::NO_SHARD, start);
-    _key_encode_u64(-1ull + 0x8000000000000000ull, start);
+    start->shard_id = shard_id_t::NO_SHARD;
+    start->hobj.pool = -1ull;
+
     *end = *start;
-    _key_encode_u32(0, start);
-    _key_encode_u32(0xffffffff, end);
+    start->hobj.set_bitwise_key_u32(0);
+    end->hobj.set_bitwise_key_u32(0xffffffff);
 
     // no separate temp section
     *temp_start = *end;
     *temp_end = *end;
   }
+
+  start->generation = 0;
+  end->generation = 0;
+  temp_start->generation = 0;
+  temp_end->generation = 0;
 }
 
 static void get_shared_blob_key(uint64_t sbid, string *key)
@@ -713,9 +714,8 @@ public:
 
   virtual bool valid() const = 0;
   virtual const ghobject_t &oid() const = 0;
-  virtual const std::string &key() const = 0;
-  virtual void lower_bound(const std::string &key) = 0;
-  virtual void upper_bound(const std::string &key) = 0;
+  virtual void lower_bound(const ghobject_t &oid) = 0;
+  virtual void upper_bound(const ghobject_t &oid) = 0;
   virtual void next() = 0;
 
 protected:
@@ -724,8 +724,8 @@ protected:
 
 class SimpleCollectionListIterator : public CollectionListIterator {
 public:
-  SimpleCollectionListIterator(const KeyValueDB::Iterator &it)
-    : CollectionListIterator(it) {
+  SimpleCollectionListIterator(CephContext *cct, const KeyValueDB::Iterator &it)
+    : CollectionListIterator(it), m_cct(cct) {
   }
 
   bool valid() const override {
@@ -738,41 +738,46 @@ public:
     return m_oid;
   }
 
-  virtual const std::string &key() const override {
-    ceph_assert(valid());
-
-    return m_key;
-  }
+  void lower_bound(const ghobject_t &oid) override {
+    string key;
+    get_object_key(m_cct, oid, &key);
 
-  void lower_bound(const std::string &key) override {
     m_it->lower_bound(key);
-    cache_key();
+    get_oid();
   }
 
-  void upper_bound(const std::string &key) override {
+  void upper_bound(const ghobject_t &oid) override {
+    string key;
+    get_object_key(m_cct, oid, &key);
+
     m_it->upper_bound(key);
-    cache_key();
+    get_oid();
   }
 
   void next() override {
     ceph_assert(valid());
 
     m_it->next();
-    cache_key();
+    get_oid();
   }
 
 private:
-  std::string m_key;
+  CephContext *m_cct;
   ghobject_t m_oid;
 
-  void cache_key() {
+  void get_oid() {
     if (!valid()) {
       return;
     }
 
-    m_key = m_it->key();
-    int r = get_key_object(m_key, &m_oid);
-    ceph_assert(r != -1);
+    if (is_extent_shard_key(m_it->key())) {
+      next();
+      return;
+    }
+
+    m_oid = ghobject_t();
+    int r = get_key_object(m_it->key(), &m_oid);
+    ceph_assert(r == 0);
   }
 };
 
@@ -792,21 +797,11 @@ public:
     return m_chunk_iter->first;
   }
 
-  const std::string &key() const override {
-    ceph_assert(valid());
-
-    return m_chunk_iter->second;
-  }
-
-  void lower_bound(const std::string &key) override {
-    ghobject_t oid;
-    int r = get_key_object(key, &oid);
-    ceph_assert(r != -1);
+  void lower_bound(const ghobject_t &oid) override {
+    std::string key;
+    _key_encode_prefix(oid, &key);
 
-    std::string pkey;
-    _key_encode_prefix(oid, &pkey);
-
-    m_it->lower_bound(pkey);
+    m_it->lower_bound(key);
     m_chunk_iter = m_chunk.end();
     if (!get_next_chunk()) {
       return;
@@ -824,10 +819,10 @@ public:
     }
   }
 
-  void upper_bound(const std::string &key) override {
-    lower_bound(key);
+  void upper_bound(const ghobject_t &oid) override {
+    lower_bound(oid);
 
-    if (valid() && this->key() == key) {
+    if (valid() && this->oid() == oid) {
       next();
     }
   }
@@ -846,26 +841,33 @@ private:
   std::map<ghobject_t, std::string>::iterator m_chunk_iter;
 
   bool get_next_chunk() {
+    while (m_it->valid() && is_extent_shard_key(m_it->key())) {
+      m_it->next();
+    }
+
     if (!m_it->valid()) {
       return false;
     }
 
     ghobject_t oid;
     int r = get_key_object(m_it->key(), &oid);
-    ceph_assert(r != -1);
+    ceph_assert(r == 0);
 
     m_chunk.clear();
     while (true) {
       m_chunk.insert({oid, m_it->key()});
 
-      m_it->next();
+      do {
+        m_it->next();
+      } while (m_it->valid() && is_extent_shard_key(m_it->key()));
+
       if (!m_it->valid()) {
         break;
       }
 
       ghobject_t next;
       r = get_key_object(m_it->key(), &next);
-      ceph_assert(r != -1);
+      ceph_assert(r == 0);
       if (next.shard_id != oid.shard_id ||
           next.hobj.pool != oid.hobj.pool ||
           next.hobj.get_bitwise_key_u32() != oid.hobj.get_bitwise_key_u32()) {
@@ -10004,8 +10006,8 @@ int BlueStore::_collection_list(
   int r = 0;
   ghobject_t static_next;
   std::unique_ptr<CollectionListIterator> it;
-  string temp_start_key, temp_end_key;
-  string start_key, end_key;
+  ghobject_t coll_range_temp_start, coll_range_temp_end;
+  ghobject_t coll_range_start, coll_range_end;
   bool set_next = false;
   ghobject_t pend;
   bool temp;
@@ -10016,17 +10018,17 @@ int BlueStore::_collection_list(
   if (start.is_max() || start.hobj.is_max()) {
     goto out;
   }
-  get_coll_key_range(c->cid, c->cnode.bits, &temp_start_key, &temp_end_key,
-    &start_key, &end_key);
+  get_coll_range(c->cid, c->cnode.bits, &coll_range_temp_start,
+                 &coll_range_temp_end, &coll_range_start, &coll_range_end);
   dout(20) << __func__
-    << " range " << pretty_binary_string(temp_start_key)
-    << " to " << pretty_binary_string(temp_end_key)
-    << " and " << pretty_binary_string(start_key)
-    << " to " << pretty_binary_string(end_key)
+    << " range " << coll_range_temp_start
+    << " to " << coll_range_temp_end
+    << " and " << coll_range_start
+    << " to " << coll_range_end
     << " start " << start << dendl;
   if (legacy) {
     it = std::make_unique<SimpleCollectionListIterator>(
-      db->get_iterator(PREFIX_OBJ));
+      cct, db->get_iterator(PREFIX_OBJ));
   } else {
     it = std::make_unique<SortedCollectionListIterator>(
       db->get_iterator(PREFIX_OBJ));
@@ -10034,27 +10036,21 @@ int BlueStore::_collection_list(
   if (start == ghobject_t() ||
     start.hobj == hobject_t() ||
     start == c->cid.get_min_hobj()) {
-    it->upper_bound(temp_start_key);
+    it->upper_bound(coll_range_temp_start);
     temp = true;
   } else {
-    string k;
-    get_object_key(cct, start, &k);
     if (start.hobj.is_temp()) {
       temp = true;
-      ceph_assert(k >= temp_start_key && k < temp_end_key);
+      ceph_assert(start >= coll_range_temp_start && start < coll_range_temp_end);
     } else {
       temp = false;
-      ceph_assert(k >= start_key && k < end_key);
+      ceph_assert(start >= coll_range_start && start < coll_range_end);
     }
-    dout(20) << __func__ << " start from " << pretty_binary_string(k)
-      << " temp=" << (int)temp << dendl;
-    it->lower_bound(k);
+    dout(20) << __func__ << " temp=" << (int)temp << dendl;
+    it->lower_bound(start);
   }
   if (end.hobj.is_max()) {
-    if (temp)
-      get_key_object(temp_end_key, &pend);
-    else
-      get_key_object(end_key, &pend);
+    pend = temp ? coll_range_temp_end : coll_range_end;
   } else {
     if (end.hobj.is_temp()) {
       if (temp)
@@ -10062,10 +10058,7 @@ int BlueStore::_collection_list(
       else
         goto out;
     } else {
-      if (temp)
-        get_key_object(temp_end_key, &pend);
-      else
-        pend = end;
+      pend = temp ? coll_range_temp_end : end;
     }
   }
   dout(20) << __func__ << " pend " << pend << dendl;
@@ -10077,7 +10070,7 @@ int BlueStore::_collection_list(
        dout(20) << __func__ << " oid " << it->oid() << " >= " << pend << dendl;
       if (temp) {
        if (end.hobj.is_temp()) {
-          if (it->valid() && it->key() < temp_end_key) {
+          if (it->valid() && it->oid() < coll_range_temp_end) {
             *pnext = it->oid();
             set_next = true;
           }
@@ -10085,34 +10078,28 @@ int BlueStore::_collection_list(
        }
        dout(30) << __func__ << " switch to non-temp namespace" << dendl;
        temp = false;
-       it->upper_bound(start_key);
+       it->upper_bound(coll_range_start);
         if (end.hobj.is_max())
-          get_key_object(end_key, &pend);
+          pend = coll_range_end;
         else
           pend = end;
        dout(30) << __func__ << " pend " << pend << dendl;
        continue;
       }
-      if (it->valid() && it->key() < end_key) {
+      if (it->valid() && it->oid() < coll_range_end) {
         *pnext = it->oid();
         set_next = true;
       }
       break;
     }
-    dout(30) << __func__ << " key " << pretty_binary_string(it->key()) << dendl;
-    if (is_extent_shard_key(it->key())) {
-      it->next();
-      continue;
-    }
-    ghobject_t oid = it->oid();
-    dout(20) << __func__ << " oid " << oid << " end " << end << dendl;
+    dout(20) << __func__ << " oid " << it->oid() << " end " << end << dendl;
     if (ls->size() >= (unsigned)max) {
       dout(20) << __func__ << " reached max " << max << dendl;
-      *pnext = oid;
+      *pnext = it->oid();
       set_next = true;
       break;
     }
-    ls->push_back(oid);
+    ls->push_back(it->oid());
     it->next();
   }
 out: