changes relating to phase interface stuff
[dyninst.git] / visi / src / datagrid.C
1 /*
2  * Copyright (c) 1993, 1994 Barton P. Miller, Jeff Hollingsworth,
3  *     Bruce Irvin, Jon Cargille, Krishna Kunchithapadam, Karen
4  *     Karavanic, Tia Newhall, Mark Callaghan.  All rights reserved.
5  * 
6  * This software is furnished under the condition that it may not be
7  * provided or otherwise made available to, or used by, any other
8  * person, except as provided for by the terms of applicable license
9  * agreements.  No title to or ownership of the software is hereby
10  * transferred.  The name of the principals may not be used in any
11  * advertising or publicity related to this software without specific,
12  * written prior authorization.  Any use of this software must include
13  * the above copyright notice.
14  *
15  */
16 /* $Log: datagrid.C,v $
17 /* Revision 1.16  1995/08/01 01:59:33  newhall
18 /* changes relating to phase interface stuff
19 /*
20  * Revision 1.15  1995/06/02  21:02:04  newhall
21  * changed type of metric and focus handles to u_int
22  *
23  * Revision 1.14  1995/02/26  01:59:37  newhall
24  * added phase interface functions
25  *
26  * Revision 1.13  1994/11/02  04:14:57  newhall
27  * memory leak fixes
28  *
29  * Revision 1.12  1994/08/11  02:52:09  newhall
30  * removed calls to grid cell Deleted member functions
31  *
32  * Revision 1.11  1994/07/30  03:25:35  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:50  newhall
38  * added FirstValidBucket method function to visi_GridCellHisto class
39  *
40  * Revision 1.9  1994/07/07  22:40:30  newhall
41  * fixed compile warnings
42  *
43  * Revision 1.8  1994/06/16  18:24:50  newhall
44  * fix to visualization::Data
45  *
46  * Revision 1.7  1994/06/07  17:48:46  newhall
47  * support for adding metrics and resources to existing visualization
48  *
49  * Revision 1.6  1994/05/23  20:56:46  newhall
50  * To visi_GridCellHisto class: added deleted flag, SumValue
51  * method function, and fixed AggregateValue method function
52  *
53  * Revision 1.5  1994/05/11  17:12:44  newhall
54  * changed data values type from double to float
55  * fixed fold method function to support a folding
56  * at any point in the histogram, rather than only
57  * when the histogram is full
58  *
59  * Revision 1.4  1994/03/26  04:19:46  newhall
60  * changed all floats to double
61  * fix problem with null string returned for first resource name
62  *
63  * Revision 1.3  1994/03/17  05:19:59  newhall
64  * changed bucket width and time value's type to double
65  *
66  * Revision 1.2  1994/03/14  20:28:44  newhall
67  * changed visi subdirectory structure
68  *  */ 
69 ///////////////////////////////////////////////
70 // Member functions for the following classes:
71 //  Metric, Resource, visi_GridCellHisto,
72 //  visi_GridHistoArray, visi_DataGrid
73 ///////////////////////////////////////////////
74 #include "visi/h/datagrid.h" 
75
76 Metric::Metric(string metricUnits,
77                string metricName,
78                u_int id,
79                int foldMethod){
80
81   units = metricUnits;
82   name = metricName;
83   Id    = id;
84   if(foldMethod == AVE)
85     aggregate = foldMethod;
86   else
87     aggregate = SUM;
88 }
89
90 //
91 //  Metric destructor
92 //
93 Metric::~Metric(){
94   Id = 0;
95 }
96
97 ///////////////////////////////////////////
98 //
99 //  Resource constructor
100 //
101 Resource::Resource(string resourceName,
102                    u_int id){
103
104   if(resourceName.string_of() != NULL){
105     name = resourceName; 
106     Id = id;
107   }
108   else {
109     name = NULL;
110     Id = 0;
111   }
112 }
113
114 //
115 //  Resource destructor
116 //
117 Resource::~Resource(){
118 }
119
120 ///////////////////////////////////////////
121 //
122 //  visi_GridCellHisto constructor
123 //
124 visi_GridCellHisto::visi_GridCellHisto(int numElements){
125
126  int i;
127     
128  if(numElements > 0){  
129    value = new sampleType[numElements];
130    for(i = 0; i < numElements; i++)
131      value[i] = ERROR;
132    valid      = 1;
133  }
134  enabled = 0;
135  size       = numElements;
136  lastBucketFilled = -1;
137  firstValidBucket = -1;
138 }
139
140 //
141 // destructor for class visi_GridCellHisto
142 //
143 visi_GridCellHisto::~visi_GridCellHisto(){
144
145   if(value) delete[] value;
146   value = 0;
147   valid = 0;
148   enabled = 0;
149   size = 0;
150 }
151
152 ///////////////////////////////////////////
153 //
154 // constructor for class GridHistoArray
155 //
156 visi_GridHistoArray::visi_GridHistoArray(int numElements){
157
158  if(numElements > 0){  
159    values = new visi_GridCellHisto[numElements];
160  }
161  size = numElements;
162
163 }
164
165
166 //
167 // destructor for class GridHistoArray
168 //
169 visi_GridHistoArray::~visi_GridHistoArray(){
170
171   delete[] values;
172 }
173
174 //
175 // evaluates to true if the grid cell indexed by i (foucus index)
176 // contains a histogram (is a valid metric/focus pair)
177 //
178 int visi_GridHistoArray::Valid(int i){
179
180   if ((i< 0) || (i>= size)){
181     visi_ErrorHandler(ERROR_SUBSCRIPT,"visi_GridHistoArray::Valid");
182     return(ERROR_SUBSCRIPT);  
183   }
184   return(values[i].Valid());
185
186 }
187
188
189 //
190 // invalidates the grid cell indexed by i 
191 //
192 int visi_GridHistoArray::Invalidate(int i){
193
194   if ((i< 0) || (i>= size)){
195     visi_ErrorHandler(ERROR_SUBSCRIPT,"visi_GridHistoArray::Invalidate");
196     return(ERROR_SUBSCRIPT);  
197   }
198   values[i].Invalidate();
199   return(OK);
200 }
201
202
203 //
204 // add new elements to the values array
205 //
206 int visi_GridHistoArray::AddNewResources(int howmany){
207
208 visi_GridCellHisto *temp = 0;
209
210   if(howmany > 0){
211     temp = values;
212     values = new visi_GridCellHisto[howmany + size];
213     for(int i = 0; i < size; i++){
214        if(values[i].AddNewValues(temp[i].Value(),
215                                   temp[i].Size(),
216                                   temp[i].LastBucketFilled(),
217                                   temp[i].userdata,
218                                   temp[i].Valid(),
219                                   temp[i].Enabled()) != OK){
220          return(ERROR_CREATEGRID);
221        }
222        temp[i].userdata = NULL;
223     }
224     size += howmany;
225     
226   }
227   delete[] temp;
228   return(OK);
229
230 }
231
232
233 //
234 //  add new elements to the values array
235 //
236 int visi_GridHistoArray::AddNewValues(visi_GridCellHisto *rarray,int howmany){
237
238   values = rarray;
239   size   = howmany;
240   rarray = NULL;
241   return(OK);
242
243 }
244
245 ///////////////////////////////////////////
246 //
247 // DataGrid constructor: creates metric and 
248 // resource lists and empty datagrid
249 //
250 visi_DataGrid::visi_DataGrid(int noMetrics,
251                              int noResources,
252                              Metric *metricList,
253                              Resource *resourceList,
254                              int noBins,
255                              timeType width,
256                              timeType startTime,
257                              int phaseHandle){
258 int i;
259
260   numMetrics   = noMetrics;
261   numResources = noResources;
262   metrics      = new Metric[noMetrics];
263   resources    = new Resource[noResources];
264
265   for(i = 0; i < noMetrics; i++){
266     metrics[i].Metric(metricList[i].Units(),metricList[i].Name(),
267                       metricList[i].Identifier(),metricList[i].Aggregate());
268   }
269   for(i = 0; i < noResources; i++){
270     resources[i].Resource(resourceList[i].Name(),resourceList[i].Identifier());
271   }
272
273   data_values = new visi_GridHistoArray[noMetrics];
274   for (i = 0; i < noMetrics; i++)
275     data_values[i].visi_GridHistoArray(noResources);
276   numBins  = noBins;
277   binWidth = width;
278   start_time = startTime;
279   phase_handle = phaseHandle;
280
281 }
282
283
284 //
285 // DataGrid constructor: creates metric and 
286 // resource lists and empty datagrid
287 //
288 visi_DataGrid::visi_DataGrid(int noMetrics,
289                              int noResources,
290                              visi_metricType *metricList,
291                              visi_resourceType *resourceList,
292                              int noBins,
293                              timeType width,
294                              timeType startTime,
295                              int phaseHandle){
296 int i;
297
298   numMetrics   = noMetrics;
299   numResources = noResources;
300   metrics      = new Metric[noMetrics];
301   resources    = new Resource[noResources];
302
303   for(i = 0; i < noMetrics; i++){
304     metrics[i].Metric(metricList[i].units,metricList[i].name,
305                       metricList[i].Id,metricList[i].aggregate);
306   }
307   for(i = 0; i < noResources; i++){
308     resources[i].Resource(resourceList[i].name,resourceList[i].Id);
309   }
310   data_values = new visi_GridHistoArray[noMetrics];
311   for (i = 0; i < noMetrics; i++)
312     data_values[i].visi_GridHistoArray(noResources);
313   numBins  = noBins;
314   binWidth = width;
315   start_time = startTime;
316   phase_handle = phaseHandle;
317
318 }
319
320
321
322 //
323 //  DataGrid destructor 
324 //
325 visi_DataGrid::~visi_DataGrid(){
326
327   delete[] resources;
328   delete[] metrics;
329   delete[] data_values;
330 }
331
332 const char *visi_DataGrid::GetMyPhaseName(){
333
334     if (phase_handle == -1) return ("Global");
335     if (phase_handle >= 0){
336         for(unsigned i = 0; i < phases.size(); i++){
337             if(phase_handle == phases[i]->getPhaseHandle()){
338                 return phases[i]->getName();
339     }}}
340     return 0;
341 }
342
343 // 
344 // returns metric name for metric number i 
345 //
346 const char   *visi_DataGrid::MetricName(int i){
347   if((i < numMetrics) && (i>=0))
348     return(metrics[i].Name());
349   return(NULL);
350 }
351
352 // 
353 // returns metric units for metric number i 
354 //
355 const char *visi_DataGrid::MetricUnits(int i){
356
357   if((i < numMetrics) && (i>=0))
358     return(metrics[i].Units());
359   return(NULL);
360 }
361
362
363 // 
364 // returns resource name for resource number j 
365 //
366 const char     *visi_DataGrid::ResourceName(int j){
367
368   if((j < numResources) && (j>=0))
369     return(resources[j].Name());
370   return(NULL);
371 }
372
373
374 // 
375 //  returns fold method for metric i 
376 //
377 int  visi_DataGrid::FoldMethod(int i){
378
379   if((i < numMetrics) && (i >= 0))
380     return(metrics[i].Aggregate());
381   visi_ErrorHandler(ERROR_SUBSCRIPT,"visi_DataGrid::FoldMethod");
382   return(ERROR_SUBSCRIPT);
383
384 }
385
386 // 
387 // returns metric identifier associated with metric number i 
388 //
389 u_int  *visi_DataGrid::MetricId(int i){
390
391   
392   if((i < numMetrics) && (i >= 0)){
393     u_int *ret = new u_int;
394     *ret = metrics[i].Identifier();
395     return(ret);
396   }
397   visi_ErrorHandler(ERROR_SUBSCRIPT,"visi_DataGrid::MetricId");
398   return(NULL);
399 }
400
401 // 
402 // returns resource identifier associated with resource number j 
403 //
404 u_int  *visi_DataGrid::ResourceId(int j){
405
406   if((j < numResources) && (j >= 0)){
407     u_int *ret = new u_int;
408     *ret = resources[j].Identifier();
409     return(ret);
410   }
411   visi_ErrorHandler(ERROR_SUBSCRIPT,"visi_DataGrid::ResourceId");
412   return(NULL);
413 }
414
415 //
416 // returns 1 if datagrid element indicated by metric#, resource#
417 // contains histogram values, otherwise returns false
418 //
419 int visi_DataGrid::Valid(int metric, 
420                          int resource){
421
422   if((metric < 0) || (metric >= numMetrics)){
423     visi_ErrorHandler(ERROR_SUBSCRIPT,"visi_HistoDataGrid::Valid");
424     return(ERROR_SUBSCRIPT);
425   }
426   return(data_values[metric].Valid(resource));
427
428 }
429
430 //
431 // invalidates data_grid element indicated by metric#, resource#
432 // sets valid to 0 and frees histogram space 
433 //
434 int visi_DataGrid::Invalidate(int metric,
435                               int resource){
436
437   if((metric < 0) || (metric >= numMetrics)){
438     visi_ErrorHandler(ERROR_SUBSCRIPT,"visi_HistoDataGrid::Invalidate");
439     return(ERROR_SUBSCRIPT);
440   }
441   return(data_values[metric].Invalidate(resource));
442
443 }
444
445
446 //
447 // adds a new set of resources to the data grid
448 //
449 int visi_DataGrid::AddNewResource(int howmany,visi_resourceType *rlist){
450
451 Resource *temp;
452 int i,ok;
453
454   // add new values to resource list
455   temp = resources;
456   resources = new Resource[numResources + howmany];
457
458   for(i = 0; i < numResources; i++){
459       resources[i].Resource(temp[i].Name(),temp[i].Identifier());
460   }
461   for(i = numResources; i < (numResources + howmany); i++){
462       resources[i].Resource(rlist[i-numResources].name,
463                           rlist[i-numResources].Id);
464   }
465
466   numResources += howmany;
467
468   // add space to data grid for new resources
469   for(i = 0; i < numMetrics; i++){
470       if((ok = data_values[i].AddNewResources(howmany)) != OK){
471           delete[] temp;
472           temp = 0;
473           return(ok); 
474       }
475   }
476
477   delete[] temp;
478   temp = 0;
479   return(OK);
480 }
481
482
483 //
484 //  adds a new set of resources to the data grid
485 //
486 int visi_DataGrid::AddNewMetrics(int howmany,visi_metricType *mlist){
487
488 visi_GridHistoArray *tempdata;
489 Metric *temp;
490 int i;
491
492   // add new values to metric list
493   temp = metrics;
494   metrics = new Metric[numMetrics + howmany];
495
496   for(i = 0; i < numMetrics; i++){
497     metrics[i].Metric(temp[i].Units(),temp[i].Name(),
498                       temp[i].Identifier(),temp[i].Aggregate());
499   }
500   for(i = numMetrics; i < (numMetrics + howmany); i++){
501     metrics[i].Metric(mlist[i-numMetrics].units, mlist[i-numMetrics].name,
502                        mlist[i-numMetrics].Id, mlist[i-numMetrics].aggregate);
503   }
504
505
506   // add space to data grid for new metrics
507
508   tempdata = data_values;
509   data_values = new visi_GridHistoArray[numMetrics + howmany];
510
511   for(i=0; i < numMetrics; i++){
512     if(data_values[i].AddNewValues(tempdata[i].Value(),tempdata[i].Size())
513        != OK){
514        return(ERROR_CREATEGRID); 
515     }
516   }
517
518   for(i=numMetrics; i < (numMetrics + howmany); i++){
519     data_values[i].visi_GridHistoArray(numResources);
520   }
521
522   numMetrics += howmany;
523   tempdata = NULL;
524   return(OK);
525
526 }
527
528
529 //
530 //  returns 1 if metric with Id equal to test_id is in the data grid
531 //
532 int visi_DataGrid::MetricInGrid(u_int test_id){
533
534   for(int i = 0; i < numMetrics; i++){
535     if (test_id == metrics[i].Identifier()){
536       return(1);
537     }
538   }
539   return(0);
540 }
541
542
543 //
544 //  returns 1 if resource with Id equal to test_id is in the data grid
545 //
546 int visi_DataGrid::ResourceInGrid(u_int test_id){
547
548   for(int i = 0; i < numResources; i++){
549     if (test_id == resources[i].Identifier()){
550       return(1);
551     }
552   }
553   return(0);
554 }
555
556 int phaseCompare(const void *p1, const void *p2) {
557    const PhaseInfo *ph1 = *((const PhaseInfo **)p1);
558    const PhaseInfo *ph2 = *((const PhaseInfo **)p2);
559    return(ph1->getPhaseHandle() - ph2->getPhaseHandle());
560 }
561
562 void visi_DataGrid::AddNewPhase(int handle, timeType start, timeType end,
563                       timeType width, string name){
564     PhaseInfo *p = new PhaseInfo(handle,start,end,width,name);
565     phases += p;
566     phases.sort(phaseCompare);
567
568 }
569