Programming answers in double ended queue. Fix word "Coding" by "Encoding"
[anna.git] / source / core / oam / CounterScope.cpp
1 // ANNA - Anna is Not Nothingness Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // http://redmine.teslayout.com/projects/anna-suite
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     *  Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #include <string>
38
39 #include <anna/core/tracing/Logger.hpp>
40
41 #include <anna/xml/Node.hpp>
42 #include <anna/xml/Attribute.hpp>
43
44 #include <anna/timex/Engine.hpp>
45
46 #include <anna/core/oam/CounterScope.hpp>
47 #include <anna/core/oam/Counter.hpp>
48
49 using namespace std;
50 using namespace anna;
51
52 #define test_range(index) \
53    if (index < 0 || index >= MaxCounter) { \
54       string msg (asString ()); \
55       msg += functions::asText (" | Index: ", index); \
56       msg += functions::asText (" | Out of range [0, MaxCounter): ", index); \
57       throw RuntimeException (msg, __FILE__, __LINE__); \
58    }
59
60 #define test_instance(index) \
61    if (a_counters [index] == NULL) { \
62       string msg (asString ()); \
63       msg += functions::asText (" | CounterId: ", index); \
64       msg += " | Counter Id is not defined"; \
65       throw RuntimeException (msg, __FILE__, __LINE__); \
66    }
67
68
69 oam::CounterScope::~CounterScope() {
70   for(int i = 0; i < MaxCounter; i ++) {
71     if(a_counters [i] != NULL)
72       delete a_counters [i];
73   }
74 }
75
76 void oam::CounterScope::create(const int counter, const char* name)
77 throw(RuntimeException) {
78   test_range(counter);
79
80   if(a_counters [counter] != NULL) {
81     string msg("Counter '");
82     msg += name;
83     msg += "' (";
84     msg += functions::asString(counter);
85     msg += ") already registered as ";
86     msg += a_counters [counter]->asString();
87     throw RuntimeException(msg, ANNA_FILE_LOCATION);
88   }
89
90   a_counters [counter] = new Counter(*this, counter, name);
91   LOGDEBUG(
92     string msg("Creation | ");
93     msg += asString();
94     msg += " | ";
95     msg += a_counters [counter]->asString();
96     Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
97   );
98 }
99
100 oam::Counter::type_t oam::CounterScope::increment(const int counter, const oam::Counter::type_t value)
101 throw(RuntimeException) {
102   test_range(counter);
103   test_instance(counter);
104   a_counters [counter]->a_value += value;
105   a_counters [counter]->a_accValue += value;
106   LOGINFORMATION(a_counters [counter]->debug());
107   return a_counters [counter]->a_value;
108 }
109
110 oam::Counter::type_t oam::CounterScope::assign(const int counter, const oam::Counter::type_t value)
111 throw(RuntimeException) {
112   test_range(counter);
113   test_instance(counter);
114   a_counters [counter]->a_value = value;
115   a_counters [counter]->a_accValue = value;
116   LOGINFORMATION(a_counters [counter]->debug());
117   return value;
118 }
119
120 oam::Counter::type_t oam::CounterScope::getValue(const int counter) const
121 throw(RuntimeException) {
122   test_range(counter);
123   test_instance(counter);
124   return a_counters [counter]->a_value;
125 }
126
127 U64 oam::CounterScope::getAccValue(const int counter) const
128 throw(RuntimeException) {
129   test_range(counter);
130   test_instance(counter);
131   return a_counters [counter]->a_accValue;
132 }
133
134 int oam::CounterScope::resetAccValues() throw(RuntimeException) {
135   int result = 0; // affected counters
136
137   for(int ii = 0; ii < MaxCounter; ii ++)
138     if(a_counters [ii])
139       result += (a_counters [ii]->resetAcc()) ? 1 : 0;
140
141   return result;
142 }
143
144 const oam::Counter* oam::CounterScope::getCounter(const int counter) const
145 throw(RuntimeException) {
146   test_range(counter);
147   test_instance(counter);
148   return a_counters [counter];
149 }
150
151 string oam::CounterScope::asString() const
152 throw() {
153   string result("oam::CounterScope { Id: ");
154   result += functions::asString(a_id);
155   result += " | Name: ";
156   result += a_name;
157   return result += " }";
158 }
159
160 xml::Node* oam::CounterScope::asXML(xml::Node* parent) const
161 throw(RuntimeException) {
162   xml::Node* result = parent->createChild("Scope");
163   xml::Node* counter;
164
165   for(int ii = 0; ii < MaxCounter; ii ++) {
166     if(a_counters [ii] == NULL)
167       continue;
168
169     counter = result->createChild("Counter");
170     counter->createAttribute("Id", ii);
171     counter->createAttribute("Name", a_counters [ii]->getName());
172     counter->createAttribute("Value", a_counters [ii]->getValue());
173     counter->createAttribute("AccValue", a_counters [ii]->getAccumulatedValue());
174   }
175
176   return result;
177 }
178