THashList.cxx

Go to the documentation of this file.
00001 // @(#)root/cont:$Id: THashList.cxx 27904 2009-03-20 19:44:39Z pcanal $
00002 // Author: Fons Rademakers   10/08/95
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 // THashList                                                            //
00015 //                                                                      //
00016 // THashList implements a hybrid collection class consisting of a       //
00017 // hash table and a list to store TObject's. The hash table is used for //
00018 // quick access and lookup of objects while the list allows the objects //
00019 // to be ordered. The hash value is calculated using the value returned //
00020 // by the TObject's Hash() function. Each class inheriting from TObject //
00021 // can override Hash() as it sees fit.                                  //
00022 //Begin_Html
00023 /*
00024 <img src=gif/thashlist.gif>
00025 */
00026 //End_Html
00027 //                                                                      //
00028 //////////////////////////////////////////////////////////////////////////
00029 
00030 #include "THashList.h"
00031 #include "THashTable.h"
00032 
00033 
00034 ClassImp(THashList)
00035 
00036 //______________________________________________________________________________
00037 THashList::THashList(Int_t capacity, Int_t rehash)
00038 {
00039    // Create a THashList object. Capacity is the initial hashtable capacity
00040    // (i.e. number of slots), by default kInitHashTableCapacity = 17, and
00041    // rehash is the value at which a rehash will be triggered. I.e. when the
00042    // average size of the linked lists at a slot becomes longer than rehash
00043    // then the hashtable will be resized and refilled to reduce the collision
00044    // rate to about 1. The higher the collision rate, i.e. the longer the
00045    // linked lists, the longer lookup will take. If rehash=0 the table will
00046    // NOT automatically be rehashed. Use Rehash() for manual rehashing.
00047    // WARNING !!!
00048    // If the name of an object in the HashList is modified, The hashlist
00049    // must be Rehashed
00050 
00051    fTable = new THashTable(capacity, rehash);
00052 }
00053 
00054 //______________________________________________________________________________
00055 THashList::THashList(TObject *, Int_t capacity, Int_t rehash)
00056 {
00057    // For backward compatibility only. Use other ctor.
00058 
00059    fTable = new THashTable(capacity, rehash);
00060 }
00061 
00062 //______________________________________________________________________________
00063 THashList::~THashList()
00064 {
00065    // Delete a hashlist. Objects are not deleted unless the THashList is the
00066    // owner (set via SetOwner()).
00067 
00068    Clear();
00069    SafeDelete(fTable);
00070 }
00071 
00072 //______________________________________________________________________________
00073 void THashList::AddFirst(TObject *obj)
00074 {
00075    // Add object at the beginning of the list.
00076 
00077    TList::AddFirst(obj);
00078    fTable->Add(obj);
00079 }
00080 
00081 //______________________________________________________________________________
00082 void THashList::AddFirst(TObject *obj, Option_t *opt)
00083 {
00084    // Add object at the beginning of the list and also store option.
00085    // Storing an option is useful when one wants to change the behaviour
00086    // of an object a little without having to create a complete new
00087    // copy of the object. This feature is used, for example, by the Draw()
00088    // method. It allows the same object to be drawn in different ways.
00089 
00090    TList::AddFirst(obj, opt);
00091    fTable->Add(obj);
00092 }
00093 
00094 //______________________________________________________________________________
00095 void THashList::AddLast(TObject *obj)
00096 {
00097    // Add object at the end of the list.
00098 
00099    TList::AddLast(obj);
00100    fTable->Add(obj);
00101 }
00102 
00103 //______________________________________________________________________________
00104 void THashList::AddLast(TObject *obj, Option_t *opt)
00105 {
00106    // Add object at the end of the list and also store option.
00107    // Storing an option is useful when one wants to change the behaviour
00108    // of an object a little without having to create a complete new
00109    // copy of the object. This feature is used, for example, by the Draw()
00110    // method. It allows the same object to be drawn in different ways.
00111 
00112    TList::AddLast(obj, opt);
00113    fTable->Add(obj);
00114 }
00115 
00116 //______________________________________________________________________________
00117 void THashList::AddBefore(const TObject *before, TObject *obj)
00118 {
00119    // Insert object before object before in the list.
00120 
00121    TList::AddBefore(before, obj);
00122    fTable->Add(obj);
00123 }
00124 
00125 //______________________________________________________________________________
00126 void THashList::AddBefore(TObjLink *before, TObject *obj)
00127 {
00128    // Insert object before object before in the list.
00129 
00130    TList::AddBefore(before, obj);
00131    fTable->Add(obj);
00132 }
00133 
00134 //______________________________________________________________________________
00135 void THashList::AddAfter(const TObject *after, TObject *obj)
00136 {
00137    // Insert object after object after in the list.
00138 
00139    TList::AddAfter(after, obj);
00140    fTable->Add(obj);
00141 }
00142 
00143 //______________________________________________________________________________
00144 void THashList::AddAfter(TObjLink *after, TObject *obj)
00145 {
00146    // Insert object after object after in the list.
00147 
00148    TList::AddAfter(after, obj);
00149    fTable->Add(obj);
00150 }
00151 
00152 //______________________________________________________________________________
00153 void THashList::AddAt(TObject *obj, Int_t idx)
00154 {
00155    // Insert object at location idx in the list.
00156 
00157    TList::AddAt(obj, idx);
00158    fTable->Add(obj);
00159 }
00160 
00161 //______________________________________________________________________________
00162 Float_t THashList::AverageCollisions() const
00163 {
00164    // Return the average collision rate. The higher the number the longer
00165    // the linked lists in the hashtable, the slower the lookup. If the number
00166    // is high, or lookup noticeably too slow, perfrom a Rehash().
00167 
00168    return fTable->AverageCollisions();
00169 }
00170 
00171 //______________________________________________________________________________
00172 void THashList::Clear(Option_t *option)
00173 {
00174    // Remove all objects from the list. Does not delete the objects unless
00175    // the THashList is the owner (set via SetOwner()).
00176 
00177    fTable->Clear("nodelete");  // clear table so not more lookups
00178    if (IsOwner())
00179       TList::Delete(option);
00180    else
00181       TList::Clear(option);
00182 }
00183 
00184 //______________________________________________________________________________
00185 void THashList::Delete(Option_t *option)
00186 {
00187    // Remove all objects from the list AND delete all heap based objects.
00188    // If option="slow" then keep list consistent during delete. This allows
00189    // recursive list operations during the delete (e.g. during the dtor
00190    // of an object in this list one can still access the list to search for
00191    // other not yet deleted objects).
00192 
00193    Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;
00194 
00195    if (!slow) {
00196       fTable->Clear("nodelete");     // clear table so no more lookups
00197       TList::Delete(option);         // this deletes the objects
00198    } else {
00199       while (fFirst) {
00200          TObjLink *tlk = fFirst;
00201          fFirst = fFirst->Next();
00202          fSize--;
00203          // remove object from table
00204          fTable->Remove(tlk->GetObject());
00205          // delete only heap objects
00206          if (tlk->GetObject() && tlk->GetObject()->IsOnHeap())
00207             TCollection::GarbageCollect(tlk->GetObject());
00208 
00209          delete tlk;
00210       }
00211       fFirst = fLast = fCache = 0;
00212       fSize  = 0;
00213    }
00214 }
00215 
00216 //______________________________________________________________________________
00217 TObject *THashList::FindObject(const char *name) const
00218 {
00219    // Find object using its name. Uses the hash value returned by the
00220    // TString::Hash() after converting name to a TString.
00221 
00222    return fTable->FindObject(name);
00223 }
00224 
00225 //______________________________________________________________________________
00226 TObject *THashList::FindObject(const TObject *obj) const
00227 {
00228    // Find object using its hash value (returned by its Hash() member).
00229 
00230    return fTable->FindObject(obj);
00231 }
00232 
00233 //______________________________________________________________________________
00234 TList *THashList::GetListForObject(const char *name) const
00235 {
00236    // Return the THashTable's list (bucket) in which obj can be found based on
00237    // its hash; see THashTable::GetListForObject().
00238 
00239    return fTable->GetListForObject(name);
00240 }
00241 
00242 //______________________________________________________________________________
00243 TList *THashList::GetListForObject(const TObject *obj) const
00244 {
00245    // Return the THashTable's list (bucket) in which obj can be found based on
00246    // its hash; see THashTable::GetListForObject().
00247 
00248    return fTable->GetListForObject(obj);
00249 }
00250 
00251 //______________________________________________________________________________
00252 void THashList::RecursiveRemove(TObject *obj)
00253 {
00254    // Remove object from this collection and recursively remove the object
00255    // from all other objects (and collections).
00256    // This function overrides TCollection::RecursiveRemove that calls
00257    // the Remove function. THashList::Remove cannot be called because
00258    // it uses the hash value of the hash table. This hash value
00259    // is not available anymore when RecursiveRemove is called from
00260    // the TObject destructor.
00261 
00262    if (!obj) return;
00263 
00264    // Remove obj in the list itself
00265    TObject *object = TList::Remove(obj);
00266    if (object) fTable->RemoveSlow(object);
00267 
00268    // Scan again the list and invoke RecursiveRemove for all objects
00269    TIter next(this);
00270 
00271    while ((object = next())) {
00272       if (object->TestBit(kNotDeleted)) object->RecursiveRemove(obj);
00273    }
00274 }
00275 
00276 //______________________________________________________________________________
00277 void THashList::Rehash(Int_t newCapacity)
00278 {
00279    // Rehash the hashlist. If the collision rate becomes too high (i.e.
00280    // the average size of the linked lists become too long) then lookup
00281    // efficiency decreases since relatively long lists have to be searched
00282    // every time. To improve performance rehash the hashtable. This resizes
00283    // the table to newCapacity slots and refills the table. Use
00284    // AverageCollisions() to check if you need to rehash.
00285 
00286    fTable->Rehash(newCapacity);
00287 }
00288 
00289 //______________________________________________________________________________
00290 TObject *THashList::Remove(TObject *obj)
00291 {
00292    // Remove object from the list.
00293 
00294    if (!obj || !fTable->FindObject(obj)) return 0;
00295 
00296    TList::Remove(obj);
00297    return fTable->Remove(obj);
00298 }
00299 
00300 //______________________________________________________________________________
00301 TObject *THashList::Remove(TObjLink *lnk)
00302 {
00303    // Remove object via its objlink from the list.
00304 
00305    if (!lnk) return 0;
00306 
00307    TObject *obj = lnk->GetObject();
00308 
00309    TList::Remove(lnk);
00310    return fTable->Remove(obj);
00311 }

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