// @(#)root/cont:$Id$
// Author: Fons Rademakers   27/09/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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// THashTable                                                           //
//                                                                      //
// THashTable implements a hash table to store TObject's. 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.                                               //
// THashTable does not preserve the insertion order of the objects.     //
// If the insertion order is important AND fast retrieval is needed     //
// use THashList instead.                                               //
//Begin_Html
/*
<img src=gif/thashtable.gif>
*/
//End_Html
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "THashTable.h"
#include "TObjectTable.h"
#include "TList.h"
#include "TError.h"


ClassImp(THashTable)

//______________________________________________________________________________
THashTable::THashTable(Int_t capacity, Int_t rehashlevel)
{
   // Create a THashTable object. Capacity is the initial hashtable capacity
   // (i.e. number of slots), by default kInitHashTableCapacity = 17, and
   // rehashlevel 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
   // rehashlevel 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 rehashlevel=0
   // the table will NOT automatically be rehashed. Use Rehash() for manual
   // rehashing.

   if (capacity < 0) {
      Warning("THashTable", "capacity (%d) < 0", capacity);
      capacity = TCollection::kInitHashTableCapacity;
   } else if (capacity == 0)
      capacity = TCollection::kInitHashTableCapacity;

   fSize = (Int_t)TMath::NextPrime(TMath::Max(capacity,(int)TCollection::kInitHashTableCapacity));
   fCont = new TList* [fSize];
   memset(fCont, 0, fSize*sizeof(TList*));

   fEntries   = 0;
   fUsedSlots = 0;
   if (rehashlevel < 2) rehashlevel = 0;
   fRehashLevel = rehashlevel;
}

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

   if (fCont) Clear();
   delete [] fCont;
   fCont = 0;
   fSize = 0;
}

//______________________________________________________________________________
void THashTable::Add(TObject *obj)
{
   // Add object to the hash table. Its position in the table will be
   // determined by the value returned by its Hash() function.

   if (IsArgNull("Add", obj)) return;

   Int_t slot = GetHashValue(obj);
   if (!fCont[slot]) {
      fCont[slot] = new TList;
      fUsedSlots++;
   }
   fCont[slot]->Add(obj);
   fEntries++;

   if (fRehashLevel && AverageCollisions() > fRehashLevel)
      Rehash(fEntries);
}

//______________________________________________________________________________
void THashTable::AddAll(const TCollection *col)
{
   // Add all objects from collection col to this collection.
   // Implemented for more efficient rehashing.

   // Hashing after AddAll can be much more expensive than
   // hashing before, as we need to add more elements.
   // We assume an ideal hash, i.e. fUsedSlots==fSize.
   Int_t sumEntries=fEntries+col->GetEntries();
   Bool_t rehashBefore=fRehashLevel && (sumEntries > fSize*fRehashLevel);
   if (rehashBefore)
      Rehash(sumEntries);

   // prevent Add from Rehashing
   Int_t saveRehashLevel=fRehashLevel;
   fRehashLevel=0;

   TCollection::AddAll(col);

   fRehashLevel=saveRehashLevel;
   // If we didn't Rehash before, we might have to do it
   // now, due to a non-perfect hash function.
   if (!rehashBefore && fRehashLevel && AverageCollisions() > fRehashLevel)
      Rehash(fEntries);
}

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

   for (int i = 0; i < fSize; i++) {
      // option "nodelete" is passed when Clear is called from
      // THashList::Clear() or THashList::Delete() or Rehash().
      if (fCont[i]) {
         if (IsOwner())
            fCont[i]->SetOwner();
         fCont[i]->Clear(option);
      }
      SafeDelete(fCont[i]);
   }

   fEntries   = 0;
   fUsedSlots = 0;
}

//______________________________________________________________________________
Int_t THashTable::Collisions(const char *name) const
{
   // Returns the number of collisions for an object with a certain name
   // (i.e. number of objects in same slot in the hash table, i.e. length
   // of linked list).

   Int_t slot = GetHashValue(name);
   if (fCont[slot]) return fCont[slot]->GetSize();
   return 0;
}

//______________________________________________________________________________
Int_t THashTable::Collisions(TObject *obj) const
{
   // Returns the number of collisions for an object (i.e. number of objects
   // in same slot in the hash table, i.e. length of linked list).

   if (IsArgNull("Collisions", obj)) return 0;

   Int_t slot = GetHashValue(obj);
   if (fCont[slot]) return fCont[slot]->GetSize();
   return 0;
}

//______________________________________________________________________________
void THashTable::Delete(Option_t *)
{
   // Remove all objects from the table AND delete all heap based objects.

   for (int i = 0; i < fSize; i++)
      if (fCont[i]) {
         fCont[i]->Delete();
         SafeDelete(fCont[i]);
      }

   fEntries   = 0;
   fUsedSlots = 0;
}

//______________________________________________________________________________
TObject *THashTable::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.

   Int_t slot = GetHashValue(name);
   if (fCont[slot]) return fCont[slot]->FindObject(name);
   return 0;
}

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

   if (IsArgNull("FindObject", obj)) return 0;

   Int_t slot = GetHashValue(obj);
   if (fCont[slot]) return fCont[slot]->FindObject(obj);
   return 0;
}

//______________________________________________________________________________
TList *THashTable::GetListForObject(const char *name) const
{
   // Return the TList corresponding to object's name based hash value.
   // One can iterate this list "manually" to find, e.g. objects with
   // the same name.

   return fCont[GetHashValue(name)];
}

//______________________________________________________________________________
TList *THashTable::GetListForObject(const TObject *obj) const
{
   // Return the TList corresponding to object's hash value.
   // One can iterate this list "manually" to find, e.g. identical
   // objects.

   if (IsArgNull("GetListForObject", obj)) return 0;
   return fCont[GetHashValue(obj)];
}

//______________________________________________________________________________
TObject **THashTable::GetObjectRef(const TObject *obj) const
{
   // Return address of pointer to obj

   if (IsArgNull("GetObjectRef", obj)) return 0;

   Int_t slot = GetHashValue(obj);
   if (fCont[slot]) return fCont[slot]->GetObjectRef(obj);
   return 0;
}

//______________________________________________________________________________
TIterator *THashTable::MakeIterator(Bool_t dir) const
{
   // Returns a hash table iterator.

   return new THashTableIter(this, dir);
}

//______________________________________________________________________________
void THashTable::Rehash(Int_t newCapacity, Bool_t checkObjValidity)
{
   // Rehash the hashtable. 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. Set checkObjValidity
   // to kFALSE if you know that all objects in the table are still valid
   // (i.e. have not been deleted from the system in the meanwhile).

   THashTable *ht = new THashTable(newCapacity);

   TIter next(this);
   TObject *obj;

   if (checkObjValidity && TObject::GetObjectStat() && gObjectTable) {
      while ((obj = next()))
         if (gObjectTable->PtrIsValid(obj)) ht->Add(obj);
   } else {
      while ((obj = next()))
         ht->Add(obj);
   }

   Clear("nodelete");
   delete [] fCont;
   fCont = ht->fCont;
   ht->fCont = 0;

   fSize      = ht->fSize;     // idem
   fEntries   = ht->fEntries;
   fUsedSlots = ht->fUsedSlots;

   // this should not happen, but it will prevent an endless loop
   // in case of a very bad hash function
   if (fRehashLevel && AverageCollisions() > fRehashLevel)
      fRehashLevel = (int)AverageCollisions() + 1;

   delete ht;
}

//______________________________________________________________________________
TObject *THashTable::Remove(TObject *obj)
{
   // Remove object from the hashtable.

   Int_t slot = GetHashValue(obj);
   if (fCont[slot]) {
      TObject *ob = fCont[slot]->Remove(obj);
      if (ob) {
         fEntries--;
         if (fCont[slot]->GetSize() == 0) {
            SafeDelete(fCont[slot]);
            fUsedSlots--;
         }
         return ob;
      }
   }
   return 0;
}

//______________________________________________________________________________
TObject *THashTable::RemoveSlow(TObject *obj)
{
   // Remove object from the hashtable without using the hash value.

   for (int i = 0; i < fSize; i++) {
      if (fCont[i]) {
         TObject *ob = fCont[i]->Remove(obj);
         if (ob) {
            fEntries--;
            if (fCont[i]->GetSize() == 0) {
               SafeDelete(fCont[i]);
               fUsedSlots--;
            }
            return ob;
         }
      }
   }
   return 0;
}


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// THashTableIter                                                       //
//                                                                      //
// Iterator of hash table.                                              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

ClassImp(THashTableIter)

//______________________________________________________________________________
THashTableIter::THashTableIter(const THashTable *ht, Bool_t dir)
{
   // Create a hashtable iterator. By default the iteration direction
   // is kIterForward. To go backward use kIterBackward.

   fTable      = ht;
   fDirection  = dir;
   fListCursor = 0;
   Reset();
}

//______________________________________________________________________________
THashTableIter::THashTableIter(const THashTableIter &iter) : TIterator(iter)
{
   // Copy ctor.

   fTable      = iter.fTable;
   fDirection  = iter.fDirection;
   fCursor     = iter.fCursor;
   fListCursor = 0;
   if (iter.fListCursor) {
      fListCursor = (TListIter *)iter.fListCursor->GetCollection()->MakeIterator();
      if (fListCursor)
         fListCursor->operator=(*iter.fListCursor);
   }
}

//______________________________________________________________________________
TIterator &THashTableIter::operator=(const TIterator &rhs)
{
   // Overridden assignment operator.

   if (this != &rhs && rhs.IsA() == THashTableIter::Class()) {
      const THashTableIter &rhs1 = (const THashTableIter &)rhs;
      fTable     = rhs1.fTable;
      fDirection = rhs1.fDirection;
      fCursor    = rhs1.fCursor;
      if (rhs1.fListCursor) {
         fListCursor = (TListIter *)rhs1.fListCursor->GetCollection()->MakeIterator();
         if (fListCursor)
            fListCursor->operator=(*rhs1.fListCursor);
      }
   }
   return *this;
}

//______________________________________________________________________________
THashTableIter &THashTableIter::operator=(const THashTableIter &rhs)
{
   // Overloaded assignment operator.

   if (this != &rhs) {
      fTable     = rhs.fTable;
      fDirection = rhs.fDirection;
      fCursor    = rhs.fCursor;
      if (rhs.fListCursor) {
         fListCursor = (TListIter *)rhs.fListCursor->GetCollection()->MakeIterator();
         if (fListCursor)
            fListCursor->operator=(*rhs.fListCursor);
      }
   }
   return *this;
}

//______________________________________________________________________________
THashTableIter::~THashTableIter()
{
   // Delete hashtable iterator.

   delete fListCursor;
}

//______________________________________________________________________________
TObject *THashTableIter::Next()
{
   // Return next object in hashtable. Returns 0 when no more objects in table.

   while (kTRUE) {
      if (!fListCursor) {
         int slot = NextSlot();
         if (slot == -1) return 0;
         fListCursor = new TListIter(fTable->fCont[slot], fDirection);
      }

      TObject *obj = fListCursor->Next();
      if (obj) return obj;

      SafeDelete(fListCursor);
   }
}

//______________________________________________________________________________
Int_t THashTableIter::NextSlot()
{
   // Returns index of next slot in table containing list to be iterated.

   if (fDirection == kIterForward) {
      for ( ; fCursor < fTable->Capacity() && fTable->fCont[fCursor] == 0;
              fCursor++) { }

      if (fCursor < fTable->Capacity())
         return fCursor++;

   } else {
      for ( ; fCursor >= 0 && fTable->fCont[fCursor] == 0;
              fCursor--) { }

      if (fCursor >= 0)
         return fCursor--;
   }
   return -1;
}

//______________________________________________________________________________
void THashTableIter::Reset()
{
   // Reset the hashtable iterator. Either to beginning or end, depending on
   // the initial iteration direction.

   if (fDirection == kIterForward)
      fCursor = 0;
   else
      fCursor = fTable->Capacity() - 1;
   SafeDelete(fListCursor);
}

//______________________________________________________________________________
Bool_t THashTableIter::operator!=(const TIterator &aIter) const
{
   // This operator compares two TIterator objects.

   if (nullptr == (&aIter))
      return fListCursor;

   if (aIter.IsA() == THashTableIter::Class()) {
      const THashTableIter &iter(dynamic_cast<const THashTableIter &>(aIter));
      return (fListCursor != iter.fListCursor);
   }
   return false; // for base class we don't implement a comparison
}

//______________________________________________________________________________
Bool_t THashTableIter::operator!=(const THashTableIter &aIter) const
{
   // This operator compares two THashTableIter objects.

   if (nullptr == (&aIter))
      return fListCursor;

   return (fListCursor != aIter.fListCursor);
}

//______________________________________________________________________________
TObject *THashTableIter::operator*() const
{
   // Return pointer to current object or nullptr.

   return (fListCursor ? fListCursor->operator*() : nullptr);
}
 THashTable.cxx:1
 THashTable.cxx:2
 THashTable.cxx:3
 THashTable.cxx:4
 THashTable.cxx:5
 THashTable.cxx:6
 THashTable.cxx:7
 THashTable.cxx:8
 THashTable.cxx:9
 THashTable.cxx:10
 THashTable.cxx:11
 THashTable.cxx:12
 THashTable.cxx:13
 THashTable.cxx:14
 THashTable.cxx:15
 THashTable.cxx:16
 THashTable.cxx:17
 THashTable.cxx:18
 THashTable.cxx:19
 THashTable.cxx:20
 THashTable.cxx:21
 THashTable.cxx:22
 THashTable.cxx:23
 THashTable.cxx:24
 THashTable.cxx:25
 THashTable.cxx:26
 THashTable.cxx:27
 THashTable.cxx:28
 THashTable.cxx:29
 THashTable.cxx:30
 THashTable.cxx:31
 THashTable.cxx:32
 THashTable.cxx:33
 THashTable.cxx:34
 THashTable.cxx:35
 THashTable.cxx:36
 THashTable.cxx:37
 THashTable.cxx:38
 THashTable.cxx:39
 THashTable.cxx:40
 THashTable.cxx:41
 THashTable.cxx:42
 THashTable.cxx:43
 THashTable.cxx:44
 THashTable.cxx:45
 THashTable.cxx:46
 THashTable.cxx:47
 THashTable.cxx:48
 THashTable.cxx:49
 THashTable.cxx:50
 THashTable.cxx:51
 THashTable.cxx:52
 THashTable.cxx:53
 THashTable.cxx:54
 THashTable.cxx:55
 THashTable.cxx:56
 THashTable.cxx:57
 THashTable.cxx:58
 THashTable.cxx:59
 THashTable.cxx:60
 THashTable.cxx:61
 THashTable.cxx:62
 THashTable.cxx:63
 THashTable.cxx:64
 THashTable.cxx:65
 THashTable.cxx:66
 THashTable.cxx:67
 THashTable.cxx:68
 THashTable.cxx:69
 THashTable.cxx:70
 THashTable.cxx:71
 THashTable.cxx:72
 THashTable.cxx:73
 THashTable.cxx:74
 THashTable.cxx:75
 THashTable.cxx:76
 THashTable.cxx:77
 THashTable.cxx:78
 THashTable.cxx:79
 THashTable.cxx:80
 THashTable.cxx:81
 THashTable.cxx:82
 THashTable.cxx:83
 THashTable.cxx:84
 THashTable.cxx:85
 THashTable.cxx:86
 THashTable.cxx:87
 THashTable.cxx:88
 THashTable.cxx:89
 THashTable.cxx:90
 THashTable.cxx:91
 THashTable.cxx:92
 THashTable.cxx:93
 THashTable.cxx:94
 THashTable.cxx:95
 THashTable.cxx:96
 THashTable.cxx:97
 THashTable.cxx:98
 THashTable.cxx:99
 THashTable.cxx:100
 THashTable.cxx:101
 THashTable.cxx:102
 THashTable.cxx:103
 THashTable.cxx:104
 THashTable.cxx:105
 THashTable.cxx:106
 THashTable.cxx:107
 THashTable.cxx:108
 THashTable.cxx:109
 THashTable.cxx:110
 THashTable.cxx:111
 THashTable.cxx:112
 THashTable.cxx:113
 THashTable.cxx:114
 THashTable.cxx:115
 THashTable.cxx:116
 THashTable.cxx:117
 THashTable.cxx:118
 THashTable.cxx:119
 THashTable.cxx:120
 THashTable.cxx:121
 THashTable.cxx:122
 THashTable.cxx:123
 THashTable.cxx:124
 THashTable.cxx:125
 THashTable.cxx:126
 THashTable.cxx:127
 THashTable.cxx:128
 THashTable.cxx:129
 THashTable.cxx:130
 THashTable.cxx:131
 THashTable.cxx:132
 THashTable.cxx:133
 THashTable.cxx:134
 THashTable.cxx:135
 THashTable.cxx:136
 THashTable.cxx:137
 THashTable.cxx:138
 THashTable.cxx:139
 THashTable.cxx:140
 THashTable.cxx:141
 THashTable.cxx:142
 THashTable.cxx:143
 THashTable.cxx:144
 THashTable.cxx:145
 THashTable.cxx:146
 THashTable.cxx:147
 THashTable.cxx:148
 THashTable.cxx:149
 THashTable.cxx:150
 THashTable.cxx:151
 THashTable.cxx:152
 THashTable.cxx:153
 THashTable.cxx:154
 THashTable.cxx:155
 THashTable.cxx:156
 THashTable.cxx:157
 THashTable.cxx:158
 THashTable.cxx:159
 THashTable.cxx:160
 THashTable.cxx:161
 THashTable.cxx:162
 THashTable.cxx:163
 THashTable.cxx:164
 THashTable.cxx:165
 THashTable.cxx:166
 THashTable.cxx:167
 THashTable.cxx:168
 THashTable.cxx:169
 THashTable.cxx:170
 THashTable.cxx:171
 THashTable.cxx:172
 THashTable.cxx:173
 THashTable.cxx:174
 THashTable.cxx:175
 THashTable.cxx:176
 THashTable.cxx:177
 THashTable.cxx:178
 THashTable.cxx:179
 THashTable.cxx:180
 THashTable.cxx:181
 THashTable.cxx:182
 THashTable.cxx:183
 THashTable.cxx:184
 THashTable.cxx:185
 THashTable.cxx:186
 THashTable.cxx:187
 THashTable.cxx:188
 THashTable.cxx:189
 THashTable.cxx:190
 THashTable.cxx:191
 THashTable.cxx:192
 THashTable.cxx:193
 THashTable.cxx:194
 THashTable.cxx:195
 THashTable.cxx:196
 THashTable.cxx:197
 THashTable.cxx:198
 THashTable.cxx:199
 THashTable.cxx:200
 THashTable.cxx:201
 THashTable.cxx:202
 THashTable.cxx:203
 THashTable.cxx:204
 THashTable.cxx:205
 THashTable.cxx:206
 THashTable.cxx:207
 THashTable.cxx:208
 THashTable.cxx:209
 THashTable.cxx:210
 THashTable.cxx:211
 THashTable.cxx:212
 THashTable.cxx:213
 THashTable.cxx:214
 THashTable.cxx:215
 THashTable.cxx:216
 THashTable.cxx:217
 THashTable.cxx:218
 THashTable.cxx:219
 THashTable.cxx:220
 THashTable.cxx:221
 THashTable.cxx:222
 THashTable.cxx:223
 THashTable.cxx:224
 THashTable.cxx:225
 THashTable.cxx:226
 THashTable.cxx:227
 THashTable.cxx:228
 THashTable.cxx:229
 THashTable.cxx:230
 THashTable.cxx:231
 THashTable.cxx:232
 THashTable.cxx:233
 THashTable.cxx:234
 THashTable.cxx:235
 THashTable.cxx:236
 THashTable.cxx:237
 THashTable.cxx:238
 THashTable.cxx:239
 THashTable.cxx:240
 THashTable.cxx:241
 THashTable.cxx:242
 THashTable.cxx:243
 THashTable.cxx:244
 THashTable.cxx:245
 THashTable.cxx:246
 THashTable.cxx:247
 THashTable.cxx:248
 THashTable.cxx:249
 THashTable.cxx:250
 THashTable.cxx:251
 THashTable.cxx:252
 THashTable.cxx:253
 THashTable.cxx:254
 THashTable.cxx:255
 THashTable.cxx:256
 THashTable.cxx:257
 THashTable.cxx:258
 THashTable.cxx:259
 THashTable.cxx:260
 THashTable.cxx:261
 THashTable.cxx:262
 THashTable.cxx:263
 THashTable.cxx:264
 THashTable.cxx:265
 THashTable.cxx:266
 THashTable.cxx:267
 THashTable.cxx:268
 THashTable.cxx:269
 THashTable.cxx:270
 THashTable.cxx:271
 THashTable.cxx:272
 THashTable.cxx:273
 THashTable.cxx:274
 THashTable.cxx:275
 THashTable.cxx:276
 THashTable.cxx:277
 THashTable.cxx:278
 THashTable.cxx:279
 THashTable.cxx:280
 THashTable.cxx:281
 THashTable.cxx:282
 THashTable.cxx:283
 THashTable.cxx:284
 THashTable.cxx:285
 THashTable.cxx:286
 THashTable.cxx:287
 THashTable.cxx:288
 THashTable.cxx:289
 THashTable.cxx:290
 THashTable.cxx:291
 THashTable.cxx:292
 THashTable.cxx:293
 THashTable.cxx:294
 THashTable.cxx:295
 THashTable.cxx:296
 THashTable.cxx:297
 THashTable.cxx:298
 THashTable.cxx:299
 THashTable.cxx:300
 THashTable.cxx:301
 THashTable.cxx:302
 THashTable.cxx:303
 THashTable.cxx:304
 THashTable.cxx:305
 THashTable.cxx:306
 THashTable.cxx:307
 THashTable.cxx:308
 THashTable.cxx:309
 THashTable.cxx:310
 THashTable.cxx:311
 THashTable.cxx:312
 THashTable.cxx:313
 THashTable.cxx:314
 THashTable.cxx:315
 THashTable.cxx:316
 THashTable.cxx:317
 THashTable.cxx:318
 THashTable.cxx:319
 THashTable.cxx:320
 THashTable.cxx:321
 THashTable.cxx:322
 THashTable.cxx:323
 THashTable.cxx:324
 THashTable.cxx:325
 THashTable.cxx:326
 THashTable.cxx:327
 THashTable.cxx:328
 THashTable.cxx:329
 THashTable.cxx:330
 THashTable.cxx:331
 THashTable.cxx:332
 THashTable.cxx:333
 THashTable.cxx:334
 THashTable.cxx:335
 THashTable.cxx:336
 THashTable.cxx:337
 THashTable.cxx:338
 THashTable.cxx:339
 THashTable.cxx:340
 THashTable.cxx:341
 THashTable.cxx:342
 THashTable.cxx:343
 THashTable.cxx:344
 THashTable.cxx:345
 THashTable.cxx:346
 THashTable.cxx:347
 THashTable.cxx:348
 THashTable.cxx:349
 THashTable.cxx:350
 THashTable.cxx:351
 THashTable.cxx:352
 THashTable.cxx:353
 THashTable.cxx:354
 THashTable.cxx:355
 THashTable.cxx:356
 THashTable.cxx:357
 THashTable.cxx:358
 THashTable.cxx:359
 THashTable.cxx:360
 THashTable.cxx:361
 THashTable.cxx:362
 THashTable.cxx:363
 THashTable.cxx:364
 THashTable.cxx:365
 THashTable.cxx:366
 THashTable.cxx:367
 THashTable.cxx:368
 THashTable.cxx:369
 THashTable.cxx:370
 THashTable.cxx:371
 THashTable.cxx:372
 THashTable.cxx:373
 THashTable.cxx:374
 THashTable.cxx:375
 THashTable.cxx:376
 THashTable.cxx:377
 THashTable.cxx:378
 THashTable.cxx:379
 THashTable.cxx:380
 THashTable.cxx:381
 THashTable.cxx:382
 THashTable.cxx:383
 THashTable.cxx:384
 THashTable.cxx:385
 THashTable.cxx:386
 THashTable.cxx:387
 THashTable.cxx:388
 THashTable.cxx:389
 THashTable.cxx:390
 THashTable.cxx:391
 THashTable.cxx:392
 THashTable.cxx:393
 THashTable.cxx:394
 THashTable.cxx:395
 THashTable.cxx:396
 THashTable.cxx:397
 THashTable.cxx:398
 THashTable.cxx:399
 THashTable.cxx:400
 THashTable.cxx:401
 THashTable.cxx:402
 THashTable.cxx:403
 THashTable.cxx:404
 THashTable.cxx:405
 THashTable.cxx:406
 THashTable.cxx:407
 THashTable.cxx:408
 THashTable.cxx:409
 THashTable.cxx:410
 THashTable.cxx:411
 THashTable.cxx:412
 THashTable.cxx:413
 THashTable.cxx:414
 THashTable.cxx:415
 THashTable.cxx:416
 THashTable.cxx:417
 THashTable.cxx:418
 THashTable.cxx:419
 THashTable.cxx:420
 THashTable.cxx:421
 THashTable.cxx:422
 THashTable.cxx:423
 THashTable.cxx:424
 THashTable.cxx:425
 THashTable.cxx:426
 THashTable.cxx:427
 THashTable.cxx:428
 THashTable.cxx:429
 THashTable.cxx:430
 THashTable.cxx:431
 THashTable.cxx:432
 THashTable.cxx:433
 THashTable.cxx:434
 THashTable.cxx:435
 THashTable.cxx:436
 THashTable.cxx:437
 THashTable.cxx:438
 THashTable.cxx:439
 THashTable.cxx:440
 THashTable.cxx:441
 THashTable.cxx:442
 THashTable.cxx:443
 THashTable.cxx:444
 THashTable.cxx:445
 THashTable.cxx:446
 THashTable.cxx:447
 THashTable.cxx:448
 THashTable.cxx:449
 THashTable.cxx:450
 THashTable.cxx:451
 THashTable.cxx:452
 THashTable.cxx:453
 THashTable.cxx:454
 THashTable.cxx:455
 THashTable.cxx:456
 THashTable.cxx:457
 THashTable.cxx:458
 THashTable.cxx:459
 THashTable.cxx:460
 THashTable.cxx:461
 THashTable.cxx:462
 THashTable.cxx:463
 THashTable.cxx:464
 THashTable.cxx:465
 THashTable.cxx:466
 THashTable.cxx:467
 THashTable.cxx:468
 THashTable.cxx:469
 THashTable.cxx:470
 THashTable.cxx:471
 THashTable.cxx:472
 THashTable.cxx:473
 THashTable.cxx:474
 THashTable.cxx:475
 THashTable.cxx:476
 THashTable.cxx:477
 THashTable.cxx:478
 THashTable.cxx:479
 THashTable.cxx:480
 THashTable.cxx:481
 THashTable.cxx:482
 THashTable.cxx:483
 THashTable.cxx:484
 THashTable.cxx:485
 THashTable.cxx:486
 THashTable.cxx:487
 THashTable.cxx:488
 THashTable.cxx:489
 THashTable.cxx:490
 THashTable.cxx:491
 THashTable.cxx:492
 THashTable.cxx:493
 THashTable.cxx:494
 THashTable.cxx:495
 THashTable.cxx:496
 THashTable.cxx:497
 THashTable.cxx:498
 THashTable.cxx:499
 THashTable.cxx:500
 THashTable.cxx:501
 THashTable.cxx:502
 THashTable.cxx:503
 THashTable.cxx:504
 THashTable.cxx:505