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
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 #include <stdlib.h>
00177 #include "TBtree.h"
00178
00179
00180 ClassImp(TBtree)
00181
00182
00183 TBtree::TBtree(int order)
00184 {
00185
00186
00187 Init(order);
00188 }
00189
00190
00191 TBtree::~TBtree()
00192 {
00193
00194
00195
00196 if (fRoot) {
00197 Clear();
00198 SafeDelete(fRoot);
00199 }
00200 }
00201
00202
00203 void TBtree::Add(TObject *obj)
00204 {
00205
00206
00207 if (IsArgNull("Add", obj)) return;
00208 if (!obj->IsSortable()) {
00209 Error("Add", "object must be sortable");
00210 return;
00211 }
00212 if (!fRoot) {
00213 fRoot = new TBtLeafNode(0, obj, this);
00214 R__CHECK(fRoot != 0);
00215 IncrNofKeys();
00216 } else {
00217 TBtNode *loc;
00218 Int_t idx;
00219 if (fRoot->Found(obj, &loc, &idx) != 0) {
00220
00221
00222
00223
00224
00225 }
00226 loc->Add(obj, idx);
00227 }
00228 }
00229
00230
00231 TObject *TBtree::After(const TObject *) const
00232 {
00233
00234
00235 MayNotUse("After");
00236 return 0;
00237 }
00238
00239
00240 TObject *TBtree::Before(const TObject *) const
00241 {
00242
00243
00244 MayNotUse("Before");
00245 return 0;
00246 }
00247
00248
00249 void TBtree::Clear(Option_t *)
00250 {
00251
00252
00253
00254 if (IsOwner())
00255 Delete();
00256 else {
00257 SafeDelete(fRoot);
00258 fSize = 0;
00259 }
00260 }
00261
00262
00263 void TBtree::Delete(Option_t *)
00264 {
00265
00266
00267 for (Int_t i = 0; i < fSize; i++) {
00268 TObject *obj = At(i);
00269 if (obj && obj->IsOnHeap())
00270 TCollection::GarbageCollect(obj);
00271 }
00272 SafeDelete(fRoot);
00273 fSize = 0;
00274 }
00275
00276
00277 TObject *TBtree::FindObject(const char *name) const
00278 {
00279
00280
00281
00282 return TCollection::FindObject(name);
00283 }
00284
00285
00286 TObject *TBtree::FindObject(const TObject *obj) const
00287 {
00288
00289
00290 if (!obj->IsSortable()) {
00291 Error("FindObject", "object must be sortable");
00292 return 0;
00293 }
00294 if (!fRoot)
00295 return 0;
00296 else {
00297 TBtNode *loc;
00298 Int_t idx;
00299 return fRoot->Found(obj, &loc, &idx);
00300 }
00301 }
00302
00303
00304 Int_t TBtree::IdxAdd(const TObject &obj)
00305 {
00306
00307
00308 Int_t r;
00309 if (!obj.IsSortable()) {
00310 Error("IdxAdd", "object must be sortable");
00311 return -1;
00312 }
00313 if (!fRoot) {
00314 fRoot = new TBtLeafNode(0, &obj, this);
00315 R__ASSERT(fRoot != 0);
00316 IncrNofKeys();
00317 r = 0;
00318 } else {
00319 TBtNode *loc;
00320 int idx;
00321 if (fRoot->Found(&obj, &loc, &idx) != 0) {
00322
00323
00324
00325
00326
00327
00328 } else {
00329 R__CHECK(loc->fIsLeaf);
00330 }
00331 if (loc->fIsLeaf) {
00332 if (loc->fParent == 0)
00333 r = idx;
00334 else
00335 r = idx + loc->fParent->FindRankUp(loc);
00336 } else {
00337 TBtInnerNode *iloc = (TBtInnerNode*) loc;
00338 r = iloc->FindRankUp(iloc->GetTree(idx));
00339 }
00340 loc->Add(&obj, idx);
00341 }
00342 R__CHECK(r == Rank(&obj) || &obj == (*this)[r]);
00343 return r;
00344 }
00345
00346
00347 void TBtree::Init(Int_t order)
00348 {
00349
00350
00351 if (order < 3) {
00352 Warning("Init", "order must be at least 3");
00353 order = 3;
00354 }
00355 fRoot = 0;
00356 fOrder = order;
00357 fOrder2 = 2 * (fOrder+1);
00358 fLeafMaxIndex = fOrder2 - 1;
00359 fInnerMaxIndex = fOrder;
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 fLeafLowWaterMark = ((fLeafMaxIndex+1)-1) / 2 - 1;
00373 fInnerLowWaterMark = (fOrder-1) / 2;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 TIterator *TBtree::MakeIterator(Bool_t dir) const
00389 {
00390
00391
00392 return new TBtreeIter(this, dir);
00393 }
00394
00395
00396 Int_t TBtree::Rank(const TObject *obj) const
00397 {
00398
00399
00400 if (!obj->IsSortable()) {
00401 Error("Rank", "object must be sortable");
00402 return -1;
00403 }
00404 if (!fRoot)
00405 return -1;
00406 else
00407 return fRoot->FindRank(obj);
00408 }
00409
00410
00411 TObject *TBtree::Remove(TObject *obj)
00412 {
00413
00414
00415 if (!obj->IsSortable()) {
00416 Error("Remove", "object must be sortable");
00417 return 0;
00418 }
00419 if (!fRoot)
00420 return 0;
00421
00422 TBtNode *loc;
00423 Int_t idx;
00424 TObject *ob = fRoot->Found(obj, &loc, &idx);
00425 if (!ob)
00426 return 0;
00427 loc->Remove(idx);
00428 return ob;
00429 }
00430
00431
00432 void TBtree::RootIsFull()
00433 {
00434
00435
00436
00437 TBtNode *oldroot = fRoot;
00438 fRoot = new TBtInnerNode(0, this, oldroot);
00439 R__ASSERT(fRoot != 0);
00440 oldroot->Split();
00441 }
00442
00443
00444 void TBtree::RootIsEmpty()
00445 {
00446
00447
00448 if (fRoot->fIsLeaf) {
00449 TBtLeafNode *lroot = (TBtLeafNode*)fRoot;
00450 R__CHECK(lroot->Psize() == 0);
00451 delete lroot;
00452 fRoot = 0;
00453 } else {
00454 TBtInnerNode *iroot = (TBtInnerNode*)fRoot;
00455 R__CHECK(iroot->Psize() == 0);
00456 fRoot = iroot->GetTree(0);
00457 fRoot->fParent = 0;
00458 delete iroot;
00459 }
00460 }
00461
00462
00463 void TBtree::Streamer(TBuffer &b)
00464 {
00465
00466
00467 UInt_t R__s, R__c;
00468 if (b.IsReading()) {
00469 b.ReadVersion(&R__s, &R__c);
00470 b >> fOrder;
00471 b >> fOrder2;
00472 b >> fInnerLowWaterMark;
00473 b >> fLeafLowWaterMark;
00474 b >> fInnerMaxIndex;
00475 b >> fLeafMaxIndex;
00476 TSeqCollection::Streamer(b);
00477 b.CheckByteCount(R__s, R__c,TBtree::IsA());
00478 } else {
00479 R__c = b.WriteVersion(TBtree::IsA(), kTRUE);
00480 b << fOrder;
00481 b << fOrder2;
00482 b << fInnerLowWaterMark;
00483 b << fLeafLowWaterMark;
00484 b << fInnerMaxIndex;
00485 b << fLeafMaxIndex;
00486 TSeqCollection::Streamer(b);
00487 b.SetByteCount(R__c, kTRUE);
00488 }
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 TBtItem::TBtItem()
00502 {
00503
00504
00505
00506
00507 fNofKeysInTree = 0;
00508 fTree = 0;
00509 fKey = 0;
00510 }
00511
00512
00513 TBtItem::TBtItem(TBtNode *n, TObject *obj)
00514 {
00515
00516
00517
00518
00519 fNofKeysInTree = n->NofKeys()+1;
00520 fTree = n;
00521 fKey = obj;
00522 }
00523
00524
00525 TBtItem::TBtItem(TObject *obj, TBtNode *n)
00526 {
00527
00528
00529
00530
00531 fNofKeysInTree = n->NofKeys()+1;
00532 fTree = n;
00533 fKey = obj;
00534 }
00535
00536
00537 TBtItem::~TBtItem()
00538 {
00539
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 TBtNode::TBtNode(Int_t isleaf, TBtInnerNode *p, TBtree *t)
00553 {
00554
00555
00556 fLast = -1;
00557 fIsLeaf = isleaf;
00558 fParent = p;
00559 if (p == 0) {
00560 R__CHECK(t != 0);
00561 fTree = t;
00562 } else
00563 #ifdef cxxbug
00564
00565
00566
00567
00568 fTree = p->GetParentTree();
00569 #else
00570 fTree = p->fTree;
00571 #endif
00572 }
00573
00574
00575 TBtNode::~TBtNode()
00576 {
00577
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 ClassImp(TBtreeIter)
00590
00591
00592 TBtreeIter::TBtreeIter(const TBtree *t, Bool_t dir)
00593 : fTree(t), fCurCursor(0), fCursor(0), fDirection(dir)
00594 {
00595
00596
00597 Reset();
00598 }
00599
00600
00601 TBtreeIter::TBtreeIter(const TBtreeIter &iter) : TIterator(iter)
00602 {
00603
00604
00605 fTree = iter.fTree;
00606 fCursor = iter.fCursor;
00607 fCurCursor = iter.fCurCursor;
00608 fDirection = iter.fDirection;
00609 }
00610
00611
00612 TIterator &TBtreeIter::operator=(const TIterator &rhs)
00613 {
00614
00615
00616 if (this != &rhs && rhs.IsA() == TBtreeIter::Class()) {
00617 const TBtreeIter &rhs1 = (const TBtreeIter &)rhs;
00618 fTree = rhs1.fTree;
00619 fCursor = rhs1.fCursor;
00620 fCurCursor = rhs1.fCurCursor;
00621 fDirection = rhs1.fDirection;
00622 }
00623 return *this;
00624 }
00625
00626
00627 TBtreeIter &TBtreeIter::operator=(const TBtreeIter &rhs)
00628 {
00629
00630
00631 if (this != &rhs) {
00632 fTree = rhs.fTree;
00633 fCursor = rhs.fCursor;
00634 fCurCursor = rhs.fCurCursor;
00635 fDirection = rhs.fDirection;
00636 }
00637 return *this;
00638 }
00639
00640
00641 void TBtreeIter::Reset()
00642 {
00643
00644
00645 if (fDirection == kIterForward)
00646 fCursor = 0;
00647 else
00648 fCursor = fTree->GetSize() - 1;
00649
00650 fCurCursor = fCursor;
00651 }
00652
00653
00654 TObject *TBtreeIter::Next()
00655 {
00656
00657
00658 fCurCursor = fCursor;
00659 if (fDirection == kIterForward) {
00660 if (fCursor < fTree->GetSize())
00661 return (*fTree)[fCursor++];
00662 } else {
00663 if (fCursor >= 0)
00664 return (*fTree)[fCursor--];
00665 }
00666 return 0;
00667 }
00668
00669
00670 bool TBtreeIter::operator!=(const TIterator &aIter) const
00671 {
00672
00673
00674 if (nullptr == (&aIter))
00675 return (fCurCursor < fTree->GetSize());
00676
00677 if (aIter.IsA() == TBtreeIter::Class()) {
00678 const TBtreeIter &iter(dynamic_cast<const TBtreeIter &>(aIter));
00679 return (fCurCursor != iter.fCurCursor);
00680 }
00681 return false;
00682 }
00683
00684
00685 bool TBtreeIter::operator!=(const TBtreeIter &aIter) const
00686 {
00687
00688
00689 if (nullptr == (&aIter))
00690 return (fCurCursor < fTree->GetSize());
00691 return (fCurCursor != aIter.fCurCursor);
00692 }
00693
00694
00695 TObject* TBtreeIter::operator*() const
00696 {
00697
00698
00699 return (((fCurCursor >= 0) && (fCurCursor < fTree->GetSize())) ?
00700 (*fTree)[fCurCursor] : nullptr);
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 TBtInnerNode::TBtInnerNode(TBtInnerNode *p, TBtree *t) : TBtNode(0,p,t)
00714 {
00715
00716
00717 const Int_t index = MaxIndex() + 1;
00718 fItem = new TBtItem[ index ];
00719 if (fItem == 0)
00720 ::Fatal("TBtInnerNode::TBtInnerNode", "no more memory");
00721 }
00722
00723
00724 TBtInnerNode::TBtInnerNode(TBtInnerNode *parent, TBtree *tree, TBtNode *oldroot)
00725 : TBtNode(0, parent, tree)
00726 {
00727
00728
00729
00730 fItem = new TBtItem[MaxIndex()+1];
00731 if (fItem == 0)
00732 ::Fatal("TBtInnerNode::TBtInnerNode", "no more memory");
00733 Append(0, oldroot);
00734 }
00735
00736
00737 TBtInnerNode::~TBtInnerNode()
00738 {
00739
00740
00741 if (fLast > 0)
00742 delete fItem[0].fTree;
00743 for (Int_t i = 1; i <= fLast; i++)
00744 delete fItem[i].fTree;
00745
00746 delete [] fItem;
00747 }
00748
00749
00750 void TBtInnerNode::Add(const TObject *obj, Int_t index)
00751 {
00752
00753
00754 R__ASSERT(index >= 1 && obj->IsSortable());
00755 TBtLeafNode *ln = GetTree(index-1)->LastLeafNode();
00756 ln->Add(obj, ln->fLast+1);
00757 }
00758
00759
00760 void TBtInnerNode::AddElt(TBtItem &itm, Int_t at)
00761 {
00762
00763
00764 R__ASSERT(0 <= at && at <= fLast+1);
00765 R__ASSERT(fLast < MaxIndex());
00766 for (Int_t i = fLast+1; i > at ; i--)
00767 GetItem(i) = GetItem(i-1);
00768 SetItem(at, itm);
00769 fLast++;
00770 }
00771
00772
00773 void TBtInnerNode::AddElt(Int_t at, TObject *k, TBtNode *t)
00774 {
00775
00776
00777 TBtItem newitem(k, t);
00778 AddElt(newitem, at);
00779 }
00780
00781
00782 void TBtInnerNode::Add(TBtItem &itm, Int_t at)
00783 {
00784
00785
00786 AddElt(itm, at);
00787 if (IsFull())
00788 InformParent();
00789 }
00790
00791
00792 void TBtInnerNode::Add(Int_t at, TObject *k, TBtNode *t)
00793 {
00794
00795
00796 TBtItem newitem(k, t);
00797 Add(newitem, at);
00798 }
00799
00800
00801 void TBtInnerNode::AppendFrom(TBtInnerNode *src, Int_t start, Int_t stop)
00802 {
00803
00804
00805
00806 if (start > stop)
00807 return;
00808 R__ASSERT(0 <= start && start <= src->fLast);
00809 R__ASSERT(0 <= stop && stop <= src->fLast );
00810 R__ASSERT(fLast + stop - start + 1 < MaxIndex());
00811 for (Int_t i = start; i <= stop; i++)
00812 SetItem(++fLast, src->GetItem(i));
00813 }
00814
00815
00816 void TBtInnerNode::Append(TObject *d, TBtNode *n)
00817 {
00818
00819
00820 R__ASSERT(fLast < MaxIndex());
00821 if (d) R__ASSERT(d->IsSortable());
00822 SetItem(++fLast, d, n);
00823 }
00824
00825
00826 void TBtInnerNode::Append(TBtItem &itm)
00827 {
00828
00829
00830 R__ASSERT(fLast < MaxIndex());
00831 SetItem(++fLast, itm);
00832 }
00833
00834
00835 void TBtInnerNode::BalanceWithLeft(TBtInnerNode *leftsib, Int_t pidx)
00836 {
00837
00838
00839
00840
00841 R__ASSERT(Vsize() >= leftsib->Psize());
00842 R__ASSERT(fParent->GetTree(pidx) == this);
00843 Int_t newThisSize = (Vsize() + leftsib->Psize())/2;
00844 Int_t noFromThis = Psize() - newThisSize;
00845 PushLeft(noFromThis, leftsib, pidx);
00846 }
00847
00848
00849 void TBtInnerNode::BalanceWithRight(TBtInnerNode *rightsib, Int_t pidx)
00850 {
00851
00852
00853
00854
00855 R__ASSERT(Psize() >= rightsib->Vsize());
00856 R__ASSERT(fParent->GetTree(pidx) == rightsib);
00857 Int_t newThisSize = (Psize() + rightsib->Vsize())/2;
00858 Int_t noFromThis = Psize() - newThisSize;
00859 PushRight(noFromThis, rightsib, pidx);
00860 }
00861
00862
00863 void TBtInnerNode::BalanceWith(TBtInnerNode *rightsib, Int_t pindx)
00864 {
00865
00866
00867
00868 if (Psize() < rightsib->Vsize())
00869 rightsib->BalanceWithLeft(this, pindx);
00870 else
00871 BalanceWithRight(rightsib, pindx);
00872 }
00873
00874
00875 void TBtInnerNode::DecrNofKeys(TBtNode *that)
00876 {
00877
00878
00879 Int_t i = IndexOf(that);
00880 fItem[i].fNofKeysInTree--;
00881 if (fParent != 0)
00882 fParent->DecrNofKeys(this);
00883 else
00884 fTree->DecrNofKeys();
00885 }
00886
00887
00888 Int_t TBtInnerNode::FindRank(const TObject *what) const
00889 {
00890
00891
00892 if (((TObject *)what)->Compare(GetKey(1)) < 0)
00893 return GetTree(0)->FindRank(what);
00894 Int_t sum = GetNofKeys(0);
00895 for (Int_t i = 1; i < fLast; i++) {
00896 if (((TObject*)what)->Compare(GetKey(i)) == 0)
00897 return sum;
00898 sum++;
00899 if (((TObject *)what)->Compare(GetKey(i+1)) < 0)
00900 return sum + GetTree(i)->FindRank(what);
00901 sum += GetNofKeys(i);
00902 }
00903 if (((TObject*)what)->Compare(GetKey(fLast)) == 0)
00904 return sum;
00905 sum++;
00906
00907 return sum + GetTree(fLast)->FindRank(what);
00908 }
00909
00910
00911 Int_t TBtInnerNode::FindRankUp(const TBtNode *that) const
00912 {
00913
00914
00915
00916
00917
00918
00919 Int_t l = IndexOf(that);
00920 Int_t sum = 0;
00921 for (Int_t i = 0; i < l; i++)
00922 sum += GetNofKeys(i);
00923 return sum + l + (fParent == 0 ? 0 : fParent->FindRankUp(this));
00924 }
00925
00926
00927 TBtLeafNode *TBtInnerNode::FirstLeafNode()
00928 {
00929
00930
00931 return GetTree(0)->FirstLeafNode();
00932 }
00933
00934
00935 TObject *TBtInnerNode::Found(const TObject *what, TBtNode **which, Int_t *where)
00936 {
00937
00938
00939 R__ASSERT(what->IsSortable());
00940 for (Int_t i = 1 ; i <= fLast; i++) {
00941 if (GetKey(i)->Compare(what) == 0) {
00942
00943
00944
00945 *which = this;
00946 *where = i;
00947 return GetKey(i);
00948 }
00949 if (GetKey(i)->Compare(what) > 0)
00950 return GetTree(i-1)->Found(what, which, where);
00951 }
00952
00953 return GetTree(fLast)->Found(what, which, where);
00954 }
00955
00956
00957 void TBtInnerNode::IncrNofKeys(TBtNode *that)
00958 {
00959
00960
00961 Int_t i = IndexOf(that);
00962 fItem[i].fNofKeysInTree++;
00963 if (fParent != 0)
00964 fParent->IncrNofKeys(this);
00965 else
00966 fTree->IncrNofKeys();
00967 }
00968
00969
00970 Int_t TBtInnerNode::IndexOf(const TBtNode *that) const
00971 {
00972
00973
00974
00975 for (Int_t i = 0; i <= fLast; i++)
00976 if (GetTree(i) == that)
00977 return i;
00978 R__CHECK(0);
00979 return 0;
00980 }
00981
00982
00983 void TBtInnerNode::InformParent()
00984 {
00985
00986
00987 if (fParent == 0) {
00988
00989
00990 R__ASSERT(fTree->fRoot == this);
00991 fTree->RootIsFull();
00992 } else
00993 fParent->IsFull(this);
00994 }
00995
00996
00997 void TBtInnerNode::IsFull(TBtNode *that)
00998 {
00999
01000
01001
01002
01003
01004
01005
01006 if (that->fIsLeaf) {
01007 TBtLeafNode *leaf = (TBtLeafNode *)that;
01008 TBtLeafNode *left = 0;
01009 TBtLeafNode *right= 0;
01010
01011 Int_t leafidx = IndexOf(leaf);
01012 Int_t hasRightSib = (leafidx < fLast) &&
01013 ((right = (TBtLeafNode*)GetTree(leafidx+1)) != 0);
01014 Int_t hasLeftSib = (leafidx > 0) &&
01015 ((left = (TBtLeafNode*)GetTree(leafidx-1)) != 0);
01016 Int_t rightSibFull = (hasRightSib && right->IsAlmostFull());
01017 Int_t leftSibFull = (hasLeftSib && left->IsAlmostFull());
01018 if (rightSibFull) {
01019 if (leftSibFull) {
01020
01021 left->SplitWith(leaf, leafidx);
01022 } else if (hasLeftSib) {
01023
01024 leaf->BalanceWithLeft(left, leafidx);
01025 } else {
01026
01027 leaf->SplitWith(right, leafidx+1);
01028 }
01029 } else if (hasRightSib) {
01030
01031 leaf->BalanceWithRight(right, leafidx+1);
01032 } else if (leftSibFull) {
01033
01034 left->SplitWith(leaf, leafidx);
01035 } else if (hasLeftSib) {
01036
01037 leaf->BalanceWithLeft(left, leafidx);
01038 } else {
01039
01040 R__CHECK(0);
01041 }
01042 } else {
01043 TBtInnerNode *inner = (TBtInnerNode *)that;
01044
01045 Int_t inneridx = IndexOf(inner);
01046 TBtInnerNode *left = 0;
01047 TBtInnerNode *right= 0;
01048 Int_t hasRightSib = (inneridx < fLast) &&
01049 ((right = (TBtInnerNode*)GetTree(inneridx+1)) != 0);
01050 Int_t hasLeftSib = (inneridx > 0) &&
01051 ((left=(TBtInnerNode*)GetTree(inneridx-1)) != 0);
01052 Int_t rightSibFull = (hasRightSib && right->IsAlmostFull());
01053 Int_t leftSibFull = (hasLeftSib && left->IsAlmostFull());
01054 if (rightSibFull) {
01055 if (leftSibFull) {
01056 left->SplitWith(inner, inneridx);
01057 } else if (hasLeftSib) {
01058 inner->BalanceWithLeft(left, inneridx);
01059 } else {
01060
01061 inner->SplitWith(right, inneridx+1);
01062 }
01063 } else if (hasRightSib) {
01064 inner->BalanceWithRight(right, inneridx+1);
01065 } else if (leftSibFull) {
01066 left->SplitWith(inner, inneridx);
01067 } else if (hasLeftSib) {
01068 inner->BalanceWithLeft(left, inneridx);
01069 } else {
01070 R__CHECK(0);
01071 }
01072 }
01073 }
01074
01075
01076 void TBtInnerNode::IsLow(TBtNode *that)
01077 {
01078
01079
01080
01081
01082
01083
01084
01085 if (that->fIsLeaf) {
01086 TBtLeafNode *leaf = (TBtLeafNode *)that;
01087 TBtLeafNode *left = 0;
01088 TBtLeafNode *right= 0;
01089
01090 Int_t leafidx = IndexOf(leaf);
01091 Int_t hasRightSib = (leafidx < fLast) &&
01092 ((right = (TBtLeafNode*)GetTree(leafidx+1)) != 0);
01093 Int_t hasLeftSib = (leafidx > 0) &&
01094 ((left = (TBtLeafNode*)GetTree(leafidx-1)) != 0);
01095 if (hasRightSib && (leaf->Psize() + right->Vsize()) >= leaf->MaxPsize()) {
01096
01097
01098
01099 leaf->BalanceWith(right, leafidx+1);
01100 } else if (hasLeftSib && (leaf->Vsize() + left->Psize()) >= leaf->MaxPsize()) {
01101
01102 left->BalanceWith(leaf, leafidx);
01103 } else if (hasLeftSib) {
01104
01105 left->MergeWithRight(leaf, leafidx);
01106 } else if (hasRightSib) {
01107 leaf->MergeWithRight(right, leafidx+1);
01108 } else {
01109 R__CHECK(0);
01110 }
01111 } else {
01112 TBtInnerNode *inner = (TBtInnerNode *)that;
01113
01114 Int_t inneridx = IndexOf(inner);
01115 TBtInnerNode *left = 0;
01116 TBtInnerNode *right= 0;
01117 Int_t hasRightSib = (inneridx < fLast) &&
01118 ((right = (TBtInnerNode*)GetTree(inneridx+1)) != 0);
01119 Int_t hasLeftSib = (inneridx > 0) &&
01120 ((left = (TBtInnerNode*)GetTree(inneridx-1)) != 0);
01121 if (hasRightSib && (inner->Psize() + right->Vsize()) >= inner->MaxPsize()) {
01122
01123 inner->BalanceWith(right, inneridx+1);
01124 } else if (hasLeftSib && (inner->Vsize() + left->Psize()) >= inner->MaxPsize()) {
01125
01126 left->BalanceWith(inner, inneridx);
01127 } else if (hasLeftSib) {
01128 left->MergeWithRight(inner, inneridx);
01129 } else if (hasRightSib) {
01130 inner->MergeWithRight(right, inneridx+1);
01131 } else {
01132 R__CHECK(0);
01133 }
01134 }
01135 }
01136
01137
01138 TBtLeafNode *TBtInnerNode::LastLeafNode()
01139 {
01140
01141
01142 return GetTree(fLast)->LastLeafNode();
01143 }
01144
01145
01146 void TBtInnerNode::MergeWithRight(TBtInnerNode *rightsib, Int_t pidx)
01147 {
01148
01149
01150 R__ASSERT(Psize() + rightsib->Vsize() < MaxIndex());
01151 if (rightsib->Psize() > 0)
01152 rightsib->PushLeft(rightsib->Psize(), this, pidx);
01153 rightsib->SetKey(0, fParent->GetKey(pidx));
01154 AppendFrom(rightsib, 0, 0);
01155 fParent->IncNofKeys(pidx-1, rightsib->GetNofKeys(0)+1);
01156 fParent->RemoveItem(pidx);
01157 delete rightsib;
01158 }
01159
01160
01161 Int_t TBtInnerNode::NofKeys() const
01162 {
01163
01164
01165 Int_t sum = 0;
01166 for (Int_t i = 0; i <= fLast; i++)
01167 sum += GetNofKeys(i);
01168 return sum + Psize();
01169 }
01170
01171
01172 TObject *TBtInnerNode::operator[](Int_t idx) const
01173 {
01174
01175
01176 for (Int_t j = 0; j <= fLast; j++) {
01177 Int_t r;
01178 if (idx < (r = GetNofKeys(j)))
01179 return (*GetTree(j))[idx];
01180 if (idx == r) {
01181 if (j == fLast) {
01182 ::Error("TBtInnerNode::operator[]", "should not happen, 0 returned");
01183 return 0;
01184 } else
01185 return GetKey(j+1);
01186 }
01187 idx -= r+1;
01188 }
01189 ::Error("TBtInnerNode::operator[]", "should not happen, 0 returned");
01190 return 0;
01191 }
01192
01193
01194 void TBtInnerNode::PushLeft(Int_t noFromThis, TBtInnerNode *leftsib, Int_t pidx)
01195 {
01196
01197
01198
01199 R__ASSERT(fParent->GetTree(pidx) == this);
01200 R__ASSERT(noFromThis > 0 && noFromThis <= Psize());
01201 R__ASSERT(noFromThis + leftsib->Psize() < MaxPsize());
01202 SetKey(0, fParent->GetKey(pidx));
01203 leftsib->AppendFrom(this, 0, noFromThis-1);
01204 ShiftLeft(noFromThis);
01205 fParent->SetKey(pidx, GetKey(0));
01206 fParent->SetNofKeys(pidx-1, leftsib->NofKeys());
01207 fParent->SetNofKeys(pidx, NofKeys());
01208 }
01209
01210
01211 void TBtInnerNode::PushRight(Int_t noFromThis, TBtInnerNode *rightsib, Int_t pidx)
01212 {
01213
01214
01215
01216
01217
01218 R__ASSERT(noFromThis > 0 && noFromThis <= Psize());
01219 R__ASSERT(noFromThis + rightsib->Psize() < rightsib->MaxPsize());
01220 R__ASSERT(fParent->GetTree(pidx) == rightsib);
01221
01222
01223
01224
01225 Int_t start = fLast - noFromThis + 1;
01226 Int_t tgt, src;
01227 tgt = rightsib->fLast + noFromThis;
01228 src = rightsib->fLast;
01229 rightsib->fLast = tgt;
01230 rightsib->SetKey(0, fParent->GetKey(pidx));
01231 IncNofKeys(0);
01232 while (src >= 0) {
01233
01234
01235
01236
01237 rightsib->GetItem(tgt--) = rightsib->GetItem(src--);
01238 }
01239
01240
01241 for (Int_t i = fLast; i >= start; i-- ) {
01242
01243 rightsib->SetItem(tgt--, GetItem(i));
01244 }
01245 fParent->SetKey(pidx, rightsib->GetKey(0));
01246 DecNofKeys(0);
01247 R__CHECK(tgt == -1);
01248
01249
01250 fLast -= noFromThis;
01251
01252
01253 fParent->SetNofKeys(pidx-1, NofKeys());
01254 fParent->SetNofKeys(pidx, rightsib->NofKeys());
01255 }
01256
01257
01258 void TBtInnerNode::Remove(Int_t index)
01259 {
01260
01261
01262 R__ASSERT(index >= 1 && index <= fLast);
01263 TBtLeafNode *lf = GetTree(index)->FirstLeafNode();
01264 SetKey(index, lf->fItem[0]);
01265 lf->RemoveItem(0);
01266 }
01267
01268
01269 void TBtInnerNode::RemoveItem(Int_t index)
01270 {
01271
01272
01273 R__ASSERT(index >= 1 && index <= fLast);
01274 for (Int_t to = index; to < fLast; to++)
01275 fItem[to] = fItem[to+1];
01276 fLast--;
01277 if (IsLow()) {
01278 if (fParent == 0) {
01279
01280 if (Psize() == 0)
01281 fTree->RootIsEmpty();
01282 } else
01283 fParent->IsLow(this);
01284 }
01285 }
01286
01287
01288 void TBtInnerNode::ShiftLeft(Int_t cnt)
01289 {
01290
01291
01292 if (cnt <= 0)
01293 return;
01294 for (Int_t i = cnt; i <= fLast; i++)
01295 GetItem(i-cnt) = GetItem(i);
01296 fLast -= cnt;
01297 }
01298
01299
01300 void TBtInnerNode::Split()
01301 {
01302
01303
01304
01305
01306 TBtInnerNode *newnode = new TBtInnerNode(fParent);
01307 R__CHECK(newnode != 0);
01308 fParent->Append(GetKey(fLast), newnode);
01309 newnode->AppendFrom(this, fLast, fLast);
01310 fLast--;
01311 fParent->IncNofKeys(1, newnode->GetNofKeys(0));
01312 fParent->DecNofKeys(0, newnode->GetNofKeys(0));
01313 BalanceWithRight(newnode, 1);
01314 }
01315
01316
01317 void TBtInnerNode::SplitWith(TBtInnerNode *rightsib, Int_t keyidx)
01318 {
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344 R__ASSERT(keyidx > 0 && keyidx <= fParent->fLast);
01345
01346 rightsib->SetKey(0, fParent->GetKey(keyidx));
01347 Int_t nofKeys = Psize() + rightsib->Vsize();
01348 Int_t newSizeThis = nofKeys / 3;
01349 Int_t newSizeNew = (nofKeys - newSizeThis) / 2;
01350 Int_t newSizeSib = (nofKeys - newSizeThis - newSizeNew);
01351 Int_t noFromThis = Psize() - newSizeThis;
01352 Int_t noFromSib = rightsib->Vsize() - newSizeSib;
01353
01354
01355
01356
01357 R__CHECK(noFromThis >= 0);
01358 R__CHECK(noFromSib >= 1);
01359 TBtInnerNode *newNode = new TBtInnerNode(fParent);
01360 R__CHECK(newNode != 0);
01361 if (noFromThis > 0) {
01362 newNode->Append(GetItem(fLast));
01363 fParent->AddElt(keyidx, GetKey(fLast--), newNode);
01364 if (noFromThis > 2)
01365 this->PushRight(noFromThis-1, newNode, keyidx);
01366 rightsib->PushLeft(noFromSib, newNode, keyidx+1);
01367 } else {
01368
01369 newNode->Append(rightsib->GetItem(0));
01370 fParent->AddElt(keyidx+1, rightsib->GetKey(1), rightsib);
01371 rightsib->ShiftLeft(1);
01372 fParent->SetTree(keyidx, newNode);
01373 rightsib->PushLeft(noFromSib-1, newNode, keyidx+1);
01374 }
01375 fParent->SetNofKeys(keyidx-1, this->NofKeys());
01376 fParent->SetNofKeys(keyidx, newNode->NofKeys());
01377 fParent->SetNofKeys(keyidx+1, rightsib->NofKeys());
01378 if (fParent->IsFull())
01379 fParent->InformParent();
01380 }
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392 TBtLeafNode::TBtLeafNode(TBtInnerNode *p, const TObject *obj, TBtree *t): TBtNode(1, p, t)
01393 {
01394
01395
01396 fItem = new TObject *[MaxIndex()+1];
01397 memset(fItem, 0, (MaxIndex()+1)*sizeof(TObject*));
01398
01399 R__ASSERT(fItem != 0);
01400 if (obj != 0)
01401 fItem[++fLast] = (TObject*)obj;
01402 }
01403
01404
01405 TBtLeafNode::~TBtLeafNode()
01406 {
01407
01408
01409 delete [] fItem;
01410 }
01411
01412
01413 void TBtLeafNode::Add(const TObject *obj, Int_t index)
01414 {
01415
01416
01417
01418 R__ASSERT(obj->IsSortable());
01419 R__ASSERT(0 <= index && index <= fLast+1);
01420 R__ASSERT(fLast <= MaxIndex());
01421 for (Int_t i = fLast+1; i > index ; i--)
01422 fItem[i] = fItem[i-1];
01423 fItem[index] = (TObject *)obj;
01424 fLast++;
01425
01426
01427 if (fParent == 0)
01428 fTree->IncrNofKeys();
01429 else
01430 fParent->IncrNofKeys(this);
01431
01432 if (IsFull()) {
01433
01434 if (fParent == 0) {
01435
01436
01437 R__CHECK(fTree->fRoot == this);
01438
01439
01440 fTree->RootIsFull();
01441 } else {
01442
01443 fParent->IsFull(this);
01444 }
01445 }
01446 }
01447
01448
01449 void TBtLeafNode::AppendFrom(TBtLeafNode *src, Int_t start, Int_t stop)
01450 {
01451
01452
01453
01454
01455
01456
01457
01458
01459 if (start > stop)
01460 return;
01461 R__ASSERT(0 <= start && start <= src->fLast);
01462 R__ASSERT(0 <= stop && stop <= src->fLast);
01463 R__ASSERT(fLast + stop - start + 1 < MaxIndex());
01464 for (Int_t i = start; i <= stop; i++)
01465 fItem[++fLast] = src->fItem[i];
01466 R__CHECK(fLast < MaxIndex());
01467 }
01468
01469
01470 void TBtLeafNode::Append(TObject *obj)
01471 {
01472
01473
01474
01475 R__ASSERT(obj->IsSortable());
01476 fItem[++fLast] = obj;
01477 R__CHECK(fLast < MaxIndex());
01478 }
01479
01480
01481 void TBtLeafNode::BalanceWithLeft(TBtLeafNode *leftsib, Int_t pidx)
01482 {
01483
01484
01485 R__ASSERT(Vsize() >= leftsib->Psize());
01486 Int_t newThisSize = (Vsize() + leftsib->Psize())/2;
01487 Int_t noFromThis = Psize() - newThisSize;
01488 PushLeft(noFromThis, leftsib, pidx);
01489 }
01490
01491
01492 void TBtLeafNode::BalanceWithRight(TBtLeafNode *rightsib, Int_t pidx)
01493 {
01494
01495
01496 R__ASSERT(Psize() >= rightsib->Vsize());
01497 Int_t newThisSize = (Psize() + rightsib->Vsize())/2;
01498 Int_t noFromThis = Psize() - newThisSize;
01499 PushRight(noFromThis, rightsib, pidx);
01500 }
01501
01502
01503 void TBtLeafNode::BalanceWith(TBtLeafNode *rightsib, Int_t pidx)
01504 {
01505
01506
01507
01508 if (Psize() < rightsib->Vsize())
01509 rightsib->BalanceWithLeft(this, pidx);
01510 else
01511 BalanceWithRight(rightsib, pidx);
01512 }
01513
01514
01515 Int_t TBtLeafNode::FindRank(const TObject *what) const
01516 {
01517
01518
01519
01520 for (Int_t i = 0; i <= fLast; i++) {
01521 if (fItem[i]->Compare(what) == 0)
01522 return i;
01523 if (fItem[i]->Compare(what) > 0)
01524 return -1;
01525 }
01526 return -1;
01527 }
01528
01529
01530 TBtLeafNode *TBtLeafNode::FirstLeafNode()
01531 {
01532
01533
01534 return this;
01535 }
01536
01537
01538 TObject *TBtLeafNode::Found(const TObject *what, TBtNode **which, Int_t *where)
01539 {
01540
01541
01542
01543 R__ASSERT(what->IsSortable());
01544 for (Int_t i = 0; i <= fLast; i++) {
01545 if (fItem[i]->Compare(what) == 0) {
01546 *which = this;
01547 *where = i;
01548 return fItem[i];
01549 }
01550 if (fItem[i]->Compare(what) > 0) {
01551 *which = this;
01552 *where = i;
01553 return 0;
01554 }
01555 }
01556 *which = this;
01557 *where = fLast+1;
01558 return 0;
01559 }
01560
01561
01562 Int_t TBtLeafNode::IndexOf(const TObject *that) const
01563 {
01564
01565
01566 for (Int_t i = 0; i <= fLast; i++) {
01567 if (fItem[i] == that)
01568 return i;
01569 }
01570 R__CHECK(0);
01571 return -1;
01572 }
01573
01574
01575 TBtLeafNode *TBtLeafNode::LastLeafNode()
01576 {
01577
01578 return this;
01579 }
01580
01581
01582 void TBtLeafNode::MergeWithRight(TBtLeafNode *rightsib, Int_t pidx)
01583 {
01584
01585
01586 R__ASSERT(Psize() + rightsib->Vsize() < MaxPsize());
01587 rightsib->PushLeft(rightsib->Psize(), this, pidx);
01588 Append(fParent->GetKey(pidx));
01589 fParent->SetNofKeys(pidx-1, NofKeys());
01590 fParent->RemoveItem(pidx);
01591 delete rightsib;
01592 }
01593
01594
01595 Int_t TBtLeafNode::NofKeys(Int_t ) const
01596 {
01597
01598 return 1;
01599 }
01600
01601
01602 Int_t TBtLeafNode::NofKeys() const
01603 {
01604
01605 return Psize();
01606 }
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618 void TBtLeafNode::PushLeft(Int_t noFromThis, TBtLeafNode *leftsib, Int_t pidx)
01619 {
01620
01621
01622
01623 R__ASSERT(noFromThis > 0 && noFromThis <= Psize());
01624 R__ASSERT(noFromThis + leftsib->Psize() < MaxPsize());
01625 R__ASSERT(fParent->GetTree(pidx) == this);
01626 leftsib->Append(fParent->GetKey(pidx));
01627 if (noFromThis > 1)
01628 leftsib->AppendFrom(this, 0, noFromThis-2);
01629 fParent->SetKey(pidx, fItem[noFromThis-1]);
01630 ShiftLeft(noFromThis);
01631 fParent->SetNofKeys(pidx-1, leftsib->NofKeys());
01632 fParent->SetNofKeys(pidx, NofKeys());
01633 }
01634
01635
01636 void TBtLeafNode::PushRight(Int_t noFromThis, TBtLeafNode *rightsib, Int_t pidx)
01637 {
01638
01639
01640
01641
01642 R__ASSERT(noFromThis > 0 && noFromThis <= Psize());
01643 R__ASSERT(noFromThis + rightsib->Psize() < MaxPsize());
01644 R__ASSERT(fParent->GetTree(pidx) == rightsib);
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654 Int_t start = fLast - noFromThis + 1;
01655 Int_t tgt, src;
01656 tgt = rightsib->fLast + noFromThis;
01657 src = rightsib->fLast;
01658 rightsib->fLast = tgt;
01659 while (src >= 0)
01660 rightsib->fItem[tgt--] = rightsib->fItem[src--];
01661
01662
01663 rightsib->fItem[tgt--] = fParent->GetKey(pidx);
01664
01665
01666 for (Int_t i = fLast; i > start; i--)
01667 rightsib->fItem[tgt--] = fItem[i];
01668 R__CHECK(tgt == -1);
01669
01670
01671 fParent->SetKey(pidx, fItem[start]);
01672
01673
01674 fLast -= noFromThis;
01675
01676
01677 fParent->SetNofKeys(pidx-1, NofKeys());
01678 fParent->SetNofKeys(pidx, rightsib->NofKeys());
01679 }
01680
01681
01682 void TBtLeafNode::Remove(Int_t index)
01683 {
01684
01685
01686 R__ASSERT(index >= 0 && index <= fLast);
01687 for (Int_t to = index; to < fLast; to++)
01688 fItem[to] = fItem[to+1];
01689 fLast--;
01690 if (fParent == 0)
01691 fTree->DecrNofKeys();
01692 else
01693 fParent->DecrNofKeys(this);
01694 if (IsLow()) {
01695 if (fParent == 0) {
01696
01697 if (Psize() == 0)
01698 fTree->RootIsEmpty();
01699 } else
01700 fParent->IsLow(this);
01701 }
01702 }
01703
01704
01705 void TBtLeafNode::ShiftLeft(Int_t cnt)
01706 {
01707
01708
01709 if (cnt <= 0)
01710 return;
01711 for (Int_t i = cnt; i <= fLast; i++)
01712 fItem[i-cnt] = fItem[i];
01713 fLast -= cnt;
01714 }
01715
01716
01717 void TBtLeafNode::Split()
01718 {
01719
01720
01721
01722
01723 TBtLeafNode *newnode = new TBtLeafNode(fParent);
01724 R__ASSERT(newnode != 0);
01725 fParent->Append(fItem[fLast--], newnode);
01726 fParent->SetNofKeys(0, fParent->GetTree(0)->NofKeys());
01727 fParent->SetNofKeys(1, fParent->GetTree(1)->NofKeys());
01728 BalanceWithRight(newnode, 1);
01729 }
01730
01731
01732 void TBtLeafNode::SplitWith(TBtLeafNode *rightsib, Int_t keyidx)
01733 {
01734
01735
01736 R__ASSERT(fParent == rightsib->fParent);
01737 R__ASSERT(keyidx > 0 && keyidx <= fParent->fLast);
01738 Int_t nofKeys = Psize() + rightsib->Vsize();
01739 Int_t newSizeThis = nofKeys / 3;
01740 Int_t newSizeNew = (nofKeys - newSizeThis) / 2;
01741 Int_t newSizeSib = (nofKeys - newSizeThis - newSizeNew);
01742 Int_t noFromThis = Psize() - newSizeThis;
01743 Int_t noFromSib = rightsib->Vsize() - newSizeSib;
01744 R__CHECK(noFromThis >= 0);
01745 R__CHECK(noFromSib >= 1);
01746 TBtLeafNode *newNode = new TBtLeafNode(fParent);
01747 R__ASSERT(newNode != 0);
01748 fParent->AddElt(keyidx, fItem[fLast--], newNode);
01749 fParent->SetNofKeys(keyidx, 0);
01750 fParent->DecNofKeys(keyidx-1);
01751 this->PushRight(noFromThis-1, newNode, keyidx);
01752 rightsib->PushLeft(noFromSib, newNode, keyidx+1);
01753 if (fParent->IsFull())
01754 fParent->InformParent();
01755 }