ROOT logo
// @(#)root/cont:$Id: THashList.cxx 27904 2009-03-20 19:44:39Z pcanal $
// Author: Fons Rademakers   10/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// THashList                                                            //
//                                                                      //
// THashList implements a hybrid collection class consisting of a       //
// hash table and a list to store TObject's. The hash table is used for //
// quick access and lookup of objects while the list allows the objects //
// to be ordered. The hash value is calculated using the value returned //
// by the TObject's Hash() function. Each class inheriting from TObject //
// can override Hash() as it sees fit.                                  //
//Begin_Html
/*
<img src=gif/thashlist.gif>
*/
//End_Html
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "THashList.h"
#include "THashTable.h"


ClassImp(THashList)

//______________________________________________________________________________
THashList::THashList(Int_t capacity, Int_t rehash)
{
   // Create a THashList object. Capacity is the initial hashtable capacity
   // (i.e. number of slots), by default kInitHashTableCapacity = 17, and
   // rehash is the value at which a rehash will be triggered. I.e. when the
   // average size of the linked lists at a slot becomes longer than rehash
   // then the hashtable will be resized and refilled to reduce the collision
   // rate to about 1. The higher the collision rate, i.e. the longer the
   // linked lists, the longer lookup will take. If rehash=0 the table will
   // NOT automatically be rehashed. Use Rehash() for manual rehashing.
   // WARNING !!!
   // If the name of an object in the HashList is modified, The hashlist
   // must be Rehashed

   fTable = new THashTable(capacity, rehash);
}

//______________________________________________________________________________
THashList::THashList(TObject *, Int_t capacity, Int_t rehash)
{
   // For backward compatibility only. Use other ctor.

   fTable = new THashTable(capacity, rehash);
}

//______________________________________________________________________________
THashList::~THashList()
{
   // Delete a hashlist. Objects are not deleted unless the THashList is the
   // owner (set via SetOwner()).

   Clear();
   SafeDelete(fTable);
}

//______________________________________________________________________________
void THashList::AddFirst(TObject *obj)
{
   // Add object at the beginning of the list.

   TList::AddFirst(obj);
   fTable->Add(obj);
}

//______________________________________________________________________________
void THashList::AddFirst(TObject *obj, Option_t *opt)
{
   // Add object at the beginning of the list and also store option.
   // Storing an option is useful when one wants to change the behaviour
   // of an object a little without having to create a complete new
   // copy of the object. This feature is used, for example, by the Draw()
   // method. It allows the same object to be drawn in different ways.

   TList::AddFirst(obj, opt);
   fTable->Add(obj);
}

//______________________________________________________________________________
void THashList::AddLast(TObject *obj)
{
   // Add object at the end of the list.

   TList::AddLast(obj);
   fTable->Add(obj);
}

//______________________________________________________________________________
void THashList::AddLast(TObject *obj, Option_t *opt)
{
   // Add object at the end of the list and also store option.
   // Storing an option is useful when one wants to change the behaviour
   // of an object a little without having to create a complete new
   // copy of the object. This feature is used, for example, by the Draw()
   // method. It allows the same object to be drawn in different ways.

   TList::AddLast(obj, opt);
   fTable->Add(obj);
}

//______________________________________________________________________________
void THashList::AddBefore(const TObject *before, TObject *obj)
{
   // Insert object before object before in the list.

   TList::AddBefore(before, obj);
   fTable->Add(obj);
}

//______________________________________________________________________________
void THashList::AddBefore(TObjLink *before, TObject *obj)
{
   // Insert object before object before in the list.

   TList::AddBefore(before, obj);
   fTable->Add(obj);
}

//______________________________________________________________________________
void THashList::AddAfter(const TObject *after, TObject *obj)
{
   // Insert object after object after in the list.

   TList::AddAfter(after, obj);
   fTable->Add(obj);
}

//______________________________________________________________________________
void THashList::AddAfter(TObjLink *after, TObject *obj)
{
   // Insert object after object after in the list.

   TList::AddAfter(after, obj);
   fTable->Add(obj);
}

//______________________________________________________________________________
void THashList::AddAt(TObject *obj, Int_t idx)
{
   // Insert object at location idx in the list.

   TList::AddAt(obj, idx);
   fTable->Add(obj);
}

//______________________________________________________________________________
Float_t THashList::AverageCollisions() const
{
   // Return the average collision rate. The higher the number the longer
   // the linked lists in the hashtable, the slower the lookup. If the number
   // is high, or lookup noticeably too slow, perfrom a Rehash().

   return fTable->AverageCollisions();
}

//______________________________________________________________________________
void THashList::Clear(Option_t *option)
{
   // Remove all objects from the list. Does not delete the objects unless
   // the THashList is the owner (set via SetOwner()).

   fTable->Clear("nodelete");  // clear table so not more lookups
   if (IsOwner())
      TList::Delete(option);
   else
      TList::Clear(option);
}

//______________________________________________________________________________
void THashList::Delete(Option_t *option)
{
   // Remove all objects from the list AND delete all heap based objects.
   // If option="slow" then keep list consistent during delete. This allows
   // recursive list operations during the delete (e.g. during the dtor
   // of an object in this list one can still access the list to search for
   // other not yet deleted objects).

   Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;

   if (!slow) {
      fTable->Clear("nodelete");     // clear table so no more lookups
      TList::Delete(option);         // this deletes the objects
   } else {
      while (fFirst) {
         TObjLink *tlk = fFirst;
         fFirst = fFirst->Next();
         fSize--;
         // remove object from table
         fTable->Remove(tlk->GetObject());
         // delete only heap objects
         if (tlk->GetObject() && tlk->GetObject()->IsOnHeap())
            TCollection::GarbageCollect(tlk->GetObject());

         delete tlk;
      }
      fFirst = fLast = fCache = 0;
      fSize  = 0;
   }
}

//______________________________________________________________________________
TObject *THashList::FindObject(const char *name) const
{
   // Find object using its name. Uses the hash value returned by the
   // TString::Hash() after converting name to a TString.

   return fTable->FindObject(name);
}

//______________________________________________________________________________
TObject *THashList::FindObject(const TObject *obj) const
{
   // Find object using its hash value (returned by its Hash() member).

   return fTable->FindObject(obj);
}

//______________________________________________________________________________
TList *THashList::GetListForObject(const char *name) const
{
   // Return the THashTable's list (bucket) in which obj can be found based on
   // its hash; see THashTable::GetListForObject().

   return fTable->GetListForObject(name);
}

//______________________________________________________________________________
TList *THashList::GetListForObject(const TObject *obj) const
{
   // Return the THashTable's list (bucket) in which obj can be found based on
   // its hash; see THashTable::GetListForObject().

   return fTable->GetListForObject(obj);
}

//______________________________________________________________________________
void THashList::RecursiveRemove(TObject *obj)
{
   // Remove object from this collection and recursively remove the object
   // from all other objects (and collections).
   // This function overrides TCollection::RecursiveRemove that calls
   // the Remove function. THashList::Remove cannot be called because
   // it uses the hash value of the hash table. This hash value
   // is not available anymore when RecursiveRemove is called from
   // the TObject destructor.

   if (!obj) return;

   // Remove obj in the list itself
   TObject *object = TList::Remove(obj);
   if (object) fTable->RemoveSlow(object);

   // Scan again the list and invoke RecursiveRemove for all objects
   TIter next(this);

   while ((object = next())) {
      if (object->TestBit(kNotDeleted)) object->RecursiveRemove(obj);
   }
}

//______________________________________________________________________________
void THashList::Rehash(Int_t newCapacity)
{
   // Rehash the hashlist. If the collision rate becomes too high (i.e.
   // the average size of the linked lists become too long) then lookup
   // efficiency decreases since relatively long lists have to be searched
   // every time. To improve performance rehash the hashtable. This resizes
   // the table to newCapacity slots and refills the table. Use
   // AverageCollisions() to check if you need to rehash.

   fTable->Rehash(newCapacity);
}

//______________________________________________________________________________
TObject *THashList::Remove(TObject *obj)
{
   // Remove object from the list.

   if (!obj || !fTable->FindObject(obj)) return 0;

   TList::Remove(obj);
   return fTable->Remove(obj);
}

//______________________________________________________________________________
TObject *THashList::Remove(TObjLink *lnk)
{
   // Remove object via its objlink from the list.

   if (!lnk) return 0;

   TObject *obj = lnk->GetObject();

   TList::Remove(lnk);
   return fTable->Remove(obj);
}
 THashList.cxx:1
 THashList.cxx:2
 THashList.cxx:3
 THashList.cxx:4
 THashList.cxx:5
 THashList.cxx:6
 THashList.cxx:7
 THashList.cxx:8
 THashList.cxx:9
 THashList.cxx:10
 THashList.cxx:11
 THashList.cxx:12
 THashList.cxx:13
 THashList.cxx:14
 THashList.cxx:15
 THashList.cxx:16
 THashList.cxx:17
 THashList.cxx:18
 THashList.cxx:19
 THashList.cxx:20
 THashList.cxx:21
 THashList.cxx:22
 THashList.cxx:23
 THashList.cxx:24
 THashList.cxx:25
 THashList.cxx:26
 THashList.cxx:27
 THashList.cxx:28
 THashList.cxx:29
 THashList.cxx:30
 THashList.cxx:31
 THashList.cxx:32
 THashList.cxx:33
 THashList.cxx:34
 THashList.cxx:35
 THashList.cxx:36
 THashList.cxx:37
 THashList.cxx:38
 THashList.cxx:39
 THashList.cxx:40
 THashList.cxx:41
 THashList.cxx:42
 THashList.cxx:43
 THashList.cxx:44
 THashList.cxx:45
 THashList.cxx:46
 THashList.cxx:47
 THashList.cxx:48
 THashList.cxx:49
 THashList.cxx:50
 THashList.cxx:51
 THashList.cxx:52
 THashList.cxx:53
 THashList.cxx:54
 THashList.cxx:55
 THashList.cxx:56
 THashList.cxx:57
 THashList.cxx:58
 THashList.cxx:59
 THashList.cxx:60
 THashList.cxx:61
 THashList.cxx:62
 THashList.cxx:63
 THashList.cxx:64
 THashList.cxx:65
 THashList.cxx:66
 THashList.cxx:67
 THashList.cxx:68
 THashList.cxx:69
 THashList.cxx:70
 THashList.cxx:71
 THashList.cxx:72
 THashList.cxx:73
 THashList.cxx:74
 THashList.cxx:75
 THashList.cxx:76
 THashList.cxx:77
 THashList.cxx:78
 THashList.cxx:79
 THashList.cxx:80
 THashList.cxx:81
 THashList.cxx:82
 THashList.cxx:83
 THashList.cxx:84
 THashList.cxx:85
 THashList.cxx:86
 THashList.cxx:87
 THashList.cxx:88
 THashList.cxx:89
 THashList.cxx:90
 THashList.cxx:91
 THashList.cxx:92
 THashList.cxx:93
 THashList.cxx:94
 THashList.cxx:95
 THashList.cxx:96
 THashList.cxx:97
 THashList.cxx:98
 THashList.cxx:99
 THashList.cxx:100
 THashList.cxx:101
 THashList.cxx:102
 THashList.cxx:103
 THashList.cxx:104
 THashList.cxx:105
 THashList.cxx:106
 THashList.cxx:107
 THashList.cxx:108
 THashList.cxx:109
 THashList.cxx:110
 THashList.cxx:111
 THashList.cxx:112
 THashList.cxx:113
 THashList.cxx:114
 THashList.cxx:115
 THashList.cxx:116
 THashList.cxx:117
 THashList.cxx:118
 THashList.cxx:119
 THashList.cxx:120
 THashList.cxx:121
 THashList.cxx:122
 THashList.cxx:123
 THashList.cxx:124
 THashList.cxx:125
 THashList.cxx:126
 THashList.cxx:127
 THashList.cxx:128
 THashList.cxx:129
 THashList.cxx:130
 THashList.cxx:131
 THashList.cxx:132
 THashList.cxx:133
 THashList.cxx:134
 THashList.cxx:135
 THashList.cxx:136
 THashList.cxx:137
 THashList.cxx:138
 THashList.cxx:139
 THashList.cxx:140
 THashList.cxx:141
 THashList.cxx:142
 THashList.cxx:143
 THashList.cxx:144
 THashList.cxx:145
 THashList.cxx:146
 THashList.cxx:147
 THashList.cxx:148
 THashList.cxx:149
 THashList.cxx:150
 THashList.cxx:151
 THashList.cxx:152
 THashList.cxx:153
 THashList.cxx:154
 THashList.cxx:155
 THashList.cxx:156
 THashList.cxx:157
 THashList.cxx:158
 THashList.cxx:159
 THashList.cxx:160
 THashList.cxx:161
 THashList.cxx:162
 THashList.cxx:163
 THashList.cxx:164
 THashList.cxx:165
 THashList.cxx:166
 THashList.cxx:167
 THashList.cxx:168
 THashList.cxx:169
 THashList.cxx:170
 THashList.cxx:171
 THashList.cxx:172
 THashList.cxx:173
 THashList.cxx:174
 THashList.cxx:175
 THashList.cxx:176
 THashList.cxx:177
 THashList.cxx:178
 THashList.cxx:179
 THashList.cxx:180
 THashList.cxx:181
 THashList.cxx:182
 THashList.cxx:183
 THashList.cxx:184
 THashList.cxx:185
 THashList.cxx:186
 THashList.cxx:187
 THashList.cxx:188
 THashList.cxx:189
 THashList.cxx:190
 THashList.cxx:191
 THashList.cxx:192
 THashList.cxx:193
 THashList.cxx:194
 THashList.cxx:195
 THashList.cxx:196
 THashList.cxx:197
 THashList.cxx:198
 THashList.cxx:199
 THashList.cxx:200
 THashList.cxx:201
 THashList.cxx:202
 THashList.cxx:203
 THashList.cxx:204
 THashList.cxx:205
 THashList.cxx:206
 THashList.cxx:207
 THashList.cxx:208
 THashList.cxx:209
 THashList.cxx:210
 THashList.cxx:211
 THashList.cxx:212
 THashList.cxx:213
 THashList.cxx:214
 THashList.cxx:215
 THashList.cxx:216
 THashList.cxx:217
 THashList.cxx:218
 THashList.cxx:219
 THashList.cxx:220
 THashList.cxx:221
 THashList.cxx:222
 THashList.cxx:223
 THashList.cxx:224
 THashList.cxx:225
 THashList.cxx:226
 THashList.cxx:227
 THashList.cxx:228
 THashList.cxx:229
 THashList.cxx:230
 THashList.cxx:231
 THashList.cxx:232
 THashList.cxx:233
 THashList.cxx:234
 THashList.cxx:235
 THashList.cxx:236
 THashList.cxx:237
 THashList.cxx:238
 THashList.cxx:239
 THashList.cxx:240
 THashList.cxx:241
 THashList.cxx:242
 THashList.cxx:243
 THashList.cxx:244
 THashList.cxx:245
 THashList.cxx:246
 THashList.cxx:247
 THashList.cxx:248
 THashList.cxx:249
 THashList.cxx:250
 THashList.cxx:251
 THashList.cxx:252
 THashList.cxx:253
 THashList.cxx:254
 THashList.cxx:255
 THashList.cxx:256
 THashList.cxx:257
 THashList.cxx:258
 THashList.cxx:259
 THashList.cxx:260
 THashList.cxx:261
 THashList.cxx:262
 THashList.cxx:263
 THashList.cxx:264
 THashList.cxx:265
 THashList.cxx:266
 THashList.cxx:267
 THashList.cxx:268
 THashList.cxx:269
 THashList.cxx:270
 THashList.cxx:271
 THashList.cxx:272
 THashList.cxx:273
 THashList.cxx:274
 THashList.cxx:275
 THashList.cxx:276
 THashList.cxx:277
 THashList.cxx:278
 THashList.cxx:279
 THashList.cxx:280
 THashList.cxx:281
 THashList.cxx:282
 THashList.cxx:283
 THashList.cxx:284
 THashList.cxx:285
 THashList.cxx:286
 THashList.cxx:287
 THashList.cxx:288
 THashList.cxx:289
 THashList.cxx:290
 THashList.cxx:291
 THashList.cxx:292
 THashList.cxx:293
 THashList.cxx:294
 THashList.cxx:295
 THashList.cxx:296
 THashList.cxx:297
 THashList.cxx:298
 THashList.cxx:299
 THashList.cxx:300
 THashList.cxx:301
 THashList.cxx:302
 THashList.cxx:303
 THashList.cxx:304
 THashList.cxx:305
 THashList.cxx:306
 THashList.cxx:307
 THashList.cxx:308
 THashList.cxx:309
 THashList.cxx:310
 THashList.cxx:311