1#pragma once
2
3#include <Processors/IProcessor.h>
4#include <IO/Operators.h>
5
6namespace DB
7{
8
9/** Print pipeline in "dot" format for GraphViz.
10 * You can render it with:
11 * dot -T png < pipeline.dot > pipeline.png
12 */
13
14template <typename Processors, typename Statuses>
15void printPipeline(const Processors & processors, const Statuses & statuses, WriteBuffer & out)
16{
17 out << "digraph\n{\n";
18
19 auto get_proc_id = [](const IProcessor & proc) -> UInt64
20 {
21 return reinterpret_cast<std::uintptr_t>(&proc);
22 };
23
24 auto statuses_iter = statuses.begin();
25
26 /// Nodes // TODO quoting and escaping
27 for (const auto & processor : processors)
28 {
29 out << "n" << get_proc_id(*processor) << "[label=\"" << processor->getName() << processor->getDescription();
30
31 if (statuses_iter != statuses.end())
32 {
33 out << " (" << IProcessor::statusToName(*statuses_iter) << ")";
34 ++statuses_iter;
35 }
36
37 out << "\"];\n";
38 }
39
40 /// Edges
41 for (const auto & processor : processors)
42 {
43 for (const auto & port : processor->getOutputs())
44 {
45 const IProcessor & curr = *processor;
46 const IProcessor & next = port.getInputPort().getProcessor();
47
48 out << "n" << get_proc_id(curr) << " -> " << "n" << get_proc_id(next) << ";\n";
49 }
50 }
51 out << "}\n";
52}
53
54template <typename Processors>
55void printPipeline(const Processors & processors, WriteBuffer & out)
56{
57 printPipeline(processors, std::vector<IProcessor::Status>(), out);
58}
59
60}
61