TProcessID.cxx

Go to the documentation of this file.
00001 // @(#)root/cont:$Id: TProcessID.cxx 35949 2010-09-30 16:11:21Z brun $
00002 // Author: Rene Brun   28/09/2001
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //
00014 // TProcessID
00015 //
00016 // A TProcessID identifies a ROOT job in a unique way in time and space.
00017 // The TProcessID title consists of a TUUID object which provides a globally
00018 // unique identifier (for more see TUUID.h).
00019 //
00020 // A TProcessID is automatically created by the TROOT constructor.
00021 // When a TFile contains referenced objects (see TRef), the TProcessID
00022 // object is written to the file.
00023 // If a file has been written in multiple sessions (same machine or not),
00024 // a TProcessID is written for each session.
00025 // These objects are used by the class TRef to uniquely identified
00026 // any TObject pointed by a TRef.
00027 //
00028 // When a referenced object is read from a file (its bit kIsReferenced is set),
00029 // this object is entered into the objects table of the corresponding TProcessID.
00030 // Each TFile has a list of TProcessIDs (see TFile::fProcessIDs) also
00031 // accessible via TProcessID::fgPIDs (for all files).
00032 // When this object is deleted, it is removed from the table via the cleanup
00033 // mechanism invoked by the TObject destructor.
00034 //
00035 // Each TProcessID has a table (TObjArray *fObjects) that keeps track
00036 // of all referenced objects. If a referenced object has a fUniqueID set,
00037 // a pointer to this unique object may be found via fObjects->At(fUniqueID).
00038 // In the same way, when a TRef::GetObject is called, GetObject uses
00039 // its own fUniqueID to find the pointer to the referenced object.
00040 // See TProcessID::GetObjectWithID and PutObjectWithID.
00041 //
00042 // When a referenced object is deleted, its slot in fObjects is set to null.
00043 //
00044 // See also TProcessUUID: a specialized TProcessID to manage the single list
00045 // of TUUIDs.
00046 //
00047 //////////////////////////////////////////////////////////////////////////
00048 
00049 #include "TProcessID.h"
00050 #include "TROOT.h"
00051 #include "TObjArray.h"
00052 #include "TExMap.h"
00053 #include "TVirtualMutex.h"
00054 
00055 TObjArray  *TProcessID::fgPIDs   = 0; //pointer to the list of TProcessID
00056 TProcessID *TProcessID::fgPID    = 0; //pointer to the TProcessID of the current session
00057 UInt_t      TProcessID::fgNumber = 0; //Current referenced object instance count
00058 TExMap     *TProcessID::fgObjPIDs= 0; //Table (pointer,pids)
00059 ClassImp(TProcessID)
00060 
00061 //______________________________________________________________________________
00062 static inline ULong_t Void_Hash(const void *ptr)
00063 {
00064    // Return hash value for this object.
00065 
00066    return TString::Hash(&ptr, sizeof(void*));
00067 }
00068 
00069 //______________________________________________________________________________
00070 TProcessID::TProcessID()
00071 {
00072    // Default constructor.
00073 
00074    fCount = 0;
00075    fObjects = 0;
00076 }
00077 
00078 //______________________________________________________________________________
00079 TProcessID::~TProcessID()
00080 {
00081    // Destructor.
00082 
00083    delete fObjects;
00084    fObjects = 0;
00085    R__LOCKGUARD2(gROOTMutex);
00086    fgPIDs->Remove(this);
00087 }
00088 
00089 //______________________________________________________________________________
00090 TProcessID *TProcessID::AddProcessID()
00091 {
00092    // Static function to add a new TProcessID to the list of PIDs.
00093 
00094    R__LOCKGUARD2(gROOTMutex);
00095 
00096    TProcessID *pid = new TProcessID();
00097 
00098    if (!fgPIDs) {
00099       fgPID  = pid;
00100       fgPIDs = new TObjArray(10);
00101       gROOT->GetListOfCleanups()->Add(fgPIDs);
00102    }
00103    UShort_t apid = fgPIDs->GetEntriesFast();
00104    pid->IncrementCount();
00105 
00106    fgPIDs->Add(pid);
00107    char name[20];
00108    snprintf(name,20,"ProcessID%d",apid);
00109    pid->SetName(name);
00110    TUUID u;
00111    apid = fgPIDs->GetEntriesFast();
00112    pid->SetTitle(u.AsString());
00113    return pid;
00114 }
00115 
00116 //______________________________________________________________________________
00117 UInt_t TProcessID::AssignID(TObject *obj)
00118 {
00119    // static function returning the ID assigned to obj
00120    // If the object is not yet referenced, its kIsReferenced bit is set
00121    // and its fUniqueID set to the current number of referenced objects so far.
00122 
00123    R__LOCKGUARD2(gROOTMutex);
00124 
00125    UInt_t uid = obj->GetUniqueID() & 0xffffff;
00126    if (obj == fgPID->GetObjectWithID(uid)) return uid;
00127    if (obj->TestBit(kIsReferenced)) {
00128       fgPID->PutObjectWithID(obj,uid);
00129       return uid;
00130    }
00131    fgNumber++;
00132    obj->SetBit(kIsReferenced);
00133    uid = fgNumber;
00134    obj->SetUniqueID(uid);
00135    fgPID->PutObjectWithID(obj,uid);
00136    return uid;
00137 }
00138 
00139 //______________________________________________________________________________
00140 void TProcessID::CheckInit()
00141 {
00142    // Initialize fObjects.
00143    if (!fObjects) fObjects = new TObjArray(100);
00144 }
00145 
00146 //______________________________________________________________________________
00147 void TProcessID::Cleanup()
00148 {
00149    // static function (called by TROOT destructor) to delete all TProcessIDs
00150 
00151    R__LOCKGUARD2(gROOTMutex);
00152 
00153    fgPIDs->Delete();
00154    gROOT->GetListOfCleanups()->Remove(fgPIDs);
00155    delete fgPIDs;
00156 }
00157 
00158 //______________________________________________________________________________
00159 void TProcessID::Clear(Option_t *)
00160 {
00161    // delete the TObjArray pointing to referenced objects
00162    // this function is called by TFile::Close("R")
00163 
00164    delete fObjects; fObjects = 0;
00165 }
00166 
00167 //______________________________________________________________________________
00168 Int_t TProcessID::DecrementCount()
00169 {
00170 
00171    // the reference fCount is used to delete the TProcessID
00172    // in the TFile destructor when fCount = 0
00173 
00174    fCount--;
00175    if (fCount < 0) fCount = 0;
00176    return fCount;
00177 }
00178 
00179 //______________________________________________________________________________
00180 TProcessID *TProcessID::GetProcessID(UShort_t pid)
00181 {
00182    // static function returning a pointer to TProcessID number pid in fgPIDs
00183 
00184    return (TProcessID*)fgPIDs->At(pid);
00185 }
00186 
00187 //______________________________________________________________________________
00188 UInt_t TProcessID::GetNProcessIDs()
00189 {
00190    // Return the (static) number of process IDs.
00191    return fgPIDs ? fgPIDs->GetLast()+1 : 0;
00192 }
00193 
00194 //______________________________________________________________________________
00195 TProcessID *TProcessID::GetProcessWithUID(UInt_t uid, const void *obj)
00196 {
00197    // static function returning a pointer to TProcessID with its pid
00198    // encoded in the highest byte of uid
00199 
00200    R__LOCKGUARD2(gROOTMutex);
00201 
00202    Int_t pid = (uid>>24)&0xff;
00203    if (pid==0xff) {
00204       // Look up the pid in the table (pointer,pid)
00205       if (fgObjPIDs==0) return 0;
00206       ULong_t hash = Void_Hash(obj);
00207       pid = fgObjPIDs->GetValue(hash,(Long_t)obj);
00208    }
00209    return (TProcessID*)fgPIDs->At(pid);
00210 }
00211 
00212 //______________________________________________________________________________
00213 TProcessID *TProcessID::GetProcessWithUID(const TObject *obj)
00214 {
00215    // static function returning a pointer to TProcessID with its pid
00216    // encoded in the highest byte of obj->GetUniqueID()
00217 
00218    return GetProcessWithUID(obj->GetUniqueID(),obj);
00219 }
00220 
00221 //______________________________________________________________________________
00222 TProcessID *TProcessID::GetSessionProcessID()
00223 {
00224    // static function returning the pointer to the session TProcessID
00225 
00226    return fgPID;
00227 }
00228 
00229 //______________________________________________________________________________
00230 Int_t TProcessID::IncrementCount()
00231 {
00232    // Increase the reference count to this object.
00233 
00234    if (!fObjects) fObjects = new TObjArray(100);
00235    fCount++;
00236    return fCount;
00237 }
00238 
00239 //______________________________________________________________________________
00240 UInt_t TProcessID::GetObjectCount()
00241 {
00242    // Return the current referenced object count
00243    // fgNumber is incremented everytime a new object is referenced
00244 
00245    return fgNumber;
00246 }
00247 
00248 //______________________________________________________________________________
00249 TObject *TProcessID::GetObjectWithID(UInt_t uidd)
00250 {
00251    //returns the TObject with unique identifier uid in the table of objects
00252 
00253    Int_t uid = uidd & 0xffffff;  //take only the 24 lower bits
00254 
00255    if (fObjects==0 || uid >= fObjects->GetSize()) return 0;
00256    return fObjects->UncheckedAt(uid);
00257 }
00258 
00259 //______________________________________________________________________________
00260 TProcessID *TProcessID::GetPID()
00261 {
00262    //static: returns pointer to current TProcessID
00263    
00264    return fgPID;
00265 }
00266 
00267 //______________________________________________________________________________
00268 TObjArray *TProcessID::GetPIDs()
00269 {
00270    //static: returns array of TProcessIDs
00271    
00272    return fgPIDs;
00273 }
00274 
00275 
00276 //______________________________________________________________________________
00277 Bool_t TProcessID::IsValid(TProcessID *pid)
00278 {
00279    // static function. return kTRUE if pid is a valid TProcessID
00280 
00281    R__LOCKGUARD2(gROOTMutex);
00282 
00283    if (fgPIDs->IndexOf(pid) >= 0) return kTRUE;
00284    if (pid == (TProcessID*)gROOT->GetUUIDs())  return kTRUE;
00285    return kFALSE;
00286 }
00287 
00288 //______________________________________________________________________________
00289 void TProcessID::PutObjectWithID(TObject *obj, UInt_t uid)
00290 {
00291    //stores the object at the uid th slot in the table of objects
00292    //The object uniqueid is set as well as its kMustCleanup bit
00293 
00294    if (uid == 0) uid = obj->GetUniqueID() & 0xffffff;
00295 
00296    if (!fObjects) fObjects = new TObjArray(100);
00297    fObjects->AddAtAndExpand(obj,uid);
00298 
00299    obj->SetBit(kMustCleanup);
00300    if ( (obj->GetUniqueID()&0xff000000)==0xff000000 ) {
00301       // We have more than 255 pids we need to store this
00302       // pointer in the table(pointer,pid) since there is no
00303       // more space in fUniqueID
00304       if (fgObjPIDs==0) fgObjPIDs = new TExMap;
00305       ULong_t hash = Void_Hash(obj);
00306 
00307       // We use operator() rather than Add() because
00308       // if the address has already been registered, we want to
00309       // update it's uniqueID (this can easily happen when the
00310       // referenced object have been stored in a TClonesArray.
00311       (*fgObjPIDs)(hash, (Long_t)obj) = GetUniqueID();
00312    }
00313 }
00314 
00315 //______________________________________________________________________________
00316 void TProcessID::RecursiveRemove(TObject *obj)
00317 {
00318    // called by the object destructor
00319    // remove reference to obj from the current table if it is referenced
00320 
00321    if (!fObjects) return;
00322    if (!obj->TestBit(kIsReferenced)) return;
00323    UInt_t uid = obj->GetUniqueID() & 0xffffff;
00324    if (obj == GetObjectWithID(uid)) fObjects->RemoveAt(uid);
00325 }
00326 
00327 
00328 //______________________________________________________________________________
00329 void TProcessID::SetObjectCount(UInt_t number)
00330 {
00331    // static function to set the current referenced object count
00332    // fgNumber is incremented everytime a new object is referenced
00333 
00334    fgNumber = number;
00335 }

Generated on Tue Jul 5 14:11:21 2011 for ROOT_528-00b_version by  doxygen 1.5.1