]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush/CrushWrapper: add dump_tree()
authorSage Weil <sage@inktank.com>
Sat, 2 Nov 2013 17:56:20 +0000 (10:56 -0700)
committerSage Weil <sage@inktank.com>
Tue, 3 Dec 2013 22:41:24 +0000 (14:41 -0800)
This is based on the OSDMap::print_tree(), but is a bit simpler because
we do not have up/down information at this level.

Signed-off-by: Sage Weil <sage@inktank.com>
src/crush/CrushWrapper.cc
src/crush/CrushWrapper.h

index d17166bc4a9fe7905e167b22e47dde8d504bc5d9..9c3783029ea68b78538eee84b59e167e22beb6e2 100644 (file)
@@ -1119,6 +1119,115 @@ 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) {}
+};
+
+void CrushWrapper::dump_tree(const vector<__u32>& w, ostream *out, Formatter *f) const
+{
+  if (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) {
+
+       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);
+       }
+
+       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;
+      }
+
+      // 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();
+      }
+
+    }
+  }
+  if (f) {
+    f->close_section();
+    f->open_array_section("stray");
+  }
+
+  if (f)
+    f->close_section();
+}
+
 void CrushWrapper::generate_test_instances(list<CrushWrapper*>& o)
 {
   o.push_back(new CrushWrapper);
index 3c4a4518124e9daf33f96ea422588976e54d764e..c4ef1040d57aeb3f3deafccc86d14265e76d9d13 100644 (file)
@@ -794,6 +794,7 @@ public:
   void dump(Formatter *f) const;
   void dump_rules(Formatter *f) const;
   void list_rules(Formatter *f) const;
+  void dump_tree(const vector<__u32>& w, ostream *out, Formatter *f) const;
   static void generate_test_instances(list<CrushWrapper*>& o);