array bounds error fix to visi_GridCellHisto::Value
[dyninst.git] / visi / h / datagrid.h
1 #ifndef _datagrid_h
2 #define _datagrid_h
3 /*
4  * Copyright (c) 1993, 1994 Barton P. Miller, Jeff Hollingsworth,
5  *     Bruce Irvin, Jon Cargille, Krishna Kunchithapadam, Karen
6  *     Karavanic, Tia Newhall, Mark Callaghan.  All rights reserved.
7  * 
8  * This software is furnished under the condition that it may not be
9  * provided or otherwise made available to, or used by, any other
10  * person, except as provided for by the terms of applicable license
11  * agreements.  No title to or ownership of the software is hereby
12  * transferred.  The name of the principals may not be used in any
13  * advertising or publicity related to this software without specific,
14  * written prior authorization.  Any use of this software must include
15  * the above copyright notice.
16  *
17  */
18
19 /* $Log: datagrid.h,v $
20 /* Revision 1.15  1994/11/08 01:51:04  newhall
21 /* array bounds error fix to visi_GridCellHisto::Value
22 /*
23  * Revision 1.14  1994/11/02  04:14:35  newhall
24  * memory leak fixes
25  *
26  * Revision 1.13  1994/09/25  01:57:45  newhall
27  * added visi_DataGrid method functions ResourceIndex, MetricIndex
28  *
29  * Revision 1.12  1994/08/11  02:49:35  newhall
30  * removed deleted member to gridcell
31  *
32  * Revision 1.11  1994/07/30  03:25:25  newhall
33  * added enabled member to gridcell to indicate that the metric associated
34  * w/ this cell has been enabled and data will arrive for it eventually
35  * updated member functions affected by this addition
36  *
37  * Revision 1.10  1994/07/20  22:17:20  newhall
38  * added FirstValidBucket method function to visi_GridCellHisto class
39  *
40  * Revision 1.9  1994/06/16  18:21:46  newhall
41  * bug fix to AddNewValues
42  *
43  * Revision 1.8  1994/06/07  17:47:16  newhall
44  * added method functions to support adding metrics
45  * and resources to an existing data grid
46  *
47  * Revision 1.7  1994/05/23  20:55:16  newhall
48  * To visi_GridCellHisto class: added deleted flag, SumValue
49  * method function, and fixed AggregateValue method function
50  *
51  * Revision 1.6  1994/05/11  17:11:03  newhall
52  * changed data values from double to float
53  *
54  * Revision 1.5  1994/04/13  21:22:51  newhall
55  * *** empty log message ***
56  *
57  * Revision 1.4  1994/03/26  04:17:44  newhall
58  * change all floats to double
59  *
60  * Revision 1.3  1994/03/17  05:17:25  newhall
61  * added lastBucketFilled data member to class visi_GridCellHisto:  value of
62  * the largest bucket number for which new data values have been added
63  *
64  * Revision 1.2  1994/03/15  02:03:19  newhall
65  * added public member "userdata" to class visi_GridCellHisto
66  * to allow visi writer to add info to grid cells
67  *
68  * Revision 1.1  1994/03/14  20:27:26  newhall
69  * changed visi subdirectory structure
70  *  */ 
71 /////////////////////////////////
72 //  Data Grid Class definitions
73 /////////////////////////////////
74
75 #include <string.h>
76 #include  <math.h>
77 #include <values.h>
78 #include "visiTypes.h"
79
80 #define SUM     0
81 #define AVE     1
82
83 class Metric{
84      char       *units;    // how units are measured  i.e. "ms" 
85      char       *name;     // for y-axis labeling  
86      int         Id;       // unique metric Id
87      int         aggregate; //either SUM or AVE, for fold operation 
88   public:
89      Metric(){units = NULL; name = NULL; Id = NOVALUE; aggregate=SUM;}
90      Metric(char* ,char*,int,int); 
91      ~Metric(); 
92      char       *Units(){return(units);}
93      char       *Name(){return(name);}
94      int         Identifier(){return(Id);}
95      int         Aggregate(){return(aggregate);}
96 };
97
98
99 class Resource{
100      char    *name;     // obj. name for graph labeling
101      int      Id;       // unique resource id
102    public:
103      Resource(){name = NULL; Id = -1;}
104      Resource(char*,int);
105      ~Resource();
106      char     *Name(){return(name);}
107      int       Identifier(){return(Id);}
108 };
109
110
111 ///////////////////////////////////////////////////////////////////
112 // visi_GridCellHisto: 
113 // size: number of buckets
114 // lastBucketFilled: number of full buckets 
115 // valid:   indicates that the cell contains histogram data  
116 // enabled: indicates that the cell can accept data values 
117 // if enabled == 0 then no values can be added to the data grid
118 // if enabled == 1 and valid == 1 then data values are present
119 // if enabled == 1 and valid == 0 then values are not present, 
120 //                                but instrumentation  has been
121 //                                enabled for this cell
122 ///////////////////////////////////////////////////////////////////
123
124 class visi_GridCellHisto {
125   private:
126      int   valid;    // set when data values are present for this cell
127      int   firstValidBucket;  // first index into "value" that is not NaN
128      int   size;              // size of array "value"
129      int   lastBucketFilled;  // bucket number of last data value added
130      int   enabled;   // set when data values can be added to this cell
131      sampleType *value;   // array of data values
132   public: 
133      void *userdata;  // to allow visi writer to add info to grid cells
134      visi_GridCellHisto(){value = NULL; valid = 0; size = 0; 
135                           userdata = NULL; lastBucketFilled = -1; 
136                           firstValidBucket = -1; enabled = 0;}
137      visi_GridCellHisto(int);
138      ~visi_GridCellHisto();
139      int    LastBucketFilled(){return(lastBucketFilled);}
140      sampleType  *Value(){ return(value);}
141
142      sampleType  Value(int i) { 
143             if((i < 0) || (i >= size)){
144              return(ERROR);
145             }
146             return(value[i]);
147      }
148
149      int    Size(){return(size);}
150      int    Valid(){return(valid);}
151      int    Enabled(){return(enabled);}
152      void   SetEnabled(){enabled = 1;}
153      void   ClearEnabled(){enabled = 0;}
154      int    FirstValidBucket() { return(firstValidBucket); }
155      void   Invalidate(){delete[] value; value = NULL; size = 0; 
156                          valid = 0; lastBucketFilled = -1;}
157
158      int    AddNewValues(sampleType *temp,
159                          int arraySize,
160                          int lbf,
161                          void *ud,
162                          int v, 
163                          int e){
164         
165         if(temp == NULL){
166           value = NULL;
167           size = 0;
168         }
169         else{
170           // initialize cell to temp values
171           value = new sampleType[arraySize];
172           size = arraySize;
173           for(int i=0;i<size;i++){
174             if(!isnan(temp[i])){
175               value[i] = temp[i]; 
176               if(firstValidBucket == -1)
177                  firstValidBucket = i;
178             }
179             else
180               value[i] = ERROR; 
181           }
182         }
183         lastBucketFilled = lbf;
184         userdata = ud;
185         valid = v;
186         enabled = e;
187         return(OK);
188      }
189
190      void   Fold(int method){
191        int i,j;
192        if(valid){
193          firstValidBucket = -1;
194          for(i=0,j=0;(i< (lastBucketFilled+1)/2) // new bucket counter
195              && (j< (lastBucketFilled+1)); // old bucket counter
196              i++,j+=2){
197            if((!isnan(value[j])) && (!isnan(value[j+1]))){
198              value[i] = value[j] + value[j+1];
199              if(firstValidBucket == -1){
200                firstValidBucket = i;
201              }
202            }
203            else{
204              value[i] = ERROR;
205            }
206            if((value[i] != ERROR))
207              value[i] = value[i]/2; 
208          }
209          for(i=(lastBucketFilled+1)/2; i < size; i++){
210            value[i] = ERROR;
211          }
212          lastBucketFilled = ((lastBucketFilled+1)/2)-1;
213        }
214      }
215
216      sampleType  SumValue(timeType width){
217        int i;
218        sampleType sum;
219
220         if(value != NULL){
221            for(sum=0.0,i=0; i< size; i++){
222              if(!isnan(value[i])){
223                sum += value[i]; 
224              }
225            }
226            return(sum*width);
227         }
228         else{
229           return(ERROR);
230         }
231      }
232
233      sampleType  AggregateValue(int method){
234         int i,num;
235         sampleType sum;
236
237         if(value != NULL){
238            for(sum=0.0,num=i=0; i< size; i++){
239              if(!isnan(value[i])){
240                sum += value[i]; 
241                num++;
242              }
243            }
244
245            if(num != 0){
246              return(sum/(1.0*num));
247            }
248            else{
249              return(ERROR);
250            }
251         }
252         else{
253           visi_ErrorHandler(ERROR_AGGREGATE,"values == NULL");
254           return(ERROR_AGGREGATE);
255         }
256      }
257
258      int    AddValue(sampleType x,
259                      int i,
260                      int numElements){
261         
262        int j;
263
264        if (!enabled){ // if this cell has not been enabled don't add values
265          return(OK);
266        }
267        if (!valid){ // if this is the first value create a histo cell array 
268          if(value == NULL)
269            value = new sampleType[numElements];
270          size = numElements;
271          valid = 1;
272          enabled = 1;
273          for(j=0;j<size;j++){
274            value[j] = ERROR;
275          }
276        }
277        if((i < 0) || (i >= size))
278          return(ERROR_SUBSCRIPT);
279        value[i] = x;
280        if(i > lastBucketFilled)
281         lastBucketFilled = i;
282        if(firstValidBucket == -1)
283          firstValidBucket = i;
284        return(OK);
285      }
286
287      sampleType  operator[](int i){
288        if((i >= size) || (i < 0)){
289          visi_ErrorHandler(ERROR_SUBSCRIPT,
290                            "error in [] operator in histogridcell");
291          return(ERROR);
292        }
293        return(value[i]);
294      }
295 };
296
297
298 ////////////////////////////////////////
299 // visi_GridHistoArray: 
300 ////////////////////////////////////////
301 class  visi_GridHistoArray {
302    private:
303       visi_GridCellHisto *values;
304       int size;
305    public:
306       visi_GridHistoArray(){values = NULL; size = 0;}
307       visi_GridHistoArray(int);
308       ~visi_GridHistoArray();
309
310       int LastBucketFilled(int resource){
311          if((resource < 0) || (resource >= size))
312            return(ERROR_SUBSCRIPT);
313          else
314            return(values[resource].LastBucketFilled());
315       }
316
317       int AddValue(sampleType x,
318                    int resource,
319                    int bucketNum,
320                    int numBuckets){
321
322          if((resource < 0) || (resource >= size))
323            return(ERROR_SUBSCRIPT);
324          return(values[resource].AddValue(x,bucketNum,numBuckets));
325       }
326       int   Size(){ return(size);}
327       visi_GridCellHisto *Value(){return(values);}
328       int    Valid(int);
329       int    Invalidate(int);
330       int    AddNewResources(int);
331       int    AddNewValues(visi_GridCellHisto *,int);
332
333       void   Fold(int method){
334         int i;
335         for(i=0; i< size; i++)
336           values[i].Fold(method);
337       } 
338
339       sampleType  AggregateValue(int i,
340                              int method){
341         if((i>=0)&&(i<size))
342           return(values[i].AggregateValue(method));
343         else
344           return(ERROR);
345       }
346       sampleType  SumValue(int i,timeType width){
347         if((i>=0)&&(i<size))
348           return(values[i].SumValue(width));
349         else
350           return(ERROR);
351       }
352
353       visi_GridCellHisto&   operator[](int i){
354         if ((i>= 0) && (i < size)){
355           return(values[i]);
356         }
357         else{
358           visi_ErrorHandler(ERROR_SUBSCRIPT,
359                             "error in [] operator GridHistoArray");
360           return(values[0]);
361         }
362       }
363 };
364
365
366 ///////////////////////////////////////////////////////////////
367 // visi_DataGrid: 
368 // metrics:  list of metric info. for metrics in data grid 
369 // resources: list of resource info. for resources in data grid 
370 // numBins: number of bins in the histogram of each datagrid cell 
371 // binWidth: size of each bin in seconds
372 // data_values: array of size numMetrics each containing an array
373 //              of size numResources
374 ///////////////////////////////////////////////////////////////
375 class visi_DataGrid {
376  protected:
377      Metric     *metrics;
378      Resource   *resources;
379      int         numMetrics;
380      int         numResources;
381      int         numBins;
382      timeType    binWidth;
383      visi_GridHistoArray  *data_values;
384   public:
385      visi_DataGrid(){
386          metrics=NULL; 
387          resources=NULL; 
388          numMetrics=numResources=0;
389          data_values=NULL; 
390          numBins= 0; 
391          binWidth=0.0;
392      }
393
394      visi_DataGrid(int,int,Metric *,Resource *,int,timeType);
395      visi_DataGrid(int,int,visi_metricType *,visi_resourceType *,int,timeType);
396      virtual   ~visi_DataGrid();
397      char      *MetricName(int i);
398      char      *MetricUnits(int i);
399      char      *ResourceName(int j);
400      int        NumMetrics(){return(numMetrics);}
401      int        FoldMethod(int);
402      int        NumResources(){return(numResources);}
403      int        MetricId(int); // returns metric Id
404      int        ResourceId(int); // returns Resource Id
405      int        NumBins(){return(numBins);}
406      timeType   BinWidth(){return(binWidth);}
407      int        Valid(int,int);  
408      int        Invalidate(int,int);
409      int        AddNewMetrics(int,visi_metricType *);
410      int        AddNewResource(int,visi_resourceType *);
411      int        ResourceInGrid(int);
412      int        MetricInGrid(int);
413
414
415      int        ResourceIndex(int resId){
416              for(int i = 0; i < numResources; i++){
417                  if(resources[i].Identifier() == resId)
418                     return(i);
419              }
420              return(-1);
421      }
422
423      int        MetricIndex(int metId){
424              for(int i = 0; i < numMetrics; i++){
425                  if(metrics[i].Identifier() == metId)
426                     return(i);
427              }
428              return(-1);
429      }
430
431      sampleType AggregateValue(int i,int j){
432        if((i>=0)&&(i<numMetrics))
433          return(data_values[i].AggregateValue(j,metrics[i].Aggregate())); 
434        else
435          return(ERROR);
436      }
437
438      sampleType  SumValue(int i,int j){
439        if((i>=0)&&(i<numMetrics))
440          return(data_values[i].SumValue(j,binWidth)); 
441        else
442          return(ERROR);
443      }
444
445      void  Fold(timeType width){
446        int i;
447        for(i=0; i < numMetrics; i++)
448          data_values[i].Fold(metrics[i].Aggregate());
449        binWidth = width;
450      }
451
452      int AddValue(int metric, 
453                   int resource, 
454                   int bucket,
455                   sampleType value){
456         if((metric < 0) || (metric >= numMetrics))
457            return(ERROR_SUBSCRIPT);
458         return(data_values[metric].AddValue(value,resource,bucket,numBins));
459      }
460
461      visi_GridHistoArray&  operator[](int i){
462         if((i < 0) || (i >= numMetrics)){
463            visi_ErrorHandler(ERROR_SUBSCRIPT,
464                            "error in [] operator DATAGRID");
465            return(data_values[0]);
466         }
467         return(data_values[i]);
468      }
469
470      int LastBucketFilled(int metric,int resource){
471         if((metric < 0) || (metric >= numMetrics))
472           return(ERROR_SUBSCRIPT);
473         return(data_values[metric].LastBucketFilled(resource));
474      }
475
476 };
477 #endif