//*CMZ :  2.23/07 26/10/99  18.24.59  by  Rene Brun
//*CMZ :  2.22/08 07/07/99  13.26.14  by  Fons Rademakers
//*CMZ :  2.22/02 27/05/99  16.44.34  by  Fons Rademakers
//*-- Author :    Fons Rademakers   26/05/99

//*KEEP,CopyRight,T=C.
/*************************************************************************
 * Copyright(c) 1995-1999, The ROOT System, All rights reserved.         *
 * Authors: Rene Brun and Fons Rademakers.                               *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/AA_LICENSE.                      *
 * For the list of contributors see $ROOTSYS/AA_CREDITS.                 *
 *************************************************************************/
//*KEND.

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TExMap                                                               //
//                                                                      //
// This class stores a (key,value) pair using an external hash.         //
// The (key,value) are Long_t's and therefore can contain object        //
// pointers or any longs. The map uses an open addressing hashing       //
// method (linear probing).                                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

//*KEEP,TExMap.
#include "TExMap.h"
//*KEEP,TMath.
#include "TMath.h"
//*KEND.


ClassImp(TExMap)

//______________________________________________________________________________
 TExMap::TExMap(Int_t mapSize)
{
   // Create a TExMap.

   fSize  = (Int_t)TMath::NextPrime(mapSize);
   fTable = new Assoc_t* [fSize];
   memset(fTable, 0, fSize*sizeof(Assoc_t*));
   fTally = 0;
}

//______________________________________________________________________________
 TExMap::~TExMap()
{
   // Delete TExMap.

   for (int i = 0; i < fSize; i++)
      delete fTable[i];
   delete [] fTable; fTable = 0;
}

//______________________________________________________________________________
 void TExMap::Add(ULong_t hash, Long_t key, Long_t value)
{
   // Add an (key,value) pair to the table. The key should be unique.

   if (!fTable)
      return;

   Int_t slot = FindElement(hash, key);
   if (fTable[slot] == 0) {
      fTable[slot] = new Assoc_t(hash, key, value);
      fTally++;
      if (HighWaterMark())
         Expand(2 * fSize);
   } else
      Error("Add", "key %ld is not unique", key);
}

//______________________________________________________________________________
 void TExMap::Delete(Option_t *)
{
   // Delete all entries stored in the TExMap.

   for (int i = 0; i < fSize; i++) {
      if (fTable[i]) {
         delete fTable[i];
         fTable[i] = 0;
      }
   }
   fTally = 0;
}

//______________________________________________________________________________
 Long_t TExMap::GetValue(ULong_t hash, Long_t key)
{
   // Return the value belonging to specified key and hash value. If key not
   // found return 0.

   if (!fTable) return 0;

   Int_t slot = Int_t(hash % fSize);
   for (int n = 0; n < fSize; n++) {
      if (!fTable[slot]) return 0;
      if (key == fTable[slot]->fKey) return fTable[slot]->fValue;
      if (++slot == fSize) slot = 0;
   }

   if (fTable[slot]) return fTable[slot]->fValue;
   else              return 0;
}

//______________________________________________________________________________
 void TExMap::Remove(ULong_t hash, Long_t key)
{
   // Remove entry with specified key from the TExMap.

   if (!fTable)
      return;

   Int_t i = FindElement(hash, key);
   if (fTable[i] == 0) {
      Warning("Remove", "key %ld not found at %d", key, i);
      for (int j = 0; j < fSize; j++) {
         if (fTable[j] && fTable[j]->fKey == key) {
            Error("Remove", "%ld found at %d !!!", key, j);
            i = j;
         }
      }
   }

   if (fTable[i]) {
      delete fTable[i];
      fTable[i] = 0;
      FixCollisions(i);
      fTally--;
   }
}

//______________________________________________________________________________
 Int_t TExMap::FindElement(ULong_t hash, Long_t key)
{
   // Find an entry with specified hash and key in the TExMap.
   // Returns the slot of the key or the next empty slot.

   if (!fTable) return 0;

   Int_t slot = Int_t(hash % fSize);
   for (int n = 0; n < fSize; n++) {
      if (!fTable[slot]) return slot;
      if (key == fTable[slot]->fKey) return slot;
      if (++slot == fSize) slot = 0;
   }
   return slot;
}

//______________________________________________________________________________
 void TExMap::FixCollisions(Int_t index)
{
   // Rehash the map in case an entry has been removed.

   Int_t oldIndex, nextIndex;
   Assoc_t *nextObject;

   for (oldIndex = index+1; ;oldIndex++) {
      if (oldIndex >= fSize)
         oldIndex = 0;
      nextObject = fTable[oldIndex];
      if (nextObject == 0)
         break;
      nextIndex = FindElement(nextObject->fHash, nextObject->fKey);
      if (nextIndex != oldIndex) {
         fTable[nextIndex] = nextObject;
         fTable[oldIndex] = 0;
      }
   }
}

//______________________________________________________________________________
 void TExMap::Expand(Int_t newSize)
{
   // Expand the TExMap.

   Assoc_t **oldTable = fTable, *op;
   Int_t oldsize = fSize;
   newSize = (Int_t)TMath::NextPrime(newSize);
   fTable  = new Assoc_t* [newSize];
   memset(fTable, 0, newSize*sizeof(Assoc_t*));
   fSize   = newSize;
   for (int i = 0; i < oldsize; i++)
      if ((op = oldTable[i])) {
         Int_t slot = FindElement(op->fHash, op->fKey);
         if (fTable[slot] == 0)
            fTable[slot] = op;
         else
            Error("Expand", "slot %d not empty (should never happen)", slot);
      }
   delete [] oldTable;
}



ROOT page - Class index - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.