statistics.hh (5598:345ef3bda3d2) statistics.hh (5599:5bad83cddb8c)
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
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
89{
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. */
99 const StatData *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
106 StatData();
107 virtual ~StatData();
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 */
141 static bool less(StatData *stat1, StatData *stat2);
142};
143
144class ScalarData : public StatData
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>
154class ScalarStatData : public ScalarData
155{
156 protected:
157 Stat &s;
158
159 public:
160 ScalarStatData(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
170struct VectorData : public StatData
171{
172 /** Names and descriptions of subfields. */
173 mutable std::vector<std::string> subnames;
174 mutable std::vector<std::string> subdescs;
175
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
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
89{
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. */
99 const StatData *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
106 StatData();
107 virtual ~StatData();
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 */
141 static bool less(StatData *stat1, StatData *stat2);
142};
143
144class ScalarData : public StatData
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>
154class ScalarStatData : public ScalarData
155{
156 protected:
157 Stat &s;
158
159 public:
160 ScalarStatData(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
170struct VectorData : public StatData
171{
172 /** Names and descriptions of subfields. */
173 mutable std::vector<std::string> subnames;
174 mutable std::vector<std::string> subdescs;
175
176 virtual size_t size() const = 0;
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()) {
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 int s = size();
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>
196class VectorStatData : public VectorData
197{
198 protected:
199 Stat &s;
200 mutable VCounter cvec;
201 mutable VResult rvec;
202
203 public:
204 VectorStatData(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
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>
196class VectorStatData : public VectorData
197{
198 protected:
199 Stat &s;
200 mutable VCounter cvec;
201 mutable VResult rvec;
202
203 public:
204 VectorStatData(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_t size() const { return s.size(); }
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
237struct DistDataData
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;
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
237struct DistDataData
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 int size;
251 size_type size;
252 bool fancy;
253};
254
255struct DistData : public StatData
256{
257 /** Local storage for the entry values, used for printing. */
258 DistDataData data;
259};
260
261template <class Stat>
262class DistStatData : public DistData
263{
264 protected:
265 Stat &s;
266
267 public:
268 DistStatData(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
282struct VectorDistData : public StatData
283{
284 std::vector<DistDataData> data;
285
286 /** Names and descriptions of subfields. */
287 mutable std::vector<std::string> subnames;
288 mutable std::vector<std::string> subdescs;
289
290 /** Local storage for the entry values, used for printing. */
291 mutable VResult rvec;
292
252 bool fancy;
253};
254
255struct DistData : public StatData
256{
257 /** Local storage for the entry values, used for printing. */
258 DistDataData data;
259};
260
261template <class Stat>
262class DistStatData : public DistData
263{
264 protected:
265 Stat &s;
266
267 public:
268 DistStatData(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
282struct VectorDistData : public StatData
283{
284 std::vector<DistDataData> data;
285
286 /** Names and descriptions of subfields. */
287 mutable std::vector<std::string> subnames;
288 mutable std::vector<std::string> subdescs;
289
290 /** Local storage for the entry values, used for printing. */
291 mutable VResult rvec;
292
293 virtual size_t size() const = 0;
293 virtual size_type size() const = 0;
294
295 void
296 update()
297 {
294
295 void
296 update()
297 {
298 int s = size();
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>
308class VectorDistStatData : public VectorDistData
309{
310 protected:
311 Stat &s;
312
313 public:
314 VectorDistStatData(Stat &stat) : s(stat) {}
315
316 virtual bool check() const { return s.check(); }
317 virtual void reset() { s.reset(); }
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>
308class VectorDistStatData : public VectorDistData
309{
310 protected:
311 Stat &s;
312
313 public:
314 VectorDistStatData(Stat &stat) : s(stat) {}
315
316 virtual bool check() const { return s.check(); }
317 virtual void reset() { s.reset(); }
318 virtual size_t size() const { return s.size(); }
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
330struct Vector2dData : public StatData
331{
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;
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
330struct Vector2dData : public StatData
331{
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 int x;
340 mutable int y;
339 mutable size_type x;
340 mutable size_type y;
341
342 void
343 update()
344 {
345 if (subnames.size() < x)
346 subnames.resize(x);
347 }
348};
349
350template <class Stat>
351class Vector2dStatData : public Vector2dData
352{
353 protected:
354 Stat &s;
355
356 public:
357 Vector2dStatData(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
372class DataAccess
373{
374 protected:
375 StatData *find() const;
376 void map(StatData *data);
377
378 StatData *statData();
379 const StatData *statData() const;
380
381 void setInit();
382 void setPrint();
383};
384
385template <class Parent, class Child, template <class> class Data>
386class Wrap : public Child
387{
388 protected:
389 Parent &self() { return *reinterpret_cast<Parent *>(this); }
390
391 protected:
392 Data<Child> *
393 statData()
394 {
395 StatData *__data = DataAccess::statData();
396 Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
397 assert(ptr);
398 return ptr;
399 }
400
401 public:
402 const Data<Child> *
403 statData() const
404 {
405 const StatData *__data = DataAccess::statData();
406 const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
407 assert(ptr);
408 return ptr;
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 {
425 this->map(new Data<Child>(*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 {
436 Data<Child> *data = this->statData();
437 data->name = _name;
438 this->setPrint();
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 {
451 this->statData()->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 {
463 this->statData()->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 {
475 this->statData()->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 {
489 this->statData()->prereq = prereq.statData();
490 return this->self();
491 }
492};
493
494template <class Parent, class Child, template <class Child> class Data>
495class WrapVec : public Wrap<Parent, Child, Data>
496{
497 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 &
341
342 void
343 update()
344 {
345 if (subnames.size() < x)
346 subnames.resize(x);
347 }
348};
349
350template <class Stat>
351class Vector2dStatData : public Vector2dData
352{
353 protected:
354 Stat &s;
355
356 public:
357 Vector2dStatData(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
372class DataAccess
373{
374 protected:
375 StatData *find() const;
376 void map(StatData *data);
377
378 StatData *statData();
379 const StatData *statData() const;
380
381 void setInit();
382 void setPrint();
383};
384
385template <class Parent, class Child, template <class> class Data>
386class Wrap : public Child
387{
388 protected:
389 Parent &self() { return *reinterpret_cast<Parent *>(this); }
390
391 protected:
392 Data<Child> *
393 statData()
394 {
395 StatData *__data = DataAccess::statData();
396 Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
397 assert(ptr);
398 return ptr;
399 }
400
401 public:
402 const Data<Child> *
403 statData() const
404 {
405 const StatData *__data = DataAccess::statData();
406 const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
407 assert(ptr);
408 return ptr;
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 {
425 this->map(new Data<Child>(*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 {
436 Data<Child> *data = this->statData();
437 data->name = _name;
438 this->setPrint();
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 {
451 this->statData()->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 {
463 this->statData()->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 {
475 this->statData()->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 {
489 this->statData()->prereq = prereq.statData();
490 return this->self();
491 }
492};
493
494template <class Parent, class Child, template <class Child> class Data>
495class WrapVec : public Wrap<Parent, Child, Data>
496{
497 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(int index, const std::string &name)
509 subname(off_type index, const std::string &name)
510 {
511 std::vector<std::string> &subn = this->statData()->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 &
510 {
511 std::vector<std::string> &subn = this->statData()->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(int index, const std::string &desc)
526 subdesc(off_type index, const std::string &desc)
527 {
528 std::vector<std::string> &subd = this->statData()->subdescs;
529 if (subd.size() <= index)
530 subd.resize(index + 1);
531 subd[index] = desc;
532
533 return this->self();
534 }
535
536};
537
538template <class Parent, class Child, template <class Child> class Data>
539class WrapVec2d : public WrapVec<Parent, Child, Data>
540{
541 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 {
549 Data<Child> *data = this->statData();
550 data->y_subnames.resize(this->y);
527 {
528 std::vector<std::string> &subd = this->statData()->subdescs;
529 if (subd.size() <= index)
530 subd.resize(index + 1);
531 subd[index] = desc;
532
533 return this->self();
534 }
535
536};
537
538template <class Parent, class Child, template <class Child> class Data>
539class WrapVec2d : public WrapVec<Parent, Child, Data>
540{
541 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 {
549 Data<Child> *data = this->statData();
550 data->y_subnames.resize(this->y);
551 for (int i = 0; i < this->y; ++i)
551 for (off_type i = 0; i < this->y; ++i)
552 data->y_subnames[i] = names[i];
553 return this->self();
554 }
555
556 Parent &
552 data->y_subnames[i] = names[i];
553 return this->self();
554 }
555
556 Parent &
557 ysubname(int index, const std::string subname)
557 ysubname(off_type index, const std::string subname)
558 {
559 Data<Child> *data = this->statData();
560 assert(index < this->y);
561 data->y_subnames.resize(this->y);
562 data->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 */
576struct 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 */
641struct 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
668 set(Counter val, Params &p) {
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>
729class ScalarBase : public DataAccess
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 */
558 {
559 Data<Child> *data = this->statData();
560 assert(index < this->y);
561 data->y_subnames.resize(this->y);
562 data->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 */
576struct 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 */
641struct 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
668 set(Counter val, Params &p) {
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>
729class ScalarBase : public DataAccess
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_t size() const { return 1; }
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
854class ProxyData : public ScalarData
855{
856 public:
857 virtual void visit(Visit &visitor) { visitor.visit(*this); }
858 virtual std::string str() const { return to_string(value()); }
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
854class ProxyData : public ScalarData
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_t size() const { return 1; }
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>
866class ValueProxy : public ProxyData
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>
879class FunctorProxy : public ProxyData
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
891class ValueBase : public DataAccess
892{
893 private:
894 ProxyData *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(); };
860 virtual bool zero() const { return value() == 0; }
861 virtual bool check() const { return true; }
862 virtual void reset() { }
863};
864
865template <class T>
866class ValueProxy : public ProxyData
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>
879class FunctorProxy : public ProxyData
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
891class ValueBase : public DataAccess
892{
893 private:
894 ProxyData *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_t size() const { return proxy->size(); }
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. */
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 int index;
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 */
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, int i)
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 &
986 operator=(const ScalarProxy &sp) {
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 */
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 &
986 operator=(const ScalarProxy &sp) {
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_t size() const { return 1; }
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 {
1061 return csprintf("%s[%d]", stat->statData()->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>
1070class VectorBase : public DataAccess
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;
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 {
1061 return csprintf("%s[%d]", stat->statData()->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>
1070class VectorBase : public DataAccess
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_t _size;
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 */
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(int index) { return &storage[index]; }
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 */
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(int index) const { return &storage[index]; }
1104 const Storage *data(off_type index) const { return &storage[index]; }
1105
1106 void
1105
1106 void
1107 doInit(int s)
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
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 (int i = 0; i < _size; ++i)
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());
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 (int i = 0; i < size(); ++i)
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());
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 (int i = 0; i < size(); ++i)
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;
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 (int i = 0; i < size(); ++i)
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 */
1152 total += data(i)->result(params);
1153 return total;
1154 }
1155
1156 /**
1157 * @return the number of elements in this vector.
1158 */
1159 size_t size() const { return _size; }
1159 size_type size() const { return _size; }
1160
1161 bool
1162 zero() const
1163 {
1160
1161 bool
1162 zero() const
1163 {
1164 for (int i = 0; i < size(); ++i)
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 {
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 (int i = 0; i < size(); ++i)
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
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 (int i = 0; i < _size; ++i)
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
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[](int index)
1204 operator[](off_type index)
1205 {
1206 assert (index >= 0 && index < size());
1207 return Proxy(this, index);
1208 }
1209
1210 void update(StatData *data) {}
1211};
1212
1213template <class Stat>
1214class VectorProxy
1215{
1216 private:
1217 Stat *stat;
1205 {
1206 assert (index >= 0 && index < size());
1207 return Proxy(this, index);
1208 }
1209
1210 void update(StatData *data) {}
1211};
1212
1213template <class Stat>
1214class VectorProxy
1215{
1216 private:
1217 Stat *stat;
1218 int offset;
1219 int len;
1218 off_type offset;
1219 size_type len;
1220
1221 private:
1222 mutable VResult vec;
1223
1224 typename Stat::Storage *
1220
1221 private:
1222 mutable VResult vec;
1223
1224 typename Stat::Storage *
1225 data(int index)
1225 data(off_type index)
1226 {
1227 assert(index < len);
1228 return stat->data(offset + index);
1229 }
1230
1231 const typename Stat::Storage *
1226 {
1227 assert(index < len);
1228 return stat->data(offset + index);
1229 }
1230
1231 const typename Stat::Storage *
1232 data(int index) const
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
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 (int i = 0; i < size(); ++i)
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;
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 (int i = 0; i < size(); ++i)
1254 for (off_type i = 0; i < size(); ++i)
1255 total += data(i)->result(stat->params);
1256 return total;
1257 }
1258
1259 public:
1255 total += data(i)->result(stat->params);
1256 return total;
1257 }
1258
1259 public:
1260 VectorProxy(Stat *s, int o, int l)
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>
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[](int index)
1280 operator[](off_type index)
1281 {
1282 assert (index >= 0 && index < size());
1283 return ScalarProxy<Stat>(stat, offset + index);
1284 }
1285
1281 {
1282 assert (index >= 0 && index < size());
1283 return ScalarProxy<Stat>(stat, offset + index);
1284 }
1285
1286 size_t size() const { return len; }
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>
1295class Vector2dBase : public DataAccess
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:
1287
1288 /**
1289 * This stat has no state. Nothing to reset.
1290 */
1291 void reset() { }
1292};
1293
1294template <class Stor>
1295class Vector2dBase : public DataAccess
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_t x;
1306 size_t y;
1307 size_t _size;
1305 size_type x;
1306 size_type y;
1307 size_type _size;
1308 Storage *storage;
1309 Params params;
1310
1311 protected:
1308 Storage *storage;
1309 Params params;
1310
1311 protected:
1312 Storage *data(int index) { return &storage[index]; }
1313 const Storage *data(int index) const { return &storage[index]; }
1312 Storage *data(off_type index) { return &storage[index]; }
1313 const Storage *data(off_type index) const { return &storage[index]; }
1314
1315 void
1314
1315 void
1316 doInit(int _x, int _y)
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
1321 Vector2dData *statdata = dynamic_cast<Vector2dData *>(find());
1322
1323 x = _x;
1324 y = _y;
1325 statdata->x = _x;
1326 statdata->y = _y;
1327 _size = x * y;
1328
1329 char *ptr = new char[_size * sizeof(Storage)];
1330 storage = reinterpret_cast<Storage *>(ptr);
1331
1317 {
1318 assert(_x > 0 && _y > 0 && "sizes must be positive!");
1319 assert(!storage && "already initialized");
1320
1321 Vector2dData *statdata = dynamic_cast<Vector2dData *>(find());
1322
1323 x = _x;
1324 y = _y;
1325 statdata->x = _x;
1326 statdata->y = _y;
1327 _size = x * y;
1328
1329 char *ptr = new char[_size * sizeof(Storage)];
1330 storage = reinterpret_cast<Storage *>(ptr);
1331
1332 for (int i = 0; i < _size; ++i)
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
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 (int i = 0; i < _size; ++i)
1348 for (off_type i = 0; i < _size; ++i)
1349 data(i)->~Storage();
1350 delete [] reinterpret_cast<char *>(storage);
1351 }
1352
1353 void
1354 update(Vector2dData *newdata)
1355 {
1349 data(i)->~Storage();
1350 delete [] reinterpret_cast<char *>(storage);
1351 }
1352
1353 void
1354 update(Vector2dData *newdata)
1355 {
1356 int size = this->size();
1356 size_type size = this->size();
1357 newdata->cvec.resize(size);
1357 newdata->cvec.resize(size);
1358 for (int i = 0; i < size; ++i)
1358 for (off_type i = 0; i < size; ++i)
1359 newdata->cvec[i] = data(i)->value(params);
1360 }
1361
1359 newdata->cvec[i] = data(i)->value(params);
1360 }
1361
1362 std::string ysubname(int i) const { return (*this->y_subnames)[i]; }
1362 std::string ysubname(off_type i) const { return (*this->y_subnames)[i]; }
1363
1364 Proxy
1363
1364 Proxy
1365 operator[](int index)
1365 operator[](off_type index)
1366 {
1366 {
1367 int offset = index * y;
1367 off_type offset = index * y;
1368 assert (index >= 0 && offset + index < size());
1369 return Proxy(this, offset, y);
1370 }
1371
1372
1368 assert (index >= 0 && offset + index < size());
1369 return Proxy(this, offset, y);
1370 }
1371
1372
1373 size_t
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
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 (int i = 0; i < size(); ++i)
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 {
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 (int i = 0; i < size(); ++i)
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 */
1417struct 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. */
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 */
1417struct 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 int 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 {
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_t index = std::floor((val - params.min) / params.bucket_size);
1473 size_type index =
1474 (size_type)std::floor((val - params.min) / params.bucket_size);
1474 assert(index < size(params));
1475 cvec[index] += number;
1476 }
1477
1478 if (val < min_val)
1479 min_val = val;
1480
1481 if (val > max_val)
1482 max_val = val;
1483
1484 Counter sample = val * number;
1485 sum += sample;
1486 squares += sample * sample;
1487 samples += number;
1488 }
1489
1490 /**
1491 * Return the number of buckets in this distribution.
1492 * @return the number of buckets.
1493 * @todo Is it faster to return the size from the parameters?
1494 */
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 */
1495 size_t size(const Params &) const { return cvec.size(); }
1496 size_type size(const Params &) const { return cvec.size(); }
1496
1497 /**
1498 * Returns true if any calls to sample have been made.
1499 * @param params The paramters of the distribution.
1500 * @return True if any values have been sampled.
1501 */
1502 bool
1503 zero(const Params &params) const
1504 {
1505 return samples == Counter();
1506 }
1507
1508 void
1509 update(DistDataData *data, const Params &params)
1510 {
1511 data->min = params.min;
1512 data->max = params.max;
1513 data->bucket_size = params.bucket_size;
1514 data->size = params.size;
1515
1516 data->min_val = (min_val == CounterLimits::max()) ? 0 : min_val;
1517 data->max_val = (max_val == CounterLimits::min()) ? 0 : max_val;
1518 data->underflow = underflow;
1519 data->overflow = overflow;
1520 data->cvec.resize(params.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
1510 update(DistDataData *data, const Params &params)
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);
1521 for (int i = 0; i < params.size; ++i)
1522 for (off_type i = 0; i < params.size; ++i)
1522 data->cvec[i] = cvec[i];
1523
1524 data->sum = sum;
1525 data->squares = squares;
1526 data->samples = samples;
1527 }
1528
1529 /**
1530 * Reset stat value to default
1531 */
1532 void
1533 reset()
1534 {
1535 min_val = CounterLimits::max();
1536 max_val = CounterLimits::min();
1537 underflow = 0;
1538 overflow = 0;
1539
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
1540 int size = cvec.size();
1541 for (int i = 0; i < size; ++i)
1541 size_type size = cvec.size();
1542 for (off_type i = 0; i < size; ++i)
1542 cvec[i] = Counter();
1543
1544 sum = Counter();
1545 squares = Counter();
1546 samples = Counter();
1547 }
1548};
1549
1550/**
1551 * Templatized storage and interface for a distribution that calculates mean
1552 * and variance.
1553 */
1554struct FancyStor
1555{
1556 public:
1557 /**
1558 * No paramters for this storage.
1559 */
1560 struct Params {};
1561 enum { fancy = true };
1562
1563 private:
1564 /** The current sum. */
1565 Counter sum;
1566 /** The sum of squares. */
1567 Counter squares;
1568 /** The number of samples. */
1569 Counter samples;
1570
1571 public:
1572 /**
1573 * Create and initialize this storage.
1574 */
1575 FancyStor(const Params &)
1576 : sum(Counter()), squares(Counter()), samples(Counter())
1577 { }
1578
1579 /**
1580 * Add a value the given number of times to this running average.
1581 * Update the running sum and sum of squares, increment the number of
1582 * values seen by the given number.
1583 * @param val The value to add.
1584 * @param number The number of times to add the value.
1585 * @param p The parameters of this stat.
1586 */
1587 void
1588 sample(Counter val, int number, const Params &p)
1589 {
1590 Counter value = val * number;
1591 sum += value;
1592 squares += value * value;
1593 samples += number;
1594 }
1595
1596 void
1597 update(DistDataData *data, const Params &params)
1598 {
1599 data->sum = sum;
1600 data->squares = squares;
1601 data->samples = samples;
1602 }
1603
1604 /**
1605 * Return the number of entries in this stat, 1
1606 * @return 1.
1607 */
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 */
1555struct 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
1598 update(DistDataData *data, const Params &params)
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 */
1608 size_t size(const Params &) const { return 1; }
1609 size_type size(const Params &) const { return 1; }
1609
1610 /**
1611 * Return true if no samples have been added.
1612 * @return True if no samples have been added.
1613 */
1614 bool zero(const Params &) const { return samples == Counter(); }
1615
1616 /**
1617 * Reset stat value to default
1618 */
1619 void
1620 reset()
1621 {
1622 sum = Counter();
1623 squares = Counter();
1624 samples = Counter();
1625 }
1626};
1627
1628/**
1629 * Templatized storage for distribution that calculates per tick mean and
1630 * variance.
1631 */
1632struct AvgFancy
1633{
1634 public:
1635 /** No parameters for this storage. */
1636 struct Params {};
1637 enum { fancy = true };
1638
1639 private:
1640 /** Current total. */
1641 Counter sum;
1642 /** Current sum of squares. */
1643 Counter squares;
1644
1645 public:
1646 /**
1647 * Create and initialize this storage.
1648 */
1649 AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {}
1650
1651 /**
1652 * Add a value to the distribution for the given number of times.
1653 * Update the running sum and sum of squares.
1654 * @param val The value to add.
1655 * @param number The number of times to add the value.
1656 * @param p The paramters of the distribution.
1657 */
1658 void
1659 sample(Counter val, int number, const Params &p)
1660 {
1661 Counter value = val * number;
1662 sum += value;
1663 squares += value * value;
1664 }
1665
1666 void
1667 update(DistDataData *data, const Params &params)
1668 {
1669 data->sum = sum;
1670 data->squares = squares;
1671 data->samples = curTick;
1672 }
1673
1674 /**
1675 * Return the number of entries, in this case 1.
1676 * @return 1.
1677 */
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 */
1633struct 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
1668 update(DistDataData *data, const Params &params)
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 */
1678 size_t size(const Params ¶ms) const { return 1; }
1679 size_type size(const Params &params) const { return 1; }
1679
1680 /**
1681 * Return true if no samples have been added.
1682 * @return True if the sum is zero.
1683 */
1684 bool zero(const Params &params) const { return sum == Counter(); }
1685
1686 /**
1687 * Reset stat value to default
1688 */
1689 void
1690 reset()
1691 {
1692 sum = Counter();
1693 squares = Counter();
1694 }
1695};
1696
1697/**
1698 * Implementation of a distribution stat. The type of distribution is
1699 * determined by the Storage template. @sa ScalarBase
1700 */
1701template <class Stor>
1702class DistBase : public DataAccess
1703{
1704 public:
1705 typedef Stor Storage;
1706 /** Define the params of the storage class. */
1707 typedef typename Storage::Params Params;
1708
1709 protected:
1710 /** The storage for this stat. */
1711 char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
1712
1713 /** The parameters for this stat. */
1714 Params params;
1715
1716 protected:
1717 /**
1718 * Retrieve the storage.
1719 * @return The storage object for this stat.
1720 */
1721 Storage *
1722 data()
1723 {
1724 return reinterpret_cast<Storage *>(storage);
1725 }
1726
1727 /**
1728 * Retrieve a const pointer to the storage.
1729 * @return A const pointer to the storage object for this stat.
1730 */
1731 const Storage *
1732 data() const
1733 {
1734 return reinterpret_cast<const Storage *>(storage);
1735 }
1736
1737 void
1738 doInit()
1739 {
1740 new (storage) Storage(params);
1741 setInit();
1742 }
1743
1744 public:
1745 DistBase() { }
1746
1747 /**
1748 * Add a value to the distribtion n times. Calls sample on the storage
1749 * class.
1750 * @param v The value to add.
1751 * @param n The number of times to add it, defaults to 1.
1752 */
1753 template <typename U>
1754 void sample(const U &v, int n = 1) { data()->sample(v, n, params); }
1755
1756 /**
1757 * Return the number of entries in this stat.
1758 * @return The number of entries.
1759 */
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>
1703class DistBase : public DataAccess
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 */
1760 size_t size() const { return data()->size(params); }
1761 size_type size() const { return data()->size(params); }
1761 /**
1762 * Return true if no samples have been added.
1763 * @return True if there haven't been any samples.
1764 */
1765 bool zero() const { return data()->zero(params); }
1766
1767 void
1768 update(DistData *base)
1769 {
1770 base->data.fancy = Storage::fancy;
1771 data()->update(&(base->data), params);
1772 }
1773
1774 /**
1775 * Reset stat value to default
1776 */
1777 void
1778 reset()
1779 {
1780 data()->reset();
1781 }
1782
1783 bool
1784 check()
1785 {
1786 return true;
1787 }
1788};
1789
1790template <class Stat>
1791class DistProxy;
1792
1793template <class Stor>
1794class VectorDistBase : public DataAccess
1795{
1796 public:
1797 typedef Stor Storage;
1798 typedef typename Storage::Params Params;
1799 typedef DistProxy<VectorDistBase<Storage> > Proxy;
1800 friend class DistProxy<VectorDistBase<Storage> >;
1801
1802 protected:
1803 Storage *storage;
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
1769 update(DistData *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>
1795class VectorDistBase : public DataAccess
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;
1804 size_t _size;
1805 size_type _size;
1805 Params params;
1806
1807 protected:
1808 Storage *
1806 Params params;
1807
1808 protected:
1809 Storage *
1809 data(int index)
1810 data(off_type index)
1810 {
1811 return &storage[index];
1812 }
1813
1814 const Storage *
1811 {
1812 return &storage[index];
1813 }
1814
1815 const Storage *
1815 data(int index) const
1816 data(off_type index) const
1816 {
1817 return &storage[index];
1818 }
1819
1820 void
1817 {
1818 return &storage[index];
1819 }
1820
1821 void
1821 doInit(int s)
1822 doInit(size_type s)
1822 {
1823 assert(s > 0 && "size must be positive!");
1824 assert(!storage && "already initialized");
1825 _size = s;
1826
1827 char *ptr = new char[_size * sizeof(Storage)];
1828 storage = reinterpret_cast<Storage *>(ptr);
1829
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
1830 for (int i = 0; i < _size; ++i)
1831 for (off_type i = 0; i < _size; ++i)
1831 new (&storage[i]) Storage(params);
1832
1833 setInit();
1834 }
1835
1836 public:
1837 VectorDistBase()
1838 : storage(NULL)
1839 {}
1840
1841 ~VectorDistBase()
1842 {
1843 if (!storage)
1844 return ;
1845
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
1846 for (int i = 0; i < _size; ++i)
1847 for (off_type i = 0; i < _size; ++i)
1847 data(i)->~Storage();
1848 delete [] reinterpret_cast<char *>(storage);
1849 }
1850
1848 data(i)->~Storage();
1849 delete [] reinterpret_cast<char *>(storage);
1850 }
1851
1851 Proxy operator[](int index);
1852 Proxy operator[](off_type index);
1852
1853
1853 size_t
1854 size_type
1854 size() const
1855 {
1856 return _size;
1857 }
1858
1859 bool
1860 zero() const
1861 {
1862 return false;
1863#if 0
1855 size() const
1856 {
1857 return _size;
1858 }
1859
1860 bool
1861 zero() const
1862 {
1863 return false;
1864#if 0
1864 for (int i = 0; i < size(); ++i)
1865 for (off_type i = 0; i < size(); ++i)
1865 if (!data(i)->zero(params))
1866 return false;
1867 return true;
1868#endif
1869 }
1870
1871 /**
1872 * Reset stat value to default
1873 */
1874 void
1875 reset()
1876 {
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 {
1877 for (int i = 0; i < size(); ++i)
1878 for (off_type i = 0; i < size(); ++i)
1878 data(i)->reset();
1879 }
1880
1881 bool
1882 check()
1883 {
1884 return storage != NULL;
1885 }
1886
1887 void
1888 update(VectorDistData *base)
1889 {
1879 data(i)->reset();
1880 }
1881
1882 bool
1883 check()
1884 {
1885 return storage != NULL;
1886 }
1887
1888 void
1889 update(VectorDistData *base)
1890 {
1890 int size = this->size();
1891 size_type size = this->size();
1891 base->data.resize(size);
1892 base->data.resize(size);
1892 for (int i = 0; i < size; ++i) {
1893 for (off_type i = 0; i < size; ++i) {
1893 base->data[i].fancy = Storage::fancy;
1894 data(i)->update(&(base->data[i]), params);
1895 }
1896 }
1897};
1898
1899template <class Stat>
1900class DistProxy
1901{
1902 private:
1903 Stat *stat;
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;
1904 int index;
1905 off_type index;
1905
1906 protected:
1907 typename Stat::Storage *data() { return stat->data(index); }
1908 const typename Stat::Storage *data() const { return stat->data(index); }
1909
1910 public:
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:
1911 DistProxy(Stat *s, int i)
1912 DistProxy(Stat *s, off_type i)
1912 : stat(s), index(i)
1913 {}
1914
1915 DistProxy(const DistProxy &sp)
1916 : stat(sp.stat), index(sp.index)
1917 {}
1918
1919 const DistProxy &
1920 operator=(const DistProxy &sp)
1921 {
1922 stat = sp.stat;
1923 index = sp.index;
1924 return *this;
1925 }
1926
1927 public:
1928 template <typename U>
1929 void
1930 sample(const U &v, int n = 1)
1931 {
1932 data()->sample(v, n, stat->params);
1933 }
1934
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
1935 size_t
1936 size_type
1936 size() const
1937 {
1938 return 1;
1939 }
1940
1941 bool
1942 zero() const
1943 {
1944 return data()->zero(stat->params);
1945 }
1946
1947 /**
1948 * Proxy has no state. Nothing to reset.
1949 */
1950 void reset() { }
1951};
1952
1953template <class Storage>
1954inline typename VectorDistBase<Storage>::Proxy
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
1955VectorDistBase<Storage>::operator[](int index)
1956VectorDistBase<Storage>::operator[](off_type index)
1956{
1957 assert (index >= 0 && index < size());
1958 return typename VectorDistBase<Storage>::Proxy(this, index);
1959}
1960
1961#if 0
1962template <class Storage>
1963Result
1957{
1958 assert (index >= 0 && index < size());
1959 return typename VectorDistBase<Storage>::Proxy(this, index);
1960}
1961
1962#if 0
1963template <class Storage>
1964Result
1964VectorDistBase<Storage>::total(int index) const
1965VectorDistBase<Storage>::total(off_type index) const
1965{
1966{
1966 int total = 0;
1967 for (int i = 0; i < x_size(); ++i)
1967 Result total = 0;
1968 for (off_type i = 0; i < x_size(); ++i)
1968 total += data(i)->result(stat->params);
1969}
1970#endif
1971
1972//////////////////////////////////////////////////////////////////////
1973//
1974// Formula Details
1975//
1976//////////////////////////////////////////////////////////////////////
1977
1978/**
1979 * Base class for formula statistic node. These nodes are used to build a tree
1980 * that represents the formula.
1981 */
1982class Node : public RefCounted
1983{
1984 public:
1985 /**
1986 * Return the number of nodes in the subtree starting at this node.
1987 * @return the number of nodes in this subtree.
1988 */
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 */
1989 virtual size_t size() const = 0;
1990 virtual size_type size() const = 0;
1990 /**
1991 * Return the result vector of this subtree.
1992 * @return The result vector of this subtree.
1993 */
1994 virtual const VResult &result() const = 0;
1995 /**
1996 * Return the total of the result vector.
1997 * @return The total of the result vector.
1998 */
1999 virtual Result total() const = 0;
2000
2001 /**
2002 *
2003 */
2004 virtual std::string str() const = 0;
2005};
2006
2007/** Reference counting pointer to a function Node. */
2008typedef RefCountingPtr<Node> NodePtr;
2009
2010class ScalarStatNode : public Node
2011{
2012 private:
2013 const ScalarData *data;
2014 mutable VResult vresult;
2015
2016 public:
2017 ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {}
2018
2019 virtual const VResult &
2020 result() const
2021 {
2022 vresult[0] = data->result();
2023 return vresult;
2024 }
2025
2026 virtual Result total() const { return data->result(); };
2027
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:
2014 const ScalarData *data;
2015 mutable VResult vresult;
2016
2017 public:
2018 ScalarStatNode(const ScalarData *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
2028 virtual size_t size() const { return 1; }
2029 virtual size_type size() const { return 1; }
2029
2030 /**
2031 *
2032 */
2033 virtual std::string str() const { return data->name; }
2034};
2035
2036template <class Stat>
2037class ScalarProxyNode : public Node
2038{
2039 private:
2040 const ScalarProxy<Stat> proxy;
2041 mutable VResult vresult;
2042
2043 public:
2044 ScalarProxyNode(const ScalarProxy<Stat> &p)
2045 : proxy(p), vresult(1)
2046 { }
2047
2048 virtual const VResult &
2049 result() const
2050 {
2051 vresult[0] = proxy.result();
2052 return vresult;
2053 }
2054
2055 virtual Result
2056 total() const
2057 {
2058 return proxy.result();
2059 }
2060
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
2061 virtual size_t
2062 virtual size_type
2062 size() const
2063 {
2064 return 1;
2065 }
2066
2067 /**
2068 *
2069 */
2070 virtual std::string
2071 str() const
2072 {
2073 return proxy.str();
2074 }
2075};
2076
2077class VectorStatNode : public Node
2078{
2079 private:
2080 const VectorData *data;
2081
2082 public:
2083 VectorStatNode(const VectorData *d) : data(d) { }
2084 virtual const VResult &result() const { return data->result(); }
2085 virtual Result total() const { return data->total(); };
2086
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:
2081 const VectorData *data;
2082
2083 public:
2084 VectorStatNode(const VectorData *d) : data(d) { }
2085 virtual const VResult &result() const { return data->result(); }
2086 virtual Result total() const { return data->total(); };
2087
2087 virtual size_t size() const { return data->size(); }
2088 virtual size_type size() const { return data->size(); }
2088
2089 virtual std::string str() const { return data->name; }
2090};
2091
2092template <class T>
2093class ConstNode : public Node
2094{
2095 private:
2096 VResult vresult;
2097
2098 public:
2099 ConstNode(T s) : vresult(1, (Result)s) {}
2100 const VResult &result() const { return vresult; }
2101 virtual Result total() const { return vresult[0]; };
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]; };
2102 virtual size_t size() const { return 1; }
2103 virtual size_type size() const { return 1; }
2103 virtual std::string str() const { return to_string(vresult[0]); }
2104};
2105
2106template <class T>
2107class ConstVectorNode : public Node
2108{
2109 private:
2110 VResult vresult;
2111
2112 public:
2113 ConstVectorNode(const T &s) : vresult(s.begin(), s.end()) {}
2114 const VResult &result() const { return vresult; }
2115
2116 virtual Result
2117 total() const
2118 {
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 {
2119 int size = this->size();
2120 size_type size = this->size();
2120 Result tmp = 0;
2121 Result tmp = 0;
2121 for (int i = 0; i < size; i++)
2122 for (off_type i = 0; i < size; i++)
2122 tmp += vresult[i];
2123 return tmp;
2124 }
2125
2123 tmp += vresult[i];
2124 return tmp;
2125 }
2126
2126 virtual size_t size() const { return vresult.size(); }
2127 virtual size_type size() const { return vresult.size(); }
2127 virtual std::string
2128 str() const
2129 {
2128 virtual std::string
2129 str() const
2130 {
2130 int size = this->size();
2131 size_type size = this->size();
2131 std::string tmp = "(";
2132 std::string tmp = "(";
2132 for (int i = 0; i < size; i++)
2133 for (off_type i = 0; i < size; i++)
2133 tmp += csprintf("%s ",to_string(vresult[i]));
2134 tmp += ")";
2135 return tmp;
2136 }
2137};
2138
2139template <class Op>
2140struct OpString;
2141
2142template<>
2143struct OpString<std::plus<Result> >
2144{
2145 static std::string str() { return "+"; }
2146};
2147
2148template<>
2149struct OpString<std::minus<Result> >
2150{
2151 static std::string str() { return "-"; }
2152};
2153
2154template<>
2155struct OpString<std::multiplies<Result> >
2156{
2157 static std::string str() { return "*"; }
2158};
2159
2160template<>
2161struct OpString<std::divides<Result> >
2162{
2163 static std::string str() { return "/"; }
2164};
2165
2166template<>
2167struct OpString<std::modulus<Result> >
2168{
2169 static std::string str() { return "%"; }
2170};
2171
2172template<>
2173struct OpString<std::negate<Result> >
2174{
2175 static std::string str() { return "-"; }
2176};
2177
2178template <class Op>
2179class UnaryNode : public Node
2180{
2181 public:
2182 NodePtr l;
2183 mutable VResult vresult;
2184
2185 public:
2186 UnaryNode(NodePtr &p) : l(p) {}
2187
2188 const VResult &
2189 result() const
2190 {
2191 const VResult &lvec = l->result();
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();
2192 int size = lvec.size();
2193 size_type size = lvec.size();
2193
2194 assert(size > 0);
2195
2196 vresult.resize(size);
2197 Op op;
2194
2195 assert(size > 0);
2196
2197 vresult.resize(size);
2198 Op op;
2198 for (int i = 0; i < size; ++i)
2199 for (off_type i = 0; i < size; ++i)
2199 vresult[i] = op(lvec[i]);
2200
2201 return vresult;
2202 }
2203
2204 Result
2205 total() const
2206 {
2207 const VResult &vec = this->result();
2208 Result total = 0;
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;
2209 for (int i = 0; i < size(); i++)
2210 for (off_type i = 0; i < size(); i++)
2210 total += vec[i];
2211 return total;
2212 }
2213
2211 total += vec[i];
2212 return total;
2213 }
2214
2214 virtual size_t size() const { return l->size(); }
2215 virtual size_type size() const { return l->size(); }
2215
2216 virtual std::string
2217 str() const
2218 {
2219 return OpString<Op>::str() + l->str();
2220 }
2221};
2222
2223template <class Op>
2224class BinaryNode : public Node
2225{
2226 public:
2227 NodePtr l;
2228 NodePtr r;
2229 mutable VResult vresult;
2230
2231 public:
2232 BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}
2233
2234 const VResult &
2235 result() const
2236 {
2237 Op op;
2238 const VResult &lvec = l->result();
2239 const VResult &rvec = r->result();
2240
2241 assert(lvec.size() > 0 && rvec.size() > 0);
2242
2243 if (lvec.size() == 1 && rvec.size() == 1) {
2244 vresult.resize(1);
2245 vresult[0] = op(lvec[0], rvec[0]);
2246 } else if (lvec.size() == 1) {
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) {
2247 int size = rvec.size();
2248 size_type size = rvec.size();
2248 vresult.resize(size);
2249 vresult.resize(size);
2249 for (int i = 0; i < size; ++i)
2250 for (off_type i = 0; i < size; ++i)
2250 vresult[i] = op(lvec[0], rvec[i]);
2251 } else if (rvec.size() == 1) {
2251 vresult[i] = op(lvec[0], rvec[i]);
2252 } else if (rvec.size() == 1) {
2252 int size = lvec.size();
2253 size_type size = lvec.size();
2253 vresult.resize(size);
2254 vresult.resize(size);
2254 for (int i = 0; i < size; ++i)
2255 for (off_type i = 0; i < size; ++i)
2255 vresult[i] = op(lvec[i], rvec[0]);
2256 } else if (rvec.size() == lvec.size()) {
2256 vresult[i] = op(lvec[i], rvec[0]);
2257 } else if (rvec.size() == lvec.size()) {
2257 int size = rvec.size();
2258 size_type size = rvec.size();
2258 vresult.resize(size);
2259 vresult.resize(size);
2259 for (int i = 0; i < size; ++i)
2260 for (off_type i = 0; i < size; ++i)
2260 vresult[i] = op(lvec[i], rvec[i]);
2261 }
2262
2263 return vresult;
2264 }
2265
2266 Result
2267 total() const
2268 {
2269 const VResult &vec = this->result();
2270 Result total = 0;
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;
2271 for (int i = 0; i < size(); i++)
2272 for (off_type i = 0; i < size(); i++)
2272 total += vec[i];
2273 return total;
2274 }
2275
2273 total += vec[i];
2274 return total;
2275 }
2276
2276 virtual size_t
2277 virtual size_type
2277 size() const
2278 {
2278 size() const
2279 {
2279 int ls = l->size();
2280 int rs = r->size();
2280 size_type ls = l->size();
2281 size_type rs = r->size();
2281 if (ls == 1) {
2282 return rs;
2283 } else if (rs == 1) {
2284 return ls;
2285 } else {
2286 assert(ls == rs && "Node vector sizes are not equal");
2287 return ls;
2288 }
2289 }
2290
2291 virtual std::string
2292 str() const
2293 {
2294 return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
2295 }
2296};
2297
2298template <class Op>
2299class SumNode : public Node
2300{
2301 public:
2302 NodePtr l;
2303 mutable VResult vresult;
2304
2305 public:
2306 SumNode(NodePtr &p) : l(p), vresult(1) {}
2307
2308 const VResult &
2309 result() const
2310 {
2311 const VResult &lvec = l->result();
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();
2312 int size = lvec.size();
2313 size_type size = lvec.size();
2313 assert(size > 0);
2314
2315 vresult[0] = 0.0;
2316
2317 Op op;
2314 assert(size > 0);
2315
2316 vresult[0] = 0.0;
2317
2318 Op op;
2318 for (int i = 0; i < size; ++i)
2319 for (off_type i = 0; i < size; ++i)
2319 vresult[0] = op(vresult[0], lvec[i]);
2320
2321 return vresult;
2322 }
2323
2324 Result
2325 total() const
2326 {
2327 const VResult &lvec = l->result();
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();
2328 int size = lvec.size();
2329 size_type size = lvec.size();
2329 assert(size > 0);
2330
2331 Result vresult = 0.0;
2332
2333 Op op;
2330 assert(size > 0);
2331
2332 Result vresult = 0.0;
2333
2334 Op op;
2334 for (int i = 0; i < size; ++i)
2335 for (off_type i = 0; i < size; ++i)
2335 vresult = op(vresult, lvec[i]);
2336
2337 return vresult;
2338 }
2339
2336 vresult = op(vresult, lvec[i]);
2337
2338 return vresult;
2339 }
2340
2340 virtual size_t size() const { return 1; }
2341 virtual size_type size() const { return 1; }
2341
2342 virtual std::string
2343 str() const
2344 {
2345 return csprintf("total(%s)", l->str());
2346 }
2347};
2348
2349
2350//////////////////////////////////////////////////////////////////////
2351//
2352// Visible Statistics Types
2353//
2354//////////////////////////////////////////////////////////////////////
2355/**
2356 * @defgroup VisibleStats "Statistic Types"
2357 * These are the statistics that are used in the simulator.
2358 * @{
2359 */
2360
2361/**
2362 * This is a simple scalar statistic, like a counter.
2363 * @sa Stat, ScalarBase, StatStor
2364 */
2365template<int N = 0>
2366class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarStatData>
2367{
2368 public:
2369 /** The base implementation. */
2370 typedef ScalarBase<StatStor> Base;
2371
2372 Scalar()
2373 {
2374 this->doInit();
2375 }
2376
2377 /**
2378 * Sets the stat equal to the given value. Calls the base implementation
2379 * of operator=
2380 * @param v The new value.
2381 */
2382 template <typename U>
2383 void operator=(const U &v) { Base::operator=(v); }
2384};
2385
2386class Value : public Wrap<Value, ValueBase, ScalarStatData>
2387{
2388 public:
2389 /** The base implementation. */
2390 typedef ValueBase Base;
2391
2392 template <class T>
2393 Value &
2394 scalar(T &value)
2395 {
2396 Base::scalar(value);
2397 return *this;
2398 }
2399
2400 template <class T>
2401 Value &
2402 functor(T &func)
2403 {
2404 Base::functor(func);
2405 return *this;
2406 }
2407};
2408
2409/**
2410 * A stat that calculates the per tick average of a value.
2411 * @sa Stat, ScalarBase, AvgStor
2412 */
2413template<int N = 0>
2414class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarStatData>
2415{
2416 public:
2417 /** The base implementation. */
2418 typedef ScalarBase<AvgStor> Base;
2419
2420 Average()
2421 {
2422 this->doInit();
2423 }
2424
2425 /**
2426 * Sets the stat equal to the given value. Calls the base implementation
2427 * of operator=
2428 * @param v The new value.
2429 */
2430 template <typename U>
2431 void
2432 operator=(const U &v)
2433 {
2434 Base::operator=(v);
2435 }
2436};
2437
2438/**
2439 * A vector of scalar stats.
2440 * @sa Stat, VectorBase, StatStor
2441 */
2442template<int N = 0>
2443class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorStatData>
2444{
2445 public:
2446 /** The base implementation. */
2447 typedef ScalarBase<StatStor> Base;
2448
2449 /**
2450 * Set this vector to have the given size.
2451 * @param size The new size.
2452 * @return A reference to this stat.
2453 */
2454 Vector &
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>
2367class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarStatData>
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
2387class Value : public Wrap<Value, ValueBase, ScalarStatData>
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>
2415class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarStatData>
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>
2444class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorStatData>
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 &
2455 init(size_t size)
2456 init(size_type size)
2456 {
2457 this->doInit(size);
2458 return *this;
2459 }
2460};
2461
2462/**
2463 * A vector of Average stats.
2464 * @sa Stat, VectorBase, AvgStor
2465 */
2466template<int N = 0>
2467class AverageVector
2468 : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorStatData>
2469{
2470 public:
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 AverageVector &
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
2469 : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorStatData>
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 &
2477 init(size_t size)
2478 init(size_type size)
2478 {
2479 this->doInit(size);
2480 return *this;
2481 }
2482};
2483
2484/**
2485 * A 2-Dimensional vecto of scalar stats.
2486 * @sa Stat, Vector2dBase, StatStor
2487 */
2488template<int N = 0>
2489class Vector2d
2490 : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dStatData>
2491{
2492 public:
2493 Vector2d &
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 : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dStatData>
2492{
2493 public:
2494 Vector2d &
2494 init(size_t x, size_t y)
2495 init(size_type x, size_type y)
2495 {
2496 this->doInit(x, y);
2497 return *this;
2498 }
2499};
2500
2501/**
2502 * A simple distribution stat.
2503 * @sa Stat, DistBase, DistStor
2504 */
2505template<int N = 0>
2506class Distribution
2507 : public Wrap<Distribution<N>, DistBase<DistStor>, DistStatData>
2508{
2509 public:
2510 /** Base implementation. */
2511 typedef DistBase<DistStor> Base;
2512 /** The Parameter type. */
2513 typedef DistStor::Params Params;
2514
2515 public:
2516 /**
2517 * Set the parameters of this distribution. @sa DistStor::Params
2518 * @param min The minimum value of the distribution.
2519 * @param max The maximum value of the distribution.
2520 * @param bkt The number of values in each bucket.
2521 * @return A reference to this distribution.
2522 */
2523 Distribution &
2524 init(Counter min, Counter max, Counter bkt)
2525 {
2526 this->params.min = min;
2527 this->params.max = max;
2528 this->params.bucket_size = bkt;
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
2508 : public Wrap<Distribution<N>, DistBase<DistStor>, DistStatData>
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;
2529 this->params.size = (int)rint((max - min) / bkt + 1.0);
2530 this->params.size = (size_type)rint((max - min) / bkt + 1.0);
2530 this->doInit();
2531 return *this;
2532 }
2533};
2534
2535/**
2536 * Calculates the mean and variance of all the samples.
2537 * @sa Stat, DistBase, FancyStor
2538 */
2539template<int N = 0>
2540class StandardDeviation
2541 : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistStatData>
2542{
2543 public:
2544 /** The base implementation */
2545 typedef DistBase<DistStor> Base;
2546 /** The parameter type. */
2547 typedef DistStor::Params Params;
2548
2549 public:
2550 /**
2551 * Construct and initialize this distribution.
2552 */
2553 StandardDeviation()
2554 {
2555 this->doInit();
2556 }
2557};
2558
2559/**
2560 * Calculates the per tick mean and variance of the samples.
2561 * @sa Stat, DistBase, AvgFancy
2562 */
2563template<int N = 0>
2564class AverageDeviation
2565 : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistStatData>
2566{
2567 public:
2568 /** The base implementation */
2569 typedef DistBase<DistStor> Base;
2570 /** The parameter type. */
2571 typedef DistStor::Params Params;
2572
2573 public:
2574 /**
2575 * Construct and initialize this distribution.
2576 */
2577 AverageDeviation()
2578 {
2579 this->doInit();
2580 }
2581};
2582
2583/**
2584 * A vector of distributions.
2585 * @sa Stat, VectorDistBase, DistStor
2586 */
2587template<int N = 0>
2588class VectorDistribution
2589 : public WrapVec<VectorDistribution<N>,
2590 VectorDistBase<DistStor>,
2591 VectorDistStatData>
2592{
2593 public:
2594 /** The base implementation */
2595 typedef VectorDistBase<DistStor> Base;
2596 /** The parameter type. */
2597 typedef DistStor::Params Params;
2598
2599 public:
2600 /**
2601 * Initialize storage and parameters for this distribution.
2602 * @param size The size of the vector (the number of distributions).
2603 * @param min The minimum value of the distribution.
2604 * @param max The maximum value of the distribution.
2605 * @param bkt The number of values in each bucket.
2606 * @return A reference to this distribution.
2607 */
2608 VectorDistribution &
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
2542 : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistStatData>
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
2566 : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistStatData>
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>,
2592 VectorDistStatData>
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 &
2609 init(int size, Counter min, Counter max, Counter bkt)
2610 init(size_type size, Counter min, Counter max, Counter bkt)
2610 {
2611 this->params.min = min;
2612 this->params.max = max;
2613 this->params.bucket_size = bkt;
2611 {
2612 this->params.min = min;
2613 this->params.max = max;
2614 this->params.bucket_size = bkt;
2614 this->params.size = (int)rint((max - min) / bkt + 1.0);
2615 this->params.size = rint((max - min) / bkt + 1.0);
2615 this->doInit(size);
2616 return *this;
2617 }
2618};
2619
2620/**
2621 * This is a vector of StandardDeviation stats.
2622 * @sa Stat, VectorDistBase, FancyStor
2623 */
2624template<int N = 0>
2625class VectorStandardDeviation
2626 : public WrapVec<VectorStandardDeviation<N>,
2627 VectorDistBase<FancyStor>,
2628 VectorDistStatData>
2629{
2630 public:
2631 /** The base implementation */
2632 typedef VectorDistBase<FancyStor> Base;
2633 /** The parameter type. */
2634 typedef DistStor::Params Params;
2635
2636 public:
2637 /**
2638 * Initialize storage for this distribution.
2639 * @param size The size of the vector.
2640 * @return A reference to this distribution.
2641 */
2642 VectorStandardDeviation &
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>,
2629 VectorDistStatData>
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 &
2643 init(int size)
2644 init(size_type size)
2644 {
2645 this->doInit(size);
2646 return *this;
2647 }
2648};
2649
2650/**
2651 * This is a vector of AverageDeviation stats.
2652 * @sa Stat, VectorDistBase, AvgFancy
2653 */
2654template<int N = 0>
2655class VectorAverageDeviation
2656 : public WrapVec<VectorAverageDeviation<N>,
2657 VectorDistBase<AvgFancy>,
2658 VectorDistStatData>
2659{
2660 public:
2661 /** The base implementation */
2662 typedef VectorDistBase<AvgFancy> Base;
2663 /** The parameter type. */
2664 typedef DistStor::Params Params;
2665
2666 public:
2667 /**
2668 * Initialize storage for this distribution.
2669 * @param size The size of the vector.
2670 * @return A reference to this distribution.
2671 */
2672 VectorAverageDeviation &
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>,
2659 VectorDistStatData>
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 &
2673 init(int size)
2674 init(size_type size)
2674 {
2675 this->doInit(size);
2676 return *this;
2677 }
2678};
2679
2680/**
2681 * A formula for statistics that is calculated when printed. A formula is
2682 * stored as a tree of Nodes that represent the equation to calculate.
2683 * @sa Stat, ScalarStat, VectorStat, Node, Temp
2684 */
2685class FormulaBase : public DataAccess
2686{
2687 protected:
2688 /** The root of the tree which represents the Formula */
2689 NodePtr root;
2690 friend class Temp;
2691
2692 public:
2693 /**
2694 * Return the result of the Fomula in a vector. If there were no Vector
2695 * components to the Formula, then the vector is size 1. If there were,
2696 * like x/y with x being a vector of size 3, then the result returned will
2697 * be x[0]/y, x[1]/y, x[2]/y, respectively.
2698 * @return The result vector.
2699 */
2700 void result(VResult &vec) const;
2701
2702 /**
2703 * Return the total Formula result. If there is a Vector
2704 * component to this Formula, then this is the result of the
2705 * Formula if the formula is applied after summing all the
2706 * components of the Vector. For example, if Formula is x/y where
2707 * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If
2708 * there is no Vector component, total() returns the same value as
2709 * the first entry in the VResult val() returns.
2710 * @return The total of the result vector.
2711 */
2712 Result total() const;
2713
2714 /**
2715 * Return the number of elements in the tree.
2716 */
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 */
2686class FormulaBase : public DataAccess
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 */
2717 size_t size() const;
2718 size_type size() const;
2718
2719 bool check() const { return true; }
2720
2721 /**
2722 * Formulas don't need to be reset
2723 */
2724 void reset();
2725
2726 /**
2727 *
2728 */
2729 bool zero() const;
2730
2731 /**
2732 *
2733 */
2734 void update(StatData *);
2735
2736 std::string str() const;
2737};
2738
2739class FormulaData : public VectorData
2740{
2741 public:
2742 virtual std::string str() const = 0;
2743 virtual bool check() const { return true; }
2744};
2745
2746template <class Stat>
2747class FormulaStatData : public FormulaData
2748{
2749 protected:
2750 Stat &s;
2751 mutable VResult vec;
2752 mutable VCounter cvec;
2753
2754 public:
2755 FormulaStatData(Stat &stat) : s(stat) {}
2756
2757 virtual bool zero() const { return s.zero(); }
2758 virtual void reset() { s.reset(); }
2759
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 */
2735 void update(StatData *);
2736
2737 std::string str() const;
2738};
2739
2740class FormulaData : public VectorData
2741{
2742 public:
2743 virtual std::string str() const = 0;
2744 virtual bool check() const { return true; }
2745};
2746
2747template <class Stat>
2748class FormulaStatData : public FormulaData
2749{
2750 protected:
2751 Stat &s;
2752 mutable VResult vec;
2753 mutable VCounter cvec;
2754
2755 public:
2756 FormulaStatData(Stat &stat) : s(stat) {}
2757
2758 virtual bool zero() const { return s.zero(); }
2759 virtual void reset() { s.reset(); }
2760
2760 virtual size_t size() const { return s.size(); }
2761 virtual size_type size() const { return s.size(); }
2761
2762 virtual const VResult &
2763 result() const
2764 {
2765 s.result(vec);
2766 return vec;
2767 }
2768 virtual Result total() const { return s.total(); }
2769 virtual VCounter &value() const { return cvec; }
2770
2771 virtual void
2772 visit(Visit &visitor)
2773 {
2774 update();
2775 s.update(this);
2776 visitor.visit(*this);
2777 }
2778
2779 virtual std::string str() const { return s.str(); }
2780};
2781
2782class Temp;
2783class Formula
2784 : public WrapVec<Formula,
2785 FormulaBase,
2786 FormulaStatData>
2787{
2788 public:
2789 /**
2790 * Create and initialize thie formula, and register it with the database.
2791 */
2792 Formula();
2793
2794 /**
2795 * Create a formula with the given root node, register it with the
2796 * database.
2797 * @param r The root of the expression tree.
2798 */
2799 Formula(Temp r);
2800
2801 /**
2802 * Set an unitialized Formula to the given root.
2803 * @param r The root of the expression tree.
2804 * @return a reference to this formula.
2805 */
2806 const Formula &operator=(Temp r);
2807
2808 /**
2809 * Add the given tree to the existing one.
2810 * @param r The root of the expression tree.
2811 * @return a reference to this formula.
2812 */
2813 const Formula &operator+=(Temp r);
2814};
2815
2816class FormulaNode : public Node
2817{
2818 private:
2819 const Formula &formula;
2820 mutable VResult vec;
2821
2822 public:
2823 FormulaNode(const Formula &f) : formula(f) {}
2824
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,
2787 FormulaStatData>
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
2825 virtual size_t size() const { return formula.size(); }
2826 virtual size_type size() const { return formula.size(); }
2826 virtual const VResult &result() const { formula.result(vec); return vec; }
2827 virtual Result total() const { return formula.total(); }
2828
2829 virtual std::string str() const { return formula.str(); }
2830};
2831
2832/**
2833 * Helper class to construct formula node trees.
2834 */
2835class Temp
2836{
2837 protected:
2838 /**
2839 * Pointer to a Node object.
2840 */
2841 NodePtr node;
2842
2843 public:
2844 /**
2845 * Copy the given pointer to this class.
2846 * @param n A pointer to a Node object to copy.
2847 */
2848 Temp(NodePtr n) : node(n) { }
2849
2850 /**
2851 * Return the node pointer.
2852 * @return the node pointer.
2853 */
2854 operator NodePtr&() { return node;}
2855
2856 public:
2857 /**
2858 * Create a new ScalarStatNode.
2859 * @param s The ScalarStat to place in a node.
2860 */
2861 template <int N>
2862 Temp(const Scalar<N> &s)
2863 : node(new ScalarStatNode(s.statData()))
2864 { }
2865
2866 /**
2867 * Create a new ScalarStatNode.
2868 * @param s The ScalarStat to place in a node.
2869 */
2870 Temp(const Value &s)
2871 : node(new ScalarStatNode(s.statData()))
2872 { }
2873
2874 /**
2875 * Create a new ScalarStatNode.
2876 * @param s The ScalarStat to place in a node.
2877 */
2878 template <int N>
2879 Temp(const Average<N> &s)
2880 : node(new ScalarStatNode(s.statData()))
2881 { }
2882
2883 /**
2884 * Create a new VectorStatNode.
2885 * @param s The VectorStat to place in a node.
2886 */
2887 template <int N>
2888 Temp(const Vector<N> &s)
2889 : node(new VectorStatNode(s.statData()))
2890 { }
2891
2892 /**
2893 *
2894 */
2895 Temp(const Formula &f)
2896 : node(new FormulaNode(f))
2897 { }
2898
2899 /**
2900 * Create a new ScalarProxyNode.
2901 * @param p The ScalarProxy to place in a node.
2902 */
2903 template <class Stat>
2904 Temp(const ScalarProxy<Stat> &p)
2905 : node(new ScalarProxyNode<Stat>(p))
2906 { }
2907
2908 /**
2909 * Create a ConstNode
2910 * @param value The value of the const node.
2911 */
2912 Temp(signed char value)
2913 : node(new ConstNode<signed char>(value))
2914 { }
2915
2916 /**
2917 * Create a ConstNode
2918 * @param value The value of the const node.
2919 */
2920 Temp(unsigned char value)
2921 : node(new ConstNode<unsigned char>(value))
2922 { }
2923
2924 /**
2925 * Create a ConstNode
2926 * @param value The value of the const node.
2927 */
2928 Temp(signed short value)
2929 : node(new ConstNode<signed short>(value))
2930 { }
2931
2932 /**
2933 * Create a ConstNode
2934 * @param value The value of the const node.
2935 */
2936 Temp(unsigned short value)
2937 : node(new ConstNode<unsigned short>(value))
2938 { }
2939
2940 /**
2941 * Create a ConstNode
2942 * @param value The value of the const node.
2943 */
2944 Temp(signed int value)
2945 : node(new ConstNode<signed int>(value))
2946 { }
2947
2948 /**
2949 * Create a ConstNode
2950 * @param value The value of the const node.
2951 */
2952 Temp(unsigned int value)
2953 : node(new ConstNode<unsigned int>(value))
2954 { }
2955
2956 /**
2957 * Create a ConstNode
2958 * @param value The value of the const node.
2959 */
2960 Temp(signed long value)
2961 : node(new ConstNode<signed long>(value))
2962 { }
2963
2964 /**
2965 * Create a ConstNode
2966 * @param value The value of the const node.
2967 */
2968 Temp(unsigned long value)
2969 : node(new ConstNode<unsigned long>(value))
2970 { }
2971
2972 /**
2973 * Create a ConstNode
2974 * @param value The value of the const node.
2975 */
2976 Temp(signed long long value)
2977 : node(new ConstNode<signed long long>(value))
2978 { }
2979
2980 /**
2981 * Create a ConstNode
2982 * @param value The value of the const node.
2983 */
2984 Temp(unsigned long long value)
2985 : node(new ConstNode<unsigned long long>(value))
2986 { }
2987
2988 /**
2989 * Create a ConstNode
2990 * @param value The value of the const node.
2991 */
2992 Temp(float value)
2993 : node(new ConstNode<float>(value))
2994 { }
2995
2996 /**
2997 * Create a ConstNode
2998 * @param value The value of the const node.
2999 */
3000 Temp(double value)
3001 : node(new ConstNode<double>(value))
3002 { }
3003};
3004
3005
3006/**
3007 * @}
3008 */
3009
3010void check();
3011void dump();
3012void reset();
3013void registerResetCallback(Callback *cb);
3014
3015inline Temp
3016operator+(Temp l, Temp r)
3017{
3018 return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
3019}
3020
3021inline Temp
3022operator-(Temp l, Temp r)
3023{
3024 return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
3025}
3026
3027inline Temp
3028operator*(Temp l, Temp r)
3029{
3030 return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
3031}
3032
3033inline Temp
3034operator/(Temp l, Temp r)
3035{
3036 return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
3037}
3038
3039inline Temp
3040operator-(Temp l)
3041{
3042 return NodePtr(new UnaryNode<std::negate<Result> >(l));
3043}
3044
3045template <typename T>
3046inline Temp
3047constant(T val)
3048{
3049 return NodePtr(new ConstNode<T>(val));
3050}
3051
3052template <typename T>
3053inline Temp
3054constantVector(T val)
3055{
3056 return NodePtr(new ConstVectorNode<T>(val));
3057}
3058
3059inline Temp
3060sum(Temp val)
3061{
3062 return NodePtr(new SumNode<std::plus<Result> >(val));
3063}
3064
3065/* namespace Stats */ }
3066
3067#endif // __BASE_STATISTICS_HH__
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)
2864 : node(new ScalarStatNode(s.statData()))
2865 { }
2866
2867 /**
2868 * Create a new ScalarStatNode.
2869 * @param s The ScalarStat to place in a node.
2870 */
2871 Temp(const Value &s)
2872 : node(new ScalarStatNode(s.statData()))
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)
2881 : node(new ScalarStatNode(s.statData()))
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)
2890 : node(new VectorStatNode(s.statData()))
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__