PlexLoanPool Class Reference

#include <PlexLoanPool.h>

Inheritance diagram for PlexLoanPool:

CfgConfigurable List of all members.

Public Member Functions

virtual void Config ()
virtual const RegistryDefaultConfig () const
virtual void SetConfigFromEnvironment ()
void ClearPool (Bool_t shared, Bool_t modifiable)
void PurgeComponents (UInt_t purgeMask=0)
bool DoesValidPlexExist (const VldContext &vldc, Bool_t shared=kTRUE)
bool PurgeDbiTableCache () const
void Print (Option_t *option="") const
 PlexLoanPool ()

Static Public Member Functions

static PlexLoanPoolInstance ()
static void SaveToFile (const char *filename, bool recreate=true)
static void ReadFromFile (const char *filename)

Private Member Functions

 PlexLoanPool (const PlexLoanPool &plp)
virtual ~PlexLoanPool ()
PlexusGetPlexus (const VldContext &vldc, Bool_t shared)
PlexusGetExistingPlexus (const VldContext &vldc, Bool_t shared)
PlexusBuildPlexus (const VldContext &vldc)

Private Attributes

TObjArray fSharedPlexusList
TObjArray fPrivatePlexusList
Int_t fMaxSharedUnref

Static Private Attributes

static PlexLoanPoolfgInstance = 0

Friends

class PlexHandle
struct Cleaner

Classes

struct  Cleaner

Detailed Description

Definition at line 23 of file PlexLoanPool.h.


Constructor & Destructor Documentation

PlexLoanPool::PlexLoanPool (  ) 

Definition at line 189 of file PlexLoanPool.cxx.

References fgInstance, fPrivatePlexusList, fSharedPlexusList, Msg::kSynopsis, Msg::kWarning, and MSG.

00190    : fMaxSharedUnref(dfltMaxUnused)
00191 {
00192    // Default ctor -- called by self only
00193 
00194    if (fgInstance && fgInstance != this) {
00195      MSG("Plex",Msg::kWarning)
00196        << "PlexLoanPool ctor() called but global already exists"
00197        << " -- memory leak (existing one will be lost)"
00198        << endl;
00199    }
00200    fgInstance = this;
00201 
00202    MSG("Plex",Msg::kSynopsis) << "PlexLoanPool ctor" << endl;
00203 
00204    fSharedPlexusList.SetOwner(true);
00205    fPrivatePlexusList.SetOwner(true);
00206 }

PlexLoanPool::PlexLoanPool ( const PlexLoanPool plp  )  [private]

Definition at line 209 of file PlexLoanPool.cxx.

References Msg::kFatal, and MSG.

00210   : TObject(plp), CfgConfigurable(plp)
00211 {
00212    // copy constuctor should never get called
00213    MSG("Plex",Msg::kFatal) << 
00214                "PlexLoanPool copy constructor called" << endl;
00215    assert(0);
00216 }

PlexLoanPool::~PlexLoanPool (  )  [private, virtual]

Definition at line 219 of file PlexLoanPool.cxx.

References fPrivatePlexusList, fSharedPlexusList, Registry::Get(), CfgConfigurable::GetConfig(), Registry::KeyExists(), Msg::kInfo, Msg::kSynopsis, MSG, and SaveToFile().

00220 {
00221   // Destroy PlexLoanPool
00222   // Write out to Cache first (if requested)
00223 
00224   MSG("Plex",Msg::kSynopsis) << "PlexLoanPool shutdown" << endl;
00225 
00226   Registry& r = GetConfig();
00227   if ( r.KeyExists("Cache") ) {
00228     const char* cache_location = "";
00229     if ( r.Get("Cache",cache_location) && strlen(cache_location) ) {
00230       int dowrite = true;
00231       if ( ! r.Get("CacheWrite",dowrite) ) {
00232         MSG("Plex",Msg::kInfo)
00233           << "PlexLoanPool not configured for 'CacheWrite', assume "
00234           << dowrite << "." << endl;
00235       }
00236       if (dowrite) {
00237         MSG("Plex",Msg::kInfo) 
00238           << "PlexLoanPool writing file " 
00239           << cache_location << " ..." << flush;
00240         PlexLoanPool::SaveToFile(cache_location);
00241         MSG("Plex",Msg::kInfo) << " done" << endl;
00242       }
00243     }
00244   }
00245   
00246   // delete all the owned sub-objects
00247   fSharedPlexusList.Delete();
00248   fPrivatePlexusList.Delete();
00249 }


Member Function Documentation

Plexus * PlexLoanPool::BuildPlexus ( const VldContext vldc  )  [private]

Definition at line 336 of file PlexLoanPool.cxx.

References Detector::AsString(), VldContext::GetDetector(), VldContext::GetSimFlag(), Detector::kCalDet, Detector::kFar, Msg::kFatal, Detector::kNear, SimFlag::kReroot, MSG, and Plexus::Plexus().

Referenced by GetPlexus().

00337 {
00338    // create a new Plexus from whereever
00339 
00340    Bool_t use_dbi = true;
00341 
00342    switch (vldc.GetDetector()) {
00343    case Detector::kNear:
00344       break;
00345    case Detector::kFar:
00346       break;
00347    case Detector::kCalDet:
00348       break;
00349    default:
00350       // not a detector that has DBI info
00351       use_dbi = false;
00352       break;
00353    }
00354 
00355    Plexus *plexus = 0;
00356 
00357    if (use_dbi) {
00358       plexus = new Plexus(vldc);
00359    }
00360    else if (vldc.GetSimFlag() == SimFlag::kReroot) {
00361       // use the PlexusReroot if it's reroot data and the database
00362       // isn't in place (which is the preferred option)
00363       //
00364       // was: plexus = new PlexusReroot(vldc);
00365       // remove circular dependency by using RTTI-like info
00366       // for PlexusReroot default ctor picks up vldc from RerootExodus
00367 
00368       static bool first = true;
00369       if (first) {
00370          first = false;
00371          gROOT->LoadClass("PlexusReroot","libRerootExodus.so");
00372       }
00373       void *ptr = gROOT->GetClass("PlexusReroot",kTRUE)->New();
00374       if (!ptr) {
00375          MSG("Plex",Msg::kFatal) 
00376             << "BuildPlexus failed to instantiate PlexusReroot "
00377             << vldc << endl;
00378          assert(0);
00379       }
00380       // can't dynamic_cast void* pointers
00381       //    plexus = dynamic_cast<PlexusReroot*>(ptr);
00382       //    plexus = dynamic_cast<Plexus *>(ptr);
00383       // PlexusReroot isn't know to be a base type for Plexus
00384       //    plexus = (PlexusReroot *)(ptr);
00385       plexus = (Plexus *)(ptr);
00386    }
00387    else {
00388       // the database isn't there and it's not reroot data
00389       TString detname = Detector::AsString(vldc.GetDetector());
00390       TString detNAME = detname;
00391       detNAME.ToUpper();
00392       MSG("Plex",Msg::kFatal)
00393          << "BuildPlexus " << endl << " vldc "<< vldc << endl 
00394          << "  no database info for the " << detname 
00395          << " detector (or this VldContext) is available yet" << endl
00396          << "  or NO_" << detNAME
00397          << "_PLEX_DATABASE needs to be switched off in GNUmakefile"
00398          << endl;
00399       exit(1);
00400    }
00401    return plexus;
00402 }

void PlexLoanPool::ClearPool ( Bool_t  shared,
Bool_t  modifiable 
)

Definition at line 141 of file PlexLoanPool.cxx.

References fPrivatePlexusList, and fSharedPlexusList.

00142 {
00143    if (shared)     fSharedPlexusList.Delete();
00144    if (modifiable) fPrivatePlexusList.Delete();
00145 }

void PlexLoanPool::Config (  )  [virtual]

Implements CfgConfigurable.

Definition at line 79 of file PlexLoanPool.cxx.

References fMaxSharedUnref, Registry::Get(), CfgConfigurable::GetConfig(), Msg::kDebug, and MSG.

00080 {
00081   // Reconfigure after internal registry update
00082 
00083   MSG("Plex",Msg::kDebug) << "PlexLoanPool::Config " << endl;
00084 
00085   Registry& r = GetConfig();
00086   // r.Print();
00087 
00088   int tmpi;
00089   if (r.Get("MaxUnref",tmpi)) fMaxSharedUnref = tmpi;
00090 
00091 }

const Registry & PlexLoanPool::DefaultConfig (  )  const [virtual]

Reimplemented from CfgConfigurable.

Definition at line 94 of file PlexLoanPool.cxx.

References dfltMaxUnused, Nav::GetName(), Registry::LockValues(), Registry::Set(), and Registry::UnLockValues().

00095 {
00096  //======================================================================
00097   // The default configuration for this framework component
00098   //======================================================================
00099   int itrue  = 1; // Work around for Registry's lack of bool
00100   //int ifalse = 0; // Work around for Registry's lack of bool
00101   static Registry r;
00102  
00103   std::string name = this->GetName();
00104   name += ".config.default";
00105   r.SetName(name.c_str());
00106 
00107   r.UnLockValues();
00108   r.Set("MaxUnref",              dfltMaxUnused);
00109   r.Set("Cache",                 "");     // use no cache by default
00110   r.Set("CacheWrite",            itrue);  // if cache used, write at job end
00111   r.Set("PurgeDbiTableCache",    itrue);  // purge Dbi cache when Plexus filled
00112   r.Set("Paranoia",              0);      // paranoia level for input checking
00113   r.LockValues();
00114 
00115   return r;
00116 
00117 }

bool PlexLoanPool::DoesValidPlexExist ( const VldContext vldc,
Bool_t  shared = kTRUE 
)

Definition at line 166 of file PlexLoanPool.cxx.

References GetExistingPlexus().

00167 {
00168    // testing if ctor of PlexHandle will construct a new plexus.
00169 
00170    Plexus *plex = GetExistingPlexus(vldc,shared);
00171    if (plex) return true;
00172    else      return false;
00173 }

Plexus * PlexLoanPool::GetExistingPlexus ( const VldContext vldc,
Bool_t  shared 
) [private]

Definition at line 308 of file PlexLoanPool.cxx.

References fPrivatePlexusList, fSharedPlexusList, Plexus::IsCompatible(), Msg::kVerbose, and MSG.

Referenced by DoesValidPlexExist(), and GetPlexus().

00309 {
00310    // Find the right plexus if it exists
00311 
00312    Plexus *plexus = 0;
00313 
00314    // plex should come from one of the two lists
00315    TObjArray*   plexList = &fSharedPlexusList;
00316    if (!shared) plexList = &fPrivatePlexusList; 
00317 
00318    // iterate from the back as that is what was added most recently
00319    // and thus most likely what we want
00320    TObjArrayIter iter(plexList,kIterBackward);
00321    // search the current list
00322    while ( ( plexus = dynamic_cast<Plexus *>(iter.Next()) ) ) {
00323      // check if it is compatible
00324      if ( plexus->IsCompatible(vldc) ) {
00325        // create another handle to this plexus
00326        MSG("Plex",Msg::kVerbose) << 
00327          "GetPlexus returned found handle " << endl;
00328        return plexus;
00329      }
00330    }
00331    return 0; // found nothing appropriate
00332 }

Plexus * PlexLoanPool::GetPlexus ( const VldContext vldc,
Bool_t  shared 
) [private]

Definition at line 252 of file PlexLoanPool.cxx.

References BuildPlexus(), Plexus::CountRef(), fMaxSharedUnref, fPrivatePlexusList, fSharedPlexusList, GetExistingPlexus(), Msg::kFatal, Msg::kVerbose, MSG, and VldContext::Print().

Referenced by PlexHandle::PlexHandle().

00253 {
00254    // Create/Find the right plexus to give to a handle
00255 
00256    Plexus *plexus = GetExistingPlexus(vldc,shared);
00257    if (plexus) return plexus;
00258    
00259    // no valid Plexus available, choose oen of the managed lists
00260    // plexus should be placed in
00261    TObjArray*   plexList = &fSharedPlexusList;
00262    if (!shared) plexList = &fPrivatePlexusList; 
00263    
00264    // first count the # of (other) unreferenced plexii
00265    Plexus *other_plex = 0;
00266    Int_t todelete = -fMaxSharedUnref;
00267    TObjArrayIter iter_cnt(plexList);
00268    while ( ( other_plex = (Plexus *)iter_cnt.Next() ) ) {
00269      if ( other_plex->CountRef() <= 0 ) todelete ++;
00270    }
00271    // if more unreferenced plexii than desired clean them out
00272    // iterate from the front (default) so oldest get cleaned out first
00273    if (todelete > 0) {
00274      TObjArrayIter iter_rm(plexList);
00275      while ( ( other_plex = (Plexus *)iter_rm.Next() ) &&
00276              todelete > 0 ) {
00277        if (other_plex->CountRef() <= 0 ) {
00278          fSharedPlexusList.Remove(other_plex);
00279          delete other_plex;
00280          todelete--;
00281        }
00282      }
00283      // remove the spaces we freed up
00284      plexList->Compress();
00285      MSG("Plex",Msg::kVerbose)
00286        << "GetPlexus removed old unref'd plexii" << endl;
00287    }
00288 
00289    // no valid Plexus available need to build one
00290    plexus = BuildPlexus(vldc);
00291    if ( !plexus ) {
00292      MSG("Plex",Msg::kFatal)
00293        << "PlexLoanPool failed to build for: " << endl;
00294      vldc.Print();
00295      assert(plexus);
00296    }
00297 
00298    // append this new plexus into the list
00299    MSG("Plex",Msg::kVerbose) << 
00300      "GetPlexus returned created new 'shared' Plexus " << endl;
00301    plexList->AddLast(plexus);
00302    
00303    return plexus;
00304 
00305 }

PlexLoanPool * PlexLoanPool::Instance (  )  [static]

Definition at line 49 of file PlexLoanPool.cxx.

References PlexLoanPool::Cleaner::ClassIsUsed(), Registry::Get(), Registry::KeyExists(), Msg::kSynopsis, Registry::LockKeys(), Registry::Merge(), MSG, and ReadFromFile().

Referenced by Plexus::BuildLedMaps(), Plexus::BuildPinDiodeMap(), Plexus::BuildPixelMaps(), Plexus::BuildReadoutMap(), PlexHandle::PlexHandle(), Plexus::Plexus(), SaveToFile(), and ExodusValidate::TestPlexHandle().

00050 {
00051 // protect Singleton to ensure there is only one
00052    if (fgInstance == 0) {
00053       MSG("Plex",Msg::kSynopsis) << "PlexLoanPool instance creation" << endl;
00054       static PlexLoanPool::Cleaner c; // end-of-run clean up
00055       c.ClassIsUsed();
00056 
00057       fgInstance = new PlexLoanPool;
00058 
00059       // initialize default configuration
00060       Registry& r = fgInstance->GetConfig();
00061       r.SetName("PlexLoanPool Configuration");
00062       r.Merge(fgInstance->DefaultConfig());
00063       r.LockKeys();
00064       fgInstance->SetConfigFromEnvironment();
00065       fgInstance->Update();
00066       // if Config has 'Cache' try reading that 
00067       // do this here rather than in Config() so that it only happens
00068       // on the first creation (i.e. later Config's don't redo this)
00069       if ( r.KeyExists("Cache") ) {
00070         const char* cache_location = "";
00071         if ( r.Get("Cache",cache_location) && strlen(cache_location) ) 
00072           PlexLoanPool::ReadFromFile(cache_location);
00073       }
00074    }
00075    return fgInstance;
00076 }

void PlexLoanPool::Print ( Option_t *  option = ""  )  const

Definition at line 405 of file PlexLoanPool.cxx.

References fPrivatePlexusList, fSharedPlexusList, CfgConfigurable::GetConfig(), Msg::kVerbose, MSG, option, Plexus::Print(), and Registry::Print().

Referenced by ExodusValidate::TestPlexHandle().

00406 {
00407 // Print info about the current loan pool
00408 
00409    Plexus *plexus;
00410 
00411    MSG("Plex",Msg::kVerbose) << "Print" << endl;
00412 
00413    GetConfig().Print();
00414 
00415    cout << " --- Shared PlexLoanPool ---" << endl;
00416    TIter shared(&fSharedPlexusList);
00417    while ( ( plexus = (Plexus *)shared.Next() ) ) plexus->Print(option);
00418 
00419    cout << " --- Private PlexLoanPool ---" << endl;
00420    TIter nonshared(&fPrivatePlexusList);
00421    while ( ( plexus = (Plexus *)nonshared.Next() ) ) plexus->Print(option);
00422 
00423    cout << " --- End of PlexLoanPool ---" << endl;
00424 }

void PlexLoanPool::PurgeComponents ( UInt_t  purgeMask = 0  ) 

Definition at line 148 of file PlexLoanPool.cxx.

References fPrivatePlexusList, fSharedPlexusList, and Plexus::PurgeComponents().

00149 {
00150   // loop through plexii held by the loan pool and
00151   // have them purge themselves of unwanted components
00152   // (generally only done before writing loan pool out)
00153 
00154   Plexus *plexus = 0;
00155 
00156   TObjArrayIter iter_shared(&fSharedPlexusList);
00157   while (( plexus = dynamic_cast<Plexus*>(iter_shared.Next()) )) 
00158     plexus->PurgeComponents(purgeMask);
00159 
00160   TObjArrayIter iter_private(&fPrivatePlexusList);
00161   while (( plexus = dynamic_cast<Plexus*>(iter_private.Next()) )) 
00162     plexus->PurgeComponents(purgeMask);
00163 }

bool PlexLoanPool::PurgeDbiTableCache (  )  const

Definition at line 176 of file PlexLoanPool.cxx.

References fgInstance, Registry::Get(), and CfgConfigurable::GetConfig().

00177 {
00178    // Does the config suggest that DbiTable caches should be purged
00179    // after the Plexus has been constructed?
00180 
00181    Registry& r = fgInstance->GetConfig();
00182    int dopurge = true;  // default
00183    r.Get("PurgeDbiTableCache",dopurge);
00184    return dopurge;
00185 
00186 }

void PlexLoanPool::ReadFromFile ( const char *  filename  )  [static]

Definition at line 442 of file PlexLoanPool.cxx.

References fgInstance, fPrivatePlexusList, fSharedPlexusList, CfgConfigurable::GetConfig(), gSystem(), Msg::kInfo, Msg::kWarning, MSG, and Registry::RemoveKey().

Referenced by Instance().

00443 {
00444   // read a PlexLoanPool from a file
00445   // ensure that there isn't a memory leak if a PlexLoanPool already exists
00446   // by merging the two
00447 
00448   if ( gSystem->AccessPathName(filename,kFileExists) ) {
00449     // note funky return value:  FALSE is you _can_ access file
00450     MSG("Plex",Msg::kInfo)
00451       << "PlexLoanPool::ReadFromFile() no such file: " << filename << endl;
00452     return;
00453   }
00454 
00455   // bitch in general because it really isn't a good idea!
00456   MSG("Plex",Msg::kInfo)
00457     << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl 
00458     << "PlexLoanPool::ReadFromFile() used to build some plexii. " << endl
00459     << "This is really not a safe thing to do in that it bypasses the" << endl
00460     << "database and thus is not subject to rolling updates.  Any plex" << endl
00461     << "will thus reflect the status at the time the file was written" << endl
00462     << "and may be outdated.  Use at your own risk." << endl
00463     << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
00464 
00465   PlexLoanPool* plpPrev = fgInstance;  // save any existing global
00466   fgInstance = 0;  // so we don't complain about a memory leak
00467 
00468   TFile f(filename);
00469   PlexLoanPool* plp = dynamic_cast<PlexLoanPool*>(f.Get("PlexLoanPool"));
00470 
00471   if (!plp) {
00472     // file didn't have any PlexLoanPool!
00473     MSG("Plex",Msg::kWarning)
00474       << "PlexLoanPool::ReadFromFile() found no pool in file:"
00475       << filename
00476       << endl;
00477     // revert to old
00478     fgInstance = plpPrev;
00479   }
00480   else if (plpPrev) {
00481     // file had a PlexLoanPool, but we already had one as well
00482     // merge the two
00483     MSG("Plex",Msg::kInfo)
00484       << "PlexLoanPool::ReadFromFile() will now merge newly read data "
00485       << "into prior loan pool" << endl;
00486     // make old loan pool the global one to preserve order
00487     fgInstance = plpPrev;
00488     // loop over elements of newly read pool and move them to global copy
00489     TObjArray *from, *to;
00490     for (int pubpriv = 0; pubpriv <= 1; ++pubpriv) {
00491       if (pubpriv) {
00492         from = &plp->fSharedPlexusList;
00493         to   = &fgInstance->fSharedPlexusList;
00494       }
00495       else {
00496         from = &plp->fPrivatePlexusList;
00497         to   = &fgInstance->fPrivatePlexusList;
00498       }
00499       for (int indx = 0; indx <= from->GetLast(); ++indx) {
00500         TObject* plexus = from->RemoveAt(indx);
00501         if (plexus) to->Add(plexus);
00502       } // loop over elements
00503     } // shared/private 
00504     // delete newly read, but now empty, pool
00505     // inhibit writing it out though
00506     plp->GetConfig().RemoveKey("Cache");
00507     delete plp;
00508   }
00509 
00510 }

void PlexLoanPool::SaveToFile ( const char *  filename,
bool  recreate = true 
) [static]

Definition at line 427 of file PlexLoanPool.cxx.

References Instance().

Referenced by ~PlexLoanPool().

00428 {
00429   // save a PlexLoanPool to a file
00430 
00431   PlexLoanPool* plp = PlexLoanPool::Instance(); // make sure there is one
00432 
00433   const char* fmode = "RECREATE";
00434   if (!recreate) fmode = "UPDATE";
00435   TFile f(filename,fmode);
00436   plp->Write();
00437   f.Write();
00438   f.Close();
00439 }

void PlexLoanPool::SetConfigFromEnvironment (  )  [virtual]

Definition at line 120 of file PlexLoanPool.cxx.

References gSystem(), Msg::kInfo, MSG, and UtilString::StringTok().

00121 {
00122   // Setup configuration from ENV_PLEX environment variable
00123   // which conists of a semi-colon separated list of DBI
00124   // configuration requests.
00125 
00126   const char* strENV_PLEX = gSystem->Getenv("ENV_PLEX");
00127   if ( strENV_PLEX == 0 || strlen(strENV_PLEX) == 0 ) return;
00128   
00129   MSG("Plex",Msg::kInfo) 
00130     << "Configuring Plex from the environment variable ENV_PLEX:" << endl
00131     << "   " << strENV_PLEX << endl;
00132 
00133   std::vector<std::string> configRequests;
00134   UtilString::StringTok(configRequests, strENV_PLEX, ";");
00135 
00136   for (unsigned entry = 0; entry < configRequests.size(); ++entry)
00137     this->Set(configRequests[entry].c_str());
00138 }


Friends And Related Function Documentation

friend struct Cleaner [friend]

Definition at line 64 of file PlexLoanPool.h.

friend class PlexHandle [friend]

Definition at line 25 of file PlexLoanPool.h.


Member Data Documentation

PlexLoanPool * PlexLoanPool::fgInstance = 0 [static, private]

Definition at line 71 of file PlexLoanPool.h.

Referenced by PlexLoanPool(), PurgeDbiTableCache(), ReadFromFile(), and PlexLoanPool::Cleaner::~Cleaner().

Int_t PlexLoanPool::fMaxSharedUnref [private]

Definition at line 81 of file PlexLoanPool.h.

Referenced by Config(), and GetPlexus().

TObjArray PlexLoanPool::fPrivatePlexusList [private]

Definition at line 79 of file PlexLoanPool.h.

Referenced by ClearPool(), GetExistingPlexus(), GetPlexus(), PlexLoanPool(), Print(), PurgeComponents(), ReadFromFile(), and ~PlexLoanPool().

TObjArray PlexLoanPool::fSharedPlexusList [private]

Definition at line 78 of file PlexLoanPool.h.

Referenced by ClearPool(), GetExistingPlexus(), GetPlexus(), PlexLoanPool(), Print(), PurgeComponents(), ReadFromFile(), and ~PlexLoanPool().


The documentation for this class was generated from the following files:
Generated on Mon Nov 10 00:56:16 2014 for loon by  doxygen 1.4.7