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