TMap.cxx

Go to the documentation of this file.
00001 // @(#)root/cont:$Id: TMap.cxx 31714 2009-12-09 10:01:32Z rdm $
00002 // Author: Fons Rademakers   12/11/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 // TMap                                                                 //
00015 //                                                                      //
00016 // TMap implements an associative array of (key,value) pairs using a    //
00017 // THashTable for efficient retrieval (therefore TMap does not conserve //
00018 // the order of the entries). The hash value is calculated              //
00019 // using the value returned by the keys Hash() function and the         //
00020 // key comparison is done via the IsEqual() function.                   //
00021 // Both key and value must inherit from TObject.                        //
00022 //Begin_Html
00023 /*
00024 <img src=gif/tmap.gif>
00025 */
00026 //End_Html
00027 //                                                                      //
00028 //////////////////////////////////////////////////////////////////////////
00029 
00030 #include "TMap.h"
00031 #include "THashTable.h"
00032 #include "TROOT.h"
00033 #include "TBrowser.h"
00034 #include "TRegexp.h"
00035 
00036 ClassImp(TMap)
00037 
00038 //______________________________________________________________________________
00039 TMap::TMap(Int_t capacity, Int_t rehashlevel)
00040 {
00041    // TMap ctor. See THashTable for a description of the arguments.
00042 
00043    fSize  = 0;
00044    fTable = new THashTable(capacity, rehashlevel);
00045 }
00046 
00047 //______________________________________________________________________________
00048 TMap::~TMap()
00049 {
00050    // TMap dtor. Objects are not deleted unless the TMap is the
00051    // owner (set via SetOwner()).
00052 
00053    Clear();
00054    delete fTable;
00055 }
00056 
00057 //______________________________________________________________________________
00058 void TMap::Add(TObject *)
00059 {
00060    // This function may not be used (but we need to provide it since it is
00061    // a pure virtual in TCollection). Use Add(key,value) instead.
00062 
00063    MayNotUse("Add(TObject *obj)");
00064 }
00065 
00066 //______________________________________________________________________________
00067 void TMap::Add(TObject *key, TObject *value)
00068 {
00069    // Add a (key,value) pair to the map.
00070 
00071    if (IsArgNull("Add", key)) return;
00072 
00073    fTable->Add(new TPair(key, value));
00074    fSize++;
00075 }
00076 
00077 //______________________________________________________________________________
00078 Float_t TMap::AverageCollisions() const
00079 {
00080    // Return the ratio of entries vs occupied slots.
00081 
00082    return fTable->AverageCollisions();
00083 }
00084 
00085 //______________________________________________________________________________
00086 Int_t TMap::Capacity() const
00087 {
00088    // Return number of slots in the hashtable. Use GetSize() to get the
00089    // number of objects stored in the TMap.
00090 
00091    return fTable->Capacity();
00092 }
00093 
00094 //______________________________________________________________________________
00095 void TMap::Clear(Option_t *option)
00096 {
00097    // Remove all (key,value) pairs from the map. The keys/values are
00098    // deleted depending on the state of key-ownership (SetOwner()) and
00099    // value-ownership (SetOwnerValue()).
00100    //
00101    // To delete these objects regardless of the ownership state use:
00102    //  - Delete()       to delete only keys;
00103    //  - DeleteValues() to delete only values;
00104    //  - DeleteAll()    to delete both keys and values.
00105 
00106    if (IsOwner() && IsOwnerValue())
00107       DeleteAll();
00108    else if (IsOwner())
00109       Delete();
00110    else if (IsOwnerValue())
00111       DeleteValues();
00112    else {
00113       fTable->Delete(option);    // delete the TPair's
00114       fSize = 0;
00115    }
00116 }
00117 
00118 //______________________________________________________________________________
00119 Int_t TMap::Collisions(const char *keyname) const
00120 {
00121    // Returns the number of collisions for a key with a certain name
00122    // (i.e. number of objects in same slot in the hash table, i.e. length
00123    // of linked list).
00124 
00125    return fTable->Collisions(keyname);
00126 }
00127 
00128 //______________________________________________________________________________
00129 Int_t TMap::Collisions(TObject *key) const
00130 {
00131    // Returns the number of collisions for a key (i.e. number of objects
00132    // in same slot in the hash table, i.e. length of linked list).
00133 
00134    return fTable->Collisions(key);
00135 }
00136 
00137 //______________________________________________________________________________
00138 void TMap::Delete(Option_t *option)
00139 {
00140    // Remove all (key,value) pairs from the map AND delete the keys
00141    // when they are allocated on the heap.
00142 
00143    TIter next(fTable);
00144    TPair *a;
00145 
00146    while ((a = (TPair *)next()))
00147       if (a->Key() && a->Key()->IsOnHeap())
00148          TCollection::GarbageCollect(a->Key());
00149 
00150    fTable->Delete(option);   // delete the TPair's
00151    fSize = 0;
00152 }
00153 
00154 //______________________________________________________________________________
00155 void TMap::DeleteValues()
00156 {
00157    // Remove all (key,value) pairs from the map AND delete the values
00158    // when they are allocated on the heap.
00159 
00160    TIter next(fTable);
00161    TPair *a;
00162 
00163    while ((a = (TPair *)next()))
00164       if (a->Value() && a->Value()->IsOnHeap())
00165          TCollection::GarbageCollect(a->Value());
00166 
00167    fTable->Delete();   // delete the TPair's
00168    fSize = 0;
00169 }
00170 
00171 //______________________________________________________________________________
00172 void TMap::DeleteAll()
00173 {
00174    // Remove all (key,value) pairs from the map AND delete the keys AND
00175    // values when they are allocated on the heap.
00176 
00177    TIter next(fTable);
00178    TPair *a;
00179 
00180    while ((a = (TPair *)next())) {
00181       if (a->Key()   && a->Key()->IsOnHeap())
00182          TCollection::GarbageCollect(a->Key());
00183       if (a->Value() && a->Value()->IsOnHeap())
00184          TCollection::GarbageCollect(a->Value());
00185    }
00186 
00187    fTable->Delete();   // delete the TPair's
00188    fSize = 0;
00189 }
00190 
00191 //______________________________________________________________________________
00192 Bool_t TMap::DeleteEntry(TObject *key)
00193 {
00194    // Remove (key,value) pair with key from the map. Returns true
00195    // if the key was found and removed, false otherwise.
00196    // The key and value objects are deleted if map is the owner
00197    // of keys and values respectively.
00198 
00199    if (!key) return kFALSE;
00200 
00201    TPair *a;
00202    if ((a = (TPair *)fTable->FindObject(key))) {
00203       if (fTable->Remove(key)) {
00204          if (IsOwner() && a->Key() && a->Key()->IsOnHeap())
00205             TCollection::GarbageCollect(a->Key());
00206          if (IsOwnerValue() && a->Value() && a->Value()->IsOnHeap())
00207             TCollection::GarbageCollect(a->Value());
00208          delete a;
00209          fSize--;
00210          return kTRUE;
00211       }
00212    }
00213    return kFALSE;
00214 }
00215 
00216 //______________________________________________________________________________
00217 TObject *TMap::FindObject(const char *keyname) const
00218 {
00219    // Check if a (key,value) pair exists with keyname as name of the key.
00220    // Returns a TPair* (need to downcast from TObject). Use Key() and
00221    // Value() to get the pointers to the key and value, respectively.
00222    // Returns 0 if not found.
00223 
00224    return fTable->FindObject(keyname);
00225 }
00226 
00227 //______________________________________________________________________________
00228 TObject *TMap::FindObject(const TObject *key) const
00229 {
00230    // Check if a (key,value) pair exists with key as key.
00231    // Returns a TPair* (need to downcast from TObject). Use Key() and
00232    // Value() to get the pointers to the key and value, respectively.
00233    // Returns 0 if not found.
00234 
00235    if (IsArgNull("FindObject", key)) return 0;
00236 
00237    return fTable->FindObject(key);
00238 }
00239 
00240 //______________________________________________________________________________
00241 TObject *TMap::GetValue(const char *keyname) const
00242 {
00243    // Returns a pointer to the value associated with keyname as name of the key.
00244 
00245    TPair *a = (TPair *)fTable->FindObject(keyname);
00246    if (a) return a->Value();
00247    return 0;
00248 }
00249 
00250 //______________________________________________________________________________
00251 TObject *TMap::GetValue(const TObject *key) const
00252 {
00253    // Returns a pointer to the value associated with key.
00254 
00255    if (IsArgNull("GetValue", key)) return 0;
00256 
00257    TPair *a = (TPair *)fTable->FindObject(key);
00258    if (a) return a->Value();
00259    return 0;
00260 }
00261 
00262 //______________________________________________________________________________
00263 TIterator *TMap::MakeIterator(Bool_t dir) const
00264 {
00265    // Create an iterator for TMap.
00266 
00267    return new TMapIter(this, dir);
00268 }
00269 
00270 //______________________________________________________________________________
00271 void TMap::PrintCollectionEntry(TObject* entry, Option_t* option, Int_t recurse) const
00272 {
00273    // Print the collection entry.
00274 
00275    TObject* val = GetValue(entry);
00276 
00277    TROOT::IndentLevel();
00278    printf("Key:   ");
00279    entry->Print();
00280    TROOT::IndentLevel();
00281    if (TStorage::IsOnHeap(val)) {
00282       printf("Value: ");
00283       TCollection* coll = dynamic_cast<TCollection*>(val);
00284       if (coll) {
00285          coll->Print(option, recurse);
00286       } else {
00287          val->Print(option);
00288       }
00289    } else {
00290       printf("Value: 0x%lx\n", (ULong_t) val);
00291    }
00292 }
00293 
00294 //______________________________________________________________________________
00295 void TMap::Rehash(Int_t newCapacity, Bool_t checkObjValidity)
00296 {
00297    // Rehash the underlaying THashTable (see THashTable::Rehash()).
00298 
00299    fTable->Rehash(newCapacity, checkObjValidity);
00300 }
00301 
00302 //______________________________________________________________________________
00303 TObject *TMap::Remove(TObject *key)
00304 {
00305    // Remove the (key,value) pair with key from the map. Returns the
00306    // key object or 0 in case key was not found. If map is the owner
00307    // of values, the value is deleted.
00308 
00309    if (!key) return 0;
00310 
00311    TPair *a;
00312    if ((a = (TPair *)fTable->FindObject(key))) {
00313       if (fTable->Remove(key)) {
00314          if (IsOwnerValue() && a->Value() && a->Value()->IsOnHeap())
00315             TCollection::GarbageCollect(a->Value());
00316          TObject *kobj = a->Key();
00317          delete a;
00318          fSize--;
00319          return kobj;
00320       }
00321    }
00322    return 0;
00323 }
00324 
00325 //______________________________________________________________________________
00326 TPair *TMap::RemoveEntry(TObject *key)
00327 {
00328    // Remove (key,value) pair with key from the map. Returns the
00329    // pair object or 0 in case the key was not found.
00330    // It is caller's responsibility to delete the pair and, eventually,
00331    // the key and value objects.
00332 
00333    if (!key) return 0;
00334 
00335    TPair *a;
00336    if ((a = (TPair *)fTable->FindObject(key))) {
00337       if (fTable->Remove(key)) {
00338          fSize--;
00339          return a;
00340       }
00341    }
00342    return 0;
00343 }
00344 
00345 //______________________________________________________________________________
00346 void TMap::SetOwnerValue(Bool_t enable)
00347 {
00348    // Set whether this map is the owner (enable==true)
00349    // of its values.  If it is the owner of its contents,
00350    // these objects will be deleted whenever the collection itself
00351    // is deleted. The objects might also be deleted or destructed when Clear
00352    // is called (depending on the collection).
00353 
00354    if (enable)
00355       SetBit(kIsOwnerValue);
00356    else
00357       ResetBit(kIsOwnerValue);
00358 }
00359 
00360 //______________________________________________________________________________
00361 void TMap::SetOwnerKeyValue(Bool_t ownkeys, Bool_t ownvals)
00362 {
00363    // Set ownership for keys and values.
00364 
00365    SetOwner(ownkeys);
00366    SetOwnerValue(ownvals);
00367 }
00368 
00369 //______________________________________________________________________________
00370 void TMap::Streamer(TBuffer &b)
00371 {
00372    // Stream all key/value pairs in the map to or from the I/O buffer.
00373 
00374    TObject *obj=0;
00375    UInt_t R__s, R__c;
00376 
00377    if (b.IsReading()) {
00378       Int_t    nobjects;
00379       TObject *value=0;
00380 
00381       Version_t v = b.ReadVersion(&R__s, &R__c);
00382       if (v > 2)
00383          TObject::Streamer(b);
00384       if (v > 1)
00385          fName.Streamer(b);
00386       b >> nobjects;
00387       for (Int_t i = 0; i < nobjects; i++) {
00388          b >> obj;
00389          b >> value;
00390          if (obj) Add(obj, value);
00391       }
00392       b.CheckByteCount(R__s, R__c,TMap::IsA());
00393    } else {
00394       R__c = b.WriteVersion(TMap::IsA(), kTRUE);
00395       TObject::Streamer(b);
00396       fName.Streamer(b);
00397       b << GetSize();
00398       TIter next(fTable);
00399       TPair *a;
00400       while ((a = (TPair*) next())) {
00401          b << a->Key();
00402          b << a->Value();
00403       }
00404       b.SetByteCount(R__c, kTRUE);
00405    }
00406 }
00407 
00408 //////////////////////////////////////////////////////////////////////////
00409 //                                                                      //
00410 // TPair                                                                //
00411 //                                                                      //
00412 //////////////////////////////////////////////////////////////////////////
00413 
00414 //______________________________________________________________________________
00415 void TPair::Browse(TBrowser *b)
00416 {
00417    // Browse the pair.
00418 
00419    if (b) {
00420       if (fKey)   b->Add(fKey);
00421       if (fValue) b->Add(fValue);
00422    } else {
00423       if (fKey)   fKey->Browse(b);
00424       if (fValue) fValue->Browse(b);
00425    }
00426 }
00427 
00428 //////////////////////////////////////////////////////////////////////////
00429 //                                                                      //
00430 // TMapIter                                                             //
00431 //                                                                      //
00432 // Iterator of map.                                                     //
00433 //                                                                      //
00434 //////////////////////////////////////////////////////////////////////////
00435 
00436 ClassImp(TMapIter)
00437 
00438 //______________________________________________________________________________
00439 TMapIter::TMapIter(const TMap *m, Bool_t dir)
00440 {
00441    // Create a map iterator. Use dir to specify the desired iteration direction.
00442 
00443    fMap        = m;
00444    fDirection  = dir;
00445    fCursor     = 0;
00446 }
00447 
00448 //______________________________________________________________________________
00449 TMapIter::TMapIter(const TMapIter &iter) : TIterator(iter)
00450 {
00451    // Copy ctor.
00452 
00453    fMap       = iter.fMap;
00454    fDirection = iter.fDirection;
00455    fCursor    = 0;
00456    if (iter.fCursor) {
00457       fCursor = (THashTableIter *)iter.fCursor->GetCollection()->MakeIterator();
00458       fCursor->operator=(*iter.fCursor);
00459    }
00460 }
00461 
00462 //______________________________________________________________________________
00463 TIterator &TMapIter::operator=(const TIterator &rhs)
00464 {
00465    // Overridden assignment operator.
00466 
00467    if (this != &rhs && rhs.IsA() == TMapIter::Class()) {
00468       const TMapIter &rhs1 = (const TMapIter &)rhs;
00469       fMap       = rhs1.fMap;
00470       fDirection = rhs1.fDirection;
00471       if (rhs1.fCursor) {
00472          fCursor = (THashTableIter *)rhs1.fCursor->GetCollection()->MakeIterator();
00473          fCursor->operator=(*rhs1.fCursor);
00474       }
00475    }
00476    return *this;
00477 }
00478 
00479 //______________________________________________________________________________
00480 TMapIter &TMapIter::operator=(const TMapIter &rhs)
00481 {
00482    // Overloaded assignment operator.
00483 
00484    if (this != &rhs) {
00485       fMap       = rhs.fMap;
00486       fDirection = rhs.fDirection;
00487       if (rhs.fCursor) {
00488          fCursor = (THashTableIter *)rhs.fCursor->GetCollection()->MakeIterator();
00489          fCursor->operator=(*rhs.fCursor);
00490       }
00491    }
00492    return *this;
00493 }
00494 
00495 //______________________________________________________________________________
00496 TMapIter::~TMapIter()
00497 {
00498    // Map iterator dtor.
00499 
00500    Reset();
00501 }
00502 
00503 //______________________________________________________________________________
00504 TObject *TMapIter::Next()
00505 {
00506    // Returns the next key from a map. Use TMap::GetValue() to get the value
00507    // associated with the key. Returns 0 when no more items in map.
00508 
00509    if (!fCursor)
00510       fCursor = new THashTableIter(fMap->fTable, fDirection);
00511 
00512    TPair *a = (TPair *)fCursor->Next();
00513    if (a) return a->Key();
00514    return 0;
00515 }
00516 
00517 //______________________________________________________________________________
00518 void TMapIter::Reset()
00519 {
00520    // Reset the map iterator.
00521 
00522    SafeDelete(fCursor);
00523 }
00524 
00525 //______________________________________________________________________________
00526 bool TMapIter::operator!=(const TIterator &aIter) const
00527 {
00528    // This operator compares two TIterator objects.
00529 
00530    if (nullptr == (&aIter))
00531       return fCursor->operator*();
00532 
00533    if (aIter.IsA() == TMapIter::Class()) {
00534       const TMapIter &iter(dynamic_cast<const TMapIter &>(aIter));
00535       return (fCursor->operator*() != iter.fCursor->operator*());
00536    }
00537    return false; // for base class we don't implement a comparison
00538 }
00539 
00540 //______________________________________________________________________________
00541 bool TMapIter::operator!=(const TMapIter &aIter) const
00542 {
00543    // This operator compares two TMapIter objects.
00544 
00545    if (nullptr == (&aIter))
00546       return fCursor->operator*();
00547 
00548    return (fCursor->operator*() != aIter.fCursor->operator*());
00549 }
00550 
00551 //______________________________________________________________________________
00552 TObject *TMapIter::operator*() const
00553 {
00554    // Return pointer to current object (a TPair) or nullptr.
00555 
00556    return (fCursor ? fCursor->operator*() : nullptr);
00557 }

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