]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore/FreelistManager: use btree_map instead of map
authorSage Weil <sage@redhat.com>
Wed, 13 Jan 2016 19:53:37 +0000 (14:53 -0500)
committerSage Weil <sage@redhat.com>
Wed, 20 Jan 2016 15:48:48 +0000 (10:48 -0500)
btree_map is about twice as memory efficient.

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/FreelistManager.cc
src/os/bluestore/FreelistManager.h

index a9385ad8142a9fc935ca799b100a316768ab53a1..0a025f56904b21a1657c194e7d4abedb81200f11 100644 (file)
@@ -144,9 +144,11 @@ int FreelistManager::allocate(
       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
@@ -170,9 +172,11 @@ int FreelistManager::allocate(
       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();
@@ -199,7 +203,20 @@ int FreelistManager::release(
               << " (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;
index b0115e54831e9f667bf0bd2d0759ed96e0ba1ac9..1694f530cf5a6bc1db5a89b9cebdad8f324f46fc 100644 (file)
 #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();
@@ -35,7 +40,7 @@ public:
     return total_free;
   }
 
-  const std::map<uint64_t,uint64_t>& get_freelist() {
+  const map_t& get_freelist() {
     return kv_free;
   }