GENEIAL  0.2=/
 All Classes Pages
Bookkeeper.h
1 #pragma once
2 
3 #include <geneial/namespaces.h>
4 
5 #include <unordered_map>
6 #include <chrono>
7 #include <ctime>
8 #include <ratio>
9 #include <functional>
10 #include <memory>
11 #include <iostream>
12 
13 //TODO(bewo): Clean this up.
14 
15 geneial_private_namespace(geneial)
16 {
17 geneial_private_namespace(population)
18 {
19 geneial_private_namespace(management)
20 {
21 
22 geneial_export_namespace
23 {
24 
25 struct ScopedTrace
26 {
27  virtual ~ScopedTrace()
28  {
29  }
30 };
31 
32 struct EventData
33 {
34  virtual ~EventData()
35  {
36  }
37 };
38 
39 class BaseBookkeeper
40 {
41 public:
42  virtual ~BaseBookkeeper()
43  {
44  }
45 
46  virtual std::unique_ptr<ScopedTrace> scopedEventTrace(const char* traceName) = 0;
47 
48  virtual void traceEvent(const char* traceName) = 0;
49 
50  virtual void traceEvent(const char* traceName, EventData* data) = 0;
51 };
52 
53 template<typename T>
54 class EventValueData : public EventData
55 {
56  T _value;
57 private:
58  EventValueData(const T value) :
59  _value(value)
60  {
61  }
62 
63 public:
64  virtual ~EventValueData()
65  {
66  }
67 
68  static inline void create(BaseBookkeeper &bookkeeper, const char* name, const T value)
69  {
70  EventValueData * evd = new EventValueData(value);
71  bookkeeper.traceEvent(name,evd);
72  }
73 
74  T getValue() const
75  {
76  return _value;
77  }
78 };
79 
80 class DefaultBookkeeper: public BaseBookkeeper
81 {
82 public:
83  virtual ~DefaultBookkeeper()
84  {
85  }
86 
87  virtual std::unique_ptr<ScopedTrace> scopedEventTrace(const char*) override
88  {
89  return std::unique_ptr<ScopedTrace>(nullptr);
90  }
91 
92  virtual void traceEvent(const char*) override
93  {
94  }
95 
96  virtual void traceEvent(const char*, EventData* evd) override
97  {
98  delete evd;
99  }
100 };
101 
102 class ScopedTimeTrace;
103 
104 
105 class StatisticBookkeeper: public BaseBookkeeper
106 {
107 private:
108  friend ScopedTimeTrace;
109 
110  //We use an unordered map since we want insert to be as fast as possible.
111  //Later when diagnosing on this data-structure we do not care about speed.
112  std::unordered_multimap<std::string,
113  std::unique_ptr<EventData>> _events;
114 
115  StatisticBookkeeper& operator= ( const StatisticBookkeeper & ) = delete;
116  StatisticBookkeeper(StatisticBookkeeper const&) = delete;
117 protected:
118  void traceTime(const char* name, const double duration)
119  {
120  EventValueData<double>::create(*this,name,duration);
121  }
122 
123 
124 public:
125  StatisticBookkeeper()
126  {
127  }
128  virtual std::unique_ptr<ScopedTrace> scopedEventTrace(const char* traceName) override;
129 
130  virtual void traceEvent(const char* traceName) override
131  {
132  _events.insert(std::make_pair(std::string(traceName),std::unique_ptr<EventData>(new EventData())));
133  }
134 
135  virtual void traceEvent(const char* traceName, EventData* data) override
136  {
137  _events.insert(std::make_pair(std::string(traceName),std::unique_ptr<EventData>(data)));
138  }
139 
140  virtual ~StatisticBookkeeper()
141  {
142  }
143 
144  std::unordered_multimap<std::string, std::unique_ptr<EventData> >& getEvents()
145  {
146  return _events;
147  }
148 };
149 
150 class ScopedTimeTrace: public ScopedTrace
151 {
152 private:
153  std::chrono::high_resolution_clock::time_point _start;
154  StatisticBookkeeper* _bookKeeper;
155  std::string _name;
156 
157  friend StatisticBookkeeper;
158 
159 protected:
160  ScopedTimeTrace(StatisticBookkeeper *bookKeeper, const char* traceName) :
161  _start(std::chrono::high_resolution_clock::now()),
162  _bookKeeper(bookKeeper),
163  _name(traceName)
164  {
165  }
166 
167 public:
168  virtual ~ScopedTimeTrace()
169  {
170  const std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
171  const auto duration = std::chrono::duration_cast<std::chrono::duration<double,std::milli>>(end - _start).count();
172  //TODO (bewo):string?
173  _bookKeeper->traceTime(_name.c_str(), duration);
174  }
175 };
176 
177 
178 class ScopedEvent
179 {
180  std::unique_ptr<ScopedTrace> _trace;
181 public:
182  ScopedEvent(const char* name,BaseBookkeeper &bookkeeper):
183  _trace(bookkeeper.scopedEventTrace(name))
184  {
185  }
186 };
187 
188 }
189 }
190 }
191 }
192