forest-net
an overlay networks for large-scale virtual worlds
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
StatsModule.cpp
1 
9 #include "StatsModule.h"
10 
11 namespace forest {
12 
13 
14 StatsModule::StatsModule(int maxStats1, int maxLnk1, int maxQ1,
15  ComtreeTable* ctt1)
16  : maxStats(maxStats1), maxLnk(maxLnk1), maxQ(maxQ1),
17  ctt(ctt1) {
18  stat = new StatItem[maxStats+1];
19  lnkCnts = new LinkCounts[maxLnk+1];
20  qCnts = new QueueCounts[maxQ+1];
21  for (int i = 1; i <= maxLnk; i++) {
22  lnkCnts[i].inByte = lnkCnts[i].outByte = 0;
23  lnkCnts[i].inPkt = lnkCnts[i].outPkt = 0;
24  lnkCnts[i].numPkt = 0;
25  }
26  for (int i = 1; i <= maxQ; i++) {
27  qCnts[i].bytLen = qCnts[i].pktLen = 0;
28  }
29  n = 0;
30  totInByte = 0; totInPkt = 0; totDiscards = 0;
31  rtrInByte = 0; rtrInPkt = 0;
32  leafInByte = 0; leafInPkt = 0;
33  totOutByte = 0; totOutPkt = 0;
34  rtrOutByte = 0; rtrOutPkt = 0; rtrDiscards = 0;
35  leafOutByte = 0; leafOutPkt = 0; leafDiscards = 0;
36 };
37 
38 StatsModule::~StatsModule() { delete [] stat; }
39 
40 void StatsModule::record(uint64_t now) {
41 // Record statistics at time now.
42  int i, val, cLnk, qid;
43 
44  val = -1;
45  if (n == 0) return;
46 
47  // check for the statsSwitch file
48  string fname = "statsSwitch";
49  ifstream sfs; sfs.open(fname.c_str());
50  string statsSwitch;
51  if (sfs.fail()) return;
52  if (!Misc::readWord(sfs,statsSwitch) || statsSwitch != "on") {
53  sfs.close(); return;
54  }
55  sfs.close();
56  for (i = 1; i <= n; i++) {
57  StatItem& s = stat[i];
58  switch(s.typ) {
59  case inPkt:
60  if (s.lnk == 0) val = totInPkt;
61  else if (s.lnk == -1) val = rtrInPkt;
62  else if (s.lnk == -2) val = leafInPkt;
63  else val = lnkCnts[s.lnk].inPkt;
64  break;
65  case outPkt:
66  if (s.lnk == 0) val = totOutPkt;
67  else if (s.lnk == -1) val = rtrOutPkt;
68  else if (s.lnk == -2) val = leafOutPkt;
69  else val = lnkCnts[s.lnk].outPkt;
70  break;
71  case inByt:
72  if (s.lnk == 0) val = totInByte;
73  else if (s.lnk == -1) val = rtrInByte;
74  else if (s.lnk == -2) val = leafInByte;
75  else val = lnkCnts[s.lnk].inByte;
76  break;
77  case outByt:
78  if (s.lnk == 0) val = totOutByte;
79  else if (s.lnk == -1) val = rtrOutByte;
80  else if (s.lnk == -2) val = leafOutByte;
81  else val = lnkCnts[s.lnk].outByte;
82  break;
83  case qPkt:
84  if (s.comt == 0) {
85  val = getLinkQlen(s.lnk);
86  break;
87  }
88  cLnk = ctt->getComtLink(s.comt,s.lnk);
89  qid = ctt->getLinkQ(cLnk);
90  val = getQlen(qid);
91  break;
92  case qByt:
93  if (s.comt == 0) {
94  val = discCnt(s.lnk);
95  break;
96  }
97  cLnk = ctt->getComtLink(s.comt,s.lnk);
98  qid = ctt->getLinkQ(cLnk);
99  val = qDiscCnt(qid);
100  break;
101  case disc:
102  cLnk = ctt->getComtLink(s.comt,s.lnk);
103  qid = ctt->getLinkQ(cLnk);
104  val = getQlen(qid);
105  break;
106  default: break;
107  }
108  fs << val << " ";
109  }
110  fs << double(now)/1000000000 << endl;
111  fs.flush();
112 }
113 
141 bool StatsModule::readStat(istream& in) {
142  int lnk, comt;
143  cntrTyp typ; string typStr, fname;
144 
145  Misc::skipBlank(in);
146  if (!Misc::readWord(in,typStr)) return false;
147 
148  if (typStr == "inPkt") typ = inPkt;
149  else if (typStr == "outPkt") typ = outPkt;
150  else if (typStr == "inByt") typ = inByt;
151  else if (typStr == "outByt") typ = outByt;
152  else if (typStr == "qPkt") typ = qPkt;
153  else if (typStr == "qByt") typ = qByt;
154  else if (typStr == "disc") typ = disc;
155  else return false;
156 
157  switch (typ) {
158  case inPkt: case outPkt: case inByt: case outByt:
159  if (!Misc::readNum(in,lnk)) return false;
160  break;
161  case qPkt: case qByt: case disc:
162  if (!Misc::readNum(in,lnk) || !Misc::readNum(in,comt))
163  return false;
164  break;
165  }
166  Misc::cflush(in,'\n');
167 
168  if (n >= maxStats) return false;
169  n++;
170 
171  StatItem& s = stat[n];
172  s.typ = typ;
173  s.lnk = lnk;
174  s.comt = comt;
175 
176  return true;
177 }
178 
179 bool StatsModule::read(istream& in) {
180 // Read statistics items from the input. The first line must contain an
181 // integer, giving the number of items to be read. The input may
182 // include blank lines and comment lines (any text starting with '#').
183 // Each entry must be on a line by itself (possibly with a trailing comment).
184  int num;
185  Misc::skipBlank(in);
186  if (!Misc::readNum(in,num)) return false;
187  Misc::cflush(in,'\n');
188  while (num--) {
189  if (readStat(in) == Null) return false;
190  }
191  string fname = "stats";
192  fs.open(fname.c_str(),fstream::app);
193  if (fs.fail()) return false;
194  return true;
195 }
196 
202 string& StatsModule::stat2string(int i, string& s) const {
203  stringstream ss;
204  StatItem& si = stat[i];
205  switch(si.typ) {
206  case inPkt:
207  ss << " inPkt " << setw(2) << si.lnk << endl;
208  break;
209  case outPkt:
210  ss << "outPkt " << setw(2) << si.lnk << endl;
211  break;
212  case inByt:
213  ss << " inByt " << setw(2) << si.lnk << endl;
214  break;
215  case outByt:
216  ss << "outByt " << setw(2) << si.lnk << endl;
217  break;
218  case qPkt:
219  ss << " qPkt " << setw(2) << si.lnk
220  << " " << setw(2) << si.comt << endl;
221  break;
222  case qByt:
223  ss << " qByt " << setw(2) << si.lnk
224  << " " << setw(2) << si.comt << endl;
225  break;
226  case disc:
227  ss << " disc " << setw(2) << si.lnk
228  << " " << setw(2) << si.comt << endl;
229  break;
230  }
231  s = ss.str();
232  return s;
233 }
234 
239 string& StatsModule::toString(string& s) const {
240  string s1;
241  s = "";
242  for (int i = 1; i <= n; i++) s += stat2string(i,s1);
243  return s;
244 }
245 
246 } // ends namespace
247