split tunable constant into Boolean and Float sub-classes.
[dyninst.git] / common / src / aggregateSample.C
1
2 /*
3  * 
4  * $Log: aggregateSample.C,v $
5  * Revision 1.7  1994/07/02 01:47:31  markc
6  * Rename aggregation operator defines.
7  * Rename aggregation operator defines.
8  *
9  * Revision 1.6  1994/06/14  15:36:49  markc
10  * Added support for different types of aggregation (max, min, sum, avg).
11  * Previously, only summation had been done.
12  *
13  * Revision 1.5  1994/06/02  23:36:10  markc
14  * Added assertion to ensure values reported are positive.
15  *
16  * Revision 1.4  1994/05/17  00:14:44  hollings
17  * added rcs log entry.
18  *
19  *
20  */
21 #include <assert.h>
22
23 #include "util/h/aggregateSample.h"
24
25 struct sampleInterval sampleInfo::newValue(timeStamp sampleTime, 
26                                                      sampleValue newVal)
27 {
28     struct sampleInterval ret;
29
30     // use the first sample to define a baseline in time and value.
31     if (!firstSampleReceived) {
32         firstSampleReceived = True;
33         lastSampleStart = sampleTime;
34         lastSampleEnd = sampleTime;
35         lastSample = 0.0;
36         value = newVal;
37         ret.valid = FALSE;
38         return(ret);
39     }
40
41     ret.valid = TRUE;
42     ret.start = lastSampleEnd;
43     ret.end = sampleTime;
44     ret.value = newVal;
45
46     // used when it's a component of an aggregate.
47     lastSample += newVal;
48     lastSampleEnd = sampleTime;
49
50     return(ret);
51 }
52
53 struct sampleInterval sampleInfo::newValue(List<sampleInfo *> parts,
54                                            timeStamp sampleTime, 
55                                            sampleValue newVal)
56 {
57     double fract;
58     sampleInfo *curr;
59     List<sampleInfo*> cp;
60     sampleValue component;
61     timeStamp earlyestTime;
62     struct sampleInterval ret;
63     sampleValue aggregateVal;
64     int len=0;
65
66     assert((aggOp == aggSum) || (aggOp == aggAvg) ||
67            (aggOp == aggMin) || (aggOp == aggMax));
68
69     if (parts.count() <= 1) {
70        // not an aggregate.
71        return(newValue(sampleTime, newVal));
72     } else {
73         earlyestTime = (*parts)->lastSampleEnd;
74         for (cp=parts; curr = *cp; cp++) {
75             len++;
76             if (curr->lastSampleEnd < earlyestTime) {
77                 earlyestTime = curr->lastSampleEnd;
78             }
79         }
80
81
82         if (earlyestTime > lastSampleEnd + 0.0001) {
83             /* eat the first one to get a good interval basis */
84             if (!firstSampleReceived) {
85                 firstSampleReceived = True;
86                 ret.valid = FALSE;
87                 lastSampleEnd = earlyestTime;
88
89                // this gives all of the samples the same initial starting
90                // time
91                // It is very important for them to have the same time
92                // if this is not done, fract that is calculated below
93                // will fail the assertions
94                // You may want to zero the lastSample values here too
95
96                 for (cp=parts; curr=*cp; cp++) 
97                     curr->lastSampleStart = earlyestTime;
98
99                 return(ret);
100             }
101
102             aggregateVal = 0.0;
103
104             int first = 1;
105
106             for (cp=parts; curr=*cp; cp++) {
107                 // assert(earlyestTime >= curr->lastSampleStart);
108
109                 fract = (earlyestTime - lastSampleEnd)/
110                     (curr->lastSampleEnd - curr->lastSampleStart);
111                 component = (curr->lastSample) * fract;
112
113                 assert(fract > 0.0);
114                 assert(fract <= 1.0);
115                 assert(component >= -0.01);
116
117                 curr->lastSample -= component;
118
119                 // each list entry comes from a separate reporter
120                 switch (aggOp)
121                   {
122                   case aggSum:
123                   case aggAvg:
124                     aggregateVal += component;
125                     break;
126                   case aggMin:
127                     if (first) {
128                       aggregateVal = component;
129                       first = 0;
130                     } else if (component < aggregateVal)
131                       aggregateVal = component;
132                     break;
133                   case aggMax:
134                     if (component > aggregateVal)
135                       aggregateVal = component;
136                     break;
137                   }
138
139                 /* move forward our time of our earliest sample */
140                 curr->lastSampleStart = earlyestTime;
141               }
142
143             // len is the number of samples on the list
144             if (aggOp == aggAvg)
145               aggregateVal /= len;
146
147             ret.valid = TRUE;
148             ret.start = lastSampleEnd;
149             ret.end = earlyestTime;
150             ret.value = aggregateVal;
151             assert(ret.value >= 0.0);
152
153             lastSampleStart = lastSampleEnd;
154             lastSampleEnd = earlyestTime;
155         } else {
156             ret.valid = FALSE;
157         }
158     }
159     return(ret);
160 }