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