46 TRefTable *TRefTable::fgRefTable = 0;
 
   52 TRefTable::TRefTable() : fNumPIDs(0), fAllocSize(0), fN(0), fParentIDs(0), fParentID(-1),
 
   53                          fDefaultSize(10), fUID(0), fUIDContext(0), fSize(0), fParents(0), fOwner(0)
 
   61 TRefTable::TRefTable(TObject *owner, Int_t size) :
 
   62      fNumPIDs(0), fAllocSize(0), fN(0), fParentIDs(0), fParentID(-1),
 
   63      fDefaultSize(size<10 ? 10 : size), fUID(0), fUIDContext(0), fSize(0), fParents(new TObjArray(1)), fOwner(owner)
 
   71 TRefTable::~TRefTable()
 
   75    for (Int_t pid = 0; pid < fNumPIDs; ++pid) {
 
   76       delete [] fParentIDs[pid];
 
   80    if (fgRefTable == 
this) fgRefTable = 0;
 
   88 Int_t TRefTable::Add(Int_t uid, TProcessID *context)
 
   91       context = TProcessID::GetSessionProcessID();
 
   92    Int_t iid = GetInternalIdxForPID(context);
 
   96    if (uid >= fAllocSize[iid]) {
 
   97       newsize = uid + uid / 2;
 
   98       if (newsize < fDefaultSize)
 
   99          newsize = fDefaultSize;
 
  100       newsize = ExpandForIID(iid, newsize);
 
  103       Error(
"Add", 
"Cannot allocate space to store uid=%d", uid);
 
  107       Error(
"Add", 
"SetParent must be called before adding uid=%d", uid);
 
  110    fParentIDs[iid][uid] = fParentID + 1;
 
  111    if (uid >= fN[iid]) fN[iid] = uid + 1;
 
  119 Int_t TRefTable::AddInternalIdxForPID(TProcessID *procid)
 
  122       procid = TProcessID::GetSessionProcessID();
 
  123    Int_t pid = procid->GetUniqueID();
 
  124    if (fMapPIDtoInternal.size() <= (size_t) pid)
 
  125       fMapPIDtoInternal.resize(TProcessID::GetNProcessIDs(), -1);
 
  127    Int_t iid = fMapPIDtoInternal[pid];
 
  130       iid = FindPIDGUID(procid->GetTitle());
 
  132          fProcessGUIDs.push_back(procid->GetTitle());
 
  133          iid = fProcessGUIDs.size() - 1;
 
  135       fMapPIDtoInternal[pid] = iid;
 
  145 void TRefTable::Clear(Option_t *  )
 
  147    for (Int_t iid = 0; iid < fNumPIDs; ++iid) {
 
  148       memset(fParentIDs[iid], 0, 
sizeof(Int_t) * fN[iid]);
 
  150    memset(fN, 0, 
sizeof(Int_t) * fNumPIDs);
 
  157 Int_t TRefTable::Expand(Int_t pid, Int_t newsize)
 
  159    Int_t iid = GetInternalIdxForPID(pid);
 
  160    if (iid < 0) 
return -1;
 
  161    return ExpandForIID(iid, newsize);
 
  167 Int_t TRefTable::ExpandForIID(Int_t iid, Int_t newsize)
 
  169    if (newsize < 0)  
return newsize;
 
  170    if (newsize != fAllocSize[iid]) {
 
  171       Int_t *temp = fParentIDs[iid];
 
  173          fParentIDs[iid] = 
new Int_t[newsize];
 
  174          if (newsize < fAllocSize[iid])
 
  175             memcpy(fParentIDs[iid], temp, newsize * 
sizeof(Int_t));
 
  177             memcpy(fParentIDs[iid], temp, fAllocSize[iid] * 
sizeof(Int_t));
 
  178             memset(&fParentIDs[iid][fAllocSize[iid]], 0,
 
  179                    (newsize - fAllocSize[iid]) * 
sizeof(Int_t));
 
  184       if (fAllocSize[iid]) 
delete [] temp;
 
  185       fAllocSize[iid] = newsize;
 
  193 void TRefTable::ExpandPIDs(Int_t numpids)
 
  195    if (numpids <= fNumPIDs) 
return;
 
  198    Int_t oldNumPIDs = fNumPIDs;
 
  201    Int_t *temp = fAllocSize;
 
  202    fAllocSize = 
new Int_t[fNumPIDs];
 
  203    if (temp) memcpy(fAllocSize, temp, oldNumPIDs * 
sizeof(Int_t));
 
  204    memset(&fAllocSize[oldNumPIDs], 0,
 
  205           (fNumPIDs - oldNumPIDs) * 
sizeof(Int_t));
 
  209    fN = 
new Int_t[fNumPIDs];
 
  210    if (temp) memcpy(fN, temp, oldNumPIDs * 
sizeof(Int_t));
 
  211    memset(&fN[oldNumPIDs], 0, (fNumPIDs - oldNumPIDs) * 
sizeof(Int_t));
 
  214    Int_t **temp2 = fParentIDs;
 
  215    fParentIDs = 
new Int_t *[fNumPIDs];
 
  216    if (temp2) memcpy(fParentIDs, temp2, oldNumPIDs * 
sizeof(Int_t *));
 
  217    memset(&fParentIDs[oldNumPIDs], 0,
 
  218           (fNumPIDs - oldNumPIDs) * 
sizeof(Int_t*));
 
  225 void TRefTable::FillBuffer(TBuffer & b)
 
  228    for (Int_t iid = 0; iid < fNumPIDs; ++iid) {
 
  230       b.WriteFastArray(fParentIDs[iid], fN[iid]);
 
  238 Int_t TRefTable::FindPIDGUID(
const char *guid)
 const 
  240    std::vector<std::string>::const_iterator posPID
 
  241       = std::find(fProcessGUIDs.begin(), fProcessGUIDs.end(), guid);
 
  242    if (posPID == fProcessGUIDs.end()) 
return -1;
 
  243    return posPID - fProcessGUIDs.begin();
 
  249 TObject *TRefTable::GetParent(Int_t uid, TProcessID *context  )
 const 
  251    if (!fParents) 
return 0;
 
  254    if (!context) context = TProcessID::GetSessionProcessID();
 
  255    iid = GetInternalIdxForPID(context);
 
  257    uid = uid & 0xFFFFFF;
 
  258    if (uid < 0 || uid >= fN[iid]) 
return 0;
 
  259    Int_t pnumber = fParentIDs[iid][uid] - 1;
 
  260    Int_t nparents = fParents->GetEntriesFast();
 
  261    if (pnumber < 0 || pnumber >= nparents) 
return 0;
 
  262    return fParents->UncheckedAt(pnumber);
 
  269 Int_t TRefTable::GetInternalIdxForPID(TProcessID *procid)
 const 
  271    return const_cast <TRefTable*>(
this)->AddInternalIdxForPID(procid);
 
  278 Int_t TRefTable::GetInternalIdxForPID(Int_t pid)
 const 
  280    return GetInternalIdxForPID(TProcessID::GetProcessID(pid));
 
  287 TRefTable *TRefTable::GetRefTable()
 
  299 Bool_t TRefTable::Notify()
 
  301    return fOwner->Notify();
 
  308 void TRefTable::ReadBuffer(TBuffer &b)
 
  315    if (firstInt < 0) numIids = -firstInt; 
 
  320       TProcessID *fileProcessID = b.GetLastProcessID(
this);
 
  322       startIid = GetInternalIdxForPID(fileProcessID);
 
  323       if (startIid == -1) {
 
  324          fProcessGUIDs.push_back(fileProcessID->GetTitle());
 
  325          startIid = fProcessGUIDs.size() - 1;
 
  331    for (Int_t iid = startIid; iid < numIids; ++iid) {
 
  333       if (firstInt < 0) b >> newN;
 
  334       else newN = firstInt;
 
  335       if (newN > fAllocSize[iid])
 
  336          ExpandForIID(iid, newN + newN / 2);
 
  338       b.ReadFastArray(fParentIDs[iid], fN[iid]);
 
  345 void TRefTable::Reset(Option_t *  )
 
  348    if (fParents) fParents->Clear();
 
  357 Int_t TRefTable::SetParent(
const TObject* parent, Int_t branchID)
 
  362    Int_t nparents = fParents->GetEntriesFast();
 
  363    if (branchID != -1) {
 
  365       fParentID = branchID;
 
  370       fParentID = fParents->IndexOf(parent);
 
  373          fParents->AddAtAndExpand(const_cast<TObject*>(parent), nparents);
 
  374          fParentID = nparents;
 
  383 void TRefTable::SetRefTable(TRefTable *table)
 
  391 void TRefTable::Streamer(TBuffer &R__b)
 
  393    if (R__b.IsReading()) {
 
  394       R__b.ReadClassBuffer(TRefTable::Class(),
this);
 
  396       R__b.WriteClassBuffer(TRefTable::Class(),
this);
 
  400       TObjArray *pids = TProcessID::GetPIDs();
 
  401       Int_t npids = pids->GetEntries();
 
  402       Int_t npid2 = fProcessGUIDs.size();
 
  403       for (Int_t i = 0; i < npid2; i++) {
 
  405          for (Int_t ipid = 0;ipid<npids;ipid++) {
 
  406             pid = (TProcessID*)pids->At(ipid);
 
  408             if (!strcmp(pid->GetTitle(),fProcessGUIDs[i].c_str()))
 
  409                R__b.WriteProcessID(pid);