Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

RecArrayAllocator.cxx

Go to the documentation of this file.
00001 
00002 //
00003 // RecArrayAllocator
00004 //
00005 // Package: Rec (Record).
00006 //
00007 // S. Kasahara 09/02
00008 //
00009 // Purpose: Singleton class used to manage the allocation of TClonesArrays
00010 //
00012 
00013 #include <string>
00014 #include <iostream>
00015 using std::endl;
00016 
00017 #include "TClonesArray.h"
00018 #include "TClass.h"
00019 
00020 #include "Record/RecArrayAllocator.h"
00021 #include "MessageService/MsgService.h"
00022 #include "MessageService/MsgFormat.h"
00023 
00024 std::ostream& operator << (std::ostream& os, const RecArrayAllocator& raa) 
00025                                                  { return raa.Print(os); }
00026 //   Definition of static data members
00027 //   *********************************
00028 
00029 CVSID("$Id: RecArrayAllocator.cxx,v 1.10 2006/05/11 18:47:14 schubert Exp $");
00030 
00031 ClassImp(RecArrayAllocator)
00032 
00033 //   Definition of static data members
00034 //   *********************************
00035 
00036 RecArrayAllocator* RecArrayAllocator::fgInstance = 0;
00037 
00038 // Definition of methods (alphabetical order)
00039 // ******************************************
00040 
00041 
00042 TClonesArray* const RecArrayAllocator::GetArray(const char* className) {
00043   //  Purpose:  Return TClonesArray of requested type, creating it if
00044   //            necessary.
00045   //
00046   //  Arguments: none.
00047   //
00048   //  Return:  const ptr to non-const TClonesArray.
00049   //
00050   //  Contact:   S. Kasahara
00051   //
00052 
00053   for ( ArrayMapItr itr = fArrayMap.begin(); itr != fArrayMap.end(); itr++ ) {
00054     if ( itr->second ) {
00055       // Array is free, check type
00056       TClonesArray* array = itr->first;
00057       if ( !strcmp(array->GetClass()->GetName(),className) ) {
00058         itr->second = false;
00059         MSG("Rec",Msg::kVerbose) 
00060         << "GetArray retrieved existing TClonesArray of type " << className
00061         << endl;
00062         return array;
00063       }
00064     }
00065   } 
00066 
00067   // No existing TClonesArray is available for use, create one here
00068   TClonesArray* array = new TClonesArray(className);
00069   fArrayMap.insert(std::make_pair(array,false));
00070   MSG("Rec",Msg::kVerbose) 
00071     << "GetArray created new TClonesArray to support type " << className
00072     << endl;
00073   return array;
00074    
00075 }
00076 
00077 RecArrayAllocator& RecArrayAllocator::Instance() {
00078   //  Purpose:  Return unique instance of RecArrayAllocator, creating it
00079   //            if necessary.
00080   //
00081   //  Arguments: none.
00082   //
00083   //  Return:  reference to RecArrayAllocator.
00084   //
00085   //  Contact:   S. Kasahara
00086   //
00087 
00088   static Cleaner cleaner; // Cleaner destructor provides cleanup of singleton
00089   if ( fgInstance == 0 ) {
00090     cleaner.UseMe(); // dummy call to quiet compiler warnings
00091     fgInstance = new RecArrayAllocator();
00092     MSG("Rec",Msg::kDebug) << "Constructed RecArrayAllocator instance "
00093                            << fgInstance << endl;
00094   }
00095   return *fgInstance;
00096 
00097 }
00098 
00099 void RecArrayAllocator::ReleaseArray(TClonesArray* array) {
00100   //  Purpose:  Dereference use of TClonesArray, freeing it for reuse.
00101   //
00102   //  Arguments: ptr to TClonesArray to be dereferenced.
00103   //
00104   //  Return:  none.
00105   //
00106   //  Contact:   S. Kasahara
00107   //
00108 
00109   // clears array.  The user has the responsibility of i)calling 
00110   // TClonesArray::Delete() before releasing array if the stored objects 
00111   // allocate memory, or ii)alternatively implementing a Clear method for these
00112   // objects that frees up any allocated memory. This method will be called
00113   // by the array->Clear("C") call below.
00114   if ( array ) { 
00115     ArrayMapItr itr = fArrayMap.find(array);
00116     if ( itr != fArrayMap.end() ) {
00117       MSG("Rec",Msg::kVerbose) << "ReleaseArray of type " 
00118                                << array->GetClass()->GetName() << endl; 
00119       array -> Clear("C");
00120       itr->second = true;
00121     }
00122     else {
00123       MSG("Rec",Msg::kWarning) << "Release array request for type " 
00124                                << array->GetClass()->GetName() << " ptr "
00125                                << array << " is not in array map! Ignored." 
00126                                << endl;
00127     } 
00128   }
00129 }
00130 
00131 std::ostream& RecArrayAllocator::Print(std::ostream& os) const {
00132   //  Purpose:  Print current map of arrays maintained by array allocator on
00133   //            ostream.
00134   //
00135   //  Arguments: ms ostream to display on.
00136   //
00137   //  Return:  ostream reference.
00138   //
00139   //  Contact:   S. Kasahara
00140   //
00141 
00142   int size = fArrayMap.size();
00143   if ( size <= 0 ) {
00144     os << "RecArrayAllocator is currently not managing any arrays." << endl;
00145     return os;
00146   }
00147 
00148   os << "RecArrayAllocator is currently managing " << size 
00149      << " array" << ((size > 1) ? "s:" : ":") << endl;
00150   
00151   int i=0; 
00152   for( ArrayMapConstItr itr = fArrayMap.begin();itr != fArrayMap.end();itr++) {
00153     os << " " << i << ")Serves class " << itr->first->GetClass()->GetName() 
00154        << ((itr->second) ? " and is available." : 
00155        " and is in use.") << endl;
00156     i++;   
00157   }
00158   return os;
00159 
00160 }
00161 
00162 RecArrayAllocator::RecArrayAllocator()  {
00163   // Purpose: Default constructor.
00164   //
00165   // Arguments: none.
00166   //
00167   // Return: n/a.
00168   //
00169   // Contact:  S. Kasahara
00170   //
00171   // Notes: Not called directly, use RecArrayAllocator::Instance() instead.
00172 
00173 }
00174 
00175 RecArrayAllocator::~RecArrayAllocator() {
00176   //  Purpose:  Destructor.
00177   //
00178   //  Arguments: none.
00179   //
00180   //  Return:  none.
00181   //
00182   //  Contact:   S. Kasahara
00183   //
00184   
00185   // Close all managed arrays and retrieve allocated memory
00186   MSG("Rec",Msg::kDebug) << "RecArrayAllocator destructor for addr " 
00187                          << this << endl;
00188   
00189   for( ArrayMapItr itr = fArrayMap.begin(); itr != fArrayMap.end(); itr++ ) {
00190     TClonesArray* array = itr -> first;
00191     if ( array ) {
00192       if ( !(itr->second) ) {
00193         MSG("Rec",Msg::kWarning) << "RecArrayAllocator dtor deleting array "
00194                                  << array->GetClass()->GetName() 
00195                                  << " which has not been released!" << endl;
00196       }
00197       else {
00198         MSG("Rec",Msg::kDebug) << "Clearing and Deleting array of type " 
00199                                << array->GetClass()->GetName() << endl;
00200       }
00201       array -> Clear("C");
00202       delete array; array = 0;
00203     }
00204     fArrayMap.erase(itr);
00205   }
00206   
00207 }
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 

Generated on Mon Feb 15 11:07:29 2010 for loon by  doxygen 1.3.9.1