forest-net
an overlay networks for large-scale virtual worlds
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
StatsModule.h
Go to the documentation of this file.
1 
3 #ifndef STATSMODULE_H
4 #define STATSMODULE_H
5 
6 #include <thread>
7 #include <mutex>
8 #include "Forest.h"
9 #include "ComtreeTable.h"
10 
11 using std::thread;
12 using std::mutex;
13 
14 namespace forest {
15 
16 
17 class StatsModule {
18 public:
19  StatsModule(int, int, int, ComtreeTable*);
20  ~StatsModule();
21 
22  // access statistics
23  int iPktCnt(int);
24  int oPktCnt(int);
25  int discCnt(int);
26  int qDiscCnt(int);
27  int iByteCnt(int);
28  int oByteCnt(int);
29  int getQlen(int);
30  int getQbytes(int);
31  int getLinkQlen(int);
32 
33  // update statistics counts
34  void clearLnkStats(int);
35  void clearQuStats(int);
36  void cntInLink(int, int, bool);
37  void cntOutLink(int, int, bool);
38  void cntDiscards(int, int, bool);
39  void incQlen(int, int, int);
40  void decQlen(int, int, int);
41 
42  // record stats to a file
43  void record(uint64_t);
44 
45  // input/output
46  bool read(istream&);
47  string toString();
48 private:
49  int maxStats; // max number of recorded statistics
50  int maxLnk; // largest link number
51  int maxQ; // largest queue number
52  int n; // number of statistics to record
53 
54  mutex mtx; // makes all operations atomic
55 
56  enum cntrTyp {
57  inPkt, outPkt, inByt, outByt, // input/output counts
58  qPkt, qByt, // packets/bytes in queues
59  disc // discards from queues
60  };
61 
62  struct StatItem {
63  int lnk; // link number for stat
64  int comt; // for queue length stats
65  cntrTyp typ; // type of counter for this stat
66  };
67  StatItem *stat; // stat[i] is statistic number i
68  ofstream fs; // file stream for statistics
69 
70  struct LinkCounts {
71  int inByte;
72  int outByte;
73  int inPkt;
74  int outPkt;
75  int discards;
76  int numPkt;
77  };
78  LinkCounts *lnkCnts;
79 
80  struct QueueCounts {
81  int bytLen;
82  int pktLen;
83  int discards;
84  };
85  QueueCounts *qCnts;
86 
87  // system-wide counts
88  int totInByte;
89  int totInPkt;
90  int totDiscards;
91  int rtrInByte;
92  int rtrInPkt;
93  int leafInByte;
94  int leafInPkt;
95  int totOutByte;
96  int totOutPkt;
97  int rtrOutByte;
98  int rtrOutPkt;
99  int rtrDiscards;
100  int leafOutByte;
101  int leafOutPkt;
102  int leafDiscards;
103 
104  ComtreeTable *ctt;
105 
106  // helper functions
107  bool readStat(istream&);
108  string stat2string(int) const;
109 };
110 
111 inline int StatsModule::iPktCnt(int lnk) {
112  unique_lock<mutex> lck(mtx);
113  return (lnk == 0 ? totInPkt :
114  (lnk == -1 ? rtrInPkt :
115  (lnk == -2 ? leafInPkt : lnkCnts[lnk].inPkt)));
116 }
117 
118 inline int StatsModule::oPktCnt(int lnk) {
119  unique_lock<mutex> lck(mtx);
120  return (lnk == 0 ? totOutPkt :
121  (lnk == -1 ? rtrOutPkt :
122  (lnk == -2 ? leafOutPkt : lnkCnts[lnk].outPkt)));
123 }
124 
125 inline int StatsModule::iByteCnt(int lnk) {
126  unique_lock<mutex> lck(mtx);
127  return (lnk == 0 ? totInByte :
128  (lnk == -1 ? rtrInByte :
129  (lnk == -2 ? leafInByte : lnkCnts[lnk].inByte)));
130 }
131 
132 inline int StatsModule::oByteCnt(int lnk) {
133  unique_lock<mutex> lck(mtx);
134  return (lnk == 0 ? totOutByte :
135  (lnk == -1 ? rtrOutByte :
136  (lnk == -2 ? leafOutByte : lnkCnts[lnk].outByte)));
137 }
138 
139 inline int StatsModule::discCnt(int lnk) {
140  unique_lock<mutex> lck(mtx);
141  return lnkCnts[lnk].discards;
142 }
143 
144 inline int StatsModule::qDiscCnt(int qid) {
145  unique_lock<mutex> lck(mtx);
146  return qCnts[qid].discards;
147 }
148 
149 inline int StatsModule::getQlen(int qid) {
150  unique_lock<mutex> lck(mtx);
151  return qCnts[qid].pktLen;
152 }
153 
154 inline int StatsModule::getQbytes(int qid) {
155  unique_lock<mutex> lck(mtx);
156  return qCnts[qid].bytLen;
157 }
158 
159 inline int StatsModule::getLinkQlen(int lnk) {
160  unique_lock<mutex> lck(mtx);
161  return lnkCnts[lnk].numPkt;
162 }
163 
164 inline void StatsModule::clearLnkStats(int lnk) {
165  lnkCnts[lnk].inByte = lnkCnts[lnk].outByte = 0;
166  lnkCnts[lnk].inPkt = lnkCnts[lnk].outPkt = 0;
167  lnkCnts[lnk].numPkt = lnkCnts[lnk].discards = 0;
168 }
169 
170 inline void StatsModule::clearQuStats(int qid) {
171  qCnts[qid].bytLen = qCnts[qid].pktLen = qCnts[qid].discards = 0;
172 }
173 
174 inline void StatsModule::cntInLink(int lnk, int len, bool isRtr) {
175  if (1 <= lnk && lnk <= maxLnk) {
176  lnkCnts[lnk].inByte += len; lnkCnts[lnk].inPkt++;
177  totInByte += len; totInPkt++;
178  if (isRtr) { rtrInByte += len; rtrInPkt++; }
179  else { leafInByte += len; leafInPkt++; }
180  }
181 }
182 
183 inline void StatsModule::cntOutLink(int lnk, int len, bool isRtr) {
184  if (1 <= lnk && lnk <= maxLnk) {
185  lnkCnts[lnk].outByte += len; lnkCnts[lnk].outPkt++;
186  totOutByte += len; totOutPkt++;
187  if (isRtr) { rtrOutByte += len; rtrOutPkt++; }
188  else { leafOutByte += len; leafOutPkt++; }
189  }
190 }
191 
192 inline void StatsModule::cntDiscards(int qid, int lnk, bool isRtr) {
193  if (1 <= lnk && lnk <= maxLnk) {
194  totDiscards++;
195  lnkCnts[lnk].discards++;
196  if (isRtr) rtrDiscards++;
197  else leafDiscards++;
198  if (1 <= qid && qid <= maxQ)
199  qCnts[qid].discards++;
200  }
201 }
202 
203 inline void StatsModule::incQlen(int qid, int lnk, int len) {
204  if (1 <= lnk && lnk <= maxLnk) lnkCnts[lnk].numPkt++;
205  if (1 <= qid && qid <= maxQ) {
206  qCnts[qid].bytLen += len; qCnts[qid].pktLen++;
207  }
208 }
209 
210 inline void StatsModule::decQlen(int qid, int lnk, int len) {
211  if (1 <= lnk && lnk <= maxLnk) lnkCnts[lnk].numPkt--;
212  if (1 <= qid && qid <= maxQ) {
213  qCnts[qid].bytLen -= len; qCnts[qid].pktLen--;
214  }
215 }
216 
217 } // ends namespace
218 
219 
220 #endif