Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
THashList.cxx
Go to the documentation of this file.
1// @(#)root/cont:$Id$
2// Author: Fons Rademakers 10/08/95
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class THashList
13\ingroup Containers
14THashList implements a hybrid collection class consisting of a
15hash table and a list to store TObject's. The hash table is used for
16quick access and lookup of objects while the list allows the objects
17to be ordered. The hash value is calculated using the value returned
18by the TObject's Hash() function. Each class inheriting from TObject
19can override Hash() as it sees fit.
20*/
21
22#include "THashList.h"
23#include "THashTable.h"
24#include "TClass.h"
25
26
27
28////////////////////////////////////////////////////////////////////////////////
29/// Create a THashList object. Capacity is the initial hashtable capacity
30/// (i.e. number of slots), by default kInitHashTableCapacity = 17, and
31/// rehash is the value at which a rehash will be triggered. I.e. when the
32/// average size of the linked lists at a slot becomes longer than rehash
33/// then the hashtable will be resized and refilled to reduce the collision
34/// rate to about 1. The higher the collision rate, i.e. the longer the
35/// linked lists, the longer lookup will take. If rehash=0 the table will
36/// NOT automatically be rehashed. Use Rehash() for manual rehashing.
37///
38/// WARNING !!!
39/// If the name of an object in the HashList is modified, The hashlist
40/// must be Rehashed
41
43{
44 fTable = new THashTable(capacity, rehash);
45}
46
47////////////////////////////////////////////////////////////////////////////////
48/// For backward compatibility only. Use other ctor.
49
52 fTable = new THashTable(capacity, rehash);
53}
54
55////////////////////////////////////////////////////////////////////////////////
56/// Delete a hashlist. Objects are not deleted unless the THashList is the
57/// owner (set via SetOwner()).
58
64
65////////////////////////////////////////////////////////////////////////////////
66/// Add object at the beginning of the list.
67
75
76////////////////////////////////////////////////////////////////////////////////
77/// Add object at the beginning of the list and also store option.
78/// Storing an option is useful when one wants to change the behaviour
79/// of an object a little without having to create a complete new
80/// copy of the object. This feature is used, for example, by the Draw()
81/// method. It allows the same object to be drawn in different ways.
82
90
91////////////////////////////////////////////////////////////////////////////////
92/// Add object at the end of the list.
93
101
102////////////////////////////////////////////////////////////////////////////////
103/// Add object at the end of the list and also store option.
104/// Storing an option is useful when one wants to change the behaviour
105/// of an object a little without having to create a complete new
106/// copy of the object. This feature is used, for example, by the Draw()
107/// method. It allows the same object to be drawn in different ways.
108
110{
112
113 TList::AddLast(obj, opt);
114 fTable->Add(obj);
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Insert object before object before in the list.
119
127
128////////////////////////////////////////////////////////////////////////////////
129/// Insert object before object before in the list.
130
138
139////////////////////////////////////////////////////////////////////////////////
140/// Insert object before object before in the list, with options.
141
149
150////////////////////////////////////////////////////////////////////////////////
151/// Insert object before object before in the list, with options.
152
160
161////////////////////////////////////////////////////////////////////////////////
162/// Insert object after object after in the list.
163
171
172////////////////////////////////////////////////////////////////////////////////
173/// Insert object after object after in the list.
174
182////////////////////////////////////////////////////////////////////////////////
183/// Insert object after object after in the list, with options.
184
186{
188
189 TList::AddAfter(after, obj, opt);
190 fTable->Add(obj);
191}
192
193////////////////////////////////////////////////////////////////////////////////
194/// Insert object after object after in the list, with options.
195
203
204////////////////////////////////////////////////////////////////////////////////
205/// Insert object at location idx in the list.
206
208{
210
211 TList::AddAt(obj, idx);
212 fTable->Add(obj);
213}
214
215////////////////////////////////////////////////////////////////////////////////
216/// Insert object at location idx in the list, with options.
217
219{
221
222 TList::AddAt(obj, idx, opt);
223 fTable->Add(obj);
224}
225
226////////////////////////////////////////////////////////////////////////////////
227/// Return the average collision rate. The higher the number the longer
228/// the linked lists in the hashtable, the slower the lookup. If the number
229/// is high, or lookup noticeably too slow, perform a Rehash().
230
237
238////////////////////////////////////////////////////////////////////////////////
239/// Remove all objects from the list. Does not delete the objects unless
240/// the THashList is the owner (set via SetOwner()).
241
243{
245
246 fTable->Clear("nodelete"); // clear table so not more lookups
247 if (IsOwner())
249 else
251}
252
253////////////////////////////////////////////////////////////////////////////////
254/// Remove all objects from the list AND delete all heap based objects.
255/// If option="slow" then keep list consistent during delete. This allows
256/// recursive list operations during the delete (e.g. during the dtor
257/// of an object in this list one can still access the list to search for
258/// other not yet deleted objects).
259
261{
263
264 Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;
265
266 if (!slow) {
267 fTable->Clear("nodelete"); // clear table so no more lookups
268 TList::Delete(option); // this deletes the objects
269 } else {
270 TList removeDirectory; // need to deregister these from their directory
271
272 while (fFirst) {
273 auto tlk = fFirst;
274 fFirst = fFirst->NextSP();
275 fSize--;
276 // remove object from table
277 fTable->Remove(tlk->GetObject());
278
279 // delete only heap objects
280 auto obj = tlk->GetObject();
281 // In case somebody else access it.
282 tlk->SetObject(nullptr);
283 if (obj && ROOT::Detail::HasBeenDeleted(obj))
284 Error("Delete", "A list is accessing an object (%p) already deleted (list name = %s)",
285 obj, GetName());
286 else if (obj && obj->IsOnHeap())
288 else if (obj && obj->IsA()->GetDirectoryAutoAdd())
289 removeDirectory.Add(obj);
290
291 // tlk reference count goes down 1.
292 }
293 fFirst.reset();
294 fLast.reset();
295 fCache.reset();
296 fSize = 0;
297
298 // These objects cannot expect to have a valid TDirectory anymore;
299 // e.g. because *this is the TDirectory's list of objects. Even if
300 // not, they are supposed to be deleted, so we can as well unregister
301 // them from their directory, even if they are stack-based:
303 TObject* dirRem = nullptr;
304 while ((dirRem = iRemDir())) {
305 (*dirRem->IsA()->GetDirectoryAutoAdd())(dirRem, nullptr);
306 }
307 Changed();
308 }
309}
310
311////////////////////////////////////////////////////////////////////////////////
312/// Find object using its name. Uses the hash value returned by the
313/// TString::Hash() after converting name to a TString.
314
321
322////////////////////////////////////////////////////////////////////////////////
323/// Find object using its hash value (returned by its Hash() member).
324
331
332////////////////////////////////////////////////////////////////////////////////
333/// Return the THashTable's list (bucket) in which obj can be found based on
334/// its hash; see THashTable::GetListForObject().
335
342
343////////////////////////////////////////////////////////////////////////////////
344/// Return the THashTable's list (bucket) in which obj can be found based on
345/// its hash; see THashTable::GetListForObject().
346
353
354////////////////////////////////////////////////////////////////////////////////
355/// Remove object from this collection and recursively remove the object
356/// from all other objects (and collections).
357/// This function overrides TCollection::RecursiveRemove that calls
358/// the Remove function. THashList::Remove cannot be called because
359/// it uses the hash value of the hash table. This hash value
360/// is not available anymore when RecursiveRemove is called from
361/// the TObject destructor.
362
364{
365 if (!obj || fSize == 0)
366 return;
367
368 // It might not be safe to rely on TROOT::RecursiveRemove to take the readlock in case user code
369 // is calling directly gROOT->GetListOfCleanups()->RecursiveRemove(...)
370 // However this can become a significant bottleneck if there are a very large number of
371 // TDirectory object.
372 // If we need to enabling this read lock, we need to move the fSize check afterwards.
373 // TList::RecursiveRemove has the same pattern.
374 // R__COLLECTION_READ_LOCKGUARD(ROOT::gCoreMutex);
375
376 if (obj->HasInconsistentHash()) {
378
379 // Remove obj in the list itself
380 TObject *object = TList::Remove(obj);
381 if (object)
382 fTable->RemoveSlow(object);
383
384 } else if (fTable->FindObject(obj)) {
386
387 // Remove obj in the list itself
388 TObject *object = TList::Remove(obj);
389 if (object)
390 fTable->Remove(object);
391 }
392
393 // Scan again the list and invoke RecursiveRemove for all objects
394 // We need to make sure to go through all the node even those
395 // marked as empty by another thread (Eventhough we hold the
396 // read lock if one of the call to RecursiveRemove request
397 // the write lock then the read lock will be suspended and
398 // another thread can modify the list; thanks to the shared_pointer
399 // forward-and-backward links, our view of the list is still intact
400 // but might contains node will nullptr payload)
401 auto lnk = fFirst;
402 decltype(lnk) next;
403 while (lnk.get()) {
404 next = lnk->NextSP();
405 TObject *ob = lnk->GetObject();
407 ob->RecursiveRemove(obj);
408 }
409 lnk = next;
410 }
411}
412
413////////////////////////////////////////////////////////////////////////////////
414/// Rehash the hashlist. If the collision rate becomes too high (i.e.
415/// the average size of the linked lists become too long) then lookup
416/// efficiency decreases since relatively long lists have to be searched
417/// every time. To improve performance rehash the hashtable. This resizes
418/// the table to newCapacity slots and refills the table. Use
419/// AverageCollisions() to check if you need to rehash.
420
427
428////////////////////////////////////////////////////////////////////////////////
429/// Remove object from the list.
430
432{
434 if (!obj || !fTable->FindObject(obj)) return nullptr;
435
437 TList::Remove(obj);
438 return fTable->Remove(obj);
439}
440
441////////////////////////////////////////////////////////////////////////////////
442/// Remove object via its objlink from the list.
443
445{
446 if (!lnk) return nullptr;
447
449 TObject *obj = lnk->GetObject();
450
452 return fTable->Remove(obj);
453}
454
455////////////////////////////////////////////////////////////////////////////////
456/// Set this collection to use a RW lock upon access, making it thread safe.
457/// Return the previous state.
458///
459/// Note: To test whether the usage is enabled do:
460/// collection->TestBit(TCollection::kUseRWLock);
461
#define SafeDelete(p)
Definition RConfig.hxx:533
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
#define R__COLLECTION_READ_LOCKGUARD(mutex)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__COLLECTION_WRITE_LOCKGUARD(mutex)
Option_t Option_t option
char name[80]
Definition TGX11.cxx:110
virtual bool UseRWLock(Bool_t enable=true)
Set this collection to use a RW lock upon access, making it thread safe.
const char * GetName() const override
Return name of this collection.
Bool_t IsOwner() const
static void GarbageCollect(TObject *obj)
Add to the list of things to be cleaned up.
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
void Clear(Option_t *option="") override
Remove all objects from the list.
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
Definition THashList.cxx:68
void Rehash(Int_t newCapacity)
Rehash the hashlist.
virtual ~THashList()
Delete a hashlist.
Definition THashList.cxx:59
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
THashTable * fTable
Definition THashList.h:37
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
void AddAt(TObject *obj, Int_t idx) override
Insert object at location idx in the list.
THashList(const THashList &)=delete
const TList * GetListForObject(const char *name) const
Return the THashTable's list (bucket) in which obj can be found based on its hash; see THashTable::Ge...
bool UseRWLock(Bool_t enable=true) override
Set this collection to use a RW lock upon access, making it thread safe.
Float_t AverageCollisions() const
Return the average collision rate.
TObject * Remove(TObject *obj) override
Remove object from the list.
TObject * FindObject(const char *name) const override
Find object using its name.
void AddLast(TObject *obj) override
Add object at the end of the list.
Definition THashList.cxx:94
THashTable implements a hash table to store TObject's.
Definition THashTable.h:35
Float_t AverageCollisions() const
Definition THashTable.h:86
void Add(TObject *obj) override
Add object to the hash table.
const TList * GetListForObject(const char *name) const
Return the TList corresponding to object's name based hash value.
TObject * Remove(TObject *obj) override
Remove object from the hashtable.
void Rehash(Int_t newCapacity, Bool_t checkObjValidity=kTRUE)
Rehash the hashtable.
TObject * RemoveSlow(TObject *obj)
Remove object from the hashtable without using the hash value.
void AddBefore(const TObject *before, TObject *obj)
Add object to the hash table.
TObject * FindObject(const char *name) const override
Find object using its name.
void Clear(Option_t *option="") override
Remove all objects from the table.
A doubly linked list.
Definition TList.h:38
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
Definition TList.cxx:247
void Clear(Option_t *option="") override
Remove all objects from the list.
Definition TList.cxx:532
void AddAt(TObject *obj, Int_t idx) override
Insert object at position idx in the list.
Definition TList.cxx:413
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:952
void AddLast(TObject *obj) override
Add object at the end of the list.
Definition TList.cxx:149
TObjLinkPtr_t fLast
pointer to first entry in linked list
Definition TList.h:47
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
Definition TList.cxx:193
TObjLinkPtr_t fFirst
Definition TList.h:46
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
TObjLinkWeakPtr_t fCache
pointer to last entry in linked list
Definition TList.h:48
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
Definition TList.cxx:97
Mother of all ROOT objects.
Definition TObject.h:41
Bool_t HasInconsistentHash() const
Return true is the type of this object is known to have an inconsistent setup for Hash and RecursiveR...
Definition TObject.h:361
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1088
virtual void Changed()
R__ALWAYS_INLINE bool HasBeenDeleted(const TObject *obj)
Check if the TObject's memory has been deleted.
Definition TObject.h:405
R__EXTERN TVirtualRWMutex * gCoreMutex