110 TRefArray::TRefArray(TProcessID *pid)
112 fPID = pid ? pid : TProcessID::GetSessionProcessID();
125 TRefArray::TRefArray(Int_t s, TProcessID *pid)
128 Warning(
"TRefArray",
"size (%d) < 0", s);
129 s = TCollection::kInitCapacity;
132 fPID = pid ? pid : TProcessID::GetSessionProcessID();
142 TRefArray::TRefArray(Int_t s, Int_t lowerBound, TProcessID *pid)
145 Warning(
"TRefArray",
"size (%d) < 0", s);
146 s = TCollection::kInitCapacity;
149 fPID = pid ? pid : TProcessID::GetSessionProcessID();
157 TRefArray::TRefArray(
const TRefArray &a) : TSeqCollection()
161 Init(a.fSize, a.fLowerBound);
163 for (Int_t i = 0; i < fSize; i++)
164 fUIDs[i] = a.fUIDs[i];
173 TRefArray& TRefArray::operator=(
const TRefArray &a)
183 Init(a.fSize, a.fLowerBound);
185 for (Int_t i = 0; i < fSize; i++)
186 fUIDs[i] = a.fUIDs[i];
197 TRefArray::~TRefArray()
199 if (fUIDs)
delete [] fUIDs;
208 Bool_t TRefArray::GetObjectUID(Int_t &uid, TObject *obj,
const char *methodname)
211 Bool_t valid = kTRUE;
212 if (obj->TestBit(kHasUUID)) {
214 }
else if (obj->TestBit(kIsReferenced)) {
215 valid = (fPID == TProcessID::GetProcessWithUID(obj));
217 uid = obj->GetUniqueID();
219 if (GetAbsLast() < 0) {
221 fPID = TProcessID::GetProcessWithUID(obj);
224 Info(TString::Format(
"TRefArray::%s",methodname),
"The ProcessID for the %p has been switched to %s/%s:%d.",
225 this,fPID->GetName(),fPID->GetTitle(),fPID->GetUniqueID());
234 if (!(TProcessID::GetObjectCount() >= 16777215)) {
235 valid = (fPID == TProcessID::GetSessionProcessID());
237 uid = TProcessID::AssignID(obj);
241 if (GetAbsLast() < 0) {
243 uid = TProcessID::AssignID(obj);
244 fPID = TProcessID::GetProcessWithUID(obj);
245 Warning(TString::Format(
"TRefArray::%s",methodname),
"The ProcessID for the %p has been switched to %s/%s:%d. There are too many referenced objects.",
246 this,fPID->GetName(),fPID->GetTitle(),fPID->GetUniqueID());
249 Error(TString::Format(
"TRefArray::%s",methodname),
"The object at %p can not be registered in the process the TRefArray points to (pid = %s/%s) because the ProcessID has too many objects and the TRefArray already contains other objects.",obj,fPID->GetName(),fPID->GetTitle());
256 ::Error(TString::Format(
"TRefArray::%s",methodname),
257 "The object at %p is not registered in the process the TRefArray points to (pid = %s/%s)",obj,fPID->GetName(),fPID->GetTitle());
267 void TRefArray::AddFirst(TObject *obj)
273 if (GetObjectUID(uid, obj,
"AddFirst")) {
283 void TRefArray::AddLast(TObject *obj)
285 AddAtAndExpand(obj, GetAbsLast()+1+fLowerBound);
294 void TRefArray::AddBefore(
const TObject *before, TObject *obj)
299 Int_t idx = IndexOf(before) - fLowerBound;
301 Error(
"AddBefore",
"before not found, object not added");
305 Error(
"AddBefore",
"cannot add before lowerbound (%d)", fLowerBound);
308 AddAt(obj, idx+fLowerBound-1);
318 void TRefArray::AddAfter(
const TObject *after, TObject *obj)
323 Int_t idx = IndexOf(after) - fLowerBound;
325 Error(
"AddAfter",
"after not found, object not added");
328 AddAtAndExpand(obj, idx+fLowerBound+1);
336 void TRefArray::AddAtAndExpand(TObject *obj, Int_t idx)
339 if (idx < fLowerBound) {
340 Error(
"AddAt",
"out of bounds at %d in %lx", idx, (Long_t)
this);
343 if (idx-fLowerBound >= fSize)
344 Expand(TMath::Max(idx-fLowerBound+1, GrowBy(fSize)));
348 if (GetObjectUID(uid, obj,
"AddAtAndExpand")) {
349 fUIDs[idx-fLowerBound] = uid;
350 fLast = TMath::Max(idx-fLowerBound, GetAbsLast());
359 void TRefArray::AddAt(TObject *obj, Int_t idx)
362 if (!BoundsOk(
"AddAt", idx))
return;
366 if (GetObjectUID(uid, obj,
"AddAt")) {
367 fUIDs[idx-fLowerBound] = uid;;
368 fLast = TMath::Max(idx-fLowerBound, GetAbsLast());
377 Int_t TRefArray::AddAtFree(TObject *obj)
382 for (i = 0; i < fSize; i++)
386 if (GetObjectUID(uid, obj,
"AddAtFree")) {
388 fLast = TMath::Max(i, GetAbsLast());
390 return i+fLowerBound;
401 TObject *TRefArray::After(
const TObject *obj)
const
403 if (!obj || !fPID)
return 0;
405 Int_t idx = IndexOf(obj) - fLowerBound;
406 if (idx == -1 || idx == fSize-1)
return 0;
408 return fPID->GetObjectWithID(fUIDs[idx+1]);
414 TObject *TRefArray::Before(
const TObject *obj)
const
416 if (!obj || !fPID)
return 0;
418 Int_t idx = IndexOf(obj) - fLowerBound;
419 if (idx == -1 || idx == 0)
return 0;
421 return fPID->GetObjectWithID(fUIDs[idx-1]);
427 void TRefArray::Clear(Option_t *)
431 for (Int_t j=0 ; j < fSize; j++) fUIDs[j] = 0;
439 void TRefArray::Compress()
443 for (Int_t i = 0; i < fSize; i++) {
452 for ( ; j < fSize; j++) fUIDs[j] = 0;
458 void TRefArray::Delete(Option_t *)
474 void TRefArray::Expand(Int_t newSize)
477 Error (
"Expand",
"newSize must be positive (%d)", newSize);
480 if (newSize == fSize)
return;
481 UInt_t *temp = fUIDs;
483 fUIDs =
new UInt_t[newSize];
484 if (newSize < fSize) memcpy(fUIDs,temp, newSize*
sizeof(UInt_t));
486 memcpy(fUIDs,temp,fSize*
sizeof(UInt_t));
487 memset(&fUIDs[fSize],0,(newSize-fSize)*
sizeof(UInt_t));
492 if (temp)
delete [] temp;
499 TObject *TRefArray::GetFromTable(Int_t idx)
const
501 TRefTable *table = TRefTable::GetRefTable();
503 table->SetUID(fUIDs[idx], fPID);
505 return fPID->GetObjectWithID(fUIDs[idx]);
513 void TRefArray::Streamer(TBuffer &R__b)
518 if (R__b.IsReading()) {
519 R__b.ReadVersion(&R__s, &R__c);
520 TObject::Streamer(R__b);
521 fName.Streamer(R__b);
524 if (nobjects >= fSize) Expand(nobjects);
527 pidf += R__b.GetPidOffset();
528 fPID = R__b.ReadProcessID(pidf);
529 if (gDebug > 1) printf(
"Reading TRefArray, pidf=%d, fPID=%lx, nobjects=%d\n",pidf,(Long_t)fPID,nobjects);
530 for (Int_t i = 0; i < nobjects; i++) {
532 if (fUIDs[i] != 0) fLast = i;
534 printf(
" %d",fUIDs[i]);
535 if ((i > 0 && i%10 == 0) || (i == nobjects-1)) printf(
"\n");
538 memset(&fUIDs[fLast+1], 0, (fSize - fLast - 1)*
sizeof(fUIDs[0]));
540 R__b.CheckByteCount(R__s, R__c,TRefArray::IsA());
542 R__c = R__b.WriteVersion(TRefArray::IsA(), kTRUE);
543 TObject::Streamer(R__b);
544 fName.Streamer(R__b);
545 nobjects = GetAbsLast()+1;
548 pidf = R__b.WriteProcessID(fPID);
550 if (gDebug > 1) printf(
"Writing TRefArray, pidf=%d, fPID=%lx, nobjects=%d\n",pidf,(Long_t)fPID,nobjects);
552 for (Int_t i = 0; i < nobjects; i++) {
555 printf(
" %d",fUIDs[i]);
556 if ((i > 0 && i%10 == 0) || (i == nobjects-1)) printf(
"\n");
559 R__b.SetByteCount(R__c, kTRUE);
566 TObject *TRefArray::First()
const
568 return fPID->GetObjectWithID(fUIDs[0]);
574 TObject *TRefArray::Last()
const
579 return fPID->GetObjectWithID(fUIDs[GetAbsLast()]);
589 Int_t TRefArray::GetEntries()
const
593 for (Int_t i = 0; i < fSize; i++)
603 Int_t TRefArray::GetAbsLast()
const
609 for (Int_t i = fSize-1; i >= 0; i--)
611 ((TRefArray*)
this)->fLast = i;
614 ((TRefArray*)
this)->fLast = -1;
623 Int_t TRefArray::GetLast()
const
625 return fLowerBound+GetAbsLast();
631 TObject **TRefArray::GetObjectRef(
const TObject *)
const
641 UInt_t TRefArray::GetUID(Int_t at)
const
643 int j = at-fLowerBound;
644 if (j >= 0 && j < fSize) {
659 Int_t TRefArray::IndexOf(
const TObject *obj)
const
663 if (!TProcessID::IsValid(fPID)) {
664 return fLowerBound-1;
666 for (i = 0; i < fSize; i++)
667 if (fUIDs[i] && fPID->GetObjectWithID(fUIDs[i]) == obj)
668 return i+fLowerBound;
670 for (i = 0; i < fSize; i++)
672 return i+fLowerBound;
675 return fLowerBound-1;
681 void TRefArray::Init(Int_t s, Int_t lowerBound)
683 if (fUIDs && fSize != s) {
691 fUIDs =
new UInt_t[fSize];
692 for (Int_t i=0;i<s;i++) fUIDs[i] = 0;
696 fLowerBound = lowerBound;
704 TIterator *TRefArray::MakeIterator(Bool_t dir)
const
706 return new TRefArrayIter(
this, dir);
712 Bool_t TRefArray::OutOfBoundsError(
const char *where, Int_t i)
const
714 Error(where,
"index %d out of bounds (size: %d, this: 0x%lx)", i, fSize, (Long_t)
this);
721 TObject *TRefArray::RemoveAt(Int_t idx)
723 if (!BoundsOk(
"RemoveAt", idx))
return 0;
725 int i = idx-fLowerBound;
729 if (!TProcessID::IsValid(fPID))
return 0;
730 obj = fPID->GetObjectWithID(fUIDs[i]);
736 }
while (fLast >= 0 && fUIDs[fLast] == 0);
746 TObject *TRefArray::Remove(TObject *obj)
750 Int_t idx = IndexOf(obj) - fLowerBound;
752 if (idx == -1)
return 0;
754 TObject *ob = fPID->GetObjectWithID(fUIDs[idx]);
760 }
while (fLast >= 0 && fUIDs[fLast] == 0);
772 void TRefArray::SetLast(Int_t last)
776 else if (BoundsOk(
"SetLast", last))
777 fLast = last - fLowerBound;
784 void TRefArray::Sort(Int_t)
786 Error(
"Sort",
"Function not yet implemented");
808 Int_t TRefArray::BinarySearch(TObject *, Int_t)
810 Error(
"BinarySearch",
"Function not yet implemented");
843 ClassImp(TRefArrayIter);
849 TRefArrayIter::TRefArrayIter(
const TRefArray *arr, Bool_t dir)
859 TRefArrayIter::TRefArrayIter(
const TRefArrayIter &iter) : TIterator(iter)
861 fArray = iter.fArray;
862 fDirection = iter.fDirection;
863 fCursor = iter.fCursor;
864 fCurCursor = iter.fCurCursor;
870 TIterator &TRefArrayIter::operator=(
const TIterator &rhs)
872 if (
this != &rhs && rhs.IsA() == TRefArrayIter::Class()) {
873 const TRefArrayIter &rhs1 = (
const TRefArrayIter &)rhs;
874 fArray = rhs1.fArray;
875 fDirection = rhs1.fDirection;
876 fCursor = rhs1.fCursor;
877 fCurCursor = rhs1.fCurCursor;
885 TRefArrayIter &TRefArrayIter::operator=(
const TRefArrayIter &rhs)
889 fDirection = rhs.fDirection;
890 fCursor = rhs.fCursor;
891 fCurCursor = rhs.fCurCursor;
899 TObject *TRefArrayIter::Next()
901 if (fDirection == kIterForward) {
902 for ( ; fCursor < fArray->Capacity() && fArray->At(fCursor+fArray->LowerBound()) == 0;
905 fCurCursor = fCursor;
906 if (fCursor < fArray->Capacity()) {
908 return fArray->At(fCurCursor+fArray->LowerBound());
911 for ( ; fCursor >= 0 && fArray->At(fCursor) == 0;
914 fCurCursor = fCursor;
917 return fArray->At(fCurCursor+fArray->LowerBound());
926 void TRefArrayIter::Reset()
928 if (fDirection == kIterForward)
931 fCursor = fArray->Capacity() - 1;
933 fCurCursor = fCursor;
939 Bool_t TRefArrayIter::operator!=(
const TIterator &aIter)
const
941 if (aIter.IsA() == TRefArrayIter::Class()) {
942 const TRefArrayIter &iter(dynamic_cast<const TRefArrayIter &>(aIter));
943 return (fCurCursor != iter.fCurCursor);
951 Bool_t TRefArrayIter::operator!=(
const TRefArrayIter &aIter)
const
953 return (fCurCursor != aIter.fCurCursor);
959 TObject *TRefArrayIter::operator*()
const
961 return (((fCurCursor >= 0) && (fCurCursor < fArray->Capacity())) ?
962 fArray->At(fCurCursor) :
nullptr);