]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: use CrushTreeDumper for dumping crush tree.
authorMykola Golub <mgolub@mirantis.com>
Tue, 13 Jan 2015 15:08:17 +0000 (17:08 +0200)
committerSage Weil <sage@redhat.com>
Sat, 17 Jan 2015 16:57:26 +0000 (08:57 -0800)
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
src/crush/CrushWrapper.cc

index 8e5601cd5de1e5360b3077dec5eaa0aa60fe73ab..5b76fc02858aaa84c2fd1654910631c65f533309 100644 (file)
@@ -1,3 +1,5 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
 
 #include "osd/osd_types.h"
 #include "common/debug.h"
@@ -5,6 +7,7 @@
 #include "common/errno.h"
 
 #include "CrushWrapper.h"
+#include "CrushTreeDumper.h"
 
 #define dout_subsys ceph_subsys_crush
 
@@ -1484,113 +1487,83 @@ void CrushWrapper::list_rules(Formatter *f) const
   }
 }
 
-struct qi {
-  int item;
-  int depth;
-  float weight;
-  qi() : item(0), depth(0), weight(0) {}
-  qi(int i, int d, float w) : item(i), depth(d), weight(w) {}
-};
+class CrushTreePlainDumper : public CrushTreeDumper::Dumper<ostream> {
+public:
+  typedef CrushTreeDumper::Dumper<ostream> Parent;
 
-void CrushWrapper::dump_tree(const vector<__u32>& w, ostream *out, Formatter *f) const
-{
-  if (out)
+  CrushTreePlainDumper(const CrushWrapper *crush, const vector<__u32>& w)
+    : Parent(crush), weights(w) {}
+
+  void dump(ostream *out) {
     *out << "# id\tweight\ttype name\treweight\n";
-  if (f)
-    f->open_array_section("nodes");
-  set<int> touched;
-  set<int> roots;
-  find_roots(roots);
-  for (set<int>::iterator p = roots.begin(); p != roots.end(); ++p) {
-    list<qi> q;
-    q.push_back(qi(*p, 0, get_bucket_weight(*p) / (float)0x10000));
-    while (!q.empty()) {
-      int cur = q.front().item;
-      int depth = q.front().depth;
-      float weight = q.front().weight;
-      q.pop_front();
-
-      if (out) {
-       *out << cur << "\t";
-       int oldprecision = out->precision();
-       *out << std::setprecision(4) << weight << std::setprecision(oldprecision) << "\t";
-
-       for (int k=0; k<depth; k++)
-         *out << "\t";
-      }
-      if (f) {
-       f->open_object_section("item");
-      }
-      if (cur >= 0) {
+    Parent::dump(out);
+  }
 
-       if (f) {
-         f->dump_unsigned("id", cur);
-         f->dump_stream("name") << "osd." << cur;
-         f->dump_string("type", get_type_name(0));
-         f->dump_int("type_id", 0);
-       }
-       if (out)
-         *out << "osd." << cur << "\t";
-
-       double wf = (double)w[cur] / (double)0x10000;
-       if (out) {
-         std::streamsize p = out->precision();
-         *out << std::setprecision(4)
-              << wf
-              << std::setprecision(p)
-              << "\t";
-       }
-       if (f) {
-         f->dump_float("reweight", wf);
-       }
+protected:
+  virtual void dump_item(const CrushTreeDumper::Item &qi, ostream *out) {
+    std::streamsize p = out->precision();
 
-       if (out)
-         *out << "\n";
-       if (f) {
-         f->dump_float("crush_weight", weight);
-         f->dump_unsigned("depth", depth);
-         f->close_section();
-       }
-       touched.insert(cur);
-      }
-      if (cur >= 0) {
-       continue;
-      }
+    *out << qi.id << "\t"
+        << std::setprecision(4) << qi.weight << "\t";
 
-      // queue bucket contents...
-      int type = get_bucket_type(cur);
-      int s = get_bucket_size(cur);
-      if (f) {
-       f->dump_int("id", cur);
-       f->dump_string("name", get_item_name(cur));
-       f->dump_string("type", get_type_name(type));
-       f->dump_int("type_id", type);
-       f->open_array_section("children");
-      }
-      for (int k=s-1; k>=0; k--) {
-       int item = get_bucket_item(cur, k);
-       q.push_front(qi(item, depth+1, (float)get_bucket_item_weight(cur, k) / (float)0x10000));
-       if (f)
-         f->dump_int("child", item);
-      }
-      if (f)
-       f->close_section();
-
-      if (out)
-       *out << get_type_name(type) << " " << get_item_name(cur) << "\n";
-      if (f) {
-       f->close_section();
-      }
+    for (int k=0; k < qi.depth; k++)
+      *out << "\t";
 
+    if (qi.is_bucket())
+    {
+      *out << crush->get_type_name(crush->get_bucket_type(qi.id)) << " "
+          << crush->get_item_name(qi.id);
+    }
+    else
+    {
+      assert(qi.id >= 0 && (size_t)qi.id < weights.size());
+      *out << "osd." << qi.id << "\t"
+          << (double)weights[qi.id] / (double)0x10000 << "\t";
     }
+    *out << std::setprecision(p) << "\n";
   }
-  if (f) {
+
+private:
+    const vector<__u32>& weights;
+};
+
+
+class CrushTreeFormattingDumper : public CrushTreeDumper::FormattingDumper {
+public:
+  typedef CrushTreeDumper::FormattingDumper Parent;
+
+  CrushTreeFormattingDumper(const CrushWrapper *crush, const vector<__u32>& w)
+    : Parent(crush), weights(w) {}
+
+  void dump(Formatter *f) {
+    f->open_array_section("nodes");
+    Parent::dump(f);
     f->close_section();
     f->open_array_section("stray");
+    f->close_section();
+  }
+
+protected:
+  virtual void dump_item_fields(const CrushTreeDumper::Item &qi, Formatter *f) {
+    CrushTreeFormattingDumper::dump_item_fields(qi, f);
+    if (!qi.is_bucket())
+    {
+      assert(qi.id >= 0 && (size_t)qi.id < weights.size());
+      f->dump_float("reweight", (double)weights[qi.id] / (double)0x10000);
+    }
   }
 
+private:
+  const vector<__u32>& weights;
+};
+
+
+void CrushWrapper::dump_tree(const vector<__u32>& w, ostream *out, Formatter *f) const
+{
+  if (out)
+    CrushTreePlainDumper(this, w).dump(out);
   if (f)
-    f->close_section();
+    CrushTreeFormattingDumper(this, w).dump(f);
 }
 
 void CrushWrapper::generate_test_instances(list<CrushWrapper*>& o)