00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #include "TRefArray.h"
00066 #include "TRefTable.h"
00067 #include "TError.h"
00068 #include "TBits.h"
00069 #include "TSystem.h"
00070 #include "TROOT.h"
00071
00072 ClassImp(TRefArray)
00073
00074
00075 TRefArray::TRefArray(TProcessID *pid)
00076 {
00077
00078
00079 fPID = pid ? pid : TProcessID::GetSessionProcessID();
00080 fUIDs = 0;
00081 fSize = 0;
00082 fLast = -1;
00083 fLowerBound = 0;
00084 Changed();
00085 }
00086
00087
00088 TRefArray::TRefArray(Int_t s, TProcessID *pid)
00089 {
00090
00091
00092
00093
00094 if (s < 0) {
00095 Warning("TRefArray", "size (%d) < 0", s);
00096 s = TCollection::kInitCapacity;
00097 }
00098
00099 fPID = pid ? pid : TProcessID::GetSessionProcessID();
00100 fUIDs = 0;
00101 Init(s, 0);
00102 }
00103
00104
00105 TRefArray::TRefArray(Int_t s, Int_t lowerBound, TProcessID *pid)
00106 {
00107
00108
00109
00110
00111 if (s < 0) {
00112 Warning("TRefArray", "size (%d) < 0", s);
00113 s = TCollection::kInitCapacity;
00114 }
00115
00116 fPID = pid ? pid : TProcessID::GetSessionProcessID();
00117 fUIDs = 0;
00118 Init(s, lowerBound);
00119 }
00120
00121
00122 TRefArray::TRefArray(const TRefArray &a) : TSeqCollection()
00123 {
00124
00125
00126 fPID = a.fPID;
00127 fUIDs = 0;
00128 Init(a.fSize, a.fLowerBound);
00129
00130 for (Int_t i = 0; i < fSize; i++)
00131 fUIDs[i] = a.fUIDs[i];
00132
00133 fLast = a.fLast;
00134 fName = a.fName;
00135 }
00136
00137
00138 TRefArray& TRefArray::operator=(const TRefArray &a)
00139 {
00140
00141
00142 if (this != &a) {
00143
00144
00145 fName = a.fName;
00146 fSize = a.fSize;
00147 fSorted = a.fSorted;
00148
00149 fPID = a.fPID;
00150 Init(a.fSize, a.fLowerBound);
00151
00152 for (Int_t i = 0; i < fSize; i++)
00153 fUIDs[i] = a.fUIDs[i];
00154
00155 fLast = a.fLast;
00156 fName = a.fName;
00157 }
00158 return *this;
00159 }
00160
00161
00162 TRefArray::~TRefArray()
00163 {
00164
00165
00166 if (fUIDs) delete [] fUIDs;
00167 fPID = 0;
00168 fUIDs = 0;
00169 fSize = 0;
00170 }
00171
00172
00173 static Bool_t R__GetUID(Int_t &uid, TObject *obj, TProcessID *pid, const char *methodname)
00174 {
00175
00176
00177
00178 Bool_t valid = kTRUE;
00179 if (obj->TestBit(kHasUUID)) {
00180 valid = kFALSE;
00181 } else if (obj->TestBit(kIsReferenced)) {
00182 valid = (pid == TProcessID::GetProcessWithUID(obj));
00183 if (valid) {
00184 uid = obj->GetUniqueID();
00185 }
00186 } else {
00187 valid = (pid == TProcessID::GetSessionProcessID());
00188 if (valid) {
00189 uid = TProcessID::AssignID(obj);
00190 }
00191 }
00192
00193 if (!valid) {
00194 TString name; name.Form("TRefArray::%s",methodname);
00195 ::Error(name,
00196 "The object at %p is not registered in the process the TRefArray point to (pid = %s/%s)",obj,pid->GetName(),pid->GetTitle());
00197 }
00198 return valid;
00199 }
00200
00201
00202 void TRefArray::AddFirst(TObject *obj)
00203 {
00204
00205
00206
00207
00208 if (!obj) return;
00209
00210
00211 Int_t uid;
00212 if (R__GetUID(uid, obj, fPID, "AddFirst")) {
00213 fUIDs[0] = uid;
00214 Changed();
00215 }
00216 }
00217
00218
00219 void TRefArray::AddLast(TObject *obj)
00220 {
00221
00222
00223
00224 AddAtAndExpand(obj, GetAbsLast()+1+fLowerBound);
00225 }
00226
00227
00228 void TRefArray::AddBefore(const TObject *before, TObject *obj)
00229 {
00230
00231
00232
00233
00234
00235 if (!before)
00236 AddFirst(obj);
00237 else {
00238 Int_t idx = IndexOf(before) - fLowerBound;
00239 if (idx == -1) {
00240 Error("AddBefore", "before not found, object not added");
00241 return;
00242 }
00243 if (idx == 0) {
00244 Error("AddBefore", "cannot add before lowerbound (%d)", fLowerBound);
00245 return;
00246 }
00247 AddAt(obj, idx+fLowerBound-1);
00248 }
00249 }
00250
00251
00252 void TRefArray::AddAfter(const TObject *after, TObject *obj)
00253 {
00254
00255
00256
00257
00258
00259 if (!after)
00260 AddLast(obj);
00261 else {
00262 Int_t idx = IndexOf(after) - fLowerBound;
00263 if (idx == -1) {
00264 Error("AddAfter", "after not found, object not added");
00265 return;
00266 }
00267 AddAtAndExpand(obj, idx+fLowerBound+1);
00268 }
00269 }
00270
00271
00272 void TRefArray::AddAtAndExpand(TObject *obj, Int_t idx)
00273 {
00274
00275
00276
00277 if (!obj) return;
00278 if (idx < fLowerBound) {
00279 Error("AddAt", "out of bounds at %d in %lx", idx, (Long_t)this);
00280 return;
00281 }
00282 if (idx-fLowerBound >= fSize)
00283 Expand(TMath::Max(idx-fLowerBound+1, GrowBy(fSize)));
00284
00285
00286 Int_t uid;
00287 if (R__GetUID(uid, obj, fPID, "AddAtAndExpand")) {
00288 fUIDs[idx-fLowerBound] = uid;
00289 fLast = TMath::Max(idx-fLowerBound, GetAbsLast());
00290 Changed();
00291 }
00292 }
00293
00294
00295 void TRefArray::AddAt(TObject *obj, Int_t idx)
00296 {
00297
00298
00299
00300 if (!obj) return;
00301 if (!BoundsOk("AddAt", idx)) return;
00302
00303
00304 Int_t uid;
00305 if (R__GetUID(uid, obj, fPID, "AddAt")) {
00306 fUIDs[idx-fLowerBound] = uid;;
00307 fLast = TMath::Max(idx-fLowerBound, GetAbsLast());
00308 Changed();
00309 }
00310 }
00311
00312
00313 Int_t TRefArray::AddAtFree(TObject *obj)
00314 {
00315
00316
00317
00318 if (!obj) return 0;
00319 if (Last()) {
00320 Int_t i;
00321 for (i = 0; i < fSize; i++)
00322 if (!fUIDs[i]) {
00323
00324 Int_t uid;
00325 if (R__GetUID(uid, obj, fPID, "AddAtFree")) {
00326 fUIDs[i] = uid;
00327 fLast = TMath::Max(i, GetAbsLast());
00328 Changed();
00329 return i+fLowerBound;
00330 }
00331 }
00332 }
00333 AddLast(obj);
00334 return GetLast();
00335 }
00336
00337
00338 TObject *TRefArray::After(const TObject *obj) const
00339 {
00340
00341
00342 if (!obj || !fPID) return 0;
00343
00344 Int_t idx = IndexOf(obj) - fLowerBound;
00345 if (idx == -1 || idx == fSize-1) return 0;
00346
00347 return fPID->GetObjectWithID(fUIDs[idx+1]);
00348 }
00349
00350
00351 TObject *TRefArray::Before(const TObject *obj) const
00352 {
00353
00354
00355 if (!obj || !fPID) return 0;
00356
00357 Int_t idx = IndexOf(obj) - fLowerBound;
00358 if (idx == -1 || idx == 0) return 0;
00359
00360 return fPID->GetObjectWithID(fUIDs[idx-1]);
00361 }
00362
00363
00364 void TRefArray::Clear(Option_t *)
00365 {
00366
00367
00368 fLast = - 1;
00369
00370 for (Int_t j=0 ; j < fSize; j++) fUIDs[j] = 0;
00371
00372 Changed();
00373 }
00374
00375
00376 void TRefArray::Compress()
00377 {
00378
00379
00380 Int_t j = 0;
00381
00382 for (Int_t i = 0; i < fSize; i++) {
00383 if (fUIDs[i]) {
00384 fUIDs[j] = fUIDs[i];
00385 j++;
00386 }
00387 }
00388
00389 fLast = j - 1;
00390
00391 for ( ; j < fSize; j++) fUIDs[j] = 0;
00392 }
00393
00394
00395 void TRefArray::Delete(Option_t *)
00396 {
00397
00398
00399 fLast = -1;
00400
00401 fSize = 0;
00402 if (fUIDs) {
00403 delete [] fUIDs;
00404 fUIDs = 0;
00405 }
00406
00407 Changed();
00408 }
00409
00410
00411 void TRefArray::Expand(Int_t newSize)
00412 {
00413
00414
00415 if (newSize < 0) {
00416 Error ("Expand", "newSize must be positive (%d)", newSize);
00417 return;
00418 }
00419 if (newSize == fSize) return;
00420 UInt_t *temp = fUIDs;
00421 if (newSize != 0) {
00422 fUIDs = new UInt_t[newSize];
00423 if (newSize < fSize) memcpy(fUIDs,temp, newSize*sizeof(UInt_t));
00424 else {
00425 memcpy(fUIDs,temp,fSize*sizeof(UInt_t));
00426 memset(&fUIDs[fSize],0,(newSize-fSize)*sizeof(UInt_t));
00427 }
00428 } else {
00429 fUIDs = 0;
00430 }
00431 if (temp) delete [] temp;
00432 fSize = newSize;
00433 }
00434
00435
00436 TObject *TRefArray::GetFromTable(Int_t idx) const
00437 {
00438
00439 TRefTable *table = TRefTable::GetRefTable();
00440 if (table) {
00441 table->SetUID(fUIDs[idx], fPID);
00442 table->Notify();
00443 return fPID->GetObjectWithID(fUIDs[idx]);
00444 }
00445 return 0;
00446 }
00447
00448
00449 void TRefArray::Streamer(TBuffer &R__b)
00450 {
00451
00452
00453 UInt_t R__s, R__c;
00454 Int_t nobjects;
00455 UShort_t pidf;
00456 if (R__b.IsReading()) {
00457 R__b.ReadVersion(&R__s, &R__c);
00458 TObject::Streamer(R__b);
00459 fName.Streamer(R__b);
00460 R__b >> nobjects;
00461 R__b >> fLowerBound;
00462 if (nobjects >= fSize) Expand(nobjects);
00463 fLast = -1;
00464 R__b >> pidf;
00465 pidf += R__b.GetPidOffset();
00466 fPID = R__b.ReadProcessID(pidf);
00467 if (gDebug > 1) printf("Reading TRefArray, pidf=%d, fPID=%lx, nobjects=%d\n",pidf,(Long_t)fPID,nobjects);
00468 for (Int_t i = 0; i < nobjects; i++) {
00469 R__b >> fUIDs[i];
00470 if (fUIDs[i] != 0) fLast = i;
00471 if (gDebug > 1) {
00472 printf(" %d",fUIDs[i]);
00473 if ((i > 0 && i%10 == 0) || (i == nobjects-1)) printf("\n");
00474 }
00475 }
00476 Changed();
00477 R__b.CheckByteCount(R__s, R__c,TRefArray::IsA());
00478 } else {
00479 R__c = R__b.WriteVersion(TRefArray::IsA(), kTRUE);
00480 TObject::Streamer(R__b);
00481 fName.Streamer(R__b);
00482 nobjects = GetAbsLast()+1;
00483 R__b << nobjects;
00484 R__b << fLowerBound;
00485 pidf = R__b.WriteProcessID(fPID);
00486 R__b << pidf;
00487 if (gDebug > 1) printf("Writing TRefArray, pidf=%d, fPID=%lx, nobjects=%d\n",pidf,(Long_t)fPID,nobjects);
00488
00489 for (Int_t i = 0; i < nobjects; i++) {
00490 R__b << fUIDs[i];
00491 if (gDebug > 1) {
00492 printf(" %d",fUIDs[i]);
00493 if ((i > 0 && i%10 == 0) || (i == nobjects-1)) printf("\n");
00494 }
00495 }
00496 R__b.SetByteCount(R__c, kTRUE);
00497 }
00498 }
00499
00500
00501 TObject *TRefArray::First() const
00502 {
00503
00504
00505 return fPID->GetObjectWithID(fUIDs[0]);
00506 }
00507
00508
00509 TObject *TRefArray::Last() const
00510 {
00511
00512
00513 if (fLast == -1)
00514 return 0;
00515 else
00516 return fPID->GetObjectWithID(fUIDs[GetAbsLast()]);
00517 }
00518
00519
00520 Int_t TRefArray::GetEntries() const
00521 {
00522
00523
00524
00525
00526
00527
00528 Int_t cnt = 0;
00529
00530 for (Int_t i = 0; i < fSize; i++)
00531 if (fUIDs[i]) cnt++;
00532
00533 return cnt;
00534 }
00535
00536
00537 Int_t TRefArray::GetAbsLast() const
00538 {
00539
00540
00541
00542
00543
00544
00545 if (fLast == -2) {
00546 for (Int_t i = fSize-1; i >= 0; i--)
00547 if (fUIDs[i]) {
00548 ((TRefArray*)this)->fLast = i;
00549 return fLast;
00550 }
00551 ((TRefArray*)this)->fLast = -1;
00552 }
00553 return fLast;
00554 }
00555
00556
00557 Int_t TRefArray::GetLast() const
00558 {
00559
00560
00561
00562 return fLowerBound+GetAbsLast();
00563 }
00564
00565
00566 TObject **TRefArray::GetObjectRef(const TObject *) const
00567 {
00568
00569
00570
00571
00572 return 0;
00573 }
00574
00575
00576 UInt_t TRefArray::GetUID(Int_t at) const
00577 {
00578
00579
00580 int j = at-fLowerBound;
00581 if (j >= 0 && j < fSize) {
00582 if (!fPID) return 0;
00583 return fUIDs[j];
00584 }
00585 BoundsOk("At", at);
00586 return 0;
00587 }
00588
00589
00590 Int_t TRefArray::IndexOf(const TObject *obj) const
00591 {
00592
00593
00594
00595
00596
00597
00598 Int_t i;
00599 if (obj) {
00600 for (i = 0; i < fSize; i++)
00601 if (fUIDs[i] && fPID->GetObjectWithID(fUIDs[i]) == obj)
00602 return i+fLowerBound;
00603 } else {
00604 for (i = 0; i < fSize; i++)
00605 if (!fUIDs[i])
00606 return i+fLowerBound;
00607 }
00608
00609 return fLowerBound-1;
00610 }
00611
00612
00613 void TRefArray::Init(Int_t s, Int_t lowerBound)
00614 {
00615
00616
00617 if (fUIDs && fSize != s) {
00618 delete [] fUIDs;
00619 fUIDs = 0;
00620 }
00621
00622 fSize = s;
00623
00624 if (fSize) {
00625 fUIDs = new UInt_t[fSize];
00626 for (Int_t i=0;i<s;i++) fUIDs[i] = 0;
00627 } else {
00628 fUIDs = 0;
00629 }
00630 fLowerBound = lowerBound;
00631 fLast = -1;
00632 Changed();
00633 }
00634
00635
00636 TIterator *TRefArray::MakeIterator(Bool_t dir) const
00637 {
00638
00639
00640 return new TRefArrayIter(this, dir);
00641 }
00642
00643
00644 Bool_t TRefArray::OutOfBoundsError(const char *where, Int_t i) const
00645 {
00646
00647
00648 Error(where, "index %d out of bounds (size: %d, this: 0x%lx)", i, fSize, (Long_t)this);
00649 return kFALSE;
00650 }
00651
00652
00653 TObject *TRefArray::RemoveAt(Int_t idx)
00654 {
00655
00656
00657 if (!BoundsOk("RemoveAt", idx)) return 0;
00658
00659 int i = idx-fLowerBound;
00660
00661 TObject *obj = 0;
00662 if (fUIDs[i]) {
00663 obj = fPID->GetObjectWithID(fUIDs[i]);
00664 fUIDs[i] = 0;
00665
00666 if (i == fLast)
00667 do {
00668 fLast--;
00669 } while (fLast >= 0 && fUIDs[fLast] == 0);
00670 Changed();
00671 }
00672
00673 return obj;
00674 }
00675
00676
00677 TObject *TRefArray::Remove(TObject *obj)
00678 {
00679
00680
00681 if (!obj) return 0;
00682
00683 Int_t idx = IndexOf(obj) - fLowerBound;
00684
00685 if (idx == -1) return 0;
00686
00687 TObject *ob = fPID->GetObjectWithID(fUIDs[idx]);
00688 fUIDs[idx] = 0;
00689
00690 if (idx == fLast)
00691 do {
00692 fLast--;
00693 } while (fLast >= 0 && fUIDs[fLast] == 0);
00694 Changed();
00695 return ob;
00696 }
00697
00698
00699 void TRefArray::SetLast(Int_t last)
00700 {
00701
00702
00703
00704
00705
00706
00707 if (last == -2)
00708 fLast = -2;
00709 else if (BoundsOk("SetLast", last))
00710 fLast = last - fLowerBound;
00711 }
00712
00713
00714 void TRefArray::Sort(Int_t)
00715 {
00716
00717
00718
00719 Error("Sort","Function not yet implemented");
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 }
00736
00737
00738 Int_t TRefArray::BinarySearch(TObject *, Int_t)
00739 {
00740
00741
00742
00743 Error("BinarySearch","Function not yet implemented");
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 return -1;
00770 }
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781 ClassImp(TRefArrayIter)
00782
00783
00784 TRefArrayIter::TRefArrayIter(const TRefArray *arr, Bool_t dir)
00785 {
00786
00787
00788
00789 fArray = arr;
00790 fDirection = dir;
00791 Reset();
00792 }
00793
00794
00795 TRefArrayIter::TRefArrayIter(const TRefArrayIter &iter) : TIterator(iter)
00796 {
00797
00798
00799 fArray = iter.fArray;
00800 fDirection = iter.fDirection;
00801 fCursor = iter.fCursor;
00802 fCurCursor = iter.fCurCursor;
00803 }
00804
00805
00806 TIterator &TRefArrayIter::operator=(const TIterator &rhs)
00807 {
00808
00809
00810 if (this != &rhs && rhs.IsA() == TRefArrayIter::Class()) {
00811 const TRefArrayIter &rhs1 = (const TRefArrayIter &)rhs;
00812 fArray = rhs1.fArray;
00813 fDirection = rhs1.fDirection;
00814 fCursor = rhs1.fCursor;
00815 fCurCursor = rhs1.fCurCursor;
00816 }
00817 return *this;
00818 }
00819
00820
00821 TRefArrayIter &TRefArrayIter::operator=(const TRefArrayIter &rhs)
00822 {
00823
00824
00825 if (this != &rhs) {
00826 fArray = rhs.fArray;
00827 fDirection = rhs.fDirection;
00828 fCursor = rhs.fCursor;
00829 fCurCursor = rhs.fCurCursor;
00830 }
00831 return *this;
00832 }
00833
00834
00835 TObject *TRefArrayIter::Next()
00836 {
00837
00838
00839 if (fDirection == kIterForward) {
00840 for ( ; fCursor < fArray->Capacity() && fArray->At(fCursor+fArray->LowerBound()) == 0;
00841 fCursor++) { }
00842
00843 fCurCursor = fCursor;
00844 if (fCursor < fArray->Capacity()) {
00845 fCursor++;
00846 return fArray->At(fCurCursor+fArray->LowerBound());
00847 }
00848 } else {
00849 for ( ; fCursor >= 0 && fArray->At(fCursor) == 0;
00850 fCursor--) { }
00851
00852 fCurCursor = fCursor;
00853 if (fCursor >= 0) {
00854 fCursor--;
00855 return fArray->At(fCurCursor+fArray->LowerBound());
00856 }
00857 }
00858 return 0;
00859 }
00860
00861
00862 void TRefArrayIter::Reset()
00863 {
00864
00865
00866 if (fDirection == kIterForward)
00867 fCursor = 0;
00868 else
00869 fCursor = fArray->Capacity() - 1;
00870
00871 fCurCursor = fCursor;
00872 }
00873
00874
00875 bool TRefArrayIter::operator!=(const TIterator &aIter) const
00876 {
00877
00878
00879 if (nullptr == (&aIter))
00880 return (fCurCursor < fArray->Capacity());
00881
00882 if (aIter.IsA() == TRefArrayIter::Class()) {
00883 const TRefArrayIter &iter(dynamic_cast<const TRefArrayIter &>(aIter));
00884 return (fCurCursor != iter.fCurCursor);
00885 }
00886 return false;
00887 }
00888
00889
00890 bool TRefArrayIter::operator!=(const TRefArrayIter &aIter) const
00891 {
00892
00893
00894 if (nullptr == (&aIter))
00895 return (fCurCursor < fArray->Capacity());
00896
00897 return (fCurCursor != aIter.fCurCursor);
00898 }
00899
00900
00901 TObject *TRefArrayIter::operator*() const
00902 {
00903
00904
00905 return (((fCurCursor >= 0) && (fCurCursor < fArray->Capacity())) ?
00906 fArray->At(fCurCursor) : nullptr);
00907 }