statistics.hh (5599:5bad83cddb8c) statistics.hh (5886:12431dc9a30a)
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 * Erik Hallnor
30 */
31
32/** @file
33 * Declaration of Statistics objects.
34 */
35
36/**
37* @todo
38*
39* Generalized N-dimensinal vector
40* documentation
41* key stats
42* interval stats
43* -- these both can use the same function that prints out a
44* specific set of stats
45* VectorStandardDeviation totals
46* Document Namespaces
47*/
48#ifndef __BASE_STATISTICS_HH__
49#define __BASE_STATISTICS_HH__
50
51#include <algorithm>
52#include <cassert>
53#ifdef __SUNPRO_CC
54#include <math.h>
55#endif
56#include <cmath>
57#include <functional>
58#include <iosfwd>
59#include <limits>
60#include <string>
61#include <vector>
62
29 */
30
31/** @file
32 * Declaration of Statistics objects.
33 */
34
35/**
36* @todo
37*
38* Generalized N-dimensinal vector
39* documentation
40* key stats
41* interval stats
42* -- these both can use the same function that prints out a
43* specific set of stats
44* VectorStandardDeviation totals
45* Document Namespaces
46*/
47#ifndef __BASE_STATISTICS_HH__
48#define __BASE_STATISTICS_HH__
49
50#include <algorithm>
51#include <cassert>
52#ifdef __SUNPRO_CC
53#include <math.h>
54#endif
55#include <cmath>
56#include <functional>
57#include <iosfwd>
58#include <limits>
59#include <string>
60#include <vector>
61
62#include "base/cast.hh"
63#include "base/cprintf.hh"
64#include "base/intmath.hh"
65#include "base/refcnt.hh"
66#include "base/str.hh"
67#include "base/stats/flags.hh"
68#include "base/stats/visit.hh"
69#include "base/stats/types.hh"
70#include "sim/host.hh"
71
72class Callback;
73
74/** The current simulated tick. */
75extern Tick curTick;
76
77/* A namespace for all of the Statistics */
78namespace Stats {
79
80typedef std::numeric_limits<Counter> CounterLimits;
81
82/* Contains the statistic implementation details */
83//////////////////////////////////////////////////////////////////////
84//
85// Statistics Framework Base classes
86//
87//////////////////////////////////////////////////////////////////////
63#include "base/cprintf.hh"
64#include "base/intmath.hh"
65#include "base/refcnt.hh"
66#include "base/str.hh"
67#include "base/stats/flags.hh"
68#include "base/stats/visit.hh"
69#include "base/stats/types.hh"
70#include "sim/host.hh"
71
72class Callback;
73
74/** The current simulated tick. */
75extern Tick curTick;
76
77/* A namespace for all of the Statistics */
78namespace Stats {
79
80typedef std::numeric_limits<Counter> CounterLimits;
81
82/* Contains the statistic implementation details */
83//////////////////////////////////////////////////////////////////////
84//
85// Statistics Framework Base classes
86//
87//////////////////////////////////////////////////////////////////////
88struct StatData
88class Info
89{
89{
90 public:
90 /** The name of the stat. */
91 std::string name;
92 /** The description of the stat. */
93 std::string desc;
94 /** The formatting flags. */
95 StatFlags flags;
96 /** The display precision. */
97 int precision;
98 /** A pointer to a prerequisite Stat. */
91 /** The name of the stat. */
92 std::string name;
93 /** The description of the stat. */
94 std::string desc;
95 /** The formatting flags. */
96 StatFlags flags;
97 /** The display precision. */
98 int precision;
99 /** A pointer to a prerequisite Stat. */
99 const StatData *prereq;
100 const Info *prereq;
100 /**
101 * A unique stat ID for each stat in the simulator.
102 * Can be used externally for lookups as well as for debugging.
103 */
104 int id;
105
101 /**
102 * A unique stat ID for each stat in the simulator.
103 * Can be used externally for lookups as well as for debugging.
104 */
105 int id;
106
106 StatData();
107 virtual ~StatData();
107 public:
108 Info();
109 virtual ~Info();
108
109 /**
110 * Reset the corresponding stat to the default state.
111 */
112 virtual void reset() = 0;
113
114 /**
115 * @return true if this stat has a value and satisfies its
116 * requirement as a prereq
117 */
118 virtual bool zero() const = 0;
119
120 /**
121 * Check that this stat has been set up properly and is ready for
122 * use
123 * @return true for success
124 */
125 virtual bool check() const = 0;
126 bool baseCheck() const;
127
128 /**
129 * Visitor entry for outputing statistics data
130 */
131 virtual void visit(Visit &visitor) = 0;
132
133 /**
134 * Checks if the first stat's name is alphabetically less than the second.
135 * This function breaks names up at periods and considers each subname
136 * separately.
137 * @param stat1 The first stat.
138 * @param stat2 The second stat.
139 * @return stat1's name is alphabetically before stat2's
140 */
110
111 /**
112 * Reset the corresponding stat to the default state.
113 */
114 virtual void reset() = 0;
115
116 /**
117 * @return true if this stat has a value and satisfies its
118 * requirement as a prereq
119 */
120 virtual bool zero() const = 0;
121
122 /**
123 * Check that this stat has been set up properly and is ready for
124 * use
125 * @return true for success
126 */
127 virtual bool check() const = 0;
128 bool baseCheck() const;
129
130 /**
131 * Visitor entry for outputing statistics data
132 */
133 virtual void visit(Visit &visitor) = 0;
134
135 /**
136 * Checks if the first stat's name is alphabetically less than the second.
137 * This function breaks names up at periods and considers each subname
138 * separately.
139 * @param stat1 The first stat.
140 * @param stat2 The second stat.
141 * @return stat1's name is alphabetically before stat2's
142 */
141 static bool less(StatData *stat1, StatData *stat2);
143 static bool less(Info *stat1, Info *stat2);
142};
143
144};
145
144class ScalarData : public StatData
146class ScalarInfoBase : public Info
145{
146 public:
147 virtual Counter value() const = 0;
148 virtual Result result() const = 0;
149 virtual Result total() const = 0;
150 virtual void visit(Visit &visitor) { visitor.visit(*this); }
151};
152
153template <class Stat>
147{
148 public:
149 virtual Counter value() const = 0;
150 virtual Result result() const = 0;
151 virtual Result total() const = 0;
152 virtual void visit(Visit &visitor) { visitor.visit(*this); }
153};
154
155template <class Stat>
154class ScalarStatData : public ScalarData
156class ScalarInfo : public ScalarInfoBase
155{
156 protected:
157 Stat &s;
158
159 public:
157{
158 protected:
159 Stat &s;
160
161 public:
160 ScalarStatData(Stat &stat) : s(stat) {}
162 ScalarInfo(Stat &stat) : s(stat) {}
161
162 virtual bool check() const { return s.check(); }
163 virtual Counter value() const { return s.value(); }
164 virtual Result result() const { return s.result(); }
165 virtual Result total() const { return s.total(); }
166 virtual void reset() { s.reset(); }
167 virtual bool zero() const { return s.zero(); }
168};
169
163
164 virtual bool check() const { return s.check(); }
165 virtual Counter value() const { return s.value(); }
166 virtual Result result() const { return s.result(); }
167 virtual Result total() const { return s.total(); }
168 virtual void reset() { s.reset(); }
169 virtual bool zero() const { return s.zero(); }
170};
171
170struct VectorData : public StatData
172class VectorInfoBase : public Info
171{
173{
174 public:
172 /** Names and descriptions of subfields. */
173 mutable std::vector<std::string> subnames;
174 mutable std::vector<std::string> subdescs;
175
175 /** Names and descriptions of subfields. */
176 mutable std::vector<std::string> subnames;
177 mutable std::vector<std::string> subdescs;
178
179 public:
176 virtual size_type size() const = 0;
177 virtual const VCounter &value() const = 0;
178 virtual const VResult &result() const = 0;
179 virtual Result total() const = 0;
180
181 void
182 update()
183 {
184 if (!subnames.empty()) {
185 size_type s = size();
186 if (subnames.size() < s)
187 subnames.resize(s);
188
189 if (subdescs.size() < s)
190 subdescs.resize(s);
191 }
192 }
193};
194
195template <class Stat>
180 virtual size_type size() const = 0;
181 virtual const VCounter &value() const = 0;
182 virtual const VResult &result() const = 0;
183 virtual Result total() const = 0;
184
185 void
186 update()
187 {
188 if (!subnames.empty()) {
189 size_type s = size();
190 if (subnames.size() < s)
191 subnames.resize(s);
192
193 if (subdescs.size() < s)
194 subdescs.resize(s);
195 }
196 }
197};
198
199template <class Stat>
196class VectorStatData : public VectorData
200class VectorInfo : public VectorInfoBase
197{
198 protected:
199 Stat &s;
200 mutable VCounter cvec;
201 mutable VResult rvec;
202
203 public:
201{
202 protected:
203 Stat &s;
204 mutable VCounter cvec;
205 mutable VResult rvec;
206
207 public:
204 VectorStatData(Stat &stat) : s(stat) {}
208 VectorInfo(Stat &stat) : s(stat) {}
205
206 virtual bool check() const { return s.check(); }
207 virtual bool zero() const { return s.zero(); }
208 virtual void reset() { s.reset(); }
209
210 virtual size_type size() const { return s.size(); }
211
212 virtual VCounter &
213 value() const
214 {
215 s.value(cvec);
216 return cvec;
217 }
218
219 virtual const VResult &
220 result() const
221 {
222 s.result(rvec);
223 return rvec;
224 }
225
226 virtual Result total() const { return s.total(); }
227
228 virtual void
229 visit(Visit &visitor)
230 {
231 update();
232 s.update(this);
233 visitor.visit(*this);
234 }
235};
236
209
210 virtual bool check() const { return s.check(); }
211 virtual bool zero() const { return s.zero(); }
212 virtual void reset() { s.reset(); }
213
214 virtual size_type size() const { return s.size(); }
215
216 virtual VCounter &
217 value() const
218 {
219 s.value(cvec);
220 return cvec;
221 }
222
223 virtual const VResult &
224 result() const
225 {
226 s.result(rvec);
227 return rvec;
228 }
229
230 virtual Result total() const { return s.total(); }
231
232 virtual void
233 visit(Visit &visitor)
234 {
235 update();
236 s.update(this);
237 visitor.visit(*this);
238 }
239};
240
237struct DistDataData
241struct DistData
238{
239 Counter min_val;
240 Counter max_val;
241 Counter underflow;
242 Counter overflow;
243 VCounter cvec;
244 Counter sum;
245 Counter squares;
246 Counter samples;
247
248 Counter min;
249 Counter max;
250 Counter bucket_size;
251 size_type size;
252 bool fancy;
253};
254
242{
243 Counter min_val;
244 Counter max_val;
245 Counter underflow;
246 Counter overflow;
247 VCounter cvec;
248 Counter sum;
249 Counter squares;
250 Counter samples;
251
252 Counter min;
253 Counter max;
254 Counter bucket_size;
255 size_type size;
256 bool fancy;
257};
258
255struct DistData : public StatData
259class DistInfoBase : public Info
256{
260{
261 public:
257 /** Local storage for the entry values, used for printing. */
262 /** Local storage for the entry values, used for printing. */
258 DistDataData data;
263 DistData data;
259};
260
261template <class Stat>
264};
265
266template <class Stat>
262class DistStatData : public DistData
267class DistInfo : public DistInfoBase
263{
264 protected:
265 Stat &s;
266
267 public:
268{
269 protected:
270 Stat &s;
271
272 public:
268 DistStatData(Stat &stat) : s(stat) {}
273 DistInfo(Stat &stat) : s(stat) {}
269
270 virtual bool check() const { return s.check(); }
271 virtual void reset() { s.reset(); }
272 virtual bool zero() const { return s.zero(); }
273
274 virtual void
275 visit(Visit &visitor)
276 {
277 s.update(this);
278 visitor.visit(*this);
279 }
280};
281
274
275 virtual bool check() const { return s.check(); }
276 virtual void reset() { s.reset(); }
277 virtual bool zero() const { return s.zero(); }
278
279 virtual void
280 visit(Visit &visitor)
281 {
282 s.update(this);
283 visitor.visit(*this);
284 }
285};
286
282struct VectorDistData : public StatData
287class VectorDistInfoBase : public Info
283{
288{
284 std::vector<DistDataData> data;
289 public:
290 std::vector<DistData> data;
285
286 /** Names and descriptions of subfields. */
287 mutable std::vector<std::string> subnames;
288 mutable std::vector<std::string> subdescs;
289
291
292 /** Names and descriptions of subfields. */
293 mutable std::vector<std::string> subnames;
294 mutable std::vector<std::string> subdescs;
295
296 protected:
290 /** Local storage for the entry values, used for printing. */
291 mutable VResult rvec;
292
297 /** Local storage for the entry values, used for printing. */
298 mutable VResult rvec;
299
300 public:
293 virtual size_type size() const = 0;
294
295 void
296 update()
297 {
298 size_type s = size();
299 if (subnames.size() < s)
300 subnames.resize(s);
301
302 if (subdescs.size() < s)
303 subdescs.resize(s);
304 }
305};
306
307template <class Stat>
301 virtual size_type size() const = 0;
302
303 void
304 update()
305 {
306 size_type s = size();
307 if (subnames.size() < s)
308 subnames.resize(s);
309
310 if (subdescs.size() < s)
311 subdescs.resize(s);
312 }
313};
314
315template <class Stat>
308class VectorDistStatData : public VectorDistData
316class VectorDistInfo : public VectorDistInfoBase
309{
310 protected:
311 Stat &s;
312
313 public:
317{
318 protected:
319 Stat &s;
320
321 public:
314 VectorDistStatData(Stat &stat) : s(stat) {}
322 VectorDistInfo(Stat &stat) : s(stat) {}
315
316 virtual bool check() const { return s.check(); }
317 virtual void reset() { s.reset(); }
318 virtual size_type size() const { return s.size(); }
319 virtual bool zero() const { return s.zero(); }
320
321 virtual void
322 visit(Visit &visitor)
323 {
324 update();
325 s.update(this);
326 visitor.visit(*this);
327 }
328};
329
323
324 virtual bool check() const { return s.check(); }
325 virtual void reset() { s.reset(); }
326 virtual size_type size() const { return s.size(); }
327 virtual bool zero() const { return s.zero(); }
328
329 virtual void
330 visit(Visit &visitor)
331 {
332 update();
333 s.update(this);
334 visitor.visit(*this);
335 }
336};
337
330struct Vector2dData : public StatData
338class Vector2dInfoBase : public Info
331{
339{
340 public:
332 /** Names and descriptions of subfields. */
333 std::vector<std::string> subnames;
334 std::vector<std::string> subdescs;
335 std::vector<std::string> y_subnames;
336
337 /** Local storage for the entry values, used for printing. */
338 mutable VCounter cvec;
339 mutable size_type x;
340 mutable size_type y;
341
341 /** Names and descriptions of subfields. */
342 std::vector<std::string> subnames;
343 std::vector<std::string> subdescs;
344 std::vector<std::string> y_subnames;
345
346 /** Local storage for the entry values, used for printing. */
347 mutable VCounter cvec;
348 mutable size_type x;
349 mutable size_type y;
350
351 public:
342 void
343 update()
344 {
345 if (subnames.size() < x)
346 subnames.resize(x);
347 }
348};
349
350template <class Stat>
352 void
353 update()
354 {
355 if (subnames.size() < x)
356 subnames.resize(x);
357 }
358};
359
360template <class Stat>
351class Vector2dStatData : public Vector2dData
361class Vector2dInfo : public Vector2dInfoBase
352{
353 protected:
354 Stat &s;
355
356 public:
362{
363 protected:
364 Stat &s;
365
366 public:
357 Vector2dStatData(Stat &stat) : s(stat) {}
367 Vector2dInfo(Stat &stat) : s(stat) {}
358
359 virtual bool check() const { return s.check(); }
360 virtual void reset() { s.reset(); }
361 virtual bool zero() const { return s.zero(); }
362
363 virtual void
364 visit(Visit &visitor)
365 {
366 update();
367 s.update(this);
368 visitor.visit(*this);
369 }
370};
371
368
369 virtual bool check() const { return s.check(); }
370 virtual void reset() { s.reset(); }
371 virtual bool zero() const { return s.zero(); }
372
373 virtual void
374 visit(Visit &visitor)
375 {
376 update();
377 s.update(this);
378 visitor.visit(*this);
379 }
380};
381
372class DataAccess
382class InfoAccess
373{
374 protected:
383{
384 protected:
375 StatData *find() const;
376 void map(StatData *data);
377
378 StatData *statData();
379 const StatData *statData() const;
380
385 Info *find() const;
386 /** Set up an info class for this statistic */
387 void setInfo(Info *info);
388 /** Save Storage class parameters if any */
381 void setInit();
389 void setInit();
382 void setPrint();
390
391 Info *info();
392 const Info *info() const;
383};
384
393};
394
385template <class Parent, class Child, template <class> class Data>
395template <class Parent, class Child, template <class> class Info>
386class Wrap : public Child
387{
396class Wrap : public Child
397{
398 public:
399 typedef Parent ParentType;
400 typedef Child ChildType;
401 typedef Info<Child> InfoType;
402
388 protected:
389 Parent &self() { return *reinterpret_cast<Parent *>(this); }
390
391 protected:
403 protected:
404 Parent &self() { return *reinterpret_cast<Parent *>(this); }
405
406 protected:
392 Data<Child> *
393 statData()
407 InfoType *
408 info()
394 {
409 {
395 StatData *__data = DataAccess::statData();
396 Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
397 assert(ptr);
398 return ptr;
410 return safe_cast<InfoType *>(InfoAccess::info());
399 }
400
401 public:
411 }
412
413 public:
402 const Data<Child> *
403 statData() const
414 const InfoType *
415 info() const
404 {
416 {
405 const StatData *__data = DataAccess::statData();
406 const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
407 assert(ptr);
408 return ptr;
417 return safe_cast<const InfoType *>(InfoAccess::info());
409 }
410
411 protected:
412 /**
413 * Copy constructor, copies are not allowed.
414 */
415 Wrap(const Wrap &stat);
416
417 /**
418 * Can't copy stats.
419 */
420 void operator=(const Wrap &);
421
422 public:
423 Wrap()
424 {
418 }
419
420 protected:
421 /**
422 * Copy constructor, copies are not allowed.
423 */
424 Wrap(const Wrap &stat);
425
426 /**
427 * Can't copy stats.
428 */
429 void operator=(const Wrap &);
430
431 public:
432 Wrap()
433 {
425 this->map(new Data<Child>(*this));
434 this->setInfo(new InfoType(*this));
426 }
427
428 /**
429 * Set the name and marks this stat to print at the end of simulation.
430 * @param name The new name.
431 * @return A reference to this stat.
432 */
433 Parent &
434 name(const std::string &_name)
435 {
435 }
436
437 /**
438 * Set the name and marks this stat to print at the end of simulation.
439 * @param name The new name.
440 * @return A reference to this stat.
441 */
442 Parent &
443 name(const std::string &_name)
444 {
436 Data<Child> *data = this->statData();
437 data->name = _name;
438 this->setPrint();
445 InfoType *info = this->info();
446 info->name = _name;
447 info->flags |= print;
439 return this->self();
440 }
441
442 /**
443 * Set the description and marks this stat to print at the end of
444 * simulation.
445 * @param desc The new description.
446 * @return A reference to this stat.
447 */
448 Parent &
449 desc(const std::string &_desc)
450 {
448 return this->self();
449 }
450
451 /**
452 * Set the description and marks this stat to print at the end of
453 * simulation.
454 * @param desc The new description.
455 * @return A reference to this stat.
456 */
457 Parent &
458 desc(const std::string &_desc)
459 {
451 this->statData()->desc = _desc;
460 this->info()->desc = _desc;
452 return this->self();
453 }
454
455 /**
456 * Set the precision and marks this stat to print at the end of simulation.
457 * @param p The new precision
458 * @return A reference to this stat.
459 */
460 Parent &
461 precision(int _precision)
462 {
461 return this->self();
462 }
463
464 /**
465 * Set the precision and marks this stat to print at the end of simulation.
466 * @param p The new precision
467 * @return A reference to this stat.
468 */
469 Parent &
470 precision(int _precision)
471 {
463 this->statData()->precision = _precision;
472 this->info()->precision = _precision;
464 return this->self();
465 }
466
467 /**
468 * Set the flags and marks this stat to print at the end of simulation.
469 * @param f The new flags.
470 * @return A reference to this stat.
471 */
472 Parent &
473 flags(StatFlags _flags)
474 {
473 return this->self();
474 }
475
476 /**
477 * Set the flags and marks this stat to print at the end of simulation.
478 * @param f The new flags.
479 * @return A reference to this stat.
480 */
481 Parent &
482 flags(StatFlags _flags)
483 {
475 this->statData()->flags |= _flags;
484 this->info()->flags |= _flags;
476 return this->self();
477 }
478
479 /**
480 * Set the prerequisite stat and marks this stat to print at the end of
481 * simulation.
482 * @param prereq The prerequisite stat.
483 * @return A reference to this stat.
484 */
485 template <class Stat>
486 Parent &
487 prereq(const Stat &prereq)
488 {
485 return this->self();
486 }
487
488 /**
489 * Set the prerequisite stat and marks this stat to print at the end of
490 * simulation.
491 * @param prereq The prerequisite stat.
492 * @return A reference to this stat.
493 */
494 template <class Stat>
495 Parent &
496 prereq(const Stat &prereq)
497 {
489 this->statData()->prereq = prereq.statData();
498 this->info()->prereq = prereq.info();
490 return this->self();
491 }
492};
493
499 return this->self();
500 }
501};
502
494template <class Parent, class Child, template <class Child> class Data>
495class WrapVec : public Wrap<Parent, Child, Data>
503template <class Parent, class Child, template <class Child> class Info>
504class WrapVec : public Wrap<Parent, Child, Info>
496{
497 public:
505{
506 public:
507 typedef Parent ParentType;
508 typedef Child ChildType;
509 typedef Info<Child> InfoType;
510
511 public:
498 // The following functions are specific to vectors. If you use them
499 // in a non vector context, you will get a nice compiler error!
500
501 /**
502 * Set the subfield name for the given index, and marks this stat to print
503 * at the end of simulation.
504 * @param index The subfield index.
505 * @param name The new name of the subfield.
506 * @return A reference to this stat.
507 */
508 Parent &
509 subname(off_type index, const std::string &name)
510 {
512 // The following functions are specific to vectors. If you use them
513 // in a non vector context, you will get a nice compiler error!
514
515 /**
516 * Set the subfield name for the given index, and marks this stat to print
517 * at the end of simulation.
518 * @param index The subfield index.
519 * @param name The new name of the subfield.
520 * @return A reference to this stat.
521 */
522 Parent &
523 subname(off_type index, const std::string &name)
524 {
511 std::vector<std::string> &subn = this->statData()->subnames;
525 std::vector<std::string> &subn = this->info()->subnames;
512 if (subn.size() <= index)
513 subn.resize(index + 1);
514 subn[index] = name;
515 return this->self();
516 }
517
518 /**
519 * Set the subfield description for the given index and marks this stat to
520 * print at the end of simulation.
521 * @param index The subfield index.
522 * @param desc The new description of the subfield
523 * @return A reference to this stat.
524 */
525 Parent &
526 subdesc(off_type index, const std::string &desc)
527 {
526 if (subn.size() <= index)
527 subn.resize(index + 1);
528 subn[index] = name;
529 return this->self();
530 }
531
532 /**
533 * Set the subfield description for the given index and marks this stat to
534 * print at the end of simulation.
535 * @param index The subfield index.
536 * @param desc The new description of the subfield
537 * @return A reference to this stat.
538 */
539 Parent &
540 subdesc(off_type index, const std::string &desc)
541 {
528 std::vector<std::string> &subd = this->statData()->subdescs;
542 std::vector<std::string> &subd = this->info()->subdescs;
529 if (subd.size() <= index)
530 subd.resize(index + 1);
531 subd[index] = desc;
532
533 return this->self();
534 }
535
536};
537
543 if (subd.size() <= index)
544 subd.resize(index + 1);
545 subd[index] = desc;
546
547 return this->self();
548 }
549
550};
551
538template <class Parent, class Child, template <class Child> class Data>
539class WrapVec2d : public WrapVec<Parent, Child, Data>
552template <class Parent, class Child, template <class Child> class Info>
553class WrapVec2d : public WrapVec<Parent, Child, Info>
540{
541 public:
554{
555 public:
556 typedef Parent ParentType;
557 typedef Child ChildType;
558 typedef Info<Child> InfoType;
559
560 public:
542 /**
543 * @warning This makes the assumption that if you're gonna subnames a 2d
544 * vector, you're subnaming across all y
545 */
546 Parent &
547 ysubnames(const char **names)
548 {
561 /**
562 * @warning This makes the assumption that if you're gonna subnames a 2d
563 * vector, you're subnaming across all y
564 */
565 Parent &
566 ysubnames(const char **names)
567 {
549 Data<Child> *data = this->statData();
550 data->y_subnames.resize(this->y);
568 InfoType *info = this->info();
569 info->y_subnames.resize(this->y);
551 for (off_type i = 0; i < this->y; ++i)
570 for (off_type i = 0; i < this->y; ++i)
552 data->y_subnames[i] = names[i];
571 info->y_subnames[i] = names[i];
553 return this->self();
554 }
555
556 Parent &
557 ysubname(off_type index, const std::string subname)
558 {
572 return this->self();
573 }
574
575 Parent &
576 ysubname(off_type index, const std::string subname)
577 {
559 Data<Child> *data = this->statData();
578 InfoType *info = this->info();
560 assert(index < this->y);
579 assert(index < this->y);
561 data->y_subnames.resize(this->y);
562 data->y_subnames[index] = subname.c_str();
580 info->y_subnames.resize(this->y);
581 info->y_subnames[index] = subname.c_str();
563 return this->self();
564 }
565};
566
567//////////////////////////////////////////////////////////////////////
568//
569// Simple Statistics
570//
571//////////////////////////////////////////////////////////////////////
572
573/**
574 * Templatized storage and interface for a simple scalar stat.
575 */
582 return this->self();
583 }
584};
585
586//////////////////////////////////////////////////////////////////////
587//
588// Simple Statistics
589//
590//////////////////////////////////////////////////////////////////////
591
592/**
593 * Templatized storage and interface for a simple scalar stat.
594 */
576struct StatStor
595class StatStor
577{
578 public:
579 /** The paramaters for this storage type, none for a scalar. */
580 struct Params { };
581
582 private:
583 /** The statistic value. */
584 Counter data;
585
586 public:
587 /**
588 * Builds this storage element and calls the base constructor of the
589 * datatype.
590 */
591 StatStor(const Params &) : data(Counter()) {}
592
593 /**
594 * The the stat to the given value.
595 * @param val The new value.
596 * @param p The paramters of this storage type.
597 */
598 void set(Counter val, const Params &p) { data = val; }
599 /**
600 * Increment the stat by the given value.
601 * @param val The new value.
602 * @param p The paramters of this storage type.
603 */
604 void inc(Counter val, const Params &p) { data += val; }
605 /**
606 * Decrement the stat by the given value.
607 * @param val The new value.
608 * @param p The paramters of this storage type.
609 */
610 void dec(Counter val, const Params &p) { data -= val; }
611 /**
612 * Return the value of this stat as its base type.
613 * @param p The params of this storage type.
614 * @return The value of this stat.
615 */
616 Counter value(const Params &p) const { return data; }
617 /**
618 * Return the value of this stat as a result type.
619 * @param p The parameters of this storage type.
620 * @return The value of this stat.
621 */
622 Result result(const Params &p) const { return (Result)data; }
623 /**
624 * Reset stat value to default
625 */
626 void reset() { data = Counter(); }
627
628 /**
629 * @return true if zero value
630 */
631 bool zero() const { return data == Counter(); }
632};
633
634/**
635 * Templatized storage and interface to a per-tick average stat. This keeps
636 * a current count and updates a total (count * ticks) when this count
637 * changes. This allows the quick calculation of a per tick count of the item
638 * being watched. This is good for keeping track of residencies in structures
639 * among other things.
640 */
596{
597 public:
598 /** The paramaters for this storage type, none for a scalar. */
599 struct Params { };
600
601 private:
602 /** The statistic value. */
603 Counter data;
604
605 public:
606 /**
607 * Builds this storage element and calls the base constructor of the
608 * datatype.
609 */
610 StatStor(const Params &) : data(Counter()) {}
611
612 /**
613 * The the stat to the given value.
614 * @param val The new value.
615 * @param p The paramters of this storage type.
616 */
617 void set(Counter val, const Params &p) { data = val; }
618 /**
619 * Increment the stat by the given value.
620 * @param val The new value.
621 * @param p The paramters of this storage type.
622 */
623 void inc(Counter val, const Params &p) { data += val; }
624 /**
625 * Decrement the stat by the given value.
626 * @param val The new value.
627 * @param p The paramters of this storage type.
628 */
629 void dec(Counter val, const Params &p) { data -= val; }
630 /**
631 * Return the value of this stat as its base type.
632 * @param p The params of this storage type.
633 * @return The value of this stat.
634 */
635 Counter value(const Params &p) const { return data; }
636 /**
637 * Return the value of this stat as a result type.
638 * @param p The parameters of this storage type.
639 * @return The value of this stat.
640 */
641 Result result(const Params &p) const { return (Result)data; }
642 /**
643 * Reset stat value to default
644 */
645 void reset() { data = Counter(); }
646
647 /**
648 * @return true if zero value
649 */
650 bool zero() const { return data == Counter(); }
651};
652
653/**
654 * Templatized storage and interface to a per-tick average stat. This keeps
655 * a current count and updates a total (count * ticks) when this count
656 * changes. This allows the quick calculation of a per tick count of the item
657 * being watched. This is good for keeping track of residencies in structures
658 * among other things.
659 */
641struct AvgStor
660class AvgStor
642{
643 public:
644 /** The paramaters for this storage type */
645 struct Params { };
646
647 private:
648 /** The current count. */
649 Counter current;
650 /** The total count for all tick. */
651 mutable Result total;
652 /** The tick that current last changed. */
653 mutable Tick last;
654
655 public:
656 /**
657 * Build and initializes this stat storage.
658 */
659 AvgStor(Params &p) : current(0), total(0), last(0) { }
660
661 /**
662 * Set the current count to the one provided, update the total and last
663 * set values.
664 * @param val The new count.
665 * @param p The parameters for this storage.
666 */
667 void
661{
662 public:
663 /** The paramaters for this storage type */
664 struct Params { };
665
666 private:
667 /** The current count. */
668 Counter current;
669 /** The total count for all tick. */
670 mutable Result total;
671 /** The tick that current last changed. */
672 mutable Tick last;
673
674 public:
675 /**
676 * Build and initializes this stat storage.
677 */
678 AvgStor(Params &p) : current(0), total(0), last(0) { }
679
680 /**
681 * Set the current count to the one provided, update the total and last
682 * set values.
683 * @param val The new count.
684 * @param p The parameters for this storage.
685 */
686 void
668 set(Counter val, Params &p) {
687 set(Counter val, Params &p)
688 {
669 total += current * (curTick - last);
670 last = curTick;
671 current = val;
672 }
673
674 /**
675 * Increment the current count by the provided value, calls set.
676 * @param val The amount to increment.
677 * @param p The parameters for this storage.
678 */
679 void inc(Counter val, Params &p) { set(current + val, p); }
680
681 /**
682 * Deccrement the current count by the provided value, calls set.
683 * @param val The amount to decrement.
684 * @param p The parameters for this storage.
685 */
686 void dec(Counter val, Params &p) { set(current - val, p); }
687
688 /**
689 * Return the current count.
690 * @param p The parameters for this storage.
691 * @return The current count.
692 */
693 Counter value(const Params &p) const { return current; }
694
695 /**
696 * Return the current average.
697 * @param p The parameters for this storage.
698 * @return The current average.
699 */
700 Result
701 result(const Params &p) const
702 {
703 total += current * (curTick - last);
704 last = curTick;
705 return (Result)(total + current) / (Result)(curTick + 1);
706 }
707
708 /**
709 * Reset stat value to default
710 */
711 void
712 reset()
713 {
714 total = 0;
715 last = curTick;
716 }
717
718 /**
719 * @return true if zero value
720 */
721 bool zero() const { return total == 0.0; }
722};
723
724/**
725 * Implementation of a scalar stat. The type of stat is determined by the
726 * Storage template.
727 */
728template <class Stor>
689 total += current * (curTick - last);
690 last = curTick;
691 current = val;
692 }
693
694 /**
695 * Increment the current count by the provided value, calls set.
696 * @param val The amount to increment.
697 * @param p The parameters for this storage.
698 */
699 void inc(Counter val, Params &p) { set(current + val, p); }
700
701 /**
702 * Deccrement the current count by the provided value, calls set.
703 * @param val The amount to decrement.
704 * @param p The parameters for this storage.
705 */
706 void dec(Counter val, Params &p) { set(current - val, p); }
707
708 /**
709 * Return the current count.
710 * @param p The parameters for this storage.
711 * @return The current count.
712 */
713 Counter value(const Params &p) const { return current; }
714
715 /**
716 * Return the current average.
717 * @param p The parameters for this storage.
718 * @return The current average.
719 */
720 Result
721 result(const Params &p) const
722 {
723 total += current * (curTick - last);
724 last = curTick;
725 return (Result)(total + current) / (Result)(curTick + 1);
726 }
727
728 /**
729 * Reset stat value to default
730 */
731 void
732 reset()
733 {
734 total = 0;
735 last = curTick;
736 }
737
738 /**
739 * @return true if zero value
740 */
741 bool zero() const { return total == 0.0; }
742};
743
744/**
745 * Implementation of a scalar stat. The type of stat is determined by the
746 * Storage template.
747 */
748template <class Stor>
729class ScalarBase : public DataAccess
749class ScalarBase : public InfoAccess
730{
731 public:
732 typedef Stor Storage;
733
734 /** Define the params of the storage class. */
735 typedef typename Storage::Params Params;
736
737 protected:
738 /** The storage of this stat. */
739 char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
740
741 /** The parameters for this stat. */
742 Params params;
743
744 protected:
745 /**
746 * Retrieve the storage.
747 * @param index The vector index to access.
748 * @return The storage object at the given index.
749 */
750 Storage *
751 data()
752 {
753 return reinterpret_cast<Storage *>(storage);
754 }
755
756 /**
757 * Retrieve a const pointer to the storage.
758 * for the given index.
759 * @param index The vector index to access.
760 * @return A const pointer to the storage object at the given index.
761 */
762 const Storage *
763 data() const
764 {
765 return reinterpret_cast<const Storage *>(storage);
766 }
767
768 void
769 doInit()
770 {
771 new (storage) Storage(params);
772 setInit();
773 }
774
775 public:
776 /**
777 * Return the current value of this stat as its base type.
778 * @return The current value.
779 */
780 Counter value() const { return data()->value(params); }
781
782 public:
783 /**
784 * Create and initialize this stat, register it with the database.
785 */
786 ScalarBase()
787 { }
788
789 public:
790 // Common operators for stats
791 /**
792 * Increment the stat by 1. This calls the associated storage object inc
793 * function.
794 */
795 void operator++() { data()->inc(1, params); }
796 /**
797 * Decrement the stat by 1. This calls the associated storage object dec
798 * function.
799 */
800 void operator--() { data()->dec(1, params); }
801
802 /** Increment the stat by 1. */
803 void operator++(int) { ++*this; }
804 /** Decrement the stat by 1. */
805 void operator--(int) { --*this; }
806
807 /**
808 * Set the data value to the given value. This calls the associated storage
809 * object set function.
810 * @param v The new value.
811 */
812 template <typename U>
813 void operator=(const U &v) { data()->set(v, params); }
814
815 /**
816 * Increment the stat by the given value. This calls the associated
817 * storage object inc function.
818 * @param v The value to add.
819 */
820 template <typename U>
821 void operator+=(const U &v) { data()->inc(v, params); }
822
823 /**
824 * Decrement the stat by the given value. This calls the associated
825 * storage object dec function.
826 * @param v The value to substract.
827 */
828 template <typename U>
829 void operator-=(const U &v) { data()->dec(v, params); }
830
831 /**
832 * Return the number of elements, always 1 for a scalar.
833 * @return 1.
834 */
835 size_type size() const { return 1; }
836
837 bool check() const { return true; }
838
839 /**
840 * Reset stat value to default
841 */
842 void reset() { data()->reset(); }
843
844 Counter value() { return data()->value(params); }
845
846 Result result() { return data()->result(params); }
847
848 Result total() { return result(); }
849
850 bool zero() { return result() == 0.0; }
851
852};
853
750{
751 public:
752 typedef Stor Storage;
753
754 /** Define the params of the storage class. */
755 typedef typename Storage::Params Params;
756
757 protected:
758 /** The storage of this stat. */
759 char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
760
761 /** The parameters for this stat. */
762 Params params;
763
764 protected:
765 /**
766 * Retrieve the storage.
767 * @param index The vector index to access.
768 * @return The storage object at the given index.
769 */
770 Storage *
771 data()
772 {
773 return reinterpret_cast<Storage *>(storage);
774 }
775
776 /**
777 * Retrieve a const pointer to the storage.
778 * for the given index.
779 * @param index The vector index to access.
780 * @return A const pointer to the storage object at the given index.
781 */
782 const Storage *
783 data() const
784 {
785 return reinterpret_cast<const Storage *>(storage);
786 }
787
788 void
789 doInit()
790 {
791 new (storage) Storage(params);
792 setInit();
793 }
794
795 public:
796 /**
797 * Return the current value of this stat as its base type.
798 * @return The current value.
799 */
800 Counter value() const { return data()->value(params); }
801
802 public:
803 /**
804 * Create and initialize this stat, register it with the database.
805 */
806 ScalarBase()
807 { }
808
809 public:
810 // Common operators for stats
811 /**
812 * Increment the stat by 1. This calls the associated storage object inc
813 * function.
814 */
815 void operator++() { data()->inc(1, params); }
816 /**
817 * Decrement the stat by 1. This calls the associated storage object dec
818 * function.
819 */
820 void operator--() { data()->dec(1, params); }
821
822 /** Increment the stat by 1. */
823 void operator++(int) { ++*this; }
824 /** Decrement the stat by 1. */
825 void operator--(int) { --*this; }
826
827 /**
828 * Set the data value to the given value. This calls the associated storage
829 * object set function.
830 * @param v The new value.
831 */
832 template <typename U>
833 void operator=(const U &v) { data()->set(v, params); }
834
835 /**
836 * Increment the stat by the given value. This calls the associated
837 * storage object inc function.
838 * @param v The value to add.
839 */
840 template <typename U>
841 void operator+=(const U &v) { data()->inc(v, params); }
842
843 /**
844 * Decrement the stat by the given value. This calls the associated
845 * storage object dec function.
846 * @param v The value to substract.
847 */
848 template <typename U>
849 void operator-=(const U &v) { data()->dec(v, params); }
850
851 /**
852 * Return the number of elements, always 1 for a scalar.
853 * @return 1.
854 */
855 size_type size() const { return 1; }
856
857 bool check() const { return true; }
858
859 /**
860 * Reset stat value to default
861 */
862 void reset() { data()->reset(); }
863
864 Counter value() { return data()->value(params); }
865
866 Result result() { return data()->result(params); }
867
868 Result total() { return result(); }
869
870 bool zero() { return result() == 0.0; }
871
872};
873
854class ProxyData : public ScalarData
874class ProxyInfo : public ScalarInfoBase
855{
856 public:
857 virtual void visit(Visit &visitor) { visitor.visit(*this); }
858 virtual std::string str() const { return to_string(value()); }
859 virtual size_type size() const { return 1; }
860 virtual bool zero() const { return value() == 0; }
861 virtual bool check() const { return true; }
862 virtual void reset() { }
863};
864
865template <class T>
875{
876 public:
877 virtual void visit(Visit &visitor) { visitor.visit(*this); }
878 virtual std::string str() const { return to_string(value()); }
879 virtual size_type size() const { return 1; }
880 virtual bool zero() const { return value() == 0; }
881 virtual bool check() const { return true; }
882 virtual void reset() { }
883};
884
885template <class T>
866class ValueProxy : public ProxyData
886class ValueProxy : public ProxyInfo
867{
868 private:
869 T *scalar;
870
871 public:
872 ValueProxy(T &val) : scalar(&val) {}
873 virtual Counter value() const { return *scalar; }
874 virtual Result result() const { return *scalar; }
875 virtual Result total() const { return *scalar; }
876};
877
878template <class T>
887{
888 private:
889 T *scalar;
890
891 public:
892 ValueProxy(T &val) : scalar(&val) {}
893 virtual Counter value() const { return *scalar; }
894 virtual Result result() const { return *scalar; }
895 virtual Result total() const { return *scalar; }
896};
897
898template <class T>
879class FunctorProxy : public ProxyData
899class FunctorProxy : public ProxyInfo
880{
881 private:
882 T *functor;
883
884 public:
885 FunctorProxy(T &func) : functor(&func) {}
886 virtual Counter value() const { return (*functor)(); }
887 virtual Result result() const { return (*functor)(); }
888 virtual Result total() const { return (*functor)(); }
889};
890
900{
901 private:
902 T *functor;
903
904 public:
905 FunctorProxy(T &func) : functor(&func) {}
906 virtual Counter value() const { return (*functor)(); }
907 virtual Result result() const { return (*functor)(); }
908 virtual Result total() const { return (*functor)(); }
909};
910
891class ValueBase : public DataAccess
911class ValueBase : public InfoAccess
892{
893 private:
912{
913 private:
894 ProxyData *proxy;
914 ProxyInfo *proxy;
895
896 public:
897 ValueBase() : proxy(NULL) { }
898 ~ValueBase() { if (proxy) delete proxy; }
899
900 template <class T>
901 void
902 scalar(T &value)
903 {
904 proxy = new ValueProxy<T>(value);
905 setInit();
906 }
907
908 template <class T>
909 void
910 functor(T &func)
911 {
912 proxy = new FunctorProxy<T>(func);
913 setInit();
914 }
915
916 Counter value() { return proxy->value(); }
917 Result result() const { return proxy->result(); }
918 Result total() const { return proxy->total(); };
919 size_type size() const { return proxy->size(); }
920
921 std::string str() const { return proxy->str(); }
922 bool zero() const { return proxy->zero(); }
923 bool check() const { return proxy != NULL; }
924 void reset() { }
925};
926
927//////////////////////////////////////////////////////////////////////
928//
929// Vector Statistics
930//
931//////////////////////////////////////////////////////////////////////
932
933/**
934 * A proxy class to access the stat at a given index in a VectorBase stat.
935 * Behaves like a ScalarBase.
936 */
937template <class Stat>
938class ScalarProxy
939{
940 private:
941 /** Pointer to the parent Vector. */
942 Stat *stat;
943
944 /** The index to access in the parent VectorBase. */
945 off_type index;
946
947 public:
948 /**
949 * Return the current value of this stat as its base type.
950 * @return The current value.
951 */
952 Counter value() const { return stat->data(index)->value(stat->params); }
953
954 /**
955 * Return the current value of this statas a result type.
956 * @return The current value.
957 */
958 Result result() const { return stat->data(index)->result(stat->params); }
959
960 public:
961 /**
962 * Create and initialize this proxy, do not register it with the database.
963 * @param p The params to use.
964 * @param i The index to access.
965 */
966 ScalarProxy(Stat *s, off_type i)
967 : stat(s), index(i)
968 {
969 assert(stat);
970 }
971
972 /**
973 * Create a copy of the provided ScalarProxy.
974 * @param sp The proxy to copy.
975 */
976 ScalarProxy(const ScalarProxy &sp)
977 : stat(sp.stat), index(sp.index)
978 {}
979
980 /**
981 * Set this proxy equal to the provided one.
982 * @param sp The proxy to copy.
983 * @return A reference to this proxy.
984 */
985 const ScalarProxy &
915
916 public:
917 ValueBase() : proxy(NULL) { }
918 ~ValueBase() { if (proxy) delete proxy; }
919
920 template <class T>
921 void
922 scalar(T &value)
923 {
924 proxy = new ValueProxy<T>(value);
925 setInit();
926 }
927
928 template <class T>
929 void
930 functor(T &func)
931 {
932 proxy = new FunctorProxy<T>(func);
933 setInit();
934 }
935
936 Counter value() { return proxy->value(); }
937 Result result() const { return proxy->result(); }
938 Result total() const { return proxy->total(); };
939 size_type size() const { return proxy->size(); }
940
941 std::string str() const { return proxy->str(); }
942 bool zero() const { return proxy->zero(); }
943 bool check() const { return proxy != NULL; }
944 void reset() { }
945};
946
947//////////////////////////////////////////////////////////////////////
948//
949// Vector Statistics
950//
951//////////////////////////////////////////////////////////////////////
952
953/**
954 * A proxy class to access the stat at a given index in a VectorBase stat.
955 * Behaves like a ScalarBase.
956 */
957template <class Stat>
958class ScalarProxy
959{
960 private:
961 /** Pointer to the parent Vector. */
962 Stat *stat;
963
964 /** The index to access in the parent VectorBase. */
965 off_type index;
966
967 public:
968 /**
969 * Return the current value of this stat as its base type.
970 * @return The current value.
971 */
972 Counter value() const { return stat->data(index)->value(stat->params); }
973
974 /**
975 * Return the current value of this statas a result type.
976 * @return The current value.
977 */
978 Result result() const { return stat->data(index)->result(stat->params); }
979
980 public:
981 /**
982 * Create and initialize this proxy, do not register it with the database.
983 * @param p The params to use.
984 * @param i The index to access.
985 */
986 ScalarProxy(Stat *s, off_type i)
987 : stat(s), index(i)
988 {
989 assert(stat);
990 }
991
992 /**
993 * Create a copy of the provided ScalarProxy.
994 * @param sp The proxy to copy.
995 */
996 ScalarProxy(const ScalarProxy &sp)
997 : stat(sp.stat), index(sp.index)
998 {}
999
1000 /**
1001 * Set this proxy equal to the provided one.
1002 * @param sp The proxy to copy.
1003 * @return A reference to this proxy.
1004 */
1005 const ScalarProxy &
986 operator=(const ScalarProxy &sp) {
1006 operator=(const ScalarProxy &sp)
1007 {
987 stat = sp.stat;
988 index = sp.index;
989 return *this;
990 }
991
992 public:
993 // Common operators for stats
994 /**
995 * Increment the stat by 1. This calls the associated storage object inc
996 * function.
997 */
998 void operator++() { stat->data(index)->inc(1, stat->params); }
999 /**
1000 * Decrement the stat by 1. This calls the associated storage object dec
1001 * function.
1002 */
1003 void operator--() { stat->data(index)->dec(1, stat->params); }
1004
1005 /** Increment the stat by 1. */
1006 void operator++(int) { ++*this; }
1007 /** Decrement the stat by 1. */
1008 void operator--(int) { --*this; }
1009
1010 /**
1011 * Set the data value to the given value. This calls the associated storage
1012 * object set function.
1013 * @param v The new value.
1014 */
1015 template <typename U>
1016 void
1017 operator=(const U &v)
1018 {
1019 stat->data(index)->set(v, stat->params);
1020 }
1021
1022 /**
1023 * Increment the stat by the given value. This calls the associated
1024 * storage object inc function.
1025 * @param v The value to add.
1026 */
1027 template <typename U>
1028 void
1029 operator+=(const U &v)
1030 {
1031 stat->data(index)->inc(v, stat->params);
1032 }
1033
1034 /**
1035 * Decrement the stat by the given value. This calls the associated
1036 * storage object dec function.
1037 * @param v The value to substract.
1038 */
1039 template <typename U>
1040 void
1041 operator-=(const U &v)
1042 {
1043 stat->data(index)->dec(v, stat->params);
1044 }
1045
1046 /**
1047 * Return the number of elements, always 1 for a scalar.
1048 * @return 1.
1049 */
1050 size_type size() const { return 1; }
1051
1052 /**
1053 * This stat has no state. Nothing to reset
1054 */
1055 void reset() { }
1056
1057 public:
1058 std::string
1059 str() const
1060 {
1008 stat = sp.stat;
1009 index = sp.index;
1010 return *this;
1011 }
1012
1013 public:
1014 // Common operators for stats
1015 /**
1016 * Increment the stat by 1. This calls the associated storage object inc
1017 * function.
1018 */
1019 void operator++() { stat->data(index)->inc(1, stat->params); }
1020 /**
1021 * Decrement the stat by 1. This calls the associated storage object dec
1022 * function.
1023 */
1024 void operator--() { stat->data(index)->dec(1, stat->params); }
1025
1026 /** Increment the stat by 1. */
1027 void operator++(int) { ++*this; }
1028 /** Decrement the stat by 1. */
1029 void operator--(int) { --*this; }
1030
1031 /**
1032 * Set the data value to the given value. This calls the associated storage
1033 * object set function.
1034 * @param v The new value.
1035 */
1036 template <typename U>
1037 void
1038 operator=(const U &v)
1039 {
1040 stat->data(index)->set(v, stat->params);
1041 }
1042
1043 /**
1044 * Increment the stat by the given value. This calls the associated
1045 * storage object inc function.
1046 * @param v The value to add.
1047 */
1048 template <typename U>
1049 void
1050 operator+=(const U &v)
1051 {
1052 stat->data(index)->inc(v, stat->params);
1053 }
1054
1055 /**
1056 * Decrement the stat by the given value. This calls the associated
1057 * storage object dec function.
1058 * @param v The value to substract.
1059 */
1060 template <typename U>
1061 void
1062 operator-=(const U &v)
1063 {
1064 stat->data(index)->dec(v, stat->params);
1065 }
1066
1067 /**
1068 * Return the number of elements, always 1 for a scalar.
1069 * @return 1.
1070 */
1071 size_type size() const { return 1; }
1072
1073 /**
1074 * This stat has no state. Nothing to reset
1075 */
1076 void reset() { }
1077
1078 public:
1079 std::string
1080 str() const
1081 {
1061 return csprintf("%s[%d]", stat->statData()->name, index);
1082 return csprintf("%s[%d]", stat->info()->name, index);
1062 }
1063};
1064
1065/**
1066 * Implementation of a vector of stats. The type of stat is determined by the
1067 * Storage class. @sa ScalarBase
1068 */
1069template <class Stor>
1083 }
1084};
1085
1086/**
1087 * Implementation of a vector of stats. The type of stat is determined by the
1088 * Storage class. @sa ScalarBase
1089 */
1090template <class Stor>
1070class VectorBase : public DataAccess
1091class VectorBase : public InfoAccess
1071{
1072 public:
1073 typedef Stor Storage;
1074
1075 /** Define the params of the storage class. */
1076 typedef typename Storage::Params Params;
1077
1078 /** Proxy type */
1079 typedef ScalarProxy<VectorBase<Storage> > Proxy;
1080
1081 friend class ScalarProxy<VectorBase<Storage> >;
1082
1083 protected:
1084 /** The storage of this stat. */
1085 Storage *storage;
1086 size_type _size;
1087
1088 /** The parameters for this stat. */
1089 Params params;
1090
1091 protected:
1092 /**
1093 * Retrieve the storage.
1094 * @param index The vector index to access.
1095 * @return The storage object at the given index.
1096 */
1097 Storage *data(off_type index) { return &storage[index]; }
1098
1099 /**
1100 * Retrieve a const pointer to the storage.
1101 * @param index The vector index to access.
1102 * @return A const pointer to the storage object at the given index.
1103 */
1104 const Storage *data(off_type index) const { return &storage[index]; }
1105
1106 void
1107 doInit(size_type s)
1108 {
1109 assert(s > 0 && "size must be positive!");
1110 assert(!storage && "already initialized");
1111 _size = s;
1112
1113 char *ptr = new char[_size * sizeof(Storage)];
1114 storage = reinterpret_cast<Storage *>(ptr);
1115
1116 for (off_type i = 0; i < _size; ++i)
1117 new (&storage[i]) Storage(params);
1118
1119 setInit();
1120 }
1121
1122 public:
1123 void
1124 value(VCounter &vec) const
1125 {
1126 vec.resize(size());
1127 for (off_type i = 0; i < size(); ++i)
1128 vec[i] = data(i)->value(params);
1129 }
1130
1131 /**
1132 * Copy the values to a local vector and return a reference to it.
1133 * @return A reference to a vector of the stat values.
1134 */
1135 void
1136 result(VResult &vec) const
1137 {
1138 vec.resize(size());
1139 for (off_type i = 0; i < size(); ++i)
1140 vec[i] = data(i)->result(params);
1141 }
1142
1143 /**
1144 * Return a total of all entries in this vector.
1145 * @return The total of all vector entries.
1146 */
1147 Result
1148 total() const
1149 {
1150 Result total = 0.0;
1151 for (off_type i = 0; i < size(); ++i)
1152 total += data(i)->result(params);
1153 return total;
1154 }
1155
1156 /**
1157 * @return the number of elements in this vector.
1158 */
1159 size_type size() const { return _size; }
1160
1161 bool
1162 zero() const
1163 {
1164 for (off_type i = 0; i < size(); ++i)
1165 if (data(i)->zero())
1166 return false;
1167 return true;
1168 }
1169
1170 bool
1171 check() const
1172 {
1173 return storage != NULL;
1174 }
1175
1176 void
1177 reset()
1178 {
1179 for (off_type i = 0; i < size(); ++i)
1180 data(i)->reset();
1181 }
1182
1183 public:
1184 VectorBase()
1185 : storage(NULL)
1186 {}
1187
1188 ~VectorBase()
1189 {
1190 if (!storage)
1191 return;
1192
1193 for (off_type i = 0; i < _size; ++i)
1194 data(i)->~Storage();
1195 delete [] reinterpret_cast<char *>(storage);
1196 }
1197
1198 /**
1199 * Return a reference (ScalarProxy) to the stat at the given index.
1200 * @param index The vector index to access.
1201 * @return A reference of the stat.
1202 */
1203 Proxy
1204 operator[](off_type index)
1205 {
1206 assert (index >= 0 && index < size());
1207 return Proxy(this, index);
1208 }
1209
1092{
1093 public:
1094 typedef Stor Storage;
1095
1096 /** Define the params of the storage class. */
1097 typedef typename Storage::Params Params;
1098
1099 /** Proxy type */
1100 typedef ScalarProxy<VectorBase<Storage> > Proxy;
1101
1102 friend class ScalarProxy<VectorBase<Storage> >;
1103
1104 protected:
1105 /** The storage of this stat. */
1106 Storage *storage;
1107 size_type _size;
1108
1109 /** The parameters for this stat. */
1110 Params params;
1111
1112 protected:
1113 /**
1114 * Retrieve the storage.
1115 * @param index The vector index to access.
1116 * @return The storage object at the given index.
1117 */
1118 Storage *data(off_type index) { return &storage[index]; }
1119
1120 /**
1121 * Retrieve a const pointer to the storage.
1122 * @param index The vector index to access.
1123 * @return A const pointer to the storage object at the given index.
1124 */
1125 const Storage *data(off_type index) const { return &storage[index]; }
1126
1127 void
1128 doInit(size_type s)
1129 {
1130 assert(s > 0 && "size must be positive!");
1131 assert(!storage && "already initialized");
1132 _size = s;
1133
1134 char *ptr = new char[_size * sizeof(Storage)];
1135 storage = reinterpret_cast<Storage *>(ptr);
1136
1137 for (off_type i = 0; i < _size; ++i)
1138 new (&storage[i]) Storage(params);
1139
1140 setInit();
1141 }
1142
1143 public:
1144 void
1145 value(VCounter &vec) const
1146 {
1147 vec.resize(size());
1148 for (off_type i = 0; i < size(); ++i)
1149 vec[i] = data(i)->value(params);
1150 }
1151
1152 /**
1153 * Copy the values to a local vector and return a reference to it.
1154 * @return A reference to a vector of the stat values.
1155 */
1156 void
1157 result(VResult &vec) const
1158 {
1159 vec.resize(size());
1160 for (off_type i = 0; i < size(); ++i)
1161 vec[i] = data(i)->result(params);
1162 }
1163
1164 /**
1165 * Return a total of all entries in this vector.
1166 * @return The total of all vector entries.
1167 */
1168 Result
1169 total() const
1170 {
1171 Result total = 0.0;
1172 for (off_type i = 0; i < size(); ++i)
1173 total += data(i)->result(params);
1174 return total;
1175 }
1176
1177 /**
1178 * @return the number of elements in this vector.
1179 */
1180 size_type size() const { return _size; }
1181
1182 bool
1183 zero() const
1184 {
1185 for (off_type i = 0; i < size(); ++i)
1186 if (data(i)->zero())
1187 return false;
1188 return true;
1189 }
1190
1191 bool
1192 check() const
1193 {
1194 return storage != NULL;
1195 }
1196
1197 void
1198 reset()
1199 {
1200 for (off_type i = 0; i < size(); ++i)
1201 data(i)->reset();
1202 }
1203
1204 public:
1205 VectorBase()
1206 : storage(NULL)
1207 {}
1208
1209 ~VectorBase()
1210 {
1211 if (!storage)
1212 return;
1213
1214 for (off_type i = 0; i < _size; ++i)
1215 data(i)->~Storage();
1216 delete [] reinterpret_cast<char *>(storage);
1217 }
1218
1219 /**
1220 * Return a reference (ScalarProxy) to the stat at the given index.
1221 * @param index The vector index to access.
1222 * @return A reference of the stat.
1223 */
1224 Proxy
1225 operator[](off_type index)
1226 {
1227 assert (index >= 0 && index < size());
1228 return Proxy(this, index);
1229 }
1230
1210 void update(StatData *data) {}
1231 void update(Info *data) {}
1211};
1212
1213template <class Stat>
1214class VectorProxy
1215{
1216 private:
1217 Stat *stat;
1218 off_type offset;
1219 size_type len;
1220
1221 private:
1222 mutable VResult vec;
1223
1224 typename Stat::Storage *
1225 data(off_type index)
1226 {
1227 assert(index < len);
1228 return stat->data(offset + index);
1229 }
1230
1231 const typename Stat::Storage *
1232 data(off_type index) const
1233 {
1234 assert(index < len);
1235 return const_cast<Stat *>(stat)->data(offset + index);
1236 }
1237
1238 public:
1239 const VResult &
1240 result() const
1241 {
1242 vec.resize(size());
1243
1244 for (off_type i = 0; i < size(); ++i)
1245 vec[i] = data(i)->result(stat->params);
1246
1247 return vec;
1248 }
1249
1250 Result
1251 total() const
1252 {
1253 Result total = 0;
1254 for (off_type i = 0; i < size(); ++i)
1255 total += data(i)->result(stat->params);
1256 return total;
1257 }
1258
1259 public:
1260 VectorProxy(Stat *s, off_type o, size_type l)
1261 : stat(s), offset(o), len(l)
1262 {
1263 }
1264
1265 VectorProxy(const VectorProxy &sp)
1266 : stat(sp.stat), offset(sp.offset), len(sp.len)
1267 {
1268 }
1269
1270 const VectorProxy &
1271 operator=(const VectorProxy &sp)
1272 {
1273 stat = sp.stat;
1274 offset = sp.offset;
1275 len = sp.len;
1276 return *this;
1277 }
1278
1279 ScalarProxy<Stat>
1280 operator[](off_type index)
1281 {
1282 assert (index >= 0 && index < size());
1283 return ScalarProxy<Stat>(stat, offset + index);
1284 }
1285
1286 size_type size() const { return len; }
1287
1288 /**
1289 * This stat has no state. Nothing to reset.
1290 */
1291 void reset() { }
1292};
1293
1294template <class Stor>
1232};
1233
1234template <class Stat>
1235class VectorProxy
1236{
1237 private:
1238 Stat *stat;
1239 off_type offset;
1240 size_type len;
1241
1242 private:
1243 mutable VResult vec;
1244
1245 typename Stat::Storage *
1246 data(off_type index)
1247 {
1248 assert(index < len);
1249 return stat->data(offset + index);
1250 }
1251
1252 const typename Stat::Storage *
1253 data(off_type index) const
1254 {
1255 assert(index < len);
1256 return const_cast<Stat *>(stat)->data(offset + index);
1257 }
1258
1259 public:
1260 const VResult &
1261 result() const
1262 {
1263 vec.resize(size());
1264
1265 for (off_type i = 0; i < size(); ++i)
1266 vec[i] = data(i)->result(stat->params);
1267
1268 return vec;
1269 }
1270
1271 Result
1272 total() const
1273 {
1274 Result total = 0;
1275 for (off_type i = 0; i < size(); ++i)
1276 total += data(i)->result(stat->params);
1277 return total;
1278 }
1279
1280 public:
1281 VectorProxy(Stat *s, off_type o, size_type l)
1282 : stat(s), offset(o), len(l)
1283 {
1284 }
1285
1286 VectorProxy(const VectorProxy &sp)
1287 : stat(sp.stat), offset(sp.offset), len(sp.len)
1288 {
1289 }
1290
1291 const VectorProxy &
1292 operator=(const VectorProxy &sp)
1293 {
1294 stat = sp.stat;
1295 offset = sp.offset;
1296 len = sp.len;
1297 return *this;
1298 }
1299
1300 ScalarProxy<Stat>
1301 operator[](off_type index)
1302 {
1303 assert (index >= 0 && index < size());
1304 return ScalarProxy<Stat>(stat, offset + index);
1305 }
1306
1307 size_type size() const { return len; }
1308
1309 /**
1310 * This stat has no state. Nothing to reset.
1311 */
1312 void reset() { }
1313};
1314
1315template <class Stor>
1295class Vector2dBase : public DataAccess
1316class Vector2dBase : public InfoAccess
1296{
1297 public:
1298 typedef Stor Storage;
1299 typedef typename Storage::Params Params;
1300 typedef VectorProxy<Vector2dBase<Storage> > Proxy;
1301 friend class ScalarProxy<Vector2dBase<Storage> >;
1302 friend class VectorProxy<Vector2dBase<Storage> >;
1303
1304 protected:
1305 size_type x;
1306 size_type y;
1307 size_type _size;
1308 Storage *storage;
1309 Params params;
1310
1311 protected:
1312 Storage *data(off_type index) { return &storage[index]; }
1313 const Storage *data(off_type index) const { return &storage[index]; }
1314
1315 void
1316 doInit(size_type _x, size_type _y)
1317 {
1318 assert(_x > 0 && _y > 0 && "sizes must be positive!");
1319 assert(!storage && "already initialized");
1320
1317{
1318 public:
1319 typedef Stor Storage;
1320 typedef typename Storage::Params Params;
1321 typedef VectorProxy<Vector2dBase<Storage> > Proxy;
1322 friend class ScalarProxy<Vector2dBase<Storage> >;
1323 friend class VectorProxy<Vector2dBase<Storage> >;
1324
1325 protected:
1326 size_type x;
1327 size_type y;
1328 size_type _size;
1329 Storage *storage;
1330 Params params;
1331
1332 protected:
1333 Storage *data(off_type index) { return &storage[index]; }
1334 const Storage *data(off_type index) const { return &storage[index]; }
1335
1336 void
1337 doInit(size_type _x, size_type _y)
1338 {
1339 assert(_x > 0 && _y > 0 && "sizes must be positive!");
1340 assert(!storage && "already initialized");
1341
1321 Vector2dData *statdata = dynamic_cast<Vector2dData *>(find());
1342 Vector2dInfoBase *info = dynamic_cast<Vector2dInfoBase *>(find());
1322
1323 x = _x;
1324 y = _y;
1343
1344 x = _x;
1345 y = _y;
1325 statdata->x = _x;
1326 statdata->y = _y;
1346 info->x = _x;
1347 info->y = _y;
1327 _size = x * y;
1328
1329 char *ptr = new char[_size * sizeof(Storage)];
1330 storage = reinterpret_cast<Storage *>(ptr);
1331
1332 for (off_type i = 0; i < _size; ++i)
1333 new (&storage[i]) Storage(params);
1334
1335 setInit();
1336 }
1337
1338 public:
1339 Vector2dBase()
1340 : storage(NULL)
1341 {}
1342
1343 ~Vector2dBase()
1344 {
1345 if (!storage)
1346 return;
1347
1348 for (off_type i = 0; i < _size; ++i)
1349 data(i)->~Storage();
1350 delete [] reinterpret_cast<char *>(storage);
1351 }
1352
1353 void
1348 _size = x * y;
1349
1350 char *ptr = new char[_size * sizeof(Storage)];
1351 storage = reinterpret_cast<Storage *>(ptr);
1352
1353 for (off_type i = 0; i < _size; ++i)
1354 new (&storage[i]) Storage(params);
1355
1356 setInit();
1357 }
1358
1359 public:
1360 Vector2dBase()
1361 : storage(NULL)
1362 {}
1363
1364 ~Vector2dBase()
1365 {
1366 if (!storage)
1367 return;
1368
1369 for (off_type i = 0; i < _size; ++i)
1370 data(i)->~Storage();
1371 delete [] reinterpret_cast<char *>(storage);
1372 }
1373
1374 void
1354 update(Vector2dData *newdata)
1375 update(Vector2dInfoBase *newinfo)
1355 {
1356 size_type size = this->size();
1376 {
1377 size_type size = this->size();
1357 newdata->cvec.resize(size);
1378 newinfo->cvec.resize(size);
1358 for (off_type i = 0; i < size; ++i)
1379 for (off_type i = 0; i < size; ++i)
1359 newdata->cvec[i] = data(i)->value(params);
1380 newinfo->cvec[i] = data(i)->value();
1360 }
1361
1362 std::string ysubname(off_type i) const { return (*this->y_subnames)[i]; }
1363
1364 Proxy
1365 operator[](off_type index)
1366 {
1367 off_type offset = index * y;
1368 assert (index >= 0 && offset + index < size());
1369 return Proxy(this, offset, y);
1370 }
1371
1372
1373 size_type
1374 size() const
1375 {
1376 return _size;
1377 }
1378
1379 bool
1380 zero() const
1381 {
1382 return data(0)->zero();
1383#if 0
1384 for (off_type i = 0; i < size(); ++i)
1385 if (!data(i)->zero())
1386 return false;
1387 return true;
1388#endif
1389 }
1390
1391 /**
1392 * Reset stat value to default
1393 */
1394 void
1395 reset()
1396 {
1397 for (off_type i = 0; i < size(); ++i)
1398 data(i)->reset();
1399 }
1400
1401 bool
1402 check()
1403 {
1404 return storage != NULL;
1405 }
1406};
1407
1408//////////////////////////////////////////////////////////////////////
1409//
1410// Non formula statistics
1411//
1412//////////////////////////////////////////////////////////////////////
1413
1414/**
1415 * Templatized storage and interface for a distrbution stat.
1416 */
1381 }
1382
1383 std::string ysubname(off_type i) const { return (*this->y_subnames)[i]; }
1384
1385 Proxy
1386 operator[](off_type index)
1387 {
1388 off_type offset = index * y;
1389 assert (index >= 0 && offset + index < size());
1390 return Proxy(this, offset, y);
1391 }
1392
1393
1394 size_type
1395 size() const
1396 {
1397 return _size;
1398 }
1399
1400 bool
1401 zero() const
1402 {
1403 return data(0)->zero();
1404#if 0
1405 for (off_type i = 0; i < size(); ++i)
1406 if (!data(i)->zero())
1407 return false;
1408 return true;
1409#endif
1410 }
1411
1412 /**
1413 * Reset stat value to default
1414 */
1415 void
1416 reset()
1417 {
1418 for (off_type i = 0; i < size(); ++i)
1419 data(i)->reset();
1420 }
1421
1422 bool
1423 check()
1424 {
1425 return storage != NULL;
1426 }
1427};
1428
1429//////////////////////////////////////////////////////////////////////
1430//
1431// Non formula statistics
1432//
1433//////////////////////////////////////////////////////////////////////
1434
1435/**
1436 * Templatized storage and interface for a distrbution stat.
1437 */
1417struct DistStor
1438class DistStor
1418{
1419 public:
1420 /** The parameters for a distribution stat. */
1421 struct Params
1422 {
1423 /** The minimum value to track. */
1424 Counter min;
1425 /** The maximum value to track. */
1426 Counter max;
1427 /** The number of entries in each bucket. */
1428 Counter bucket_size;
1429 /** The number of buckets. Equal to (max-min)/bucket_size. */
1430 size_type size;
1431 };
1432 enum { fancy = false };
1433
1434 private:
1435 /** The smallest value sampled. */
1436 Counter min_val;
1437 /** The largest value sampled. */
1438 Counter max_val;
1439 /** The number of values sampled less than min. */
1440 Counter underflow;
1441 /** The number of values sampled more than max. */
1442 Counter overflow;
1443 /** The current sum. */
1444 Counter sum;
1445 /** The sum of squares. */
1446 Counter squares;
1447 /** The number of samples. */
1448 Counter samples;
1449 /** Counter for each bucket. */
1450 VCounter cvec;
1451
1452 public:
1453 DistStor(const Params &params)
1454 : cvec(params.size)
1455 {
1456 reset();
1457 }
1458
1459 /**
1460 * Add a value to the distribution for the given number of times.
1461 * @param val The value to add.
1462 * @param number The number of times to add the value.
1463 * @param params The paramters of the distribution.
1464 */
1465 void
1466 sample(Counter val, int number, const Params &params)
1467 {
1468 if (val < params.min)
1469 underflow += number;
1470 else if (val > params.max)
1471 overflow += number;
1472 else {
1473 size_type index =
1474 (size_type)std::floor((val - params.min) / params.bucket_size);
1475 assert(index < size(params));
1476 cvec[index] += number;
1477 }
1478
1479 if (val < min_val)
1480 min_val = val;
1481
1482 if (val > max_val)
1483 max_val = val;
1484
1485 Counter sample = val * number;
1486 sum += sample;
1487 squares += sample * sample;
1488 samples += number;
1489 }
1490
1491 /**
1492 * Return the number of buckets in this distribution.
1493 * @return the number of buckets.
1494 * @todo Is it faster to return the size from the parameters?
1495 */
1496 size_type size(const Params &) const { return cvec.size(); }
1497
1498 /**
1499 * Returns true if any calls to sample have been made.
1500 * @param params The paramters of the distribution.
1501 * @return True if any values have been sampled.
1502 */
1503 bool
1504 zero(const Params &params) const
1505 {
1506 return samples == Counter();
1507 }
1508
1509 void
1439{
1440 public:
1441 /** The parameters for a distribution stat. */
1442 struct Params
1443 {
1444 /** The minimum value to track. */
1445 Counter min;
1446 /** The maximum value to track. */
1447 Counter max;
1448 /** The number of entries in each bucket. */
1449 Counter bucket_size;
1450 /** The number of buckets. Equal to (max-min)/bucket_size. */
1451 size_type size;
1452 };
1453 enum { fancy = false };
1454
1455 private:
1456 /** The smallest value sampled. */
1457 Counter min_val;
1458 /** The largest value sampled. */
1459 Counter max_val;
1460 /** The number of values sampled less than min. */
1461 Counter underflow;
1462 /** The number of values sampled more than max. */
1463 Counter overflow;
1464 /** The current sum. */
1465 Counter sum;
1466 /** The sum of squares. */
1467 Counter squares;
1468 /** The number of samples. */
1469 Counter samples;
1470 /** Counter for each bucket. */
1471 VCounter cvec;
1472
1473 public:
1474 DistStor(const Params &params)
1475 : cvec(params.size)
1476 {
1477 reset();
1478 }
1479
1480 /**
1481 * Add a value to the distribution for the given number of times.
1482 * @param val The value to add.
1483 * @param number The number of times to add the value.
1484 * @param params The paramters of the distribution.
1485 */
1486 void
1487 sample(Counter val, int number, const Params &params)
1488 {
1489 if (val < params.min)
1490 underflow += number;
1491 else if (val > params.max)
1492 overflow += number;
1493 else {
1494 size_type index =
1495 (size_type)std::floor((val - params.min) / params.bucket_size);
1496 assert(index < size(params));
1497 cvec[index] += number;
1498 }
1499
1500 if (val < min_val)
1501 min_val = val;
1502
1503 if (val > max_val)
1504 max_val = val;
1505
1506 Counter sample = val * number;
1507 sum += sample;
1508 squares += sample * sample;
1509 samples += number;
1510 }
1511
1512 /**
1513 * Return the number of buckets in this distribution.
1514 * @return the number of buckets.
1515 * @todo Is it faster to return the size from the parameters?
1516 */
1517 size_type size(const Params &) const { return cvec.size(); }
1518
1519 /**
1520 * Returns true if any calls to sample have been made.
1521 * @param params The paramters of the distribution.
1522 * @return True if any values have been sampled.
1523 */
1524 bool
1525 zero(const Params &params) const
1526 {
1527 return samples == Counter();
1528 }
1529
1530 void
1510 update(DistDataData *data, const Params &params)
1531 update(DistData *data, const Params ¶ms)
1511 {
1512 data->min = params.min;
1513 data->max = params.max;
1514 data->bucket_size = params.bucket_size;
1515 data->size = params.size;
1516
1517 data->min_val = (min_val == CounterLimits::max()) ? 0 : min_val;
1518 data->max_val = (max_val == CounterLimits::min()) ? 0 : max_val;
1519 data->underflow = underflow;
1520 data->overflow = overflow;
1521 data->cvec.resize(params.size);
1522 for (off_type i = 0; i < params.size; ++i)
1523 data->cvec[i] = cvec[i];
1524
1525 data->sum = sum;
1526 data->squares = squares;
1527 data->samples = samples;
1528 }
1529
1530 /**
1531 * Reset stat value to default
1532 */
1533 void
1534 reset()
1535 {
1536 min_val = CounterLimits::max();
1537 max_val = CounterLimits::min();
1538 underflow = 0;
1539 overflow = 0;
1540
1541 size_type size = cvec.size();
1542 for (off_type i = 0; i < size; ++i)
1543 cvec[i] = Counter();
1544
1545 sum = Counter();
1546 squares = Counter();
1547 samples = Counter();
1548 }
1549};
1550
1551/**
1552 * Templatized storage and interface for a distribution that calculates mean
1553 * and variance.
1554 */
1532 {
1533 data->min = params.min;
1534 data->max = params.max;
1535 data->bucket_size = params.bucket_size;
1536 data->size = params.size;
1537
1538 data->min_val = (min_val == CounterLimits::max()) ? 0 : min_val;
1539 data->max_val = (max_val == CounterLimits::min()) ? 0 : max_val;
1540 data->underflow = underflow;
1541 data->overflow = overflow;
1542 data->cvec.resize(params.size);
1543 for (off_type i = 0; i < params.size; ++i)
1544 data->cvec[i] = cvec[i];
1545
1546 data->sum = sum;
1547 data->squares = squares;
1548 data->samples = samples;
1549 }
1550
1551 /**
1552 * Reset stat value to default
1553 */
1554 void
1555 reset()
1556 {
1557 min_val = CounterLimits::max();
1558 max_val = CounterLimits::min();
1559 underflow = 0;
1560 overflow = 0;
1561
1562 size_type size = cvec.size();
1563 for (off_type i = 0; i < size; ++i)
1564 cvec[i] = Counter();
1565
1566 sum = Counter();
1567 squares = Counter();
1568 samples = Counter();
1569 }
1570};
1571
1572/**
1573 * Templatized storage and interface for a distribution that calculates mean
1574 * and variance.
1575 */
1555struct FancyStor
1576class FancyStor
1556{
1557 public:
1558 /**
1559 * No paramters for this storage.
1560 */
1561 struct Params {};
1562 enum { fancy = true };
1563
1564 private:
1565 /** The current sum. */
1566 Counter sum;
1567 /** The sum of squares. */
1568 Counter squares;
1569 /** The number of samples. */
1570 Counter samples;
1571
1572 public:
1573 /**
1574 * Create and initialize this storage.
1575 */
1576 FancyStor(const Params &)
1577 : sum(Counter()), squares(Counter()), samples(Counter())
1578 { }
1579
1580 /**
1581 * Add a value the given number of times to this running average.
1582 * Update the running sum and sum of squares, increment the number of
1583 * values seen by the given number.
1584 * @param val The value to add.
1585 * @param number The number of times to add the value.
1586 * @param p The parameters of this stat.
1587 */
1588 void
1589 sample(Counter val, int number, const Params &p)
1590 {
1591 Counter value = val * number;
1592 sum += value;
1593 squares += value * value;
1594 samples += number;
1595 }
1596
1597 void
1577{
1578 public:
1579 /**
1580 * No paramters for this storage.
1581 */
1582 struct Params {};
1583 enum { fancy = true };
1584
1585 private:
1586 /** The current sum. */
1587 Counter sum;
1588 /** The sum of squares. */
1589 Counter squares;
1590 /** The number of samples. */
1591 Counter samples;
1592
1593 public:
1594 /**
1595 * Create and initialize this storage.
1596 */
1597 FancyStor(const Params &)
1598 : sum(Counter()), squares(Counter()), samples(Counter())
1599 { }
1600
1601 /**
1602 * Add a value the given number of times to this running average.
1603 * Update the running sum and sum of squares, increment the number of
1604 * values seen by the given number.
1605 * @param val The value to add.
1606 * @param number The number of times to add the value.
1607 * @param p The parameters of this stat.
1608 */
1609 void
1610 sample(Counter val, int number, const Params &p)
1611 {
1612 Counter value = val * number;
1613 sum += value;
1614 squares += value * value;
1615 samples += number;
1616 }
1617
1618 void
1598 update(DistDataData *data, const Params &params)
1619 update(DistData *data, const Params ¶ms)
1599 {
1600 data->sum = sum;
1601 data->squares = squares;
1602 data->samples = samples;
1603 }
1604
1605 /**
1606 * Return the number of entries in this stat, 1
1607 * @return 1.
1608 */
1609 size_type size(const Params &) const { return 1; }
1610
1611 /**
1612 * Return true if no samples have been added.
1613 * @return True if no samples have been added.
1614 */
1615 bool zero(const Params &) const { return samples == Counter(); }
1616
1617 /**
1618 * Reset stat value to default
1619 */
1620 void
1621 reset()
1622 {
1623 sum = Counter();
1624 squares = Counter();
1625 samples = Counter();
1626 }
1627};
1628
1629/**
1630 * Templatized storage for distribution that calculates per tick mean and
1631 * variance.
1632 */
1620 {
1621 data->sum = sum;
1622 data->squares = squares;
1623 data->samples = samples;
1624 }
1625
1626 /**
1627 * Return the number of entries in this stat, 1
1628 * @return 1.
1629 */
1630 size_type size(const Params &) const { return 1; }
1631
1632 /**
1633 * Return true if no samples have been added.
1634 * @return True if no samples have been added.
1635 */
1636 bool zero(const Params &) const { return samples == Counter(); }
1637
1638 /**
1639 * Reset stat value to default
1640 */
1641 void
1642 reset()
1643 {
1644 sum = Counter();
1645 squares = Counter();
1646 samples = Counter();
1647 }
1648};
1649
1650/**
1651 * Templatized storage for distribution that calculates per tick mean and
1652 * variance.
1653 */
1633struct AvgFancy
1654class AvgFancy
1634{
1635 public:
1636 /** No parameters for this storage. */
1637 struct Params {};
1638 enum { fancy = true };
1639
1640 private:
1641 /** Current total. */
1642 Counter sum;
1643 /** Current sum of squares. */
1644 Counter squares;
1645
1646 public:
1647 /**
1648 * Create and initialize this storage.
1649 */
1650 AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {}
1651
1652 /**
1653 * Add a value to the distribution for the given number of times.
1654 * Update the running sum and sum of squares.
1655 * @param val The value to add.
1656 * @param number The number of times to add the value.
1657 * @param p The paramters of the distribution.
1658 */
1659 void
1660 sample(Counter val, int number, const Params &p)
1661 {
1662 Counter value = val * number;
1663 sum += value;
1664 squares += value * value;
1665 }
1666
1667 void
1655{
1656 public:
1657 /** No parameters for this storage. */
1658 struct Params {};
1659 enum { fancy = true };
1660
1661 private:
1662 /** Current total. */
1663 Counter sum;
1664 /** Current sum of squares. */
1665 Counter squares;
1666
1667 public:
1668 /**
1669 * Create and initialize this storage.
1670 */
1671 AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {}
1672
1673 /**
1674 * Add a value to the distribution for the given number of times.
1675 * Update the running sum and sum of squares.
1676 * @param val The value to add.
1677 * @param number The number of times to add the value.
1678 * @param p The paramters of the distribution.
1679 */
1680 void
1681 sample(Counter val, int number, const Params &p)
1682 {
1683 Counter value = val * number;
1684 sum += value;
1685 squares += value * value;
1686 }
1687
1688 void
1668 update(DistDataData *data, const Params &params)
1689 update(DistData *data, const Params ¶ms)
1669 {
1670 data->sum = sum;
1671 data->squares = squares;
1672 data->samples = curTick;
1673 }
1674
1675 /**
1676 * Return the number of entries, in this case 1.
1677 * @return 1.
1678 */
1679 size_type size(const Params &params) const { return 1; }
1680
1681 /**
1682 * Return true if no samples have been added.
1683 * @return True if the sum is zero.
1684 */
1685 bool zero(const Params &params) const { return sum == Counter(); }
1686
1687 /**
1688 * Reset stat value to default
1689 */
1690 void
1691 reset()
1692 {
1693 sum = Counter();
1694 squares = Counter();
1695 }
1696};
1697
1698/**
1699 * Implementation of a distribution stat. The type of distribution is
1700 * determined by the Storage template. @sa ScalarBase
1701 */
1702template <class Stor>
1690 {
1691 data->sum = sum;
1692 data->squares = squares;
1693 data->samples = curTick;
1694 }
1695
1696 /**
1697 * Return the number of entries, in this case 1.
1698 * @return 1.
1699 */
1700 size_type size(const Params &params) const { return 1; }
1701
1702 /**
1703 * Return true if no samples have been added.
1704 * @return True if the sum is zero.
1705 */
1706 bool zero(const Params &params) const { return sum == Counter(); }
1707
1708 /**
1709 * Reset stat value to default
1710 */
1711 void
1712 reset()
1713 {
1714 sum = Counter();
1715 squares = Counter();
1716 }
1717};
1718
1719/**
1720 * Implementation of a distribution stat. The type of distribution is
1721 * determined by the Storage template. @sa ScalarBase
1722 */
1723template <class Stor>
1703class DistBase : public DataAccess
1724class DistBase : public InfoAccess
1704{
1705 public:
1706 typedef Stor Storage;
1707 /** Define the params of the storage class. */
1708 typedef typename Storage::Params Params;
1709
1710 protected:
1711 /** The storage for this stat. */
1712 char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
1713
1714 /** The parameters for this stat. */
1715 Params params;
1716
1717 protected:
1718 /**
1719 * Retrieve the storage.
1720 * @return The storage object for this stat.
1721 */
1722 Storage *
1723 data()
1724 {
1725 return reinterpret_cast<Storage *>(storage);
1726 }
1727
1728 /**
1729 * Retrieve a const pointer to the storage.
1730 * @return A const pointer to the storage object for this stat.
1731 */
1732 const Storage *
1733 data() const
1734 {
1735 return reinterpret_cast<const Storage *>(storage);
1736 }
1737
1738 void
1739 doInit()
1740 {
1741 new (storage) Storage(params);
1742 setInit();
1743 }
1744
1745 public:
1746 DistBase() { }
1747
1748 /**
1749 * Add a value to the distribtion n times. Calls sample on the storage
1750 * class.
1751 * @param v The value to add.
1752 * @param n The number of times to add it, defaults to 1.
1753 */
1754 template <typename U>
1755 void sample(const U &v, int n = 1) { data()->sample(v, n, params); }
1756
1757 /**
1758 * Return the number of entries in this stat.
1759 * @return The number of entries.
1760 */
1761 size_type size() const { return data()->size(params); }
1762 /**
1763 * Return true if no samples have been added.
1764 * @return True if there haven't been any samples.
1765 */
1766 bool zero() const { return data()->zero(params); }
1767
1768 void
1725{
1726 public:
1727 typedef Stor Storage;
1728 /** Define the params of the storage class. */
1729 typedef typename Storage::Params Params;
1730
1731 protected:
1732 /** The storage for this stat. */
1733 char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
1734
1735 /** The parameters for this stat. */
1736 Params params;
1737
1738 protected:
1739 /**
1740 * Retrieve the storage.
1741 * @return The storage object for this stat.
1742 */
1743 Storage *
1744 data()
1745 {
1746 return reinterpret_cast<Storage *>(storage);
1747 }
1748
1749 /**
1750 * Retrieve a const pointer to the storage.
1751 * @return A const pointer to the storage object for this stat.
1752 */
1753 const Storage *
1754 data() const
1755 {
1756 return reinterpret_cast<const Storage *>(storage);
1757 }
1758
1759 void
1760 doInit()
1761 {
1762 new (storage) Storage(params);
1763 setInit();
1764 }
1765
1766 public:
1767 DistBase() { }
1768
1769 /**
1770 * Add a value to the distribtion n times. Calls sample on the storage
1771 * class.
1772 * @param v The value to add.
1773 * @param n The number of times to add it, defaults to 1.
1774 */
1775 template <typename U>
1776 void sample(const U &v, int n = 1) { data()->sample(v, n, params); }
1777
1778 /**
1779 * Return the number of entries in this stat.
1780 * @return The number of entries.
1781 */
1782 size_type size() const { return data()->size(params); }
1783 /**
1784 * Return true if no samples have been added.
1785 * @return True if there haven't been any samples.
1786 */
1787 bool zero() const { return data()->zero(params); }
1788
1789 void
1769 update(DistData *base)
1790 update(DistInfoBase *base)
1770 {
1771 base->data.fancy = Storage::fancy;
1772 data()->update(&(base->data), params);
1773 }
1774
1775 /**
1776 * Reset stat value to default
1777 */
1778 void
1779 reset()
1780 {
1781 data()->reset();
1782 }
1783
1784 bool
1785 check()
1786 {
1787 return true;
1788 }
1789};
1790
1791template <class Stat>
1792class DistProxy;
1793
1794template <class Stor>
1791 {
1792 base->data.fancy = Storage::fancy;
1793 data()->update(&(base->data), params);
1794 }
1795
1796 /**
1797 * Reset stat value to default
1798 */
1799 void
1800 reset()
1801 {
1802 data()->reset();
1803 }
1804
1805 bool
1806 check()
1807 {
1808 return true;
1809 }
1810};
1811
1812template <class Stat>
1813class DistProxy;
1814
1815template <class Stor>
1795class VectorDistBase : public DataAccess
1816class VectorDistBase : public InfoAccess
1796{
1797 public:
1798 typedef Stor Storage;
1799 typedef typename Storage::Params Params;
1800 typedef DistProxy<VectorDistBase<Storage> > Proxy;
1801 friend class DistProxy<VectorDistBase<Storage> >;
1802
1803 protected:
1804 Storage *storage;
1805 size_type _size;
1806 Params params;
1807
1808 protected:
1809 Storage *
1810 data(off_type index)
1811 {
1812 return &storage[index];
1813 }
1814
1815 const Storage *
1816 data(off_type index) const
1817 {
1818 return &storage[index];
1819 }
1820
1821 void
1822 doInit(size_type s)
1823 {
1824 assert(s > 0 && "size must be positive!");
1825 assert(!storage && "already initialized");
1826 _size = s;
1827
1828 char *ptr = new char[_size * sizeof(Storage)];
1829 storage = reinterpret_cast<Storage *>(ptr);
1830
1831 for (off_type i = 0; i < _size; ++i)
1832 new (&storage[i]) Storage(params);
1833
1834 setInit();
1835 }
1836
1837 public:
1838 VectorDistBase()
1839 : storage(NULL)
1840 {}
1841
1842 ~VectorDistBase()
1843 {
1844 if (!storage)
1845 return ;
1846
1847 for (off_type i = 0; i < _size; ++i)
1848 data(i)->~Storage();
1849 delete [] reinterpret_cast<char *>(storage);
1850 }
1851
1852 Proxy operator[](off_type index);
1853
1854 size_type
1855 size() const
1856 {
1857 return _size;
1858 }
1859
1860 bool
1861 zero() const
1862 {
1863 return false;
1864#if 0
1865 for (off_type i = 0; i < size(); ++i)
1866 if (!data(i)->zero(params))
1867 return false;
1868 return true;
1869#endif
1870 }
1871
1872 /**
1873 * Reset stat value to default
1874 */
1875 void
1876 reset()
1877 {
1878 for (off_type i = 0; i < size(); ++i)
1879 data(i)->reset();
1880 }
1881
1882 bool
1883 check()
1884 {
1885 return storage != NULL;
1886 }
1887
1888 void
1817{
1818 public:
1819 typedef Stor Storage;
1820 typedef typename Storage::Params Params;
1821 typedef DistProxy<VectorDistBase<Storage> > Proxy;
1822 friend class DistProxy<VectorDistBase<Storage> >;
1823
1824 protected:
1825 Storage *storage;
1826 size_type _size;
1827 Params params;
1828
1829 protected:
1830 Storage *
1831 data(off_type index)
1832 {
1833 return &storage[index];
1834 }
1835
1836 const Storage *
1837 data(off_type index) const
1838 {
1839 return &storage[index];
1840 }
1841
1842 void
1843 doInit(size_type s)
1844 {
1845 assert(s > 0 && "size must be positive!");
1846 assert(!storage && "already initialized");
1847 _size = s;
1848
1849 char *ptr = new char[_size * sizeof(Storage)];
1850 storage = reinterpret_cast<Storage *>(ptr);
1851
1852 for (off_type i = 0; i < _size; ++i)
1853 new (&storage[i]) Storage(params);
1854
1855 setInit();
1856 }
1857
1858 public:
1859 VectorDistBase()
1860 : storage(NULL)
1861 {}
1862
1863 ~VectorDistBase()
1864 {
1865 if (!storage)
1866 return ;
1867
1868 for (off_type i = 0; i < _size; ++i)
1869 data(i)->~Storage();
1870 delete [] reinterpret_cast<char *>(storage);
1871 }
1872
1873 Proxy operator[](off_type index);
1874
1875 size_type
1876 size() const
1877 {
1878 return _size;
1879 }
1880
1881 bool
1882 zero() const
1883 {
1884 return false;
1885#if 0
1886 for (off_type i = 0; i < size(); ++i)
1887 if (!data(i)->zero(params))
1888 return false;
1889 return true;
1890#endif
1891 }
1892
1893 /**
1894 * Reset stat value to default
1895 */
1896 void
1897 reset()
1898 {
1899 for (off_type i = 0; i < size(); ++i)
1900 data(i)->reset();
1901 }
1902
1903 bool
1904 check()
1905 {
1906 return storage != NULL;
1907 }
1908
1909 void
1889 update(VectorDistData *base)
1910 update(VectorDistInfoBase *base)
1890 {
1891 size_type size = this->size();
1892 base->data.resize(size);
1893 for (off_type i = 0; i < size; ++i) {
1894 base->data[i].fancy = Storage::fancy;
1895 data(i)->update(&(base->data[i]), params);
1896 }
1897 }
1898};
1899
1900template <class Stat>
1901class DistProxy
1902{
1903 private:
1904 Stat *stat;
1905 off_type index;
1906
1907 protected:
1908 typename Stat::Storage *data() { return stat->data(index); }
1909 const typename Stat::Storage *data() const { return stat->data(index); }
1910
1911 public:
1912 DistProxy(Stat *s, off_type i)
1913 : stat(s), index(i)
1914 {}
1915
1916 DistProxy(const DistProxy &sp)
1917 : stat(sp.stat), index(sp.index)
1918 {}
1919
1920 const DistProxy &
1921 operator=(const DistProxy &sp)
1922 {
1923 stat = sp.stat;
1924 index = sp.index;
1925 return *this;
1926 }
1927
1928 public:
1929 template <typename U>
1930 void
1931 sample(const U &v, int n = 1)
1932 {
1933 data()->sample(v, n, stat->params);
1934 }
1935
1936 size_type
1937 size() const
1938 {
1939 return 1;
1940 }
1941
1942 bool
1943 zero() const
1944 {
1945 return data()->zero(stat->params);
1946 }
1947
1948 /**
1949 * Proxy has no state. Nothing to reset.
1950 */
1951 void reset() { }
1952};
1953
1954template <class Storage>
1955inline typename VectorDistBase<Storage>::Proxy
1956VectorDistBase<Storage>::operator[](off_type index)
1957{
1958 assert (index >= 0 && index < size());
1959 return typename VectorDistBase<Storage>::Proxy(this, index);
1960}
1961
1962#if 0
1963template <class Storage>
1964Result
1965VectorDistBase<Storage>::total(off_type index) const
1966{
1967 Result total = 0;
1968 for (off_type i = 0; i < x_size(); ++i)
1969 total += data(i)->result(stat->params);
1970}
1971#endif
1972
1973//////////////////////////////////////////////////////////////////////
1974//
1975// Formula Details
1976//
1977//////////////////////////////////////////////////////////////////////
1978
1979/**
1980 * Base class for formula statistic node. These nodes are used to build a tree
1981 * that represents the formula.
1982 */
1983class Node : public RefCounted
1984{
1985 public:
1986 /**
1987 * Return the number of nodes in the subtree starting at this node.
1988 * @return the number of nodes in this subtree.
1989 */
1990 virtual size_type size() const = 0;
1991 /**
1992 * Return the result vector of this subtree.
1993 * @return The result vector of this subtree.
1994 */
1995 virtual const VResult &result() const = 0;
1996 /**
1997 * Return the total of the result vector.
1998 * @return The total of the result vector.
1999 */
2000 virtual Result total() const = 0;
2001
2002 /**
2003 *
2004 */
2005 virtual std::string str() const = 0;
2006};
2007
2008/** Reference counting pointer to a function Node. */
2009typedef RefCountingPtr<Node> NodePtr;
2010
2011class ScalarStatNode : public Node
2012{
2013 private:
1911 {
1912 size_type size = this->size();
1913 base->data.resize(size);
1914 for (off_type i = 0; i < size; ++i) {
1915 base->data[i].fancy = Storage::fancy;
1916 data(i)->update(&(base->data[i]), params);
1917 }
1918 }
1919};
1920
1921template <class Stat>
1922class DistProxy
1923{
1924 private:
1925 Stat *stat;
1926 off_type index;
1927
1928 protected:
1929 typename Stat::Storage *data() { return stat->data(index); }
1930 const typename Stat::Storage *data() const { return stat->data(index); }
1931
1932 public:
1933 DistProxy(Stat *s, off_type i)
1934 : stat(s), index(i)
1935 {}
1936
1937 DistProxy(const DistProxy &sp)
1938 : stat(sp.stat), index(sp.index)
1939 {}
1940
1941 const DistProxy &
1942 operator=(const DistProxy &sp)
1943 {
1944 stat = sp.stat;
1945 index = sp.index;
1946 return *this;
1947 }
1948
1949 public:
1950 template <typename U>
1951 void
1952 sample(const U &v, int n = 1)
1953 {
1954 data()->sample(v, n, stat->params);
1955 }
1956
1957 size_type
1958 size() const
1959 {
1960 return 1;
1961 }
1962
1963 bool
1964 zero() const
1965 {
1966 return data()->zero(stat->params);
1967 }
1968
1969 /**
1970 * Proxy has no state. Nothing to reset.
1971 */
1972 void reset() { }
1973};
1974
1975template <class Storage>
1976inline typename VectorDistBase<Storage>::Proxy
1977VectorDistBase<Storage>::operator[](off_type index)
1978{
1979 assert (index >= 0 && index < size());
1980 return typename VectorDistBase<Storage>::Proxy(this, index);
1981}
1982
1983#if 0
1984template <class Storage>
1985Result
1986VectorDistBase<Storage>::total(off_type index) const
1987{
1988 Result total = 0;
1989 for (off_type i = 0; i < x_size(); ++i)
1990 total += data(i)->result(stat->params);
1991}
1992#endif
1993
1994//////////////////////////////////////////////////////////////////////
1995//
1996// Formula Details
1997//
1998//////////////////////////////////////////////////////////////////////
1999
2000/**
2001 * Base class for formula statistic node. These nodes are used to build a tree
2002 * that represents the formula.
2003 */
2004class Node : public RefCounted
2005{
2006 public:
2007 /**
2008 * Return the number of nodes in the subtree starting at this node.
2009 * @return the number of nodes in this subtree.
2010 */
2011 virtual size_type size() const = 0;
2012 /**
2013 * Return the result vector of this subtree.
2014 * @return The result vector of this subtree.
2015 */
2016 virtual const VResult &result() const = 0;
2017 /**
2018 * Return the total of the result vector.
2019 * @return The total of the result vector.
2020 */
2021 virtual Result total() const = 0;
2022
2023 /**
2024 *
2025 */
2026 virtual std::string str() const = 0;
2027};
2028
2029/** Reference counting pointer to a function Node. */
2030typedef RefCountingPtr<Node> NodePtr;
2031
2032class ScalarStatNode : public Node
2033{
2034 private:
2014 const ScalarData *data;
2035 const ScalarInfoBase *data;
2015 mutable VResult vresult;
2016
2017 public:
2036 mutable VResult vresult;
2037
2038 public:
2018 ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {}
2039 ScalarStatNode(const ScalarInfoBase *d) : data(d), vresult(1) {}
2019
2020 virtual const VResult &
2021 result() const
2022 {
2023 vresult[0] = data->result();
2024 return vresult;
2025 }
2026
2027 virtual Result total() const { return data->result(); };
2028
2029 virtual size_type size() const { return 1; }
2030
2031 /**
2032 *
2033 */
2034 virtual std::string str() const { return data->name; }
2035};
2036
2037template <class Stat>
2038class ScalarProxyNode : public Node
2039{
2040 private:
2041 const ScalarProxy<Stat> proxy;
2042 mutable VResult vresult;
2043
2044 public:
2045 ScalarProxyNode(const ScalarProxy<Stat> &p)
2046 : proxy(p), vresult(1)
2047 { }
2048
2049 virtual const VResult &
2050 result() const
2051 {
2052 vresult[0] = proxy.result();
2053 return vresult;
2054 }
2055
2056 virtual Result
2057 total() const
2058 {
2059 return proxy.result();
2060 }
2061
2062 virtual size_type
2063 size() const
2064 {
2065 return 1;
2066 }
2067
2068 /**
2069 *
2070 */
2071 virtual std::string
2072 str() const
2073 {
2074 return proxy.str();
2075 }
2076};
2077
2078class VectorStatNode : public Node
2079{
2080 private:
2040
2041 virtual const VResult &
2042 result() const
2043 {
2044 vresult[0] = data->result();
2045 return vresult;
2046 }
2047
2048 virtual Result total() const { return data->result(); };
2049
2050 virtual size_type size() const { return 1; }
2051
2052 /**
2053 *
2054 */
2055 virtual std::string str() const { return data->name; }
2056};
2057
2058template <class Stat>
2059class ScalarProxyNode : public Node
2060{
2061 private:
2062 const ScalarProxy<Stat> proxy;
2063 mutable VResult vresult;
2064
2065 public:
2066 ScalarProxyNode(const ScalarProxy<Stat> &p)
2067 : proxy(p), vresult(1)
2068 { }
2069
2070 virtual const VResult &
2071 result() const
2072 {
2073 vresult[0] = proxy.result();
2074 return vresult;
2075 }
2076
2077 virtual Result
2078 total() const
2079 {
2080 return proxy.result();
2081 }
2082
2083 virtual size_type
2084 size() const
2085 {
2086 return 1;
2087 }
2088
2089 /**
2090 *
2091 */
2092 virtual std::string
2093 str() const
2094 {
2095 return proxy.str();
2096 }
2097};
2098
2099class VectorStatNode : public Node
2100{
2101 private:
2081 const VectorData *data;
2102 const VectorInfoBase *data;
2082
2083 public:
2103
2104 public:
2084 VectorStatNode(const VectorData *d) : data(d) { }
2105 VectorStatNode(const VectorInfoBase *d) : data(d) { }
2085 virtual const VResult &result() const { return data->result(); }
2086 virtual Result total() const { return data->total(); };
2087
2088 virtual size_type size() const { return data->size(); }
2089
2090 virtual std::string str() const { return data->name; }
2091};
2092
2093template <class T>
2094class ConstNode : public Node
2095{
2096 private:
2097 VResult vresult;
2098
2099 public:
2100 ConstNode(T s) : vresult(1, (Result)s) {}
2101 const VResult &result() const { return vresult; }
2102 virtual Result total() const { return vresult[0]; };
2103 virtual size_type size() const { return 1; }
2104 virtual std::string str() const { return to_string(vresult[0]); }
2105};
2106
2107template <class T>
2108class ConstVectorNode : public Node
2109{
2110 private:
2111 VResult vresult;
2112
2113 public:
2114 ConstVectorNode(const T &s) : vresult(s.begin(), s.end()) {}
2115 const VResult &result() const { return vresult; }
2116
2117 virtual Result
2118 total() const
2119 {
2120 size_type size = this->size();
2121 Result tmp = 0;
2122 for (off_type i = 0; i < size; i++)
2123 tmp += vresult[i];
2124 return tmp;
2125 }
2126
2127 virtual size_type size() const { return vresult.size(); }
2128 virtual std::string
2129 str() const
2130 {
2131 size_type size = this->size();
2132 std::string tmp = "(";
2133 for (off_type i = 0; i < size; i++)
2134 tmp += csprintf("%s ",to_string(vresult[i]));
2135 tmp += ")";
2136 return tmp;
2137 }
2138};
2139
2140template <class Op>
2141struct OpString;
2142
2143template<>
2144struct OpString<std::plus<Result> >
2145{
2146 static std::string str() { return "+"; }
2147};
2148
2149template<>
2150struct OpString<std::minus<Result> >
2151{
2152 static std::string str() { return "-"; }
2153};
2154
2155template<>
2156struct OpString<std::multiplies<Result> >
2157{
2158 static std::string str() { return "*"; }
2159};
2160
2161template<>
2162struct OpString<std::divides<Result> >
2163{
2164 static std::string str() { return "/"; }
2165};
2166
2167template<>
2168struct OpString<std::modulus<Result> >
2169{
2170 static std::string str() { return "%"; }
2171};
2172
2173template<>
2174struct OpString<std::negate<Result> >
2175{
2176 static std::string str() { return "-"; }
2177};
2178
2179template <class Op>
2180class UnaryNode : public Node
2181{
2182 public:
2183 NodePtr l;
2184 mutable VResult vresult;
2185
2186 public:
2187 UnaryNode(NodePtr &p) : l(p) {}
2188
2189 const VResult &
2190 result() const
2191 {
2192 const VResult &lvec = l->result();
2193 size_type size = lvec.size();
2194
2195 assert(size > 0);
2196
2197 vresult.resize(size);
2198 Op op;
2199 for (off_type i = 0; i < size; ++i)
2200 vresult[i] = op(lvec[i]);
2201
2202 return vresult;
2203 }
2204
2205 Result
2206 total() const
2207 {
2208 const VResult &vec = this->result();
2209 Result total = 0;
2210 for (off_type i = 0; i < size(); i++)
2211 total += vec[i];
2212 return total;
2213 }
2214
2215 virtual size_type size() const { return l->size(); }
2216
2217 virtual std::string
2218 str() const
2219 {
2220 return OpString<Op>::str() + l->str();
2221 }
2222};
2223
2224template <class Op>
2225class BinaryNode : public Node
2226{
2227 public:
2228 NodePtr l;
2229 NodePtr r;
2230 mutable VResult vresult;
2231
2232 public:
2233 BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}
2234
2235 const VResult &
2236 result() const
2237 {
2238 Op op;
2239 const VResult &lvec = l->result();
2240 const VResult &rvec = r->result();
2241
2242 assert(lvec.size() > 0 && rvec.size() > 0);
2243
2244 if (lvec.size() == 1 && rvec.size() == 1) {
2245 vresult.resize(1);
2246 vresult[0] = op(lvec[0], rvec[0]);
2247 } else if (lvec.size() == 1) {
2248 size_type size = rvec.size();
2249 vresult.resize(size);
2250 for (off_type i = 0; i < size; ++i)
2251 vresult[i] = op(lvec[0], rvec[i]);
2252 } else if (rvec.size() == 1) {
2253 size_type size = lvec.size();
2254 vresult.resize(size);
2255 for (off_type i = 0; i < size; ++i)
2256 vresult[i] = op(lvec[i], rvec[0]);
2257 } else if (rvec.size() == lvec.size()) {
2258 size_type size = rvec.size();
2259 vresult.resize(size);
2260 for (off_type i = 0; i < size; ++i)
2261 vresult[i] = op(lvec[i], rvec[i]);
2262 }
2263
2264 return vresult;
2265 }
2266
2267 Result
2268 total() const
2269 {
2270 const VResult &vec = this->result();
2271 Result total = 0;
2272 for (off_type i = 0; i < size(); i++)
2273 total += vec[i];
2274 return total;
2275 }
2276
2277 virtual size_type
2278 size() const
2279 {
2280 size_type ls = l->size();
2281 size_type rs = r->size();
2282 if (ls == 1) {
2283 return rs;
2284 } else if (rs == 1) {
2285 return ls;
2286 } else {
2287 assert(ls == rs && "Node vector sizes are not equal");
2288 return ls;
2289 }
2290 }
2291
2292 virtual std::string
2293 str() const
2294 {
2295 return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
2296 }
2297};
2298
2299template <class Op>
2300class SumNode : public Node
2301{
2302 public:
2303 NodePtr l;
2304 mutable VResult vresult;
2305
2306 public:
2307 SumNode(NodePtr &p) : l(p), vresult(1) {}
2308
2309 const VResult &
2310 result() const
2311 {
2312 const VResult &lvec = l->result();
2313 size_type size = lvec.size();
2314 assert(size > 0);
2315
2316 vresult[0] = 0.0;
2317
2318 Op op;
2319 for (off_type i = 0; i < size; ++i)
2320 vresult[0] = op(vresult[0], lvec[i]);
2321
2322 return vresult;
2323 }
2324
2325 Result
2326 total() const
2327 {
2328 const VResult &lvec = l->result();
2329 size_type size = lvec.size();
2330 assert(size > 0);
2331
2332 Result vresult = 0.0;
2333
2334 Op op;
2335 for (off_type i = 0; i < size; ++i)
2336 vresult = op(vresult, lvec[i]);
2337
2338 return vresult;
2339 }
2340
2341 virtual size_type size() const { return 1; }
2342
2343 virtual std::string
2344 str() const
2345 {
2346 return csprintf("total(%s)", l->str());
2347 }
2348};
2349
2350
2351//////////////////////////////////////////////////////////////////////
2352//
2353// Visible Statistics Types
2354//
2355//////////////////////////////////////////////////////////////////////
2356/**
2357 * @defgroup VisibleStats "Statistic Types"
2358 * These are the statistics that are used in the simulator.
2359 * @{
2360 */
2361
2362/**
2363 * This is a simple scalar statistic, like a counter.
2364 * @sa Stat, ScalarBase, StatStor
2365 */
2366template<int N = 0>
2106 virtual const VResult &result() const { return data->result(); }
2107 virtual Result total() const { return data->total(); };
2108
2109 virtual size_type size() const { return data->size(); }
2110
2111 virtual std::string str() const { return data->name; }
2112};
2113
2114template <class T>
2115class ConstNode : public Node
2116{
2117 private:
2118 VResult vresult;
2119
2120 public:
2121 ConstNode(T s) : vresult(1, (Result)s) {}
2122 const VResult &result() const { return vresult; }
2123 virtual Result total() const { return vresult[0]; };
2124 virtual size_type size() const { return 1; }
2125 virtual std::string str() const { return to_string(vresult[0]); }
2126};
2127
2128template <class T>
2129class ConstVectorNode : public Node
2130{
2131 private:
2132 VResult vresult;
2133
2134 public:
2135 ConstVectorNode(const T &s) : vresult(s.begin(), s.end()) {}
2136 const VResult &result() const { return vresult; }
2137
2138 virtual Result
2139 total() const
2140 {
2141 size_type size = this->size();
2142 Result tmp = 0;
2143 for (off_type i = 0; i < size; i++)
2144 tmp += vresult[i];
2145 return tmp;
2146 }
2147
2148 virtual size_type size() const { return vresult.size(); }
2149 virtual std::string
2150 str() const
2151 {
2152 size_type size = this->size();
2153 std::string tmp = "(";
2154 for (off_type i = 0; i < size; i++)
2155 tmp += csprintf("%s ",to_string(vresult[i]));
2156 tmp += ")";
2157 return tmp;
2158 }
2159};
2160
2161template <class Op>
2162struct OpString;
2163
2164template<>
2165struct OpString<std::plus<Result> >
2166{
2167 static std::string str() { return "+"; }
2168};
2169
2170template<>
2171struct OpString<std::minus<Result> >
2172{
2173 static std::string str() { return "-"; }
2174};
2175
2176template<>
2177struct OpString<std::multiplies<Result> >
2178{
2179 static std::string str() { return "*"; }
2180};
2181
2182template<>
2183struct OpString<std::divides<Result> >
2184{
2185 static std::string str() { return "/"; }
2186};
2187
2188template<>
2189struct OpString<std::modulus<Result> >
2190{
2191 static std::string str() { return "%"; }
2192};
2193
2194template<>
2195struct OpString<std::negate<Result> >
2196{
2197 static std::string str() { return "-"; }
2198};
2199
2200template <class Op>
2201class UnaryNode : public Node
2202{
2203 public:
2204 NodePtr l;
2205 mutable VResult vresult;
2206
2207 public:
2208 UnaryNode(NodePtr &p) : l(p) {}
2209
2210 const VResult &
2211 result() const
2212 {
2213 const VResult &lvec = l->result();
2214 size_type size = lvec.size();
2215
2216 assert(size > 0);
2217
2218 vresult.resize(size);
2219 Op op;
2220 for (off_type i = 0; i < size; ++i)
2221 vresult[i] = op(lvec[i]);
2222
2223 return vresult;
2224 }
2225
2226 Result
2227 total() const
2228 {
2229 const VResult &vec = this->result();
2230 Result total = 0;
2231 for (off_type i = 0; i < size(); i++)
2232 total += vec[i];
2233 return total;
2234 }
2235
2236 virtual size_type size() const { return l->size(); }
2237
2238 virtual std::string
2239 str() const
2240 {
2241 return OpString<Op>::str() + l->str();
2242 }
2243};
2244
2245template <class Op>
2246class BinaryNode : public Node
2247{
2248 public:
2249 NodePtr l;
2250 NodePtr r;
2251 mutable VResult vresult;
2252
2253 public:
2254 BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}
2255
2256 const VResult &
2257 result() const
2258 {
2259 Op op;
2260 const VResult &lvec = l->result();
2261 const VResult &rvec = r->result();
2262
2263 assert(lvec.size() > 0 && rvec.size() > 0);
2264
2265 if (lvec.size() == 1 && rvec.size() == 1) {
2266 vresult.resize(1);
2267 vresult[0] = op(lvec[0], rvec[0]);
2268 } else if (lvec.size() == 1) {
2269 size_type size = rvec.size();
2270 vresult.resize(size);
2271 for (off_type i = 0; i < size; ++i)
2272 vresult[i] = op(lvec[0], rvec[i]);
2273 } else if (rvec.size() == 1) {
2274 size_type size = lvec.size();
2275 vresult.resize(size);
2276 for (off_type i = 0; i < size; ++i)
2277 vresult[i] = op(lvec[i], rvec[0]);
2278 } else if (rvec.size() == lvec.size()) {
2279 size_type size = rvec.size();
2280 vresult.resize(size);
2281 for (off_type i = 0; i < size; ++i)
2282 vresult[i] = op(lvec[i], rvec[i]);
2283 }
2284
2285 return vresult;
2286 }
2287
2288 Result
2289 total() const
2290 {
2291 const VResult &vec = this->result();
2292 Result total = 0;
2293 for (off_type i = 0; i < size(); i++)
2294 total += vec[i];
2295 return total;
2296 }
2297
2298 virtual size_type
2299 size() const
2300 {
2301 size_type ls = l->size();
2302 size_type rs = r->size();
2303 if (ls == 1) {
2304 return rs;
2305 } else if (rs == 1) {
2306 return ls;
2307 } else {
2308 assert(ls == rs && "Node vector sizes are not equal");
2309 return ls;
2310 }
2311 }
2312
2313 virtual std::string
2314 str() const
2315 {
2316 return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
2317 }
2318};
2319
2320template <class Op>
2321class SumNode : public Node
2322{
2323 public:
2324 NodePtr l;
2325 mutable VResult vresult;
2326
2327 public:
2328 SumNode(NodePtr &p) : l(p), vresult(1) {}
2329
2330 const VResult &
2331 result() const
2332 {
2333 const VResult &lvec = l->result();
2334 size_type size = lvec.size();
2335 assert(size > 0);
2336
2337 vresult[0] = 0.0;
2338
2339 Op op;
2340 for (off_type i = 0; i < size; ++i)
2341 vresult[0] = op(vresult[0], lvec[i]);
2342
2343 return vresult;
2344 }
2345
2346 Result
2347 total() const
2348 {
2349 const VResult &lvec = l->result();
2350 size_type size = lvec.size();
2351 assert(size > 0);
2352
2353 Result vresult = 0.0;
2354
2355 Op op;
2356 for (off_type i = 0; i < size; ++i)
2357 vresult = op(vresult, lvec[i]);
2358
2359 return vresult;
2360 }
2361
2362 virtual size_type size() const { return 1; }
2363
2364 virtual std::string
2365 str() const
2366 {
2367 return csprintf("total(%s)", l->str());
2368 }
2369};
2370
2371
2372//////////////////////////////////////////////////////////////////////
2373//
2374// Visible Statistics Types
2375//
2376//////////////////////////////////////////////////////////////////////
2377/**
2378 * @defgroup VisibleStats "Statistic Types"
2379 * These are the statistics that are used in the simulator.
2380 * @{
2381 */
2382
2383/**
2384 * This is a simple scalar statistic, like a counter.
2385 * @sa Stat, ScalarBase, StatStor
2386 */
2387template<int N = 0>
2367class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarStatData>
2388class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarInfo>
2368{
2369 public:
2370 /** The base implementation. */
2371 typedef ScalarBase<StatStor> Base;
2372
2373 Scalar()
2374 {
2375 this->doInit();
2376 }
2377
2378 /**
2379 * Sets the stat equal to the given value. Calls the base implementation
2380 * of operator=
2381 * @param v The new value.
2382 */
2383 template <typename U>
2384 void operator=(const U &v) { Base::operator=(v); }
2385};
2386
2389{
2390 public:
2391 /** The base implementation. */
2392 typedef ScalarBase<StatStor> Base;
2393
2394 Scalar()
2395 {
2396 this->doInit();
2397 }
2398
2399 /**
2400 * Sets the stat equal to the given value. Calls the base implementation
2401 * of operator=
2402 * @param v The new value.
2403 */
2404 template <typename U>
2405 void operator=(const U &v) { Base::operator=(v); }
2406};
2407
2387class Value : public Wrap<Value, ValueBase, ScalarStatData>
2408class Value : public Wrap<Value, ValueBase, ScalarInfo>
2388{
2389 public:
2390 /** The base implementation. */
2391 typedef ValueBase Base;
2392
2393 template <class T>
2394 Value &
2395 scalar(T &value)
2396 {
2397 Base::scalar(value);
2398 return *this;
2399 }
2400
2401 template <class T>
2402 Value &
2403 functor(T &func)
2404 {
2405 Base::functor(func);
2406 return *this;
2407 }
2408};
2409
2410/**
2411 * A stat that calculates the per tick average of a value.
2412 * @sa Stat, ScalarBase, AvgStor
2413 */
2414template<int N = 0>
2409{
2410 public:
2411 /** The base implementation. */
2412 typedef ValueBase Base;
2413
2414 template <class T>
2415 Value &
2416 scalar(T &value)
2417 {
2418 Base::scalar(value);
2419 return *this;
2420 }
2421
2422 template <class T>
2423 Value &
2424 functor(T &func)
2425 {
2426 Base::functor(func);
2427 return *this;
2428 }
2429};
2430
2431/**
2432 * A stat that calculates the per tick average of a value.
2433 * @sa Stat, ScalarBase, AvgStor
2434 */
2435template<int N = 0>
2415class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarStatData>
2436class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarInfo>
2416{
2417 public:
2418 /** The base implementation. */
2419 typedef ScalarBase<AvgStor> Base;
2420
2421 Average()
2422 {
2423 this->doInit();
2424 }
2425
2426 /**
2427 * Sets the stat equal to the given value. Calls the base implementation
2428 * of operator=
2429 * @param v The new value.
2430 */
2431 template <typename U>
2432 void
2433 operator=(const U &v)
2434 {
2435 Base::operator=(v);
2436 }
2437};
2438
2439/**
2440 * A vector of scalar stats.
2441 * @sa Stat, VectorBase, StatStor
2442 */
2443template<int N = 0>
2437{
2438 public:
2439 /** The base implementation. */
2440 typedef ScalarBase<AvgStor> Base;
2441
2442 Average()
2443 {
2444 this->doInit();
2445 }
2446
2447 /**
2448 * Sets the stat equal to the given value. Calls the base implementation
2449 * of operator=
2450 * @param v The new value.
2451 */
2452 template <typename U>
2453 void
2454 operator=(const U &v)
2455 {
2456 Base::operator=(v);
2457 }
2458};
2459
2460/**
2461 * A vector of scalar stats.
2462 * @sa Stat, VectorBase, StatStor
2463 */
2464template<int N = 0>
2444class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorStatData>
2465class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorInfo>
2445{
2446 public:
2447 /** The base implementation. */
2448 typedef ScalarBase<StatStor> Base;
2449
2450 /**
2451 * Set this vector to have the given size.
2452 * @param size The new size.
2453 * @return A reference to this stat.
2454 */
2455 Vector &
2456 init(size_type size)
2457 {
2458 this->doInit(size);
2459 return *this;
2460 }
2461};
2462
2463/**
2464 * A vector of Average stats.
2465 * @sa Stat, VectorBase, AvgStor
2466 */
2467template<int N = 0>
2468class AverageVector
2466{
2467 public:
2468 /** The base implementation. */
2469 typedef ScalarBase<StatStor> Base;
2470
2471 /**
2472 * Set this vector to have the given size.
2473 * @param size The new size.
2474 * @return A reference to this stat.
2475 */
2476 Vector &
2477 init(size_type size)
2478 {
2479 this->doInit(size);
2480 return *this;
2481 }
2482};
2483
2484/**
2485 * A vector of Average stats.
2486 * @sa Stat, VectorBase, AvgStor
2487 */
2488template<int N = 0>
2489class AverageVector
2469 : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorStatData>
2490 : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorInfo>
2470{
2471 public:
2472 /**
2473 * Set this vector to have the given size.
2474 * @param size The new size.
2475 * @return A reference to this stat.
2476 */
2477 AverageVector &
2478 init(size_type size)
2479 {
2480 this->doInit(size);
2481 return *this;
2482 }
2483};
2484
2485/**
2486 * A 2-Dimensional vecto of scalar stats.
2487 * @sa Stat, Vector2dBase, StatStor
2488 */
2489template<int N = 0>
2490class Vector2d
2491{
2492 public:
2493 /**
2494 * Set this vector to have the given size.
2495 * @param size The new size.
2496 * @return A reference to this stat.
2497 */
2498 AverageVector &
2499 init(size_type size)
2500 {
2501 this->doInit(size);
2502 return *this;
2503 }
2504};
2505
2506/**
2507 * A 2-Dimensional vecto of scalar stats.
2508 * @sa Stat, Vector2dBase, StatStor
2509 */
2510template<int N = 0>
2511class Vector2d
2491 : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dStatData>
2512 : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dInfo>
2492{
2493 public:
2494 Vector2d &
2495 init(size_type x, size_type y)
2496 {
2497 this->doInit(x, y);
2498 return *this;
2499 }
2500};
2501
2502/**
2503 * A simple distribution stat.
2504 * @sa Stat, DistBase, DistStor
2505 */
2506template<int N = 0>
2507class Distribution
2513{
2514 public:
2515 Vector2d &
2516 init(size_type x, size_type y)
2517 {
2518 this->doInit(x, y);
2519 return *this;
2520 }
2521};
2522
2523/**
2524 * A simple distribution stat.
2525 * @sa Stat, DistBase, DistStor
2526 */
2527template<int N = 0>
2528class Distribution
2508 : public Wrap<Distribution<N>, DistBase<DistStor>, DistStatData>
2529 : public Wrap<Distribution<N>, DistBase<DistStor>, DistInfo>
2509{
2510 public:
2511 /** Base implementation. */
2512 typedef DistBase<DistStor> Base;
2513 /** The Parameter type. */
2514 typedef DistStor::Params Params;
2515
2516 public:
2517 /**
2518 * Set the parameters of this distribution. @sa DistStor::Params
2519 * @param min The minimum value of the distribution.
2520 * @param max The maximum value of the distribution.
2521 * @param bkt The number of values in each bucket.
2522 * @return A reference to this distribution.
2523 */
2524 Distribution &
2525 init(Counter min, Counter max, Counter bkt)
2526 {
2527 this->params.min = min;
2528 this->params.max = max;
2529 this->params.bucket_size = bkt;
2530 this->params.size = (size_type)rint((max - min) / bkt + 1.0);
2531 this->doInit();
2532 return *this;
2533 }
2534};
2535
2536/**
2537 * Calculates the mean and variance of all the samples.
2538 * @sa Stat, DistBase, FancyStor
2539 */
2540template<int N = 0>
2541class StandardDeviation
2530{
2531 public:
2532 /** Base implementation. */
2533 typedef DistBase<DistStor> Base;
2534 /** The Parameter type. */
2535 typedef DistStor::Params Params;
2536
2537 public:
2538 /**
2539 * Set the parameters of this distribution. @sa DistStor::Params
2540 * @param min The minimum value of the distribution.
2541 * @param max The maximum value of the distribution.
2542 * @param bkt The number of values in each bucket.
2543 * @return A reference to this distribution.
2544 */
2545 Distribution &
2546 init(Counter min, Counter max, Counter bkt)
2547 {
2548 this->params.min = min;
2549 this->params.max = max;
2550 this->params.bucket_size = bkt;
2551 this->params.size = (size_type)rint((max - min) / bkt + 1.0);
2552 this->doInit();
2553 return *this;
2554 }
2555};
2556
2557/**
2558 * Calculates the mean and variance of all the samples.
2559 * @sa Stat, DistBase, FancyStor
2560 */
2561template<int N = 0>
2562class StandardDeviation
2542 : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistStatData>
2563 : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistInfo>
2543{
2544 public:
2545 /** The base implementation */
2546 typedef DistBase<DistStor> Base;
2547 /** The parameter type. */
2548 typedef DistStor::Params Params;
2549
2550 public:
2551 /**
2552 * Construct and initialize this distribution.
2553 */
2554 StandardDeviation()
2555 {
2556 this->doInit();
2557 }
2558};
2559
2560/**
2561 * Calculates the per tick mean and variance of the samples.
2562 * @sa Stat, DistBase, AvgFancy
2563 */
2564template<int N = 0>
2565class AverageDeviation
2564{
2565 public:
2566 /** The base implementation */
2567 typedef DistBase<DistStor> Base;
2568 /** The parameter type. */
2569 typedef DistStor::Params Params;
2570
2571 public:
2572 /**
2573 * Construct and initialize this distribution.
2574 */
2575 StandardDeviation()
2576 {
2577 this->doInit();
2578 }
2579};
2580
2581/**
2582 * Calculates the per tick mean and variance of the samples.
2583 * @sa Stat, DistBase, AvgFancy
2584 */
2585template<int N = 0>
2586class AverageDeviation
2566 : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistStatData>
2587 : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistInfo>
2567{
2568 public:
2569 /** The base implementation */
2570 typedef DistBase<DistStor> Base;
2571 /** The parameter type. */
2572 typedef DistStor::Params Params;
2573
2574 public:
2575 /**
2576 * Construct and initialize this distribution.
2577 */
2578 AverageDeviation()
2579 {
2580 this->doInit();
2581 }
2582};
2583
2584/**
2585 * A vector of distributions.
2586 * @sa Stat, VectorDistBase, DistStor
2587 */
2588template<int N = 0>
2589class VectorDistribution
2590 : public WrapVec<VectorDistribution<N>,
2591 VectorDistBase<DistStor>,
2588{
2589 public:
2590 /** The base implementation */
2591 typedef DistBase<DistStor> Base;
2592 /** The parameter type. */
2593 typedef DistStor::Params Params;
2594
2595 public:
2596 /**
2597 * Construct and initialize this distribution.
2598 */
2599 AverageDeviation()
2600 {
2601 this->doInit();
2602 }
2603};
2604
2605/**
2606 * A vector of distributions.
2607 * @sa Stat, VectorDistBase, DistStor
2608 */
2609template<int N = 0>
2610class VectorDistribution
2611 : public WrapVec<VectorDistribution<N>,
2612 VectorDistBase<DistStor>,
2592 VectorDistStatData>
2613 VectorDistInfo>
2593{
2594 public:
2595 /** The base implementation */
2596 typedef VectorDistBase<DistStor> Base;
2597 /** The parameter type. */
2598 typedef DistStor::Params Params;
2599
2600 public:
2601 /**
2602 * Initialize storage and parameters for this distribution.
2603 * @param size The size of the vector (the number of distributions).
2604 * @param min The minimum value of the distribution.
2605 * @param max The maximum value of the distribution.
2606 * @param bkt The number of values in each bucket.
2607 * @return A reference to this distribution.
2608 */
2609 VectorDistribution &
2610 init(size_type size, Counter min, Counter max, Counter bkt)
2611 {
2612 this->params.min = min;
2613 this->params.max = max;
2614 this->params.bucket_size = bkt;
2615 this->params.size = rint((max - min) / bkt + 1.0);
2616 this->doInit(size);
2617 return *this;
2618 }
2619};
2620
2621/**
2622 * This is a vector of StandardDeviation stats.
2623 * @sa Stat, VectorDistBase, FancyStor
2624 */
2625template<int N = 0>
2626class VectorStandardDeviation
2627 : public WrapVec<VectorStandardDeviation<N>,
2628 VectorDistBase<FancyStor>,
2614{
2615 public:
2616 /** The base implementation */
2617 typedef VectorDistBase<DistStor> Base;
2618 /** The parameter type. */
2619 typedef DistStor::Params Params;
2620
2621 public:
2622 /**
2623 * Initialize storage and parameters for this distribution.
2624 * @param size The size of the vector (the number of distributions).
2625 * @param min The minimum value of the distribution.
2626 * @param max The maximum value of the distribution.
2627 * @param bkt The number of values in each bucket.
2628 * @return A reference to this distribution.
2629 */
2630 VectorDistribution &
2631 init(size_type size, Counter min, Counter max, Counter bkt)
2632 {
2633 this->params.min = min;
2634 this->params.max = max;
2635 this->params.bucket_size = bkt;
2636 this->params.size = rint((max - min) / bkt + 1.0);
2637 this->doInit(size);
2638 return *this;
2639 }
2640};
2641
2642/**
2643 * This is a vector of StandardDeviation stats.
2644 * @sa Stat, VectorDistBase, FancyStor
2645 */
2646template<int N = 0>
2647class VectorStandardDeviation
2648 : public WrapVec<VectorStandardDeviation<N>,
2649 VectorDistBase<FancyStor>,
2629 VectorDistStatData>
2650 VectorDistInfo>
2630{
2631 public:
2632 /** The base implementation */
2633 typedef VectorDistBase<FancyStor> Base;
2634 /** The parameter type. */
2635 typedef DistStor::Params Params;
2636
2637 public:
2638 /**
2639 * Initialize storage for this distribution.
2640 * @param size The size of the vector.
2641 * @return A reference to this distribution.
2642 */
2643 VectorStandardDeviation &
2644 init(size_type size)
2645 {
2646 this->doInit(size);
2647 return *this;
2648 }
2649};
2650
2651/**
2652 * This is a vector of AverageDeviation stats.
2653 * @sa Stat, VectorDistBase, AvgFancy
2654 */
2655template<int N = 0>
2656class VectorAverageDeviation
2657 : public WrapVec<VectorAverageDeviation<N>,
2658 VectorDistBase<AvgFancy>,
2651{
2652 public:
2653 /** The base implementation */
2654 typedef VectorDistBase<FancyStor> Base;
2655 /** The parameter type. */
2656 typedef DistStor::Params Params;
2657
2658 public:
2659 /**
2660 * Initialize storage for this distribution.
2661 * @param size The size of the vector.
2662 * @return A reference to this distribution.
2663 */
2664 VectorStandardDeviation &
2665 init(size_type size)
2666 {
2667 this->doInit(size);
2668 return *this;
2669 }
2670};
2671
2672/**
2673 * This is a vector of AverageDeviation stats.
2674 * @sa Stat, VectorDistBase, AvgFancy
2675 */
2676template<int N = 0>
2677class VectorAverageDeviation
2678 : public WrapVec<VectorAverageDeviation<N>,
2679 VectorDistBase<AvgFancy>,
2659 VectorDistStatData>
2680 VectorDistInfo>
2660{
2661 public:
2662 /** The base implementation */
2663 typedef VectorDistBase<AvgFancy> Base;
2664 /** The parameter type. */
2665 typedef DistStor::Params Params;
2666
2667 public:
2668 /**
2669 * Initialize storage for this distribution.
2670 * @param size The size of the vector.
2671 * @return A reference to this distribution.
2672 */
2673 VectorAverageDeviation &
2674 init(size_type size)
2675 {
2676 this->doInit(size);
2677 return *this;
2678 }
2679};
2680
2681/**
2682 * A formula for statistics that is calculated when printed. A formula is
2683 * stored as a tree of Nodes that represent the equation to calculate.
2684 * @sa Stat, ScalarStat, VectorStat, Node, Temp
2685 */
2681{
2682 public:
2683 /** The base implementation */
2684 typedef VectorDistBase<AvgFancy> Base;
2685 /** The parameter type. */
2686 typedef DistStor::Params Params;
2687
2688 public:
2689 /**
2690 * Initialize storage for this distribution.
2691 * @param size The size of the vector.
2692 * @return A reference to this distribution.
2693 */
2694 VectorAverageDeviation &
2695 init(size_type size)
2696 {
2697 this->doInit(size);
2698 return *this;
2699 }
2700};
2701
2702/**
2703 * A formula for statistics that is calculated when printed. A formula is
2704 * stored as a tree of Nodes that represent the equation to calculate.
2705 * @sa Stat, ScalarStat, VectorStat, Node, Temp
2706 */
2686class FormulaBase : public DataAccess
2707class FormulaBase : public InfoAccess
2687{
2688 protected:
2689 /** The root of the tree which represents the Formula */
2690 NodePtr root;
2691 friend class Temp;
2692
2693 public:
2694 /**
2695 * Return the result of the Fomula in a vector. If there were no Vector
2696 * components to the Formula, then the vector is size 1. If there were,
2697 * like x/y with x being a vector of size 3, then the result returned will
2698 * be x[0]/y, x[1]/y, x[2]/y, respectively.
2699 * @return The result vector.
2700 */
2701 void result(VResult &vec) const;
2702
2703 /**
2704 * Return the total Formula result. If there is a Vector
2705 * component to this Formula, then this is the result of the
2706 * Formula if the formula is applied after summing all the
2707 * components of the Vector. For example, if Formula is x/y where
2708 * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If
2709 * there is no Vector component, total() returns the same value as
2710 * the first entry in the VResult val() returns.
2711 * @return The total of the result vector.
2712 */
2713 Result total() const;
2714
2715 /**
2716 * Return the number of elements in the tree.
2717 */
2718 size_type size() const;
2719
2720 bool check() const { return true; }
2721
2722 /**
2723 * Formulas don't need to be reset
2724 */
2725 void reset();
2726
2727 /**
2728 *
2729 */
2730 bool zero() const;
2731
2732 /**
2733 *
2734 */
2708{
2709 protected:
2710 /** The root of the tree which represents the Formula */
2711 NodePtr root;
2712 friend class Temp;
2713
2714 public:
2715 /**
2716 * Return the result of the Fomula in a vector. If there were no Vector
2717 * components to the Formula, then the vector is size 1. If there were,
2718 * like x/y with x being a vector of size 3, then the result returned will
2719 * be x[0]/y, x[1]/y, x[2]/y, respectively.
2720 * @return The result vector.
2721 */
2722 void result(VResult &vec) const;
2723
2724 /**
2725 * Return the total Formula result. If there is a Vector
2726 * component to this Formula, then this is the result of the
2727 * Formula if the formula is applied after summing all the
2728 * components of the Vector. For example, if Formula is x/y where
2729 * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If
2730 * there is no Vector component, total() returns the same value as
2731 * the first entry in the VResult val() returns.
2732 * @return The total of the result vector.
2733 */
2734 Result total() const;
2735
2736 /**
2737 * Return the number of elements in the tree.
2738 */
2739 size_type size() const;
2740
2741 bool check() const { return true; }
2742
2743 /**
2744 * Formulas don't need to be reset
2745 */
2746 void reset();
2747
2748 /**
2749 *
2750 */
2751 bool zero() const;
2752
2753 /**
2754 *
2755 */
2735 void update(StatData *);
2756 void update(Info *);
2736
2737 std::string str() const;
2738};
2739
2757
2758 std::string str() const;
2759};
2760
2740class FormulaData : public VectorData
2761class FormulaInfoBase : public VectorInfoBase
2741{
2742 public:
2743 virtual std::string str() const = 0;
2744 virtual bool check() const { return true; }
2745};
2746
2747template <class Stat>
2762{
2763 public:
2764 virtual std::string str() const = 0;
2765 virtual bool check() const { return true; }
2766};
2767
2768template <class Stat>
2748class FormulaStatData : public FormulaData
2769class FormulaInfo : public FormulaInfoBase
2749{
2750 protected:
2751 Stat &s;
2752 mutable VResult vec;
2753 mutable VCounter cvec;
2754
2755 public:
2770{
2771 protected:
2772 Stat &s;
2773 mutable VResult vec;
2774 mutable VCounter cvec;
2775
2776 public:
2756 FormulaStatData(Stat &stat) : s(stat) {}
2777 FormulaInfo(Stat &stat) : s(stat) {}
2757
2758 virtual bool zero() const { return s.zero(); }
2759 virtual void reset() { s.reset(); }
2760
2761 virtual size_type size() const { return s.size(); }
2762
2763 virtual const VResult &
2764 result() const
2765 {
2766 s.result(vec);
2767 return vec;
2768 }
2769 virtual Result total() const { return s.total(); }
2770 virtual VCounter &value() const { return cvec; }
2771
2772 virtual void
2773 visit(Visit &visitor)
2774 {
2775 update();
2776 s.update(this);
2777 visitor.visit(*this);
2778 }
2779
2780 virtual std::string str() const { return s.str(); }
2781};
2782
2783class Temp;
2784class Formula
2785 : public WrapVec<Formula,
2786 FormulaBase,
2778
2779 virtual bool zero() const { return s.zero(); }
2780 virtual void reset() { s.reset(); }
2781
2782 virtual size_type size() const { return s.size(); }
2783
2784 virtual const VResult &
2785 result() const
2786 {
2787 s.result(vec);
2788 return vec;
2789 }
2790 virtual Result total() const { return s.total(); }
2791 virtual VCounter &value() const { return cvec; }
2792
2793 virtual void
2794 visit(Visit &visitor)
2795 {
2796 update();
2797 s.update(this);
2798 visitor.visit(*this);
2799 }
2800
2801 virtual std::string str() const { return s.str(); }
2802};
2803
2804class Temp;
2805class Formula
2806 : public WrapVec<Formula,
2807 FormulaBase,
2787 FormulaStatData>
2808 FormulaInfo>
2788{
2789 public:
2790 /**
2791 * Create and initialize thie formula, and register it with the database.
2792 */
2793 Formula();
2794
2795 /**
2796 * Create a formula with the given root node, register it with the
2797 * database.
2798 * @param r The root of the expression tree.
2799 */
2800 Formula(Temp r);
2801
2802 /**
2803 * Set an unitialized Formula to the given root.
2804 * @param r The root of the expression tree.
2805 * @return a reference to this formula.
2806 */
2807 const Formula &operator=(Temp r);
2808
2809 /**
2810 * Add the given tree to the existing one.
2811 * @param r The root of the expression tree.
2812 * @return a reference to this formula.
2813 */
2814 const Formula &operator+=(Temp r);
2815};
2816
2817class FormulaNode : public Node
2818{
2819 private:
2820 const Formula &formula;
2821 mutable VResult vec;
2822
2823 public:
2824 FormulaNode(const Formula &f) : formula(f) {}
2825
2826 virtual size_type size() const { return formula.size(); }
2827 virtual const VResult &result() const { formula.result(vec); return vec; }
2828 virtual Result total() const { return formula.total(); }
2829
2830 virtual std::string str() const { return formula.str(); }
2831};
2832
2833/**
2834 * Helper class to construct formula node trees.
2835 */
2836class Temp
2837{
2838 protected:
2839 /**
2840 * Pointer to a Node object.
2841 */
2842 NodePtr node;
2843
2844 public:
2845 /**
2846 * Copy the given pointer to this class.
2847 * @param n A pointer to a Node object to copy.
2848 */
2849 Temp(NodePtr n) : node(n) { }
2850
2851 /**
2852 * Return the node pointer.
2853 * @return the node pointer.
2854 */
2855 operator NodePtr&() { return node;}
2856
2857 public:
2858 /**
2859 * Create a new ScalarStatNode.
2860 * @param s The ScalarStat to place in a node.
2861 */
2862 template <int N>
2863 Temp(const Scalar<N> &s)
2809{
2810 public:
2811 /**
2812 * Create and initialize thie formula, and register it with the database.
2813 */
2814 Formula();
2815
2816 /**
2817 * Create a formula with the given root node, register it with the
2818 * database.
2819 * @param r The root of the expression tree.
2820 */
2821 Formula(Temp r);
2822
2823 /**
2824 * Set an unitialized Formula to the given root.
2825 * @param r The root of the expression tree.
2826 * @return a reference to this formula.
2827 */
2828 const Formula &operator=(Temp r);
2829
2830 /**
2831 * Add the given tree to the existing one.
2832 * @param r The root of the expression tree.
2833 * @return a reference to this formula.
2834 */
2835 const Formula &operator+=(Temp r);
2836};
2837
2838class FormulaNode : public Node
2839{
2840 private:
2841 const Formula &formula;
2842 mutable VResult vec;
2843
2844 public:
2845 FormulaNode(const Formula &f) : formula(f) {}
2846
2847 virtual size_type size() const { return formula.size(); }
2848 virtual const VResult &result() const { formula.result(vec); return vec; }
2849 virtual Result total() const { return formula.total(); }
2850
2851 virtual std::string str() const { return formula.str(); }
2852};
2853
2854/**
2855 * Helper class to construct formula node trees.
2856 */
2857class Temp
2858{
2859 protected:
2860 /**
2861 * Pointer to a Node object.
2862 */
2863 NodePtr node;
2864
2865 public:
2866 /**
2867 * Copy the given pointer to this class.
2868 * @param n A pointer to a Node object to copy.
2869 */
2870 Temp(NodePtr n) : node(n) { }
2871
2872 /**
2873 * Return the node pointer.
2874 * @return the node pointer.
2875 */
2876 operator NodePtr&() { return node;}
2877
2878 public:
2879 /**
2880 * Create a new ScalarStatNode.
2881 * @param s The ScalarStat to place in a node.
2882 */
2883 template <int N>
2884 Temp(const Scalar<N> &s)
2864 : node(new ScalarStatNode(s.statData()))
2885 : node(new ScalarStatNode(s.info()))
2865 { }
2866
2867 /**
2868 * Create a new ScalarStatNode.
2869 * @param s The ScalarStat to place in a node.
2870 */
2871 Temp(const Value &s)
2886 { }
2887
2888 /**
2889 * Create a new ScalarStatNode.
2890 * @param s The ScalarStat to place in a node.
2891 */
2892 Temp(const Value &s)
2872 : node(new ScalarStatNode(s.statData()))
2893 : node(new ScalarStatNode(s.info()))
2873 { }
2874
2875 /**
2876 * Create a new ScalarStatNode.
2877 * @param s The ScalarStat to place in a node.
2878 */
2879 template <int N>
2880 Temp(const Average<N> &s)
2894 { }
2895
2896 /**
2897 * Create a new ScalarStatNode.
2898 * @param s The ScalarStat to place in a node.
2899 */
2900 template <int N>
2901 Temp(const Average<N> &s)
2881 : node(new ScalarStatNode(s.statData()))
2902 : node(new ScalarStatNode(s.info()))
2882 { }
2883
2884 /**
2885 * Create a new VectorStatNode.
2886 * @param s The VectorStat to place in a node.
2887 */
2888 template <int N>
2889 Temp(const Vector<N> &s)
2903 { }
2904
2905 /**
2906 * Create a new VectorStatNode.
2907 * @param s The VectorStat to place in a node.
2908 */
2909 template <int N>
2910 Temp(const Vector<N> &s)
2890 : node(new VectorStatNode(s.statData()))
2911 : node(new VectorStatNode(s.info()))
2891 { }
2892
2893 /**
2894 *
2895 */
2896 Temp(const Formula &f)
2897 : node(new FormulaNode(f))
2898 { }
2899
2900 /**
2901 * Create a new ScalarProxyNode.
2902 * @param p The ScalarProxy to place in a node.
2903 */
2904 template <class Stat>
2905 Temp(const ScalarProxy<Stat> &p)
2906 : node(new ScalarProxyNode<Stat>(p))
2907 { }
2908
2909 /**
2910 * Create a ConstNode
2911 * @param value The value of the const node.
2912 */
2913 Temp(signed char value)
2914 : node(new ConstNode<signed char>(value))
2915 { }
2916
2917 /**
2918 * Create a ConstNode
2919 * @param value The value of the const node.
2920 */
2921 Temp(unsigned char value)
2922 : node(new ConstNode<unsigned char>(value))
2923 { }
2924
2925 /**
2926 * Create a ConstNode
2927 * @param value The value of the const node.
2928 */
2929 Temp(signed short value)
2930 : node(new ConstNode<signed short>(value))
2931 { }
2932
2933 /**
2934 * Create a ConstNode
2935 * @param value The value of the const node.
2936 */
2937 Temp(unsigned short value)
2938 : node(new ConstNode<unsigned short>(value))
2939 { }
2940
2941 /**
2942 * Create a ConstNode
2943 * @param value The value of the const node.
2944 */
2945 Temp(signed int value)
2946 : node(new ConstNode<signed int>(value))
2947 { }
2948
2949 /**
2950 * Create a ConstNode
2951 * @param value The value of the const node.
2952 */
2953 Temp(unsigned int value)
2954 : node(new ConstNode<unsigned int>(value))
2955 { }
2956
2957 /**
2958 * Create a ConstNode
2959 * @param value The value of the const node.
2960 */
2961 Temp(signed long value)
2962 : node(new ConstNode<signed long>(value))
2963 { }
2964
2965 /**
2966 * Create a ConstNode
2967 * @param value The value of the const node.
2968 */
2969 Temp(unsigned long value)
2970 : node(new ConstNode<unsigned long>(value))
2971 { }
2972
2973 /**
2974 * Create a ConstNode
2975 * @param value The value of the const node.
2976 */
2977 Temp(signed long long value)
2978 : node(new ConstNode<signed long long>(value))
2979 { }
2980
2981 /**
2982 * Create a ConstNode
2983 * @param value The value of the const node.
2984 */
2985 Temp(unsigned long long value)
2986 : node(new ConstNode<unsigned long long>(value))
2987 { }
2988
2989 /**
2990 * Create a ConstNode
2991 * @param value The value of the const node.
2992 */
2993 Temp(float value)
2994 : node(new ConstNode<float>(value))
2995 { }
2996
2997 /**
2998 * Create a ConstNode
2999 * @param value The value of the const node.
3000 */
3001 Temp(double value)
3002 : node(new ConstNode<double>(value))
3003 { }
3004};
3005
3006
3007/**
3008 * @}
3009 */
3010
3011void check();
3012void dump();
3013void reset();
3014void registerResetCallback(Callback *cb);
3015
3016inline Temp
3017operator+(Temp l, Temp r)
3018{
3019 return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
3020}
3021
3022inline Temp
3023operator-(Temp l, Temp r)
3024{
3025 return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
3026}
3027
3028inline Temp
3029operator*(Temp l, Temp r)
3030{
3031 return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
3032}
3033
3034inline Temp
3035operator/(Temp l, Temp r)
3036{
3037 return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
3038}
3039
3040inline Temp
3041operator-(Temp l)
3042{
3043 return NodePtr(new UnaryNode<std::negate<Result> >(l));
3044}
3045
3046template <typename T>
3047inline Temp
3048constant(T val)
3049{
3050 return NodePtr(new ConstNode<T>(val));
3051}
3052
3053template <typename T>
3054inline Temp
3055constantVector(T val)
3056{
3057 return NodePtr(new ConstVectorNode<T>(val));
3058}
3059
3060inline Temp
3061sum(Temp val)
3062{
3063 return NodePtr(new SumNode<std::plus<Result> >(val));
3064}
3065
3066/* namespace Stats */ }
3067
3068#endif // __BASE_STATISTICS_HH__
2912 { }
2913
2914 /**
2915 *
2916 */
2917 Temp(const Formula &f)
2918 : node(new FormulaNode(f))
2919 { }
2920
2921 /**
2922 * Create a new ScalarProxyNode.
2923 * @param p The ScalarProxy to place in a node.
2924 */
2925 template <class Stat>
2926 Temp(const ScalarProxy<Stat> &p)
2927 : node(new ScalarProxyNode<Stat>(p))
2928 { }
2929
2930 /**
2931 * Create a ConstNode
2932 * @param value The value of the const node.
2933 */
2934 Temp(signed char value)
2935 : node(new ConstNode<signed char>(value))
2936 { }
2937
2938 /**
2939 * Create a ConstNode
2940 * @param value The value of the const node.
2941 */
2942 Temp(unsigned char value)
2943 : node(new ConstNode<unsigned char>(value))
2944 { }
2945
2946 /**
2947 * Create a ConstNode
2948 * @param value The value of the const node.
2949 */
2950 Temp(signed short value)
2951 : node(new ConstNode<signed short>(value))
2952 { }
2953
2954 /**
2955 * Create a ConstNode
2956 * @param value The value of the const node.
2957 */
2958 Temp(unsigned short value)
2959 : node(new ConstNode<unsigned short>(value))
2960 { }
2961
2962 /**
2963 * Create a ConstNode
2964 * @param value The value of the const node.
2965 */
2966 Temp(signed int value)
2967 : node(new ConstNode<signed int>(value))
2968 { }
2969
2970 /**
2971 * Create a ConstNode
2972 * @param value The value of the const node.
2973 */
2974 Temp(unsigned int value)
2975 : node(new ConstNode<unsigned int>(value))
2976 { }
2977
2978 /**
2979 * Create a ConstNode
2980 * @param value The value of the const node.
2981 */
2982 Temp(signed long value)
2983 : node(new ConstNode<signed long>(value))
2984 { }
2985
2986 /**
2987 * Create a ConstNode
2988 * @param value The value of the const node.
2989 */
2990 Temp(unsigned long value)
2991 : node(new ConstNode<unsigned long>(value))
2992 { }
2993
2994 /**
2995 * Create a ConstNode
2996 * @param value The value of the const node.
2997 */
2998 Temp(signed long long value)
2999 : node(new ConstNode<signed long long>(value))
3000 { }
3001
3002 /**
3003 * Create a ConstNode
3004 * @param value The value of the const node.
3005 */
3006 Temp(unsigned long long value)
3007 : node(new ConstNode<unsigned long long>(value))
3008 { }
3009
3010 /**
3011 * Create a ConstNode
3012 * @param value The value of the const node.
3013 */
3014 Temp(float value)
3015 : node(new ConstNode<float>(value))
3016 { }
3017
3018 /**
3019 * Create a ConstNode
3020 * @param value The value of the const node.
3021 */
3022 Temp(double value)
3023 : node(new ConstNode<double>(value))
3024 { }
3025};
3026
3027
3028/**
3029 * @}
3030 */
3031
3032void check();
3033void dump();
3034void reset();
3035void registerResetCallback(Callback *cb);
3036
3037inline Temp
3038operator+(Temp l, Temp r)
3039{
3040 return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
3041}
3042
3043inline Temp
3044operator-(Temp l, Temp r)
3045{
3046 return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
3047}
3048
3049inline Temp
3050operator*(Temp l, Temp r)
3051{
3052 return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
3053}
3054
3055inline Temp
3056operator/(Temp l, Temp r)
3057{
3058 return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
3059}
3060
3061inline Temp
3062operator-(Temp l)
3063{
3064 return NodePtr(new UnaryNode<std::negate<Result> >(l));
3065}
3066
3067template <typename T>
3068inline Temp
3069constant(T val)
3070{
3071 return NodePtr(new ConstNode<T>(val));
3072}
3073
3074template <typename T>
3075inline Temp
3076constantVector(T val)
3077{
3078 return NodePtr(new ConstVectorNode<T>(val));
3079}
3080
3081inline Temp
3082sum(Temp val)
3083{
3084 return NodePtr(new SumNode<std::plus<Result> >(val));
3085}
3086
3087/* namespace Stats */ }
3088
3089#endif // __BASE_STATISTICS_HH__