1 // -*- mode: c++ -*-
2 //
3 // This file is part of libyacurs.
4 // Copyright (C) 2013  Rafael Ostertag
5 //
6 // This program is free software: you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License as
8 // published by the Free Software Foundation, either version 3 of the
9 // License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program.  If not, see
18 // <http://www.gnu.org/licenses/>.
19 //
20 //
21 // $Id$
22 
23 #ifndef EVTQUEUESTATS_H
24 #define EVTQUEUESTATS_H 1
25 
26 // Can't use #ifdef HAVE_STDINT_H since that would require pulling in
27 // config.h or libyacurscfg.h which might cause undesired side
28 // effects.
29 #include <stdint.h>
30 
31 #include <list>
32 #include <map>
33 
34 #include "event.h"
35 #include "eventconnector.h"
36 
37 namespace YACURS {
38 namespace INTERNAL {
39 /**
40  * Class maintaining EventQueue Statistics.
41  */
42 class EventQueueStats {
43    private:
44     /// Max time used for one full Event queue Iteration
45     clock_t evq_max_proc_time;
46 
47     /// Min time used for one full Event queue Iteration
48     clock_t evq_min_proc_time;
49 
50     /// Max time used for processessing an Event
51     clock_t evt_max_proc_time;
52 
53     /// Min time used for processessing an Event
54     clock_t evt_min_proc_time;
55 
56     /// Max time spent in EventConnector call
57     clock_t ec_call_max_time;
58 
59     /// Min time spent in EventConnector call
60     clock_t ec_call_min_time;
61 
62     /// Number of Events submitted during run time of queue
63     uint32_t evt_submitted;
64 
65     /// Number of Events submitted during run time of
66     /// queue by type
67     std::map<EventType, uint32_t> evt_submitted_by_type;
68 
69     /// Events that were pending during cleanup()
70     uint32_t evt_pending_cleanup;
71 
72     /// Total events processed
73     uint32_t evt_proc_total;
74 
75     /// Events processed by type
76     std::map<EventType, uint32_t> evt_proc_by_type;
77 
78     /// Max Events connected
79     uint32_t ec_max;
80 
81     /// Min Events connected
82     uint32_t ec_min;
83 
84     /// Events connected by type
85     std::map<EventType, uint32_t> ec_max_by_type;
86 
87     /// Total Event Connectors calls
88     uint32_t ec_calls_total;
89 
90     /// Event connector calls by type
91     std::map<EventType, uint32_t> ec_call_by_type;
92 
93     /// Total EventConnector remove requests processed
94     uint32_t ec_rm_total;
95 
96     /// Number of Cancelled EventConnector removal requests
97     uint32_t ec_rm_cancelled;
98 
99     /// Number of skipped removal requests due to
100     /// duplicates
101     uint32_t ec_rm_skipped;
102 
103     /// Max size of EventQueue
104     uint16_t evq_size_max;
105 
106     /// Max Size of EventConnector Removal Queue.
107     uint16_t ec_rmq_size_max;
108 
109    public:
110     EventQueueStats();
111 
112     void clear();
113 
114     void update_ec_calls_by_type(const EventType t);
115 
116     void update_ec_call_time(clock_t t0, clock_t t1);
117 
118     void update_ec_rmq_size_max(uint16_t v);
119 
120     void update_ec_rm_total();
121 
122     void update_ec_rm_cancelled();
123 
124     void update_ec_rm_skipped();
125 
126     void update_evt_submitted_by_type(const EventType t);
127 
128     void update_ec_count(
129         const std::map<EventType, std::list<EventConnectorBase*> >& ec_map);
130 
131     void update_evq_size_max(uint16_t v);
132 
133     void update_evt_proc_by_type(const EventType t);
134 
135     void update_evt_pending_cleanup();
136 
137     void update_evt_proc_time(clock_t t0, clock_t t1);
138 
139     void update_evq_proc_time(clock_t t0, clock_t t1);
140 
141     void dump(std::ostream& _os) const;
142 };
143 
update_ec_calls_by_type(const EventType t)144 inline void EventQueueStats::update_ec_calls_by_type(const EventType t) {
145     ec_calls_total++;
146     ec_call_by_type[t]++;
147 }
148 
update_ec_call_time(clock_t t0,clock_t t1)149 inline void EventQueueStats::update_ec_call_time(clock_t t0, clock_t t1) {
150     ec_call_max_time = std::max(ec_call_max_time, t1 - t0);
151     ec_call_min_time = std::min(ec_call_min_time, t1 - t0);
152 }
153 
update_ec_rmq_size_max(uint16_t v)154 inline void EventQueueStats::update_ec_rmq_size_max(uint16_t v) {
155     ec_rmq_size_max = std::max(ec_rmq_size_max, v);
156 }
157 
update_ec_rm_total()158 inline void EventQueueStats::update_ec_rm_total() { ec_rm_total++; }
159 
update_ec_rm_cancelled()160 inline void EventQueueStats::update_ec_rm_cancelled() { ec_rm_cancelled++; }
161 
update_ec_rm_skipped()162 inline void EventQueueStats::update_ec_rm_skipped() { ec_rm_skipped++; }
163 
update_evt_submitted_by_type(const EventType t)164 inline void EventQueueStats::update_evt_submitted_by_type(const EventType t) {
165     evt_submitted++;
166     evt_submitted_by_type[t]++;
167 }
168 
update_ec_count(const std::map<EventType,std::list<EventConnectorBase * >> & ec_map)169 inline void EventQueueStats::update_ec_count(
170     const std::map<EventType, std::list<EventConnectorBase*> >& ec_map) {
171     std::map<EventType, std::list<EventConnectorBase*> >::const_iterator
172         map_it = ec_map.begin();
173 
174     uint32_t overall = 0;
175 
176     while (map_it != ec_map.end()) {
177         overall += map_it->second.size();
178         ec_max_by_type[map_it->first] =
179             std::max(static_cast<std::list<EventConnectorBase*>::size_type>(
180                          ec_max_by_type[map_it->first]),
181                      map_it->second.size());
182         map_it++;
183     }
184     ec_max = std::max(ec_max, overall);
185     ec_min = std::min(ec_min, overall);
186 }
187 
update_evq_size_max(uint16_t v)188 inline void EventQueueStats::update_evq_size_max(uint16_t v) {
189     evq_size_max = std::max(evq_size_max, v);
190 }
191 
update_evt_proc_by_type(const EventType t)192 inline void EventQueueStats::update_evt_proc_by_type(const EventType t) {
193     evt_proc_total++;
194     evt_proc_by_type[t]++;
195 }
196 
update_evt_pending_cleanup()197 inline void EventQueueStats::update_evt_pending_cleanup() {
198     evt_pending_cleanup++;
199 }
200 
update_evt_proc_time(clock_t t0,clock_t t1)201 inline void EventQueueStats::update_evt_proc_time(clock_t t0, clock_t t1) {
202     evt_max_proc_time = std::max(evt_max_proc_time, t1 - t0);
203     evt_min_proc_time = std::min(evt_min_proc_time, t1 - t0);
204 }
205 
update_evq_proc_time(clock_t t0,clock_t t1)206 inline void EventQueueStats::update_evq_proc_time(clock_t t0, clock_t t1) {
207     evq_max_proc_time = std::max(evq_max_proc_time, t1 - t0);
208     evq_min_proc_time = std::min(evq_min_proc_time, t1 - t0);
209 }
210 }  // namespace INTERNAL
211 }  // namespace YACURS
212 
213 #endif  // EVTQUEUESTATS_H
214