// @(#)root/base:$Id$
// Author: Rene Brun    06/07/2002

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

//////////////////////////////////////////////////////////////////////////
//
// TProcessUUID
//
// This class is a specialized TProcessID managing the list of UUIDs.
// In addition to TProcessID, this object has the following members:
//   - fUUIDs  : a THashList of TUUIDs in string format (using a TObjString)
//   - fActive : a TBits table with one bit per TUUID in the table
// When a new TUUID is entered into the list fUUIDs, it is assigned
// the first free slot in the list of bits and the TUUID UUIDNumber
// is set to this slot number.
// When a TUUID is removed from the list, the corresponding bit
// is reset in fActive.
// The object corresponding to a TUUID at slot I can be found
// via fObjects->At(I).
// One can use two mechanisms to find the object corresponding to a TUUID:
//  1- the input is the TUUID.AsString. One can find the corresponding
//     TObjString object objs in fUUIDs via THashList::FindObject(name).
//     The slot number is then objs->GetUniqueID().
//  2- The input is the UUIDNumber. The slot number is UIUIDNumber
//
// When a TRef points to an object having a TUUID, both the TRef and the
// referenced object have their bit kHasUUID set. In this case, the pointer
// TProcessID *fPID in TRef points to the unique object TProcessUUID.
// The TRef uniqueID is directly the UUIDNumber=slot number.
//
//////////////////////////////////////////////////////////////////////////

#include "TROOT.h"
#include "TProcessUUID.h"
#include "THashList.h"
#include "TBits.h"
#include "TObjString.h"
#include "TUUID.h"

ClassImp(TProcessUUID)

//______________________________________________________________________________
TProcessUUID::TProcessUUID() : TProcessID()
{
   // Default constructor.

   fUUIDs   = new THashList(100,3);
   fActive  = new TBits(100);
   IncrementCount();
}

//______________________________________________________________________________
TProcessUUID::~TProcessUUID()
{
   // Destructor.
   fUUIDs->Delete();
   delete fUUIDs;  fUUIDs  = 0;
   delete fActive; fActive = 0;
}

//______________________________________________________________________________
UInt_t TProcessUUID::AddUUID(TUUID &uuid, TObject *obj)
{
   // Add uuid to the table of UUIDs
   // The TObject *obj has its uniqueID set to the UUID number
   // return entry number in the table

   UInt_t number;
   const char *uuids = uuid.AsString();
   TObjString *objs = (TObjString*)fUUIDs->FindObject(uuids);
   if (objs) {
      number = objs->GetUniqueID();
      uuid.SetUUIDNumber(number);
      objs->SetUniqueID(number);
      obj->SetUniqueID(number);
      obj->SetBit(kHasUUID);
      if (number >= (UInt_t)fObjects->GetSize()) fObjects->AddAtAndExpand(obj,number);
      if (fObjects->UncheckedAt(number) == 0) fObjects->AddAt(obj,number);
      return number;
   }

   objs = new TObjString(uuids);
   fUUIDs->Add(objs);
   number = fActive->FirstNullBit();
   uuid.SetUUIDNumber(number);
   objs->SetUniqueID(number);
   obj->SetUniqueID(number);
   obj->SetBit(kHasUUID);
   fActive->SetBitNumber(number);
   fObjects->AddAtAndExpand(obj,number);
   return number;
}

//______________________________________________________________________________
UInt_t TProcessUUID::AddUUID(const char *uuids)
{
   // Add uuid with name uuids to the table of UUIDs
   // return entry number in the table


   TObjString *objs = (TObjString*)fUUIDs->FindObject(uuids);
   if (objs) return objs->GetUniqueID();

   UInt_t number;
   objs = new TObjString(uuids);
   fUUIDs->Add(objs);
   number = fActive->FirstNullBit();
   objs->SetUniqueID(number);
   fActive->SetBitNumber(number);
   return number;
}

//______________________________________________________________________________
TObjString *TProcessUUID::FindUUID(UInt_t number) const
{
   //Find the TObjString by slot number

   TObjLink *lnk = fUUIDs->FirstLink();
   while (lnk) {
      TObject *obj = lnk->GetObject();
      if (obj->GetUniqueID() == number) return (TObjString*)obj;
      lnk = lnk->Next();
   }
   return 0;
}

//______________________________________________________________________________
void TProcessUUID::RemoveUUID(UInt_t number)
{
   //Remove entry number in the list of uuids

   if (number > (UInt_t)fObjects->GetSize()) return;
   TObjLink *lnk = fUUIDs->FirstLink();
   while (lnk) {
      TObject *obj = lnk->GetObject();
      if (obj->GetUniqueID() == number) {
         fUUIDs->Remove(lnk);
         delete obj;
         fActive->ResetBit(number);
         fObjects->AddAt(0,number);
         return;
      }
      lnk = lnk->Next();
   }
}
 TProcessUUID.cxx:1
 TProcessUUID.cxx:2
 TProcessUUID.cxx:3
 TProcessUUID.cxx:4
 TProcessUUID.cxx:5
 TProcessUUID.cxx:6
 TProcessUUID.cxx:7
 TProcessUUID.cxx:8
 TProcessUUID.cxx:9
 TProcessUUID.cxx:10
 TProcessUUID.cxx:11
 TProcessUUID.cxx:12
 TProcessUUID.cxx:13
 TProcessUUID.cxx:14
 TProcessUUID.cxx:15
 TProcessUUID.cxx:16
 TProcessUUID.cxx:17
 TProcessUUID.cxx:18
 TProcessUUID.cxx:19
 TProcessUUID.cxx:20
 TProcessUUID.cxx:21
 TProcessUUID.cxx:22
 TProcessUUID.cxx:23
 TProcessUUID.cxx:24
 TProcessUUID.cxx:25
 TProcessUUID.cxx:26
 TProcessUUID.cxx:27
 TProcessUUID.cxx:28
 TProcessUUID.cxx:29
 TProcessUUID.cxx:30
 TProcessUUID.cxx:31
 TProcessUUID.cxx:32
 TProcessUUID.cxx:33
 TProcessUUID.cxx:34
 TProcessUUID.cxx:35
 TProcessUUID.cxx:36
 TProcessUUID.cxx:37
 TProcessUUID.cxx:38
 TProcessUUID.cxx:39
 TProcessUUID.cxx:40
 TProcessUUID.cxx:41
 TProcessUUID.cxx:42
 TProcessUUID.cxx:43
 TProcessUUID.cxx:44
 TProcessUUID.cxx:45
 TProcessUUID.cxx:46
 TProcessUUID.cxx:47
 TProcessUUID.cxx:48
 TProcessUUID.cxx:49
 TProcessUUID.cxx:50
 TProcessUUID.cxx:51
 TProcessUUID.cxx:52
 TProcessUUID.cxx:53
 TProcessUUID.cxx:54
 TProcessUUID.cxx:55
 TProcessUUID.cxx:56
 TProcessUUID.cxx:57
 TProcessUUID.cxx:58
 TProcessUUID.cxx:59
 TProcessUUID.cxx:60
 TProcessUUID.cxx:61
 TProcessUUID.cxx:62
 TProcessUUID.cxx:63
 TProcessUUID.cxx:64
 TProcessUUID.cxx:65
 TProcessUUID.cxx:66
 TProcessUUID.cxx:67
 TProcessUUID.cxx:68
 TProcessUUID.cxx:69
 TProcessUUID.cxx:70
 TProcessUUID.cxx:71
 TProcessUUID.cxx:72
 TProcessUUID.cxx:73
 TProcessUUID.cxx:74
 TProcessUUID.cxx:75
 TProcessUUID.cxx:76
 TProcessUUID.cxx:77
 TProcessUUID.cxx:78
 TProcessUUID.cxx:79
 TProcessUUID.cxx:80
 TProcessUUID.cxx:81
 TProcessUUID.cxx:82
 TProcessUUID.cxx:83
 TProcessUUID.cxx:84
 TProcessUUID.cxx:85
 TProcessUUID.cxx:86
 TProcessUUID.cxx:87
 TProcessUUID.cxx:88
 TProcessUUID.cxx:89
 TProcessUUID.cxx:90
 TProcessUUID.cxx:91
 TProcessUUID.cxx:92
 TProcessUUID.cxx:93
 TProcessUUID.cxx:94
 TProcessUUID.cxx:95
 TProcessUUID.cxx:96
 TProcessUUID.cxx:97
 TProcessUUID.cxx:98
 TProcessUUID.cxx:99
 TProcessUUID.cxx:100
 TProcessUUID.cxx:101
 TProcessUUID.cxx:102
 TProcessUUID.cxx:103
 TProcessUUID.cxx:104
 TProcessUUID.cxx:105
 TProcessUUID.cxx:106
 TProcessUUID.cxx:107
 TProcessUUID.cxx:108
 TProcessUUID.cxx:109
 TProcessUUID.cxx:110
 TProcessUUID.cxx:111
 TProcessUUID.cxx:112
 TProcessUUID.cxx:113
 TProcessUUID.cxx:114
 TProcessUUID.cxx:115
 TProcessUUID.cxx:116
 TProcessUUID.cxx:117
 TProcessUUID.cxx:118
 TProcessUUID.cxx:119
 TProcessUUID.cxx:120
 TProcessUUID.cxx:121
 TProcessUUID.cxx:122
 TProcessUUID.cxx:123
 TProcessUUID.cxx:124
 TProcessUUID.cxx:125
 TProcessUUID.cxx:126
 TProcessUUID.cxx:127
 TProcessUUID.cxx:128
 TProcessUUID.cxx:129
 TProcessUUID.cxx:130
 TProcessUUID.cxx:131
 TProcessUUID.cxx:132
 TProcessUUID.cxx:133
 TProcessUUID.cxx:134
 TProcessUUID.cxx:135
 TProcessUUID.cxx:136
 TProcessUUID.cxx:137
 TProcessUUID.cxx:138
 TProcessUUID.cxx:139
 TProcessUUID.cxx:140
 TProcessUUID.cxx:141
 TProcessUUID.cxx:142
 TProcessUUID.cxx:143
 TProcessUUID.cxx:144
 TProcessUUID.cxx:145
 TProcessUUID.cxx:146
 TProcessUUID.cxx:147
 TProcessUUID.cxx:148
 TProcessUUID.cxx:149
 TProcessUUID.cxx:150
 TProcessUUID.cxx:151
 TProcessUUID.cxx:152