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);