180 TBtree::TBtree(
int order)
200 void TBtree::Add(TObject *obj)
202 if (IsArgNull(
"Add", obj))
return;
203 if (!obj->IsSortable()) {
204 Error(
"Add",
"object must be sortable");
208 fRoot =
new TBtLeafNode(0, obj,
this);
209 R__CHECK(fRoot != 0);
214 if (fRoot->Found(obj, &loc, &idx) != 0) {
228 TObject *TBtree::After(
const TObject *)
const
237 TObject *TBtree::Before(
const TObject *)
const
247 void TBtree::Clear(Option_t *)
260 void TBtree::Delete(Option_t *)
262 for (Int_t i = 0; i < fSize; i++) {
263 TObject *obj = At(i);
264 if (obj && obj->IsOnHeap())
265 TCollection::GarbageCollect(obj);
275 TObject *TBtree::FindObject(
const char *name)
const
277 return TCollection::FindObject(name);
283 TObject *TBtree::FindObject(
const TObject *obj)
const
285 if (!obj->IsSortable()) {
286 Error(
"FindObject",
"object must be sortable");
294 return fRoot->Found(obj, &loc, &idx);
301 Int_t TBtree::IdxAdd(
const TObject &obj)
304 if (!obj.IsSortable()) {
305 Error(
"IdxAdd",
"object must be sortable");
309 fRoot =
new TBtLeafNode(0, &obj,
this);
310 R__ASSERT(fRoot != 0);
316 if (fRoot->Found(&obj, &loc, &idx) != 0) {
324 R__CHECK(loc->fIsLeaf);
327 if (loc->fParent == 0)
330 r = idx + loc->fParent->FindRankUp(loc);
332 TBtInnerNode *iloc = (TBtInnerNode*) loc;
333 r = iloc->FindRankUp(iloc->GetTree(idx));
337 R__CHECK(r == Rank(&obj) || &obj == (*
this)[r]);
344 void TBtree::Init(Int_t order)
347 Warning(
"Init",
"order must be at least 3");
352 fOrder2 = 2 * (fOrder+1);
353 fLeafMaxIndex = fOrder2 - 1;
354 fInnerMaxIndex = fOrder;
367 fLeafLowWaterMark = ((fLeafMaxIndex+1)-1) / 2 - 1;
368 fInnerLowWaterMark = (fOrder-1) / 2;
385 TIterator *TBtree::MakeIterator(Bool_t dir)
const
387 return new TBtreeIter(
this, dir);
393 Int_t TBtree::Rank(
const TObject *obj)
const
395 if (!obj->IsSortable()) {
396 Error(
"Rank",
"object must be sortable");
402 return fRoot->FindRank(obj);
408 TObject *TBtree::Remove(TObject *obj)
410 if (!obj->IsSortable()) {
411 Error(
"Remove",
"object must be sortable");
419 TObject *ob = fRoot->Found(obj, &loc, &idx);
430 void TBtree::RootIsFull()
432 TBtNode *oldroot = fRoot;
433 fRoot =
new TBtInnerNode(0,
this, oldroot);
434 R__ASSERT(fRoot != 0);
441 void TBtree::RootIsEmpty()
443 if (fRoot->fIsLeaf) {
444 TBtLeafNode *lroot = (TBtLeafNode*)fRoot;
445 R__CHECK(lroot->Psize() == 0);
449 TBtInnerNode *iroot = (TBtInnerNode*)fRoot;
450 R__CHECK(iroot->Psize() == 0);
451 fRoot = iroot->GetTree(0);
460 void TBtree::Streamer(TBuffer &b)
464 b.ReadVersion(&R__s, &R__c);
467 b >> fInnerLowWaterMark;
468 b >> fLeafLowWaterMark;
471 TSeqCollection::Streamer(b);
472 b.CheckByteCount(R__s, R__c,TBtree::IsA());
474 R__c = b.WriteVersion(TBtree::IsA(), kTRUE);
477 b << fInnerLowWaterMark;
478 b << fLeafLowWaterMark;
481 TSeqCollection::Streamer(b);
482 b.SetByteCount(R__c, kTRUE);
508 TBtItem::TBtItem(TBtNode *n, TObject *obj)
510 fNofKeysInTree = n->NofKeys()+1;
520 TBtItem::TBtItem(TObject *obj, TBtNode *n)
522 fNofKeysInTree = n->NofKeys()+1;
541 TBtNode::TBtNode(Int_t isleaf, TBtInnerNode *p, TBtree *t)
555 fTree = p->GetParentTree();
572 ClassImp(TBtreeIter);
577 TBtreeIter::TBtreeIter(
const TBtree *t, Bool_t dir)
578 : fTree(t), fCurCursor(0), fCursor(0), fDirection(dir)
586 TBtreeIter::TBtreeIter(
const TBtreeIter &iter) : TIterator(iter)
589 fCursor = iter.fCursor;
590 fCurCursor = iter.fCurCursor;
591 fDirection = iter.fDirection;
597 TIterator &TBtreeIter::operator=(
const TIterator &rhs)
599 if (
this != &rhs && rhs.IsA() == TBtreeIter::Class()) {
600 const TBtreeIter &rhs1 = (
const TBtreeIter &)rhs;
602 fCursor = rhs1.fCursor;
603 fCurCursor = rhs1.fCurCursor;
604 fDirection = rhs1.fDirection;
612 TBtreeIter &TBtreeIter::operator=(
const TBtreeIter &rhs)
616 fCursor = rhs.fCursor;
617 fCurCursor = rhs.fCurCursor;
618 fDirection = rhs.fDirection;
626 void TBtreeIter::Reset()
628 if (fDirection == kIterForward)
631 fCursor = fTree->GetSize() - 1;
633 fCurCursor = fCursor;
639 TObject *TBtreeIter::Next()
641 fCurCursor = fCursor;
642 if (fDirection == kIterForward) {
643 if (fCursor < fTree->GetSize())
644 return (*fTree)[fCursor++];
647 return (*fTree)[fCursor--];
655 Bool_t TBtreeIter::operator!=(
const TIterator &aIter)
const
657 if (aIter.IsA() == TBtreeIter::Class()) {
658 const TBtreeIter &iter(dynamic_cast<const TBtreeIter &>(aIter));
659 return (fCurCursor != iter.fCurCursor);
667 Bool_t TBtreeIter::operator!=(
const TBtreeIter &aIter)
const
669 return (fCurCursor != aIter.fCurCursor);
675 TObject* TBtreeIter::operator*()
const
677 return (((fCurCursor >= 0) && (fCurCursor < fTree->GetSize())) ?
678 (*fTree)[fCurCursor] :
nullptr);
688 TBtInnerNode::TBtInnerNode(TBtInnerNode *p, TBtree *t) : TBtNode(0,p,t)
690 const Int_t index = MaxIndex() + 1;
691 fItem =
new TBtItem[ index ];
693 ::Fatal(
"TBtInnerNode::TBtInnerNode",
"no more memory");
700 TBtInnerNode::TBtInnerNode(TBtInnerNode *parent, TBtree *tree, TBtNode *oldroot)
701 : TBtNode(0, parent, tree)
703 fItem =
new TBtItem[MaxIndex()+1];
705 ::Fatal(
"TBtInnerNode::TBtInnerNode",
"no more memory");
712 TBtInnerNode::~TBtInnerNode()
715 delete fItem[0].fTree;
716 for (Int_t i = 1; i <= fLast; i++)
717 delete fItem[i].fTree;
725 void TBtInnerNode::Add(
const TObject *obj, Int_t index)
727 R__ASSERT(index >= 1 && obj->IsSortable());
728 TBtLeafNode *ln = GetTree(index-1)->LastLeafNode();
729 ln->Add(obj, ln->fLast+1);
735 void TBtInnerNode::AddElt(TBtItem &itm, Int_t at)
737 R__ASSERT(0 <= at && at <= fLast+1);
738 R__ASSERT(fLast < MaxIndex());
739 for (Int_t i = fLast+1; i > at ; i--)
740 GetItem(i) = GetItem(i-1);
748 void TBtInnerNode::AddElt(Int_t at, TObject *k, TBtNode *t)
750 TBtItem newitem(k, t);
757 void TBtInnerNode::Add(TBtItem &itm, Int_t at)
767 void TBtInnerNode::Add(Int_t at, TObject *k, TBtNode *t)
769 TBtItem newitem(k, t);
777 void TBtInnerNode::AppendFrom(TBtInnerNode *src, Int_t start, Int_t stop)
781 R__ASSERT(0 <= start && start <= src->fLast);
782 R__ASSERT(0 <= stop && stop <= src->fLast );
783 R__ASSERT(fLast + stop - start + 1 < MaxIndex());
784 for (Int_t i = start; i <= stop; i++)
785 SetItem(++fLast, src->GetItem(i));
791 void TBtInnerNode::Append(TObject *d, TBtNode *n)
793 R__ASSERT(fLast < MaxIndex());
794 if (d) R__ASSERT(d->IsSortable());
795 SetItem(++fLast, d, n);
801 void TBtInnerNode::Append(TBtItem &itm)
803 R__ASSERT(fLast < MaxIndex());
804 SetItem(++fLast, itm);
812 void TBtInnerNode::BalanceWithLeft(TBtInnerNode *leftsib, Int_t pidx)
814 R__ASSERT(Vsize() >= leftsib->Psize());
815 R__ASSERT(fParent->GetTree(pidx) ==
this);
816 Int_t newThisSize = (Vsize() + leftsib->Psize())/2;
817 Int_t noFromThis = Psize() - newThisSize;
818 PushLeft(noFromThis, leftsib, pidx);
826 void TBtInnerNode::BalanceWithRight(TBtInnerNode *rightsib, Int_t pidx)
828 R__ASSERT(Psize() >= rightsib->Vsize());
829 R__ASSERT(fParent->GetTree(pidx) == rightsib);
830 Int_t newThisSize = (Psize() + rightsib->Vsize())/2;
831 Int_t noFromThis = Psize() - newThisSize;
832 PushRight(noFromThis, rightsib, pidx);
839 void TBtInnerNode::BalanceWith(TBtInnerNode *rightsib, Int_t pindx)
841 if (Psize() < rightsib->Vsize())
842 rightsib->BalanceWithLeft(
this, pindx);
844 BalanceWithRight(rightsib, pindx);
850 void TBtInnerNode::DecrNofKeys(TBtNode *that)
852 Int_t i = IndexOf(that);
853 fItem[i].fNofKeysInTree--;
855 fParent->DecrNofKeys(
this);
857 fTree->DecrNofKeys();
863 Int_t TBtInnerNode::FindRank(
const TObject *what)
const
865 if (((TObject *)what)->Compare(GetKey(1)) < 0)
866 return GetTree(0)->FindRank(what);
867 Int_t sum = GetNofKeys(0);
868 for (Int_t i = 1; i < fLast; i++) {
869 if (((TObject*)what)->Compare(GetKey(i)) == 0)
872 if (((TObject *)what)->Compare(GetKey(i+1)) < 0)
873 return sum + GetTree(i)->FindRank(what);
874 sum += GetNofKeys(i);
876 if (((TObject*)what)->Compare(GetKey(fLast)) == 0)
880 return sum + GetTree(fLast)->FindRank(what);
890 Int_t TBtInnerNode::FindRankUp(
const TBtNode *that)
const
892 Int_t l = IndexOf(that);
894 for (Int_t i = 0; i < l; i++)
895 sum += GetNofKeys(i);
896 return sum + l + (fParent == 0 ? 0 : fParent->FindRankUp(
this));
902 TBtLeafNode *TBtInnerNode::FirstLeafNode()
904 return GetTree(0)->FirstLeafNode();
910 TObject *TBtInnerNode::Found(
const TObject *what, TBtNode **which, Int_t *where)
912 R__ASSERT(what->IsSortable());
913 for (Int_t i = 1 ; i <= fLast; i++) {
914 if (GetKey(i)->Compare(what) == 0) {
922 if (GetKey(i)->Compare(what) > 0)
923 return GetTree(i-1)->Found(what, which, where);
926 return GetTree(fLast)->Found(what, which, where);
932 void TBtInnerNode::IncrNofKeys(TBtNode *that)
934 Int_t i = IndexOf(that);
935 fItem[i].fNofKeysInTree++;
937 fParent->IncrNofKeys(
this);
939 fTree->IncrNofKeys();
946 Int_t TBtInnerNode::IndexOf(
const TBtNode *that)
const
948 for (Int_t i = 0; i <= fLast; i++)
949 if (GetTree(i) == that)
958 void TBtInnerNode::InformParent()
963 R__ASSERT(fTree->fRoot ==
this);
966 fParent->IsFull(
this);
977 void TBtInnerNode::IsFull(TBtNode *that)
980 TBtLeafNode *leaf = (TBtLeafNode *)that;
981 TBtLeafNode *left = 0;
982 TBtLeafNode *right= 0;
984 Int_t leafidx = IndexOf(leaf);
985 Int_t hasRightSib = (leafidx < fLast) &&
986 ((right = (TBtLeafNode*)GetTree(leafidx+1)) != 0);
987 Int_t hasLeftSib = (leafidx > 0) &&
988 ((left = (TBtLeafNode*)GetTree(leafidx-1)) != 0);
989 Int_t rightSibFull = (hasRightSib && right->IsAlmostFull());
990 Int_t leftSibFull = (hasLeftSib && left->IsAlmostFull());
994 left->SplitWith(leaf, leafidx);
995 }
else if (hasLeftSib) {
997 leaf->BalanceWithLeft(left, leafidx);
1000 leaf->SplitWith(right, leafidx+1);
1002 }
else if (hasRightSib) {
1004 leaf->BalanceWithRight(right, leafidx+1);
1005 }
else if (leftSibFull) {
1007 left->SplitWith(leaf, leafidx);
1008 }
else if (hasLeftSib) {
1010 leaf->BalanceWithLeft(left, leafidx);
1016 TBtInnerNode *inner = (TBtInnerNode *)that;
1018 Int_t inneridx = IndexOf(inner);
1019 TBtInnerNode *left = 0;
1020 TBtInnerNode *right= 0;
1021 Int_t hasRightSib = (inneridx < fLast) &&
1022 ((right = (TBtInnerNode*)GetTree(inneridx+1)) != 0);
1023 Int_t hasLeftSib = (inneridx > 0) &&
1024 ((left=(TBtInnerNode*)GetTree(inneridx-1)) != 0);
1025 Int_t rightSibFull = (hasRightSib && right->IsAlmostFull());
1026 Int_t leftSibFull = (hasLeftSib && left->IsAlmostFull());
1029 left->SplitWith(inner, inneridx);
1030 }
else if (hasLeftSib) {
1031 inner->BalanceWithLeft(left, inneridx);
1034 inner->SplitWith(right, inneridx+1);
1036 }
else if (hasRightSib) {
1037 inner->BalanceWithRight(right, inneridx+1);
1038 }
else if (leftSibFull) {
1039 left->SplitWith(inner, inneridx);
1040 }
else if (hasLeftSib) {
1041 inner->BalanceWithLeft(left, inneridx);
1056 void TBtInnerNode::IsLow(TBtNode *that)
1058 if (that->fIsLeaf) {
1059 TBtLeafNode *leaf = (TBtLeafNode *)that;
1060 TBtLeafNode *left = 0;
1061 TBtLeafNode *right= 0;
1063 Int_t leafidx = IndexOf(leaf);
1064 Int_t hasRightSib = (leafidx < fLast) &&
1065 ((right = (TBtLeafNode*)GetTree(leafidx+1)) != 0);
1066 Int_t hasLeftSib = (leafidx > 0) &&
1067 ((left = (TBtLeafNode*)GetTree(leafidx-1)) != 0);
1068 if (hasRightSib && (leaf->Psize() + right->Vsize()) >= leaf->MaxPsize()) {
1072 leaf->BalanceWith(right, leafidx+1);
1073 }
else if (hasLeftSib && (leaf->Vsize() + left->Psize()) >= leaf->MaxPsize()) {
1075 left->BalanceWith(leaf, leafidx);
1076 }
else if (hasLeftSib) {
1078 left->MergeWithRight(leaf, leafidx);
1079 }
else if (hasRightSib) {
1080 leaf->MergeWithRight(right, leafidx+1);
1085 TBtInnerNode *inner = (TBtInnerNode *)that;
1087 Int_t inneridx = IndexOf(inner);
1088 TBtInnerNode *left = 0;
1089 TBtInnerNode *right= 0;
1090 Int_t hasRightSib = (inneridx < fLast) &&
1091 ((right = (TBtInnerNode*)GetTree(inneridx+1)) != 0);
1092 Int_t hasLeftSib = (inneridx > 0) &&
1093 ((left = (TBtInnerNode*)GetTree(inneridx-1)) != 0);
1094 if (hasRightSib && (inner->Psize() + right->Vsize()) >= inner->MaxPsize()) {
1096 inner->BalanceWith(right, inneridx+1);
1097 }
else if (hasLeftSib && (inner->Vsize() + left->Psize()) >= inner->MaxPsize()) {
1099 left->BalanceWith(inner, inneridx);
1100 }
else if (hasLeftSib) {
1101 left->MergeWithRight(inner, inneridx);
1102 }
else if (hasRightSib) {
1103 inner->MergeWithRight(right, inneridx+1);
1113 TBtLeafNode *TBtInnerNode::LastLeafNode()
1115 return GetTree(fLast)->LastLeafNode();
1121 void TBtInnerNode::MergeWithRight(TBtInnerNode *rightsib, Int_t pidx)
1123 R__ASSERT(Psize() + rightsib->Vsize() < MaxIndex());
1124 if (rightsib->Psize() > 0)
1125 rightsib->PushLeft(rightsib->Psize(),
this, pidx);
1126 rightsib->SetKey(0, fParent->GetKey(pidx));
1127 AppendFrom(rightsib, 0, 0);
1128 fParent->IncNofKeys(pidx-1, rightsib->GetNofKeys(0)+1);
1129 fParent->RemoveItem(pidx);
1136 Int_t TBtInnerNode::NofKeys()
const
1139 for (Int_t i = 0; i <= fLast; i++)
1140 sum += GetNofKeys(i);
1141 return sum + Psize();
1147 TObject *TBtInnerNode::operator[](Int_t idx)
const
1149 for (Int_t j = 0; j <= fLast; j++) {
1151 if (idx < (r = GetNofKeys(j)))
1152 return (*GetTree(j))[idx];
1155 ::Error(
"TBtInnerNode::operator[]",
"should not happen, 0 returned");
1162 ::Error(
"TBtInnerNode::operator[]",
"should not happen, 0 returned");
1170 void TBtInnerNode::PushLeft(Int_t noFromThis, TBtInnerNode *leftsib, Int_t pidx)
1172 R__ASSERT(fParent->GetTree(pidx) ==
this);
1173 R__ASSERT(noFromThis > 0 && noFromThis <= Psize());
1174 R__ASSERT(noFromThis + leftsib->Psize() < MaxPsize());
1175 SetKey(0, fParent->GetKey(pidx));
1176 leftsib->AppendFrom(
this, 0, noFromThis-1);
1177 ShiftLeft(noFromThis);
1178 fParent->SetKey(pidx, GetKey(0));
1179 fParent->SetNofKeys(pidx-1, leftsib->NofKeys());
1180 fParent->SetNofKeys(pidx, NofKeys());
1189 void TBtInnerNode::PushRight(Int_t noFromThis, TBtInnerNode *rightsib, Int_t pidx)
1191 R__ASSERT(noFromThis > 0 && noFromThis <= Psize());
1192 R__ASSERT(noFromThis + rightsib->Psize() < rightsib->MaxPsize());
1193 R__ASSERT(fParent->GetTree(pidx) == rightsib);
1198 Int_t start = fLast - noFromThis + 1;
1200 tgt = rightsib->fLast + noFromThis;
1201 src = rightsib->fLast;
1202 rightsib->fLast = tgt;
1203 rightsib->SetKey(0, fParent->GetKey(pidx));
1210 rightsib->GetItem(tgt--) = rightsib->GetItem(src--);
1214 for (Int_t i = fLast; i >= start; i-- ) {
1216 rightsib->SetItem(tgt--, GetItem(i));
1218 fParent->SetKey(pidx, rightsib->GetKey(0));
1220 R__CHECK(tgt == -1);
1223 fLast -= noFromThis;
1226 fParent->SetNofKeys(pidx-1, NofKeys());
1227 fParent->SetNofKeys(pidx, rightsib->NofKeys());
1233 void TBtInnerNode::Remove(Int_t index)
1235 R__ASSERT(index >= 1 && index <= fLast);
1236 TBtLeafNode *lf = GetTree(index)->FirstLeafNode();
1237 SetKey(index, lf->fItem[0]);
1244 void TBtInnerNode::RemoveItem(Int_t index)
1246 R__ASSERT(index >= 1 && index <= fLast);
1247 for (Int_t to = index; to < fLast; to++)
1248 fItem[to] = fItem[to+1];
1254 fTree->RootIsEmpty();
1256 fParent->IsLow(
this);
1263 void TBtInnerNode::ShiftLeft(Int_t cnt)
1267 for (Int_t i = cnt; i <= fLast; i++)
1268 GetItem(i-cnt) = GetItem(i);
1277 void TBtInnerNode::Split()
1279 TBtInnerNode *newnode =
new TBtInnerNode(fParent);
1280 R__CHECK(newnode != 0);
1281 fParent->Append(GetKey(fLast), newnode);
1282 newnode->AppendFrom(
this, fLast, fLast);
1284 fParent->IncNofKeys(1, newnode->GetNofKeys(0));
1285 fParent->DecNofKeys(0, newnode->GetNofKeys(0));
1286 BalanceWithRight(newnode, 1);
1316 void TBtInnerNode::SplitWith(TBtInnerNode *rightsib, Int_t keyidx)
1318 R__ASSERT(keyidx > 0 && keyidx <= fParent->fLast);
1320 rightsib->SetKey(0, fParent->GetKey(keyidx));
1321 Int_t nofKeys = Psize() + rightsib->Vsize();
1322 Int_t newSizeThis = nofKeys / 3;
1323 Int_t newSizeNew = (nofKeys - newSizeThis) / 2;
1324 Int_t newSizeSib = (nofKeys - newSizeThis - newSizeNew);
1325 Int_t noFromThis = Psize() - newSizeThis;
1326 Int_t noFromSib = rightsib->Vsize() - newSizeSib;
1331 R__CHECK(noFromThis >= 0);
1332 R__CHECK(noFromSib >= 1);
1333 TBtInnerNode *newNode =
new TBtInnerNode(fParent);
1334 R__CHECK(newNode != 0);
1335 if (noFromThis > 0) {
1336 newNode->Append(GetItem(fLast));
1337 fParent->AddElt(keyidx, GetKey(fLast--), newNode);
1339 this->PushRight(noFromThis-1, newNode, keyidx);
1340 rightsib->PushLeft(noFromSib, newNode, keyidx+1);
1343 newNode->Append(rightsib->GetItem(0));
1344 fParent->AddElt(keyidx+1, rightsib->GetKey(1), rightsib);
1345 rightsib->ShiftLeft(1);
1346 fParent->SetTree(keyidx, newNode);
1347 rightsib->PushLeft(noFromSib-1, newNode, keyidx+1);
1349 fParent->SetNofKeys(keyidx-1, this->NofKeys());
1350 fParent->SetNofKeys(keyidx, newNode->NofKeys());
1351 fParent->SetNofKeys(keyidx+1, rightsib->NofKeys());
1352 if (fParent->IsFull())
1353 fParent->InformParent();
1363 TBtLeafNode::TBtLeafNode(TBtInnerNode *p,
const TObject *obj, TBtree *t): TBtNode(1, p, t)
1365 fItem =
new TObject *[MaxIndex()+1];
1366 memset(fItem, 0, (MaxIndex()+1)*
sizeof(TObject*));
1368 R__ASSERT(fItem != 0);
1370 fItem[++fLast] = (TObject*)obj;
1376 TBtLeafNode::~TBtLeafNode()
1385 void TBtLeafNode::Add(
const TObject *obj, Int_t index)
1387 R__ASSERT(obj->IsSortable());
1388 R__ASSERT(0 <= index && index <= fLast+1);
1389 R__ASSERT(fLast <= MaxIndex());
1390 for (Int_t i = fLast+1; i > index ; i--)
1391 fItem[i] = fItem[i-1];
1392 fItem[index] = (TObject *)obj;
1397 fTree->IncrNofKeys();
1399 fParent->IncrNofKeys(
this);
1406 R__CHECK(fTree->fRoot ==
this);
1409 fTree->RootIsFull();
1412 fParent->IsFull(
this);
1426 void TBtLeafNode::AppendFrom(TBtLeafNode *src, Int_t start, Int_t stop)
1430 R__ASSERT(0 <= start && start <= src->fLast);
1431 R__ASSERT(0 <= stop && stop <= src->fLast);
1432 R__ASSERT(fLast + stop - start + 1 < MaxIndex());
1433 for (Int_t i = start; i <= stop; i++)
1434 fItem[++fLast] = src->fItem[i];
1435 R__CHECK(fLast < MaxIndex());
1442 void TBtLeafNode::Append(TObject *obj)
1444 R__ASSERT(obj->IsSortable());
1445 fItem[++fLast] = obj;
1446 R__CHECK(fLast < MaxIndex());
1452 void TBtLeafNode::BalanceWithLeft(TBtLeafNode *leftsib, Int_t pidx)
1454 R__ASSERT(Vsize() >= leftsib->Psize());
1455 Int_t newThisSize = (Vsize() + leftsib->Psize())/2;
1456 Int_t noFromThis = Psize() - newThisSize;
1457 PushLeft(noFromThis, leftsib, pidx);
1463 void TBtLeafNode::BalanceWithRight(TBtLeafNode *rightsib, Int_t pidx)
1465 R__ASSERT(Psize() >= rightsib->Vsize());
1466 Int_t newThisSize = (Psize() + rightsib->Vsize())/2;
1467 Int_t noFromThis = Psize() - newThisSize;
1468 PushRight(noFromThis, rightsib, pidx);
1475 void TBtLeafNode::BalanceWith(TBtLeafNode *rightsib, Int_t pidx)
1477 if (Psize() < rightsib->Vsize())
1478 rightsib->BalanceWithLeft(
this, pidx);
1480 BalanceWithRight(rightsib, pidx);
1487 Int_t TBtLeafNode::FindRank(
const TObject *what)
const
1489 for (Int_t i = 0; i <= fLast; i++) {
1490 if (fItem[i]->Compare(what) == 0)
1492 if (fItem[i]->Compare(what) > 0)
1501 TBtLeafNode *TBtLeafNode::FirstLeafNode()
1510 TObject *TBtLeafNode::Found(
const TObject *what, TBtNode **which, Int_t *where)
1512 R__ASSERT(what->IsSortable());
1513 for (Int_t i = 0; i <= fLast; i++) {
1514 if (fItem[i]->Compare(what) == 0) {
1519 if (fItem[i]->Compare(what) > 0) {
1533 Int_t TBtLeafNode::IndexOf(
const TObject *that)
const
1535 for (Int_t i = 0; i <= fLast; i++) {
1536 if (fItem[i] == that)
1546 TBtLeafNode *TBtLeafNode::LastLeafNode()
1554 void TBtLeafNode::MergeWithRight(TBtLeafNode *rightsib, Int_t pidx)
1556 R__ASSERT(Psize() + rightsib->Vsize() < MaxPsize());
1557 rightsib->PushLeft(rightsib->Psize(),
this, pidx);
1558 Append(fParent->GetKey(pidx));
1559 fParent->SetNofKeys(pidx-1, NofKeys());
1560 fParent->RemoveItem(pidx);
1567 Int_t TBtLeafNode::NofKeys(Int_t )
const
1575 Int_t TBtLeafNode::NofKeys()
const
1593 void TBtLeafNode::PushLeft(Int_t noFromThis, TBtLeafNode *leftsib, Int_t pidx)
1595 R__ASSERT(noFromThis > 0 && noFromThis <= Psize());
1596 R__ASSERT(noFromThis + leftsib->Psize() < MaxPsize());
1597 R__ASSERT(fParent->GetTree(pidx) ==
this);
1598 leftsib->Append(fParent->GetKey(pidx));
1600 leftsib->AppendFrom(
this, 0, noFromThis-2);
1601 fParent->SetKey(pidx, fItem[noFromThis-1]);
1602 ShiftLeft(noFromThis);
1603 fParent->SetNofKeys(pidx-1, leftsib->NofKeys());
1604 fParent->SetNofKeys(pidx, NofKeys());
1612 void TBtLeafNode::PushRight(Int_t noFromThis, TBtLeafNode *rightsib, Int_t pidx)
1614 R__ASSERT(noFromThis > 0 && noFromThis <= Psize());
1615 R__ASSERT(noFromThis + rightsib->Psize() < MaxPsize());
1616 R__ASSERT(fParent->GetTree(pidx) == rightsib);
1626 Int_t start = fLast - noFromThis + 1;
1628 tgt = rightsib->fLast + noFromThis;
1629 src = rightsib->fLast;
1630 rightsib->fLast = tgt;
1632 rightsib->fItem[tgt--] = rightsib->fItem[src--];
1635 rightsib->fItem[tgt--] = fParent->GetKey(pidx);
1638 for (Int_t i = fLast; i > start; i--)
1639 rightsib->fItem[tgt--] = fItem[i];
1640 R__CHECK(tgt == -1);
1643 fParent->SetKey(pidx, fItem[start]);
1646 fLast -= noFromThis;
1649 fParent->SetNofKeys(pidx-1, NofKeys());
1650 fParent->SetNofKeys(pidx, rightsib->NofKeys());
1656 void TBtLeafNode::Remove(Int_t index)
1658 R__ASSERT(index >= 0 && index <= fLast);
1659 for (Int_t to = index; to < fLast; to++)
1660 fItem[to] = fItem[to+1];
1663 fTree->DecrNofKeys();
1665 fParent->DecrNofKeys(
this);
1670 fTree->RootIsEmpty();
1672 fParent->IsLow(
this);
1679 void TBtLeafNode::ShiftLeft(Int_t cnt)
1683 for (Int_t i = cnt; i <= fLast; i++)
1684 fItem[i-cnt] = fItem[i];
1693 void TBtLeafNode::Split()
1695 TBtLeafNode *newnode =
new TBtLeafNode(fParent);
1696 R__ASSERT(newnode != 0);
1697 fParent->Append(fItem[fLast--], newnode);
1698 fParent->SetNofKeys(0, fParent->GetTree(0)->NofKeys());
1699 fParent->SetNofKeys(1, fParent->GetTree(1)->NofKeys());
1700 BalanceWithRight(newnode, 1);
1706 void TBtLeafNode::SplitWith(TBtLeafNode *rightsib, Int_t keyidx)
1708 R__ASSERT(fParent == rightsib->fParent);
1709 R__ASSERT(keyidx > 0 && keyidx <= fParent->fLast);
1710 Int_t nofKeys = Psize() + rightsib->Vsize();
1711 Int_t newSizeThis = nofKeys / 3;
1712 Int_t newSizeNew = (nofKeys - newSizeThis) / 2;
1713 Int_t newSizeSib = (nofKeys - newSizeThis - newSizeNew);
1714 Int_t noFromThis = Psize() - newSizeThis;
1715 Int_t noFromSib = rightsib->Vsize() - newSizeSib;
1716 R__CHECK(noFromThis >= 0);
1717 R__CHECK(noFromSib >= 1);
1718 TBtLeafNode *newNode =
new TBtLeafNode(fParent);
1719 R__ASSERT(newNode != 0);
1720 fParent->AddElt(keyidx, fItem[fLast--], newNode);
1721 fParent->SetNofKeys(keyidx, 0);
1722 fParent->DecNofKeys(keyidx-1);
1723 this->PushRight(noFromThis-1, newNode, keyidx);
1724 rightsib->PushLeft(noFromSib, newNode, keyidx+1);
1725 if (fParent->IsFull())
1726 fParent->InformParent();