Logo ROOT   master
Reference Guide
THashTable.cxx
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Fons Rademakers 27/09/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 THashTable
13 \ingroup Containers
14 THashTable implements a hash table to store TObject's. The hash
15 value is calculated using the value returned by the TObject's
16 Hash() function. Each class inheriting from TObject can override
17 Hash() as it sees fit.
18 
19 THashTable does not preserve the insertion order of the objects.
20 If the insertion order is important AND fast retrieval is needed
21 use THashList instead.
22 */
23 
24 #include "THashTable.h"
25 #include "TObjectTable.h"
26 #include "TList.h"
27 #include "TError.h"
28 #include "TROOT.h"
29 
31 
32 ////////////////////////////////////////////////////////////////////////////////
33 /// Create a THashTable object. Capacity is the initial hashtable capacity
34 /// (i.e. number of slots), by default kInitHashTableCapacity = 17, and
35 /// rehashlevel is the value at which a rehash will be triggered. I.e. when
36 /// the average size of the linked lists at a slot becomes longer than
37 /// rehashlevel then the hashtable will be resized and refilled to reduce
38 /// the collision rate to about 1. The higher the collision rate, i.e. the
39 /// longer the linked lists, the longer lookup will take. If rehashlevel=0
40 /// the table will NOT automatically be rehashed. Use Rehash() for manual
41 /// rehashing.
42 
43 THashTable::THashTable(Int_t capacity, Int_t rehashlevel)
44 {
45  if (capacity < 0) {
46  Warning("THashTable", "capacity (%d) < 0", capacity);
48  } else if (capacity == 0)
50 
52  fCont = new TList* [fSize];
53  memset(fCont, 0, fSize*sizeof(TList*));
54 
55  fEntries = 0;
56  fUsedSlots = 0;
57  if (rehashlevel < 2) rehashlevel = 0;
58  fRehashLevel = rehashlevel;
59 }
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// Delete a hashtable. Objects are not deleted unless the THashTable is the
63 /// owner (set via SetOwner()).
64 
66 {
67  if (fCont) Clear();
68  delete [] fCont;
69  fCont = 0;
70  fSize = 0;
71 }
72 
73 ////////////////////////////////////////////////////////////////////////////////
74 /// Helper function doing the actual add to the table give a slot and object.
75 /// This does not take any lock.
76 
77 inline
79 {
80  if (!fCont[slot]) {
81  fCont[slot] = new TList;
82  ++fUsedSlots;
83  }
84  fCont[slot]->Add(obj);
85  ++fEntries;
86 }
87 
88 ////////////////////////////////////////////////////////////////////////////////
89 /// Add object to the hash table. Its position in the table will be
90 /// determined by the value returned by its Hash() function.
91 
93 {
94  if (IsArgNull("Add", obj)) return;
95 
96  Int_t slot = GetCheckedHashValue(obj);
97 
99 
100  AddImpl(slot,obj);
101 
103  Rehash(fEntries);
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// Add object to the hash table. Its position in the table will be
108 /// determined by the value returned by its Hash() function.
109 /// If and only if 'before' is in the same bucket as obj, obj is added
110 /// in front of 'before' within the bucket's list.
111 
112 void THashTable::AddBefore(const TObject *before, TObject *obj)
113 {
114  if (IsArgNull("Add", obj)) return;
115 
116  Int_t slot = GetCheckedHashValue(obj);
117 
119  if (!fCont[slot]) {
120  fCont[slot] = new TList;
121  fUsedSlots++;
122  }
123  if (before && GetHashValue(before) == slot) {
124  fCont[slot]->AddBefore(before,obj);
125  } else {
126  fCont[slot]->Add(obj);
127  }
128  fEntries++;
129 
131  Rehash(fEntries);
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// Add all objects from collection col to this collection.
136 /// Implemented for more efficient rehashing.
137 
139 {
141 
142  // Hashing after AddAll can be much more expensive than
143  // hashing before, as we need to add more elements.
144  // We assume an ideal hash, i.e. fUsedSlots==fSize.
145  Int_t sumEntries=fEntries+col->GetEntries();
146  Bool_t rehashBefore=fRehashLevel && (sumEntries > fSize*fRehashLevel);
147  if (rehashBefore)
148  Rehash(sumEntries);
149 
150  // prevent Add from Rehashing
151  Int_t saveRehashLevel=fRehashLevel;
152  fRehashLevel=0;
153 
154  TCollection::AddAll(col);
155 
156  fRehashLevel=saveRehashLevel;
157  // If we didn't Rehash before, we might have to do it
158  // now, due to a non-perfect hash function.
159  if (!rehashBefore && fRehashLevel && AverageCollisions() > fRehashLevel)
160  Rehash(fEntries);
161 }
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /// Remove all objects from the table. Does not delete the objects
165 /// unless the THashTable is the owner (set via SetOwner()).
166 
168 {
170 
171  for (int i = 0; i < fSize; i++) {
172  // option "nodelete" is passed when Clear is called from
173  // THashList::Clear() or THashList::Delete() or Rehash().
174  if (fCont[i]) {
175  if (IsOwner())
176  fCont[i]->SetOwner();
177  fCont[i]->Clear(option);
178  }
179  SafeDelete(fCont[i]);
180  }
181 
182  fEntries = 0;
183  fUsedSlots = 0;
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Returns the number of collisions for an object with a certain name
188 /// (i.e. number of objects in same slot in the hash table, i.e. length
189 /// of linked list).
190 
192 {
193  Int_t slot = GetHashValue(name);
194 
196 
197  if (fCont[slot]) return fCont[slot]->GetSize();
198  return 0;
199 }
200 
201 ////////////////////////////////////////////////////////////////////////////////
202 /// Returns the number of collisions for an object (i.e. number of objects
203 /// in same slot in the hash table, i.e. length of linked list).
204 
206 {
207  if (IsArgNull("Collisions", obj)) return 0;
208 
209  Int_t slot = GetHashValue(obj);
210 
212 
213  if (fCont[slot]) return fCont[slot]->GetSize();
214  return 0;
215 }
216 
217 ////////////////////////////////////////////////////////////////////////////////
218 /// Remove all objects from the table AND delete all heap based objects.
219 
221 {
223 
224  for (int i = 0; i < fSize; i++)
225  if (fCont[i]) {
226  fCont[i]->Delete();
227  SafeDelete(fCont[i]);
228  }
229 
230  fEntries = 0;
231  fUsedSlots = 0;
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Find object using its name. Uses the hash value returned by the
236 /// TString::Hash() after converting name to a TString.
237 
239 {
240  Int_t slot = GetHashValue(name);
241 
243 
244  if (fCont[slot]) return fCont[slot]->FindObject(name);
245  return 0;
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// Find object using its hash value (returned by its Hash() member).
250 
252 {
253  if (IsArgNull("FindObject", obj)) return 0;
254 
255  Int_t slot = GetHashValue(obj);
256  if (fCont[slot]) return fCont[slot]->FindObject(obj);
257  return 0;
258 }
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 /// Return the TList corresponding to object's name based hash value.
262 /// One can iterate this list "manually" to find, e.g. objects with
263 /// the same name.
264 
265 const TList *THashTable::GetListForObject(const char *name) const
266 {
267  Int_t slot = GetHashValue(name);
268 
270 
271  return fCont[slot];
272 }
273 
274 ////////////////////////////////////////////////////////////////////////////////
275 /// Return the TList corresponding to object's hash value.
276 /// One can iterate this list "manually" to find, e.g. identical
277 /// objects.
278 
280 {
281  if (IsArgNull("GetListForObject", obj)) return 0;
282 
283  Int_t slot = GetHashValue(obj);
284 
286 
287  return fCont[slot];
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Return address of pointer to obj
292 
294 {
295  if (IsArgNull("GetObjectRef", obj)) return 0;
296 
297  Int_t slot = GetHashValue(obj);
298 
300 
301  if (fCont[slot]) return fCont[slot]->GetObjectRef(obj);
302  return 0;
303 }
304 
305 ////////////////////////////////////////////////////////////////////////////////
306 /// Returns a hash table iterator.
307 
309 {
310  return new THashTableIter(this, dir);
311 }
312 
313 ////////////////////////////////////////////////////////////////////////////
314 /// Print the collection header and its elements.
315 ///
316 /// If recurse is non-zero, descend into printing of
317 /// collection-entries with recurse - 1.
318 /// This means, if recurse is negative, the recursion is infinite.
319 ///
320 /// If option contains "details", Print will show the content of
321 /// each of the hash-slots.
322 ///
323 /// Option is passed recursively.
324 
325 void THashTable::Print(Option_t *option, Int_t recurse) const
326 {
327  if (strstr(option,"details")==nullptr) {
328  TCollection::Print(option,recurse);
329  return;
330  }
331 
332  PrintCollectionHeader(option);
333 
334  if (recurse != 0)
335  {
337  for (Int_t cursor = 0; cursor < Capacity();
338  cursor++) {
339  printf("Slot #%d:\n",cursor);
340  if (fCont[cursor])
341  fCont[cursor]->Print();
342  else {
344  printf("empty\n");
345  }
346 
347  }
349  }
350 }
351 
352 ////////////////////////////////////////////////////////////////////////////////
353 /// Rehash the hashtable. If the collision rate becomes too high (i.e.
354 /// the average size of the linked lists become too long) then lookup
355 /// efficiency decreases since relatively long lists have to be searched
356 /// every time. To improve performance rehash the hashtable. This resizes
357 /// the table to newCapacity slots and refills the table. Use
358 /// AverageCollisions() to check if you need to rehash. Set checkObjValidity
359 /// to kFALSE if you know that all objects in the table are still valid
360 /// (i.e. have not been deleted from the system in the meanwhile).
361 
362 void THashTable::Rehash(Int_t newCapacity, Bool_t checkObjValidity)
363 {
364  THashTable *ht = new THashTable(newCapacity);
365 
367 
368  TIter next(this);
369  TObject *obj;
370 
371  auto initialSize = GetEntries();
372 
373  if (checkObjValidity && TObject::GetObjectStat() && gObjectTable) {
374  while ((obj = next()))
375  if (gObjectTable->PtrIsValid(obj))
376  ht->AddImpl(ht->GetHashValue(obj),obj);
377  } else {
378  while ((obj = next()))
379  ht->AddImpl(ht->GetHashValue(obj),obj);
380  }
381 
382  if (initialSize != GetEntries()) {
383  // Somehow in the process of copy the pointer from one hash to
384  // other we ended up inducing the addition of more element to
385  // the table. Most likely those elements have not been copied ....
386  // i.e. Adding *during* the Rehashing is illegal and fatal.
387 
388  Fatal("Rehash",
389  "During the rehash of %p one or more element was added or removed. The initalize size was %d and now it is %d",
390  this, initialSize, GetEntries());
391 
392  }
393 
394  Clear("nodelete");
395  delete [] fCont;
396  fCont = ht->fCont;
397  ht->fCont = 0;
398 
399  fSize = ht->fSize; // idem
400  fEntries = ht->fEntries;
401  fUsedSlots = ht->fUsedSlots;
402 
403  // this should not happen, but it will prevent an endless loop
404  // in case of a very bad hash function
407 
408  delete ht;
409 }
410 
411 ////////////////////////////////////////////////////////////////////////////////
412 /// Remove object from the hashtable.
413 
415 {
416  Int_t slot = GetHashValue(obj);
417 
419 
420  if (fCont[slot]) {
422 
423  TObject *ob = fCont[slot]->Remove(obj);
424  if (ob) {
425  fEntries--;
426  if (fCont[slot]->GetSize() == 0) {
427  SafeDelete(fCont[slot]);
428  fUsedSlots--;
429  }
430  return ob;
431  }
432  }
433  return 0;
434 }
435 
436 ////////////////////////////////////////////////////////////////////////////////
437 /// Remove object from the hashtable without using the hash value.
438 
440 {
441 
443 
444  for (int i = 0; i < fSize; i++) {
445  if (fCont[i]) {
446  TObject *ob = fCont[i]->Remove(obj);
447  if (ob) {
448  fEntries--;
449  if (fCont[i]->GetSize() == 0) {
450  SafeDelete(fCont[i]);
451  fUsedSlots--;
452  }
453  return ob;
454  }
455  }
456  }
457  return 0;
458 }
459 
460 /** \class THashTableIter
461 Iterator of hash table.
462 */
463 
465 
466 ////////////////////////////////////////////////////////////////////////////////
467 /// Create a hashtable iterator. By default the iteration direction
468 /// is kIterForward. To go backward use kIterBackward.
469 
471 {
472  fTable = ht;
473  fDirection = dir;
474  fListCursor = 0;
475  Reset();
476 }
477 
478 ////////////////////////////////////////////////////////////////////////////////
479 /// Copy ctor.
480 
482 {
483  fTable = iter.fTable;
484  fDirection = iter.fDirection;
485  fCursor = iter.fCursor;
486  fListCursor = 0;
487  if (iter.fListCursor) {
489  if (fListCursor)
490  fListCursor->operator=(*iter.fListCursor);
491  }
492 }
493 
494 ////////////////////////////////////////////////////////////////////////////////
495 /// Overridden assignment operator.
496 
498 {
499  if (this != &rhs && rhs.IsA() == THashTableIter::Class()) {
500  const THashTableIter &rhs1 = (const THashTableIter &)rhs;
501  fTable = rhs1.fTable;
502  fDirection = rhs1.fDirection;
503  fCursor = rhs1.fCursor;
504  if (rhs1.fListCursor) {
505  // R__COLLECTION_READ_LOCKGUARD(ROOT::gCoreMutex);
506 
508  if (fListCursor)
509  fListCursor->operator=(*rhs1.fListCursor);
510  }
511  }
512  return *this;
513 }
514 
515 ////////////////////////////////////////////////////////////////////////////////
516 /// Overloaded assignment operator.
517 
519 {
520  if (this != &rhs) {
521  fTable = rhs.fTable;
522  fDirection = rhs.fDirection;
523  fCursor = rhs.fCursor;
524  if (rhs.fListCursor) {
525  // R__COLLECTION_READ_LOCKGUARD(ROOT::gCoreMutex);
526 
528  if (fListCursor)
529  fListCursor->operator=(*rhs.fListCursor);
530  }
531  }
532  return *this;
533 }
534 
535 ////////////////////////////////////////////////////////////////////////////////
536 /// Delete hashtable iterator.
537 
539 {
540  delete fListCursor;
541 }
542 
543 ////////////////////////////////////////////////////////////////////////////////
544 /// Return next object in hashtable. Returns 0 when no more objects in table.
545 
547 {
548  // R__COLLECTION_READ_LOCKGUARD(ROOT::gCoreMutex);
549 
550  while (kTRUE) {
551  if (!fListCursor) {
552  int slot = NextSlot();
553  if (slot == -1) return 0;
555  }
556 
557  TObject *obj = fListCursor->Next();
558  if (obj) return obj;
559 
561  }
562 }
563 
564 ////////////////////////////////////////////////////////////////////////////////
565 /// Returns index of next slot in table containing list to be iterated.
566 
568 {
569  // R__COLLECTION_READ_LOCKGUARD(ROOT::gCoreMutex);
570 
571  if (fDirection == kIterForward) {
572  for ( ; fCursor < fTable->Capacity() && fTable->fCont[fCursor] == 0;
573  fCursor++) { }
574 
575  if (fCursor < fTable->Capacity())
576  return fCursor++;
577 
578  } else {
579  for ( ; fCursor >= 0 && fTable->fCont[fCursor] == 0;
580  fCursor--) { }
581 
582  if (fCursor >= 0)
583  return fCursor--;
584  }
585  return -1;
586 }
587 
588 ////////////////////////////////////////////////////////////////////////////////
589 /// Reset the hashtable iterator. Either to beginning or end, depending on
590 /// the initial iteration direction.
591 
593 {
594  if (fDirection == kIterForward)
595  fCursor = 0;
596  else
597  fCursor = fTable->Capacity() - 1;
599 }
600 
601 ////////////////////////////////////////////////////////////////////////////////
602 /// This operator compares two TIterator objects.
603 
605 {
606  if (aIter.IsA() == THashTableIter::Class()) {
607  const THashTableIter &iter(dynamic_cast<const THashTableIter &>(aIter));
608  return (fListCursor != iter.fListCursor);
609  }
610  return false; // for base class we don't implement a comparison
611 }
612 
613 ////////////////////////////////////////////////////////////////////////////////
614 /// This operator compares two THashTableIter objects.
615 
617 {
618  return (fListCursor != aIter.fListCursor);
619 }
620 
621 ////////////////////////////////////////////////////////////////////////////////
622 /// Return pointer to current object or nullptr.
623 
625 {
626  return (fListCursor ? fListCursor->operator*() : nullptr);
627 }
void AddImpl(Int_t slot, TObject *object)
Helper function doing the actual add to the table give a slot and object.
Definition: THashTable.cxx:78
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition: TROOT.cxx:2725
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
Definition: THashTable.cxx:138
void AddBefore(const TObject *before, TObject *obj)
Add object to the hash table.
Definition: THashTable.cxx:112
void Reset()
Reset the hashtable iterator.
Definition: THashTable.cxx:592
TList ** fCont
Definition: THashTable.h:40
TObject ** GetObjectRef(const TObject *obj) const
Return address of pointer to obj.
Definition: THashTable.cxx:293
const char Option_t
Definition: RtypesCore.h:62
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Bool_t IsArgNull(const char *where, const TObject *obj) const
Returns true if object is a null pointer.
virtual Int_t GetEntries() const
Definition: TCollection.h:177
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
void Rehash(Int_t newCapacity, Bool_t checkObjValidity=kTRUE)
Rehash the hashtable.
Definition: THashTable.cxx:362
Float_t AverageCollisions() const
Definition: THashTable.h:84
Int_t fUsedSlots
Definition: THashTable.h:42
const TList * GetListForObject(const char *name) const
Return the TList corresponding to object&#39;s name based hash value.
Definition: THashTable.cxx:265
int Int_t
Definition: RtypesCore.h:41
TObject * RemoveSlow(TObject *obj)
Remove object from the hashtable without using the hash value.
Definition: THashTable.cxx:439
TObject * Next()
Return next object in the list. Returns 0 when no more objects in list.
Definition: TList.cxx:1110
TListIter * fListCursor
Definition: THashTable.h:118
const THashTable * fTable
Definition: THashTable.h:116
Iterator abstract base class.
Definition: TIterator.h:30
Iterator of linked list.
Definition: TList.h:197
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
THashTable(const THashTable &)
friend class THashTableIter
Definition: THashTable.h:37
Iterator of hash table.
Definition: THashTable.h:113
THashTable implements a hash table to store TObject&#39;s.
Definition: THashTable.h:35
void Class()
Definition: Class.C:29
void Clear(Option_t *option="")
Remove all objects from the table.
Definition: THashTable.cxx:167
#define R__COLLECTION_READ_LOCKGUARD(mutex)
Definition: TCollection.h:435
R__EXTERN TVirtualRWMutex * gCoreMutex
const Bool_t kIterForward
Definition: TCollection.h:40
Bool_t IsOwner() const
Definition: TCollection.h:188
Int_t NextSlot()
Returns index of next slot in table containing list to be iterated.
Definition: THashTable.cxx:567
~THashTableIter()
Delete hashtable iterator.
Definition: THashTable.cxx:538
TObject * operator*() const
Return pointer to current object or nullptr.
Definition: THashTable.cxx:624
Bool_t fDirection
Definition: THashTable.h:119
A doubly linked list.
Definition: TList.h:44
Int_t fEntries
Definition: THashTable.h:41
const TCollection * GetCollection() const
Definition: TList.h:221
virtual TIterator * MakeIterator(Bool_t dir=kIterForward) const =0
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:819
Collection abstract base class.
Definition: TCollection.h:63
virtual ~THashTable()
Delete a hashtable.
Definition: THashTable.cxx:65
Bool_t PtrIsValid(TObject *obj)
Definition: TObjectTable.h:78
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition: TROOT.cxx:2829
static Bool_t GetObjectStat()
Get status of object stat flag.
Definition: TObject.cxx:961
virtual void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition: TList.cxx:193
TIterator * MakeIterator(Bool_t dir=kIterForward) const
Returns a hash table iterator.
Definition: THashTable.cxx:308
R__EXTERN TObjectTable * gObjectTable
Definition: TObjectTable.h:82
Int_t Collisions(const char *name) const
Returns the number of collisions for an object with a certain name (i.e.
Definition: THashTable.cxx:191
#define SafeDelete(p)
Definition: RConfig.hxx:543
void Print(Option_t *option, Int_t recurse) const
Print the collection header and its elements.
Definition: THashTable.cxx:325
TIterator & operator=(const TIterator &rhs)
Overridden assignment operator.
Definition: THashTable.cxx:497
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashTable.cxx:238
#define ClassImp(name)
Definition: Rtypes.h:365
Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: THashTable.h:72
void Add(TObject *obj)
Add object to the hash table.
Definition: THashTable.cxx:92
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
Mother of all ROOT objects.
Definition: TObject.h:37
Long_t NextPrime(Long_t x)
TMath Base functionsDefine the functions Min, Max, Abs, Sign, Range for all types.
Definition: TMathBase.cxx:30
void Delete(Option_t *option="")
Remove all objects from the table AND delete all heap based objects.
Definition: THashTable.cxx:220
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition: TROOT.cxx:2821
Int_t GetCheckedHashValue(TObject *obj) const
Definition: THashTable.h:92
virtual void PrintCollectionHeader(Option_t *option) const
Print the collection header.
Int_t fRehashLevel
Definition: THashTable.h:43
virtual void Add(TObject *obj)
Definition: TList.h:87
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
Int_t Capacity() const
Definition: TCollection.h:165
Bool_t operator!=(const TIterator &aIter) const
This operator compares two TIterator objects.
Definition: THashTable.cxx:604
TObject * Next()
Return next object in hashtable. Returns 0 when no more objects in table.
Definition: THashTable.cxx:546
#define R__COLLECTION_WRITE_LOCKGUARD(mutex)
Definition: TCollection.h:438
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:915
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
const Bool_t kTRUE
Definition: RtypesCore.h:87
Int_t GetHashValue(const TObject *obj) const
Definition: THashTable.h:98
virtual TObject ** GetObjectRef(const TObject *obj) const
Return address of pointer to obj.
Definition: TList.cxx:668
char name[80]
Definition: TGX11.cxx:109
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:873
TObject * Remove(TObject *obj)
Remove object from the hashtable.
Definition: THashTable.cxx:414