more chages to visiLib interface
[dyninst.git] / visi / src / datagridP.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: datagridP.h,v $
20 /* Revision 1.2  1996/01/19 20:55:42  newhall
21 /* more chages to visiLib interface
22 /*
23  * Revision 1.1  1996/01/17 18:29:15  newhall
24  * reorginization of visiLib
25  *
26  * Revision 1.22  1995/12/18 23:22:29  newhall
27  * changed metric units type so that it can have one of 3 values (normalized,
28  * unnormalized or sampled)
29  *
30  * Revision 1.21  1995/11/17  17:27:54  newhall
31  * added normalized member to Metric class which specifies units type
32  * added MetricLabel, MetricAveLabel, and MetricSumLabel DG method functions
33  *
34  * Revision 1.20  1995/11/12  23:29:24  newhall
35  * removed warnings, removed error.C
36  *
37  * Revision 1.19  1995/11/12  00:45:05  newhall
38  * added PARADYNEXITED event, added "InvalidSpans" dataGrid method
39  *
40  * Revision 1.18  1995/08/01  01:58:43  newhall
41  * changes relating to phase interface stuff
42  *
43  * Revision 1.17  1995/06/02  21:01:54  newhall
44  * changed type of metric and focus handles to u_int
45  *
46  * Revision 1.16  1995/02/26  01:59:27  newhall
47  * added phase interface functions
48  *
49  * Revision 1.15  1994/11/08  01:51:04  newhall
50  * array bounds error fix to visi_GridCellHisto::Value
51  *
52  * Revision 1.14  1994/11/02  04:14:35  newhall
53  * memory leak fixes
54  *
55  * Revision 1.13  1994/09/25  01:57:45  newhall
56  * added visi_DataGrid method functions ResourceIndex, MetricIndex
57  *
58  * Revision 1.12  1994/08/11  02:49:35  newhall
59  * removed deleted member to gridcell
60  *
61  * Revision 1.11  1994/07/30  03:25:25  newhall
62  * added enabled member to gridcell to indicate that the metric associated
63  * w/ this cell has been enabled and data will arrive for it eventually
64  * updated member functions affected by this addition
65  *
66  * Revision 1.10  1994/07/20  22:17:20  newhall
67  * added FirstValidBucket method function to visi_GridCellHisto class
68  *
69  * Revision 1.9  1994/06/16  18:21:46  newhall
70  * bug fix to AddNewValues
71  *
72  * Revision 1.8  1994/06/07  17:47:16  newhall
73  * added method functions to support adding metrics
74  * and resources to an existing data grid
75  *
76  * Revision 1.7  1994/05/23  20:55:16  newhall
77  * To visi_GridCellHisto class: added deleted flag, SumValue
78  * method function, and fixed AggregateValue method function
79  *
80  * Revision 1.6  1994/05/11  17:11:03  newhall
81  * changed data values from double to float
82  *
83  * Revision 1.5  1994/04/13  21:22:51  newhall
84  * *** empty log message ***
85  *
86  * Revision 1.4  1994/03/26  04:17:44  newhall
87  * change all floats to double
88  *
89  * Revision 1.3  1994/03/17  05:17:25  newhall
90  * added lastBucketFilled data member to class visi_GridCellHisto:  value of
91  * the largest bucket number for which new data values have been added
92  *
93  * Revision 1.2  1994/03/15  02:03:19  newhall
94  * added public member "userdata" to class visi_GridCellHisto
95  * to allow visi writer to add info to grid cells
96  *
97  * Revision 1.1  1994/03/14  20:27:26  newhall
98  * changed visi subdirectory structure
99  *  */ 
100 /////////////////////////////////
101 //  Data Grid Class definitions
102 /////////////////////////////////
103
104 #include <string.h>
105 #include <math.h>
106 #include <values.h>
107 #include "visi/src/visiTypesP.h"
108 #include "util/h/Vector.h"
109 #include "util/h/String.h"
110
111 #define SUM     0
112 #define AVE     1
113
114 class Metric{
115      string     units;    // how units are measured  i.e. "ms" 
116      string     name;     // for y-axis labeling  
117      u_int      Id;       // unique metric Id
118      int        aggregate; //either SUM or AVE, for fold operation 
119      visi_unitsType unitstype; // specifies units type
120      string     label;      // for data values, and ave. aggregate
121      string     total_label; // for sum aggregate 
122   public:
123      Metric(){name = 0; units = 0; Id = 0; aggregate=SUM;
124               unitstype = Normalized; label = 0; total_label = 0;}
125      Metric(string,string,u_int,int,visi_unitsType); 
126      ~Metric(); 
127      const char *Units(){return(units.string_of());}
128      const char *Name(){return(name.string_of());}
129      u_int       Identifier(){return(Id);}
130      int         Aggregate(){return(aggregate);}
131      visi_unitsType UnitsType(){return(unitstype);}
132      const char *Label(){return(label.string_of());}
133      const char *AveLabel(){return(label.string_of());}
134      const char *SumLabel(){return(total_label.string_of());}
135 };
136
137
138 class Resource{
139      string   name;     // obj. name for graph labeling
140      u_int    Id;       // unique resource id
141    public:
142      Resource(){name = NULL; Id = 0;}
143      Resource(string,u_int);
144      ~Resource();
145      const char *Name(){return(name.string_of());}
146      u_int    Identifier(){return(Id);}
147 };
148
149 class PhaseInfo{
150   private:
151     u_int phaseHandle;
152     visi_timeType startTime;
153     visi_timeType endTime;
154     visi_timeType bucketWidth;
155     string phaseName;
156   public:
157     PhaseInfo(){
158             phaseHandle = 0; startTime = -1.0; 
159             endTime = -1.0; bucketWidth = -1.0; phaseName = 0;
160     }
161     PhaseInfo(u_int h,visi_timeType s,visi_timeType e,visi_timeType w, string n){
162            phaseHandle = h;
163            startTime = s;
164            endTime = e;
165            bucketWidth = w;
166            phaseName = n;
167     }
168     ~PhaseInfo(){
169     }
170     void setStartTime(visi_timeType s){ startTime = s;}
171     void setEndTime(visi_timeType e){ endTime = e;}
172     void setBucketWidth(visi_timeType w){ bucketWidth = w;}
173     u_int  getPhaseHandle() const { return(phaseHandle);}
174     const char *getName() const{ return(phaseName.string_of());}
175     visi_timeType getStartTime() const{ return(startTime);}
176     visi_timeType getEndTime() const{ return(endTime);}
177     visi_timeType getBucketWidth() const{ return(bucketWidth);}
178 };
179
180
181 ///////////////////////////////////////////////////////////////////
182 // visi_GridCellHisto: 
183 // size: number of buckets
184 // lastBucketFilled: number of full buckets 
185 // valid:   indicates that the cell contains histogram data  
186 // enabled: indicates that the cell can accept data values 
187 // if enabled == 0 then no values can be added to the data grid
188 // if enabled == 1 and valid == 1 then data values are present
189 // if enabled == 1 and valid == 0 then values are not present, 
190 //                                but instrumentation  has been
191 //                                enabled for this cell
192 ///////////////////////////////////////////////////////////////////
193
194 class visi_GridCellHisto {
195   private:
196      int   valid;    // set when data values are present for this cell
197      int   firstValidBucket;  // first index into "value" that is not NaN
198      int   size;              // size of array "value"
199      int   lastBucketFilled;  // bucket number of last data value added
200      int   enabled;   // set when data values can be added to this cell
201      visi_sampleType *value;   // array of data values
202   public: 
203      void *userdata;  // to allow visi writer to add info to grid cells
204      visi_GridCellHisto(){value = NULL; valid = 0; size = 0; 
205                           userdata = NULL; lastBucketFilled = -1; 
206                           firstValidBucket = -1; enabled = 0;}
207      visi_GridCellHisto(int);
208      ~visi_GridCellHisto();
209      int    LastBucketFilled(){return(lastBucketFilled);}
210      visi_sampleType  *Value(){ return(value);}
211
212      visi_sampleType  Value(int i) { 
213             if((i < 0) || (i >= size)){
214              return(ERROR);
215             }
216             return(value[i]);
217      }
218
219      int    Size(){return(size);}
220      int    Valid(){return(valid);}
221      int    Enabled(){return(enabled);}
222      void   SetEnabled(){enabled = 1;}
223      void   ClearEnabled(){enabled = 0;}
224      int    FirstValidBucket() { return(firstValidBucket); }
225      void   Invalidate(){delete[] value; value = NULL; size = 0; 
226                          valid = 0; lastBucketFilled = -1;}
227
228      int    AddNewValues(visi_sampleType *temp,
229                          int arraySize,
230                          int lbf,
231                          void *ud,
232                          int v, 
233                          int e){
234         
235         if(temp == NULL){
236           value = NULL;
237           size = 0;
238         }
239         else{
240           // initialize cell to temp values
241           value = new visi_sampleType[arraySize];
242           size = arraySize;
243           for(int i=0;i<size;i++){
244             if(!isnan(temp[i])){
245               value[i] = temp[i]; 
246               if(firstValidBucket == -1)
247                  firstValidBucket = i;
248             }
249             else
250               value[i] = ERROR; 
251           }
252         }
253         lastBucketFilled = lbf;
254         userdata = ud;
255         valid = v;
256         enabled = e;
257         return(OK);
258      }
259
260      void   Fold(){
261        int i,j;
262        if(valid){
263          firstValidBucket = -1;
264          for(i=0,j=0;(i< (lastBucketFilled+1)/2) // new bucket counter
265              && (j< (lastBucketFilled+1)); // old bucket counter
266              i++,j+=2){
267            if((!isnan(value[j])) && (!isnan(value[j+1]))){
268              value[i] = value[j] + value[j+1];
269              if(firstValidBucket == -1){
270                firstValidBucket = i;
271              }
272            }
273            else{
274              value[i] = ERROR;
275            }
276            if((value[i] != ERROR))
277              value[i] = value[i]/2; 
278          }
279          for(i=(lastBucketFilled+1)/2; i < size; i++){
280            value[i] = ERROR;
281          }
282          lastBucketFilled = ((lastBucketFilled+1)/2)-1;
283        }
284      }
285
286      visi_sampleType  SumValue(visi_timeType width){
287        int i;
288        visi_sampleType sum;
289
290         if(value != NULL){
291            for(sum=0.0,i=0; i< size; i++){
292              if(!isnan(value[i])){
293                sum += value[i]; 
294              }
295            }
296            return(sum*width);
297         }
298         else{
299           return(ERROR);
300         }
301      }
302
303      visi_sampleType  AggregateValue(){
304         int i,num;
305         visi_sampleType sum;
306
307         if(value != NULL){
308            for(sum=0.0,num=i=0; i< size; i++){
309              if(!isnan(value[i])){
310                sum += value[i]; 
311                num++;
312              }
313            }
314
315            if(num != 0){
316              return(sum/(1.0*num));
317            }
318            else{
319              return(ERROR);
320            }
321         }
322         else{
323           return(ERROR);
324         }
325      }
326
327      // returns true when there are NaN spans of between valid data buckets
328      bool   InvalidSpans(){
329         if(value != NULL) {
330             for(int i = firstValidBucket; i < lastBucketFilled; i++){
331                 if(isnan(value[i])) return true;
332             }
333         }
334         return false;
335      }
336
337      int    AddValue(visi_sampleType x,
338                      int i,
339                      int numElements){
340         
341        int j;
342
343        if (!enabled){ // if this cell has not been enabled don't add values
344          return(OK);
345        }
346        if (!valid){ // if this is the first value create a histo cell array 
347          if(value == NULL)
348            value = new visi_sampleType[numElements];
349          size = numElements;
350          valid = 1;
351          enabled = 1;
352          for(j=0;j<size;j++){
353            value[j] = ERROR;
354          }
355        }
356        if((i < 0) || (i >= size))
357          return(ERROR_INT);
358        value[i] = x;
359        if(i > lastBucketFilled)
360         lastBucketFilled = i;
361        if(firstValidBucket == -1)
362          firstValidBucket = i;
363        return(OK);
364      }
365
366      visi_sampleType  operator[](int i){
367        if((i >= size) || (i < 0)){
368          return(ERROR);
369        }
370        return(value[i]);
371      }
372 };
373
374
375 ////////////////////////////////////////
376 // visi_GridHistoArray: 
377 ////////////////////////////////////////
378 class  visi_GridHistoArray {
379    private:
380       visi_GridCellHisto *values;
381       int size;
382    public:
383       visi_GridHistoArray(){values = NULL; size = 0;}
384       visi_GridHistoArray(int);
385       ~visi_GridHistoArray();
386
387       int LastBucketFilled(int resource){
388          if((resource < 0) || (resource >= size))
389            return(ERROR_INT);
390          else
391            return(values[resource].LastBucketFilled());
392       }
393
394       int AddValue(visi_sampleType x,
395                    int resource,
396                    int bucketNum,
397                    int numBuckets){
398
399          if((resource < 0) || (resource >= size))
400            return(ERROR_INT);
401          return(values[resource].AddValue(x,bucketNum,numBuckets));
402       }
403       int   Size(){ return(size);}
404       visi_GridCellHisto *Value(){return(values);}
405       int    Valid(int);
406       int    Invalidate(int);
407       int    AddNewResources(int);
408       int    AddNewValues(visi_GridCellHisto *,int);
409
410       void   Fold(){
411         int i;
412         for(i=0; i< size; i++)
413           values[i].Fold();
414       } 
415
416       visi_sampleType  AggregateValue(int i){
417         if((i>=0)&&(i<size))
418           return(values[i].AggregateValue());
419         else
420           return(ERROR);
421       }
422       visi_sampleType  SumValue(int i,visi_timeType width){
423         if((i>=0)&&(i<size))
424           return(values[i].SumValue(width));
425         else
426           return(ERROR);
427       }
428
429       // returns true if histogram in element "which" contains invalid
430       // spans of bucket values
431       bool InvalidSpans(int which){
432         if((which>=0)&&(which<size))
433           return(values[which].InvalidSpans());
434         else
435           return false;
436       }
437
438       visi_GridCellHisto&   operator[](int i){
439         if ((i>= 0) && (i < size)){
440           return(values[i]);
441         }
442         else{
443           return(values[0]);
444         }
445       }
446 };
447
448
449 ///////////////////////////////////////////////////////////////
450 // visi_DataGrid: 
451 // metrics:  list of metric info. for metrics in data grid 
452 // resources: list of resource info. for resources in data grid 
453 // numBins: number of bins in the histogram of each datagrid cell 
454 // binWidth: size of each bin in seconds
455 // data_values: array of size numMetrics each containing an array
456 //              of size numResources
457 ///////////////////////////////////////////////////////////////
458 class visi_DataGrid {
459  private:
460      Metric     *metrics;
461      Resource   *resources;
462      int         numMetrics;
463      int         numResources;
464      int         numBins;
465      visi_timeType    binWidth;
466      visi_GridHistoArray  *data_values;
467      vector<PhaseInfo *> phases;
468      visi_timeType   start_time;
469      int        phase_handle; // -1: global -2: not yet defined
470   public:
471      visi_DataGrid(){
472          metrics=NULL; 
473          resources=NULL; 
474          numMetrics=numResources=0;
475          data_values=NULL; 
476          numBins= 0; 
477          binWidth=0.0;
478          start_time = 0.0;
479          phase_handle = -2;
480      }
481
482      visi_DataGrid(int, int, Metric*, Resource*, int, visi_timeType, visi_timeType, int);
483      visi_DataGrid(int, int, visi_metricType*, visi_resourceType*,
484                    int, visi_timeType, visi_timeType, int);
485      ~visi_DataGrid();
486      const char *MetricName(int i);
487      const char *MetricUnits(int i);
488      const char *MetricLabel(int i);
489      const char *MetricAveLabel(int i);
490      const char *MetricSumLabel(int i);
491      const char *ResourceName(int j);
492      int        NumMetrics(){return(numMetrics);}
493      int        FoldMethod(int);
494      int        NumResources(){return(numResources);}
495      u_int      MetricId(int,bool&); // returns metric Id
496      u_int      ResourceId(int,bool&); // returns Resource Id
497      int        NumBins(){return(numBins);}
498      visi_timeType   BinWidth(){return(binWidth);}
499      int        Valid(int,int);  
500      int        Invalidate(int,int);
501      int        AddNewMetrics(int,visi_metricType *);
502      int        AddNewResource(int,visi_resourceType *);
503      int        ResourceInGrid(u_int);
504      int        MetricInGrid(u_int);
505      u_int      NumPhases(){ return(phases.size());}
506      void       AddNewPhase(int,visi_timeType,visi_timeType,visi_timeType,string);
507      visi_timeType   GetStartTime(){ return(start_time);}
508      int        GetPhaseHandle(){return(phase_handle);}
509      const char *GetMyPhaseName();
510
511      const PhaseInfo    *GetPhaseInfo(unsigned i){
512             unsigned j = phases.size();
513             if((j == 0) || (i >= j)){
514                 return(NULL);
515             }
516             return(phases[i]);
517      }
518
519      int AddEndTime(visi_timeType end,unsigned handle){
520            PhaseInfo *p;
521
522            for(unsigned i = 0; i < phases.size(); i++){
523                p = phases[i]; 
524                if(p->getPhaseHandle() == handle){
525                   p->setEndTime(end);
526                   return(1);
527                }
528            }
529            return(0);
530      }
531
532      int        ResourceIndex(unsigned resId){
533              for(int i = 0; i < numResources; i++){
534                  if(resources[i].Identifier() == resId)
535                     return(i);
536              }
537              return(-1);
538      }
539
540      int        MetricIndex(unsigned metId){
541              for(int i = 0; i < numMetrics; i++){
542                  if(metrics[i].Identifier() == metId)
543                     return(i);
544              }
545              return(-1);
546      }
547
548      visi_sampleType AggregateValue(int i,int j){
549        if((i>=0)&&(i<numMetrics))
550          return(data_values[i].AggregateValue(j)); 
551        else
552          return(ERROR);
553      }
554
555      visi_sampleType  SumValue(int i,int j){
556        if((i>=0)&&(i<numMetrics))
557          return(data_values[i].SumValue(j,binWidth)); 
558        else
559          return(ERROR);
560      }
561
562      void  Fold(visi_timeType width){
563        int i;
564        for(i=0; i < numMetrics; i++)
565          data_values[i].Fold();
566        binWidth = width;
567      }
568
569      int AddValue(int metric, 
570                   int resource, 
571                   int bucket,
572                   visi_sampleType value){
573         if((metric < 0) || (metric >= numMetrics))
574            return(ERROR_INT);
575         return(data_values[metric].AddValue(value,resource,bucket,numBins));
576      }
577
578      visi_GridHistoArray&  operator[](int i){
579         if((i < 0) || (i >= numMetrics)){
580            return(data_values[0]);
581         }
582         return(data_values[i]);
583      }
584
585      int LastBucketFilled(int metric,int resource){
586         if((metric < 0) || (metric >= numMetrics))
587           return(ERROR_INT);
588         return(data_values[metric].LastBucketFilled(resource));
589      }
590
591      bool InvalidSpans(int metric, int resource){
592         if((metric < 0) || (metric >= numMetrics))
593             return false;
594         else 
595             return (data_values[metric].InvalidSpans(resource));
596      }
597
598 };
599 #endif