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