Remove dynamic exceptions
[anna.git] / include / anna / statistics / Accumulator.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_statistics_Accumulator_hpp
10 #define anna_statistics_Accumulator_hpp
11
12 #include <anna/core/RuntimeException.hpp>
13 #include <anna/core/functions.hpp>
14
15 // Standard
16 #include <string>
17
18 namespace anna {
19 namespace xml {
20 class Node;
21 }
22 }
23
24
25 namespace anna {
26
27 namespace statistics {
28
29
30 class Operation {
31 public:
32
33   enum Type {
34     //Sum = 0, // is not very useful
35     Average,
36     StandardDeviation,
37     BesselStandardDeviation, //This correction (the use of N - 1 instead of N) is known as Bessel's correction
38     Minimum,
39     Maximum
40   };
41 };
42
43 typedef struct {
44
45   unsigned long long Size;                           // Sample size
46   double Sum;                                        // Accumulated sum
47   double SquareSum;                                  // Accumulated sum of square values
48   double Average;                                    // Current average
49   //double SquareSumSampleDeviation;                   // Current total sum for square deviation items;
50   double MinimumProcessed;                           // Minimum value processed
51   double MaximumProcessed;                           // Maximum value processed
52   anna::Millisecond MinimumEventTimestampMs;       // Timestamp (ms) for minimum event
53   anna::Millisecond MaximumEventTimestampMs;       // Timestamp (ms) for maximum event
54   anna::Millisecond LastResetEventTimestampMs;     // Timestamp (ms) for last statistics reset
55
56
57   void reset() {
58     Size = (unsigned long long)0;
59     Sum = (double)0;
60     SquareSum = (double)0;
61     Average = (double)0;
62     //SquareSumSampleDeviation = (double)0;
63     MinimumProcessed = (double)0;
64     MaximumProcessed = (double)0;
65     MinimumEventTimestampMs = (anna::Millisecond)0;
66     MaximumEventTimestampMs = (anna::Millisecond)0;
67     LastResetEventTimestampMs = anna::Millisecond::getTime();
68   }
69
70 } _concept_data_t;
71
72 typedef std::map <int, _concept_data_t> _concept_data_map_t;
73 typedef std::map <int, _concept_data_t>::const_iterator _concept_data_map_iter;
74
75
76
77
78 //------------------------------------------------------------------------------
79 //------------------------------------------------------------ class Accumulator
80 //------------------------------------------------------------------------------
81 /**
82  * Accumulated data information for statistic sample.
83  * It can manage a set of concepts at the same time.
84  *
85  * @short Contains statistical sample information
86  */
87 class Accumulator {
88
89   std::string a_name;
90
91   void initialize(const int & conceptId) ;
92   _concept_data_t * getConcept(const int & conceptId) const noexcept(false);
93   // Gets the data structure for a existing concept Id.
94   // Initializes and returns the new data structure for a new stored concept Id which is valid (exists for the engine).
95   // Launch exception if concept id is not a valid concept registered at Engine.
96
97   /*mutable */_concept_data_map_t a_concept_data_map;
98
99   std::string floatFormat(const int & numberOfDecimals) const ;
100
101   double getStandardDeviation(const _concept_data_t * conceptData) const noexcept(false);
102   double getBesselStandardDeviation(const _concept_data_t * conceptData) const noexcept(false);
103
104
105 public:
106
107   /**
108   * Constructor.
109   *
110   * @param name Accumulator name
111   */
112   Accumulator(const std::string &name) : a_name(name) {};
113
114   /**
115   * Destructor.
116   */
117   ~Accumulator() {;}
118
119
120   /**
121    * Sets the accumulator name
122    *
123    * @param name Name provided
124    */
125   void setName(const std::string &name) { a_name = name; }
126
127   /**
128   * Adds a new statistic concept through the accumulator, to ease the concept name creation,
129   * which will be a string defined by: concept name + ': ' + accumulator name.
130   *
131   * @param description Concept description; e.g.: processing time, messages size, etc.
132   * @param unit Concept unit description
133   * @param integerNatureSample Most of cases we will measure 'time' with the unit which force integer values
134   *                            (is more intuitive 850 msecs than 0,850 secs). Then, it is @em true by default.
135   *                            This is useful to advice better representation for some indicators like minimum/maximum
136   *                             within integer samples.
137   * @param conceptNameFormat Format to register the complete concept name. Will be parsed using (in order) the provided
138   *                          description, and the accumulator name: '<concept description> [<accumulator name>]' by default.
139   *
140   * @return Assigned concept identification number (sequence)
141   */
142   int addConcept(const std::string & description, const std::string & unit, const bool & integerNatureSample = true, const char *conceptNameFormat = "%s [%s]") ;
143
144   /**
145   * Process new value for the sample regarding a concept identifier previously registered through the engine.
146   *
147   * @param conceptId statistical concept processed
148   * @param value Value for processed item
149   *
150   * @see reset()
151   */
152   void process(const int & conceptId, const double & value) noexcept(false);
153
154
155   /**
156   * Reset sample for all concepts
157   *
158   * @see process()
159   */
160   void reset(void) ;
161
162
163   /**
164   * Reset sample for provided concept
165   *
166   * @param conceptId Concept identification to be reset
167   *
168   * @see process()
169   */
170   void reset(const int & conceptId) noexcept(false);
171
172
173   /**
174   * Copy operator
175   *
176   * @param accumulator Class instance source of data
177   *
178   * @return Returns copied reference
179   */
180   const Accumulator & operator = (const Accumulator & accumulator);
181
182
183
184   // Gets
185
186   /**
187    * Gets the accumulator name
188    *
189    * @result Accumulator name
190    */
191   const std::string &getName() const { return a_name; }
192
193   /**
194   * Gets current sample size for any concept id
195   *
196   * @param conceptId Concept identification
197   *
198   * @return Sample size
199   *
200   * @see getValue()
201   * @see asXML()
202   */
203   unsigned long long int sampleSize(const int & conceptId) const noexcept(false);
204
205
206   /**
207   * Get statistical information
208   *
209   * @param conceptId Statistical concept
210   * @param operation Solicited operation
211   *
212   * @return Value for solicited conceptId/operation
213   *
214   * @see sampleSize()
215   * @see asXML()
216   */
217   double getValue(const int & conceptId, const Operation::Type & operation) const noexcept(false);
218
219
220   /**
221   * Class string representation
222   *
223   * @param numberOfDecimals Number of float decimals at representation string. Default is 2.
224   *
225   * @return String with class content
226   */
227   std::string asString(const int & numberOfDecimals = 2) const ;
228
229
230   /**
231   * Class XML representation
232   *
233   * @param numberOfDecimals Number of float decimals at XML representation. Default is 2.
234   *
235   * @return XML with class content
236   */
237   anna::xml::Node* asXML(anna::xml::Node* parent, const int & numberOfDecimals = 2) const ;
238 };
239
240 }
241 }
242
243 #endif