profiler  0.0
Node.h
1 #ifndef PROFILER_SRC_MOLPRO_PROFILER_TREE_NODE_H
2 #define PROFILER_SRC_MOLPRO_PROFILER_TREE_NODE_H
3 #include <list>
4 #include <map>
5 #include <memory>
6 #include <stdexcept>
7 #include <string>
8 
9 namespace molpro {
10 namespace profiler {
11 
12 struct NodePathError : std::runtime_error {
13  using std::runtime_error::runtime_error;
14 };
15 
19 template <class Counter>
20 class Node {
21 private:
22  explicit Node(std::string name, Counter counter, std::shared_ptr<Node<Counter>> parent)
23  : name(std::move(name)), counter(std::move(counter)), parent(std::move(parent)) {}
24 
25 public:
26  ~Node() = default;
27  Node(Node<Counter>&&) noexcept = default;
28  Node<Counter>& operator=(Node<Counter>&&) noexcept = default;
29 
30  Node(const Node<Counter>&) = delete;
31  Node<Counter>& operator=(const Node<Counter>&) = delete;
32 
34  static std::shared_ptr<Node<Counter>> make_root(const std::string& name, const Counter& counter) {
35  return std::make_shared<Node<Counter>>(Node<Counter>(name, counter, nullptr));
36  }
37 
39  static std::shared_ptr<Node<Counter>> add_child(const std::string& child_name, const Counter& child_counter,
40  const std::shared_ptr<Node<Counter>>& parent) {
41  auto child = std::make_shared<Node<Counter>>(Node<Counter>(child_name, child_counter, parent));
42  parent->children[child_name] = child;
43  return child;
44  }
45 
47  static std::shared_ptr<Node<Counter>> deep_copy(const std::shared_ptr<Node<Counter>>& subtree,
48  std::shared_ptr<Node<Counter>> parent) {
49  auto tree_copy = make_root(subtree->name, subtree->counter);
50  tree_copy->parent = std::move(parent);
51  for (auto& child : subtree->children)
52  tree_copy->children[child.first] = deep_copy(child.second, tree_copy);
53  return tree_copy;
54  }
55 
67  template <typename ForwardIt>
68  std::shared_ptr<Node<Counter>> walk(ForwardIt start_name, ForwardIt end_name) {
69  auto it = children.find(*start_name);
70  if (it == end(children))
71  throw NodePathError(std::string("Child was not found. Path is invalid."));
72  if (++start_name == end_name)
73  return it->second;
74  else
75  return it->second->walk(start_name, end_name);
76  }
77 
78  std::shared_ptr<Node<Counter>> walk(const std::list<std::string>& path_to_node) {
79  return walk(begin(path_to_node), end(path_to_node));
80  }
81 
83  std::shared_ptr<Node<Counter>> child(const std::string& child_name) { return walk({child_name}); }
84 
90  std::shared_ptr<Node<Counter>> find_parent(const std::string& parent_name) {
91  auto node = this;
92  while (node->parent != nullptr && node->parent->name != parent_name) {
93  node = node->parent.get();
94  }
95  return node->parent;
96  }
97 
103  std::shared_ptr<Node<Counter>> walk_up(int n) {
104  if (n < 1)
105  throw NodePathError("n must be > 0");
106  std::shared_ptr<Node<Counter>> node = parent;
107  while (--n > 0 && node != nullptr) {
108  node = node->parent;
109  }
110  return node;
111  }
112 
114  size_t count_nodes() const {
115  size_t n = 1;
116  for (auto& child : children)
117  n += child.second->count_nodes();
118  return n;
119  }
120 
121  std::string name;
123  std::shared_ptr<Node<Counter>> parent = nullptr;
124  std::map<std::string, std::shared_ptr<Node<Counter>>> children;
125 };
126 
127 } // namespace profiler
128 } // namespace molpro
129 #endif // PROFILER_SRC_MOLPRO_PROFILER_TREE_NODE_H
Resource counter used for storing operation count, call count, timing information.
Definition: Counter.h:15
A node in a parameter tree storing a Counter object aliased by a name.
Definition: Node.h:20
std::shared_ptr< Node< Counter > > child(const std::string &child_name)
Returns a child node, same as calling walk with one element.
Definition: Node.h:83
std::shared_ptr< Node< Counter > > walk(const std::list< std::string > &path_to_node)
Definition: Node.h:78
static std::shared_ptr< Node< Counter > > deep_copy(const std::shared_ptr< Node< Counter >> &subtree, std::shared_ptr< Node< Counter >> parent)
Creates a deep copy of the subtree with copies of Counter objects.
Definition: Node.h:47
std::shared_ptr< Node< Counter > > walk(ForwardIt start_name, ForwardIt end_name)
Recursively walks down a single branch described by node names.
Definition: Node.h:68
Counter counter
Definition: Node.h:122
std::map< std::string, std::shared_ptr< Node< Counter > > > children
child nodes
Definition: Node.h:124
static std::shared_ptr< Node< Counter > > make_root(const std::string &name, const Counter &counter)
Builds the root tree whose parent is nullptr.
Definition: Node.h:34
std::string name
name of the node. This is a duplicate, same name is stored in parent's map of children.
Definition: Node.h:121
std::shared_ptr< Node< Counter > > find_parent(const std::string &parent_name)
Searches from current parent up to the root returning a node with specified name.
Definition: Node.h:90
std::shared_ptr< Node< Counter > > parent
resource counter
Definition: Node.h:123
Node(Node< Counter > &&) noexcept=default
size_t count_nodes() const
Get total number of nodes in a tree.
Definition: Node.h:114
std::shared_ptr< Node< Counter > > walk_up(int n)
Walks up n levels by following the parent nodes.
Definition: Node.h:103
static std::shared_ptr< Node< Counter > > add_child(const std::string &child_name, const Counter &child_counter, const std::shared_ptr< Node< Counter >> &parent)
Adds a child to the current node. Overwrites any children with child_name that already exist.
Definition: Node.h:39
Definition: Profiler.h:5
Definition: Node.h:12