]>
git.proxmox.com Git - ceph.git/blob - ceph/src/crush/CrushTreeDumper.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph distributed storage system
6 * Copyright (C) 2015 Mirantis Inc
8 * Author: Mykola Golub <mgolub@mirantis.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
17 #ifndef CRUSH_TREE_DUMPER_H
18 #define CRUSH_TREE_DUMPER_H
20 #include "CrushWrapper.h"
24 * A helper class and functions to dump a crush tree.
28 * class SimpleDumper : public CrushTreeDumper::Dumper<ostream> {
30 * SimpleDumper(const CrushWrapper *crush) :
31 * CrushTreeDumper::Dumper<ostream>(crush) {}
33 * virtual void dump_item(const CrushTreeDumper::Item &qi, ostream *out) {
35 * for (int k = 0; k < qi.depth; k++)
38 * *out << crush->get_item_name(qi.id)
40 * *out << "osd." << qi.id;
45 * SimpleDumper(crush).dump(out);
49 namespace CrushTreeDumper
{
57 Item() : id(0), depth(0), weight(0) {}
58 Item(int i
, int d
, float w
) : id(i
), depth(d
), weight(w
) {}
60 bool is_bucket() const { return id
< 0; }
64 class Dumper
: public list
<Item
> {
66 explicit Dumper(const CrushWrapper
*crush_
) : crush(crush_
) {
67 crush
->find_roots(roots
);
73 virtual void reset() {
81 if (root
== roots
.end())
83 push_back(Item(*root
, 0, crush
->get_bucket_weightf(*root
)));
89 touched
.insert(qi
.id
);
92 // queue bucket contents...
93 int s
= crush
->get_bucket_size(qi
.id
);
94 for (int k
= s
- 1; k
>= 0; k
--) {
95 int id
= crush
->get_bucket_item(qi
.id
, k
);
96 qi
.children
.push_back(id
);
97 push_front(Item(id
, qi
.depth
+ 1,
98 crush
->get_bucket_item_weightf(qi
.id
, k
)));
111 bool is_touched(int id
) const { return touched
.count(id
) > 0; }
114 virtual void dump_item(const Item
&qi
, F
*f
) = 0;
117 const CrushWrapper
*crush
;
122 set
<int>::iterator root
;
125 inline void dump_item_fields(const CrushWrapper
*crush
,
126 const Item
&qi
, Formatter
*f
) {
127 f
->dump_int("id", qi
.id
);
128 if (qi
.is_bucket()) {
129 int type
= crush
->get_bucket_type(qi
.id
);
130 f
->dump_string("name", crush
->get_item_name(qi
.id
));
131 f
->dump_string("type", crush
->get_type_name(type
));
132 f
->dump_int("type_id", type
);
134 f
->dump_stream("name") << "osd." << qi
.id
;
135 f
->dump_string("type", crush
->get_type_name(0));
136 f
->dump_int("type_id", 0);
137 f
->dump_float("crush_weight", qi
.weight
);
138 f
->dump_unsigned("depth", qi
.depth
);
142 inline void dump_bucket_children(const CrushWrapper
*crush
,
143 const Item
&qi
, Formatter
*f
) {
147 f
->open_array_section("children");
148 for (list
<int>::const_iterator i
= qi
.children
.begin();
149 i
!= qi
.children
.end();
151 f
->dump_int("child", *i
);
156 class FormattingDumper
: public Dumper
<Formatter
> {
158 explicit FormattingDumper(const CrushWrapper
*crush
) : Dumper
<Formatter
>(crush
) {}
161 void dump_item(const Item
&qi
, Formatter
*f
) override
{
162 f
->open_object_section("item");
163 dump_item_fields(qi
, f
);
164 dump_bucket_children(qi
, f
);
168 virtual void dump_item_fields(const Item
&qi
, Formatter
*f
) {
169 CrushTreeDumper::dump_item_fields(crush
, qi
, f
);
172 virtual void dump_bucket_children(const Item
&qi
, Formatter
*f
) {
173 CrushTreeDumper::dump_bucket_children(crush
, qi
, f
);