250 "PointT must be a fundamental type");
252 "ValueT must be a fundamental or pointer type");
269 IntervalNode *
Left =
nullptr;
270 IntervalNode *
Right =
nullptr;
271 unsigned BucketIntervalsStart = 0;
272 unsigned BucketIntervalsSize = 0;
275 PointType middle()
const {
return MiddlePoint; }
276 unsigned start()
const {
return BucketIntervalsStart; }
277 unsigned size()
const {
return BucketIntervalsSize; }
279 IntervalNode(
PointType Point,
unsigned Start)
280 : MiddlePoint(Point), BucketIntervalsStart(Start) {}
286 IntervalNode *Root =
nullptr;
287 IntervalVector Intervals;
289 PointsVector EndPoints;
307 void deleteTree(IntervalNode *
Node) {
309 deleteTree(
Node->Left);
310 deleteTree(
Node->Right);
311 Node->~IntervalNode();
312 NodeAllocator.Deallocate(
Node);
318 unsigned Start,
unsigned Size,
bool HexFormat =
true) {
320 "Start + Size must be in bounds of the IntervalSet");
321 const char *
Format = HexFormat ?
"[0x%08x,0x%08x] " :
"[%2d,%2d] ";
323 for (
unsigned Position = Start; Position <
Start +
Size; ++Position)
325 IntervalSet[Position]->right());
333 void printNode(raw_ostream &OS,
unsigned Level, IntervalNode *Node,
334 bool HexFormat =
true) {
335 const char *
Format = HexFormat ?
"MP:0x%08x " :
"MP:%2d ";
337 OS <<
format(
"%5d: ", Level);
338 OS.indent(Level * 2);
340 printList(OS, IntervalSet,
Node->start(),
Node->size(), HexFormat);
343 PrintNodeData(
"IR", IntervalsRight);
344 PrintNodeData(
"IL", IntervalsLeft);
348 void printTree(raw_ostream &OS,
unsigned Level, IntervalNode *Node,
349 bool HexFormat =
true) {
351 printNode(OS, Level, Node, HexFormat);
353 printTree(OS, Level,
Node->Left, HexFormat);
354 printTree(OS, Level,
Node->Right, HexFormat);
365 IntervalNode *createTree(
unsigned &IntervalsSize,
int PointsBeginIndex,
366 int PointsEndIndex,
int ReferencesBeginIndex,
367 int ReferencesSize) {
378 if (PointsBeginIndex > PointsEndIndex ||
379 ReferencesBeginIndex >= ReferencesSize)
382 int MiddleIndex = (PointsBeginIndex + PointsEndIndex) / 2;
383 PointType MiddlePoint = EndPoints[MiddleIndex];
385 unsigned NewBucketStart = IntervalsSize;
386 unsigned NewBucketSize = 0;
387 int ReferencesRightIndex = ReferencesSize;
390 new (NodeAllocator) IntervalNode(MiddlePoint, NewBucketStart);
395 for (
int Index = ReferencesBeginIndex;
Index < ReferencesRightIndex;) {
398 if (References[Index]->
contains(MiddlePoint)) {
399 IntervalsLeft[IntervalsSize] = References[
Index];
400 IntervalsRight[IntervalsSize] = References[
Index];
402 Root->BucketIntervalsSize = ++NewBucketSize;
404 if (Index < --ReferencesRightIndex)
405 std::swap(References[Index], References[ReferencesRightIndex]);
406 if (ReferencesRightIndex < --ReferencesSize)
407 std::swap(References[ReferencesRightIndex],
408 References[ReferencesSize]);
412 if (References[Index]->left() > MiddlePoint) {
413 if (Index < --ReferencesRightIndex)
414 std::swap(References[Index], References[ReferencesRightIndex]);
421 if (NewBucketSize > 1) {
423 std::stable_sort(IntervalsLeft.begin() + NewBucketStart,
424 IntervalsLeft.begin() + NewBucketStart + NewBucketSize,
426 return LHS->left() < RHS->left();
429 std::stable_sort(IntervalsRight.begin() + NewBucketStart,
430 IntervalsRight.begin() + NewBucketStart + NewBucketSize,
432 return LHS->right() > RHS->right();
436 if (PointsBeginIndex <= MiddleIndex - 1) {
437 Root->Left = createTree(IntervalsSize, PointsBeginIndex, MiddleIndex - 1,
438 ReferencesBeginIndex, ReferencesRightIndex);
441 if (MiddleIndex + 1 <= PointsEndIndex) {
442 Root->Right = createTree(IntervalsSize, MiddleIndex + 1, PointsEndIndex,
443 ReferencesRightIndex, ReferencesSize);
450 class find_iterator {
464 IntervalNode *Node =
nullptr;
476 if (Point ==
Node->middle()) {
477 if (
Node->size() == 0) {
484 if (Point < Node->middle()) {
488 if (
Node->size() && (*AscendingBuckets)[
Node->start()]->left(Point)) {
494 (*DescendingBuckets)[Node->start()]->right(Point)) {
506 void nextInterval() {
510 if (++Index < Node->
size()) {
511 if (Node->middle() == Point)
513 if (Point < Node->middle()) {
515 if (!(*AscendingBuckets)[Node->start() + Index]->left(Point)) {
523 if (!(*DescendingBuckets)[Node->start() + Index]->right(Point)) {
532 if (Point == Node->middle()) {
538 Node = Point < Node->middle() ? Node->Left : Node->Right;
543 find_iterator() =
default;
547 : AscendingBuckets(
Left), DescendingBuckets(
Right), Node(Node),
548 Point(Point), Index(0) {
553 return (Point <= Node->middle())
554 ? (*AscendingBuckets)[Node->start() + Index]
555 : (*DescendingBuckets)[Node->start() + Index];
565 find_iterator Iter(*
this);
576 return (!
LHS.Node && !
RHS.Node && !
LHS.Index && !
RHS.Index) ||
592 : NodeAllocator(NodeAllocator) {}
596 bool empty()
const {
return Root ==
nullptr; }
603 IntervalsLeft.clear();
604 IntervalsRight.clear();
610 assert(
empty() &&
"Invalid insertion. Interval tree already constructed.");
617 assert(!
empty() &&
"Interval tree it is not constructed.");
619 for (find_iterator Iter =
find(Point),
E =
find_end(); Iter !=
E; ++Iter)
628 std::stable_sort(IntervalSet.
begin(), IntervalSet.
end(),
630 return Sort == Sorting::Ascending
631 ? (LHS->right() - LHS->left()) >
632 (RHS->right() - RHS->left())
633 : (LHS->right() - LHS->left()) <
634 (RHS->right() - RHS->left());
642 printTree(OS, 0, Root, HexFormat);
647 assert(
empty() &&
"Interval tree already constructed.");
654 References.push_back(std::addressof(
Data));
656 std::stable_sort(Points.
begin(), Points.
end());
660 EndPoints.assign(Points.
begin(), Points.
end());
662 IntervalsLeft.resize(Intervals.size());
663 IntervalsRight.resize(Intervals.size());
668 unsigned IntervalsSize = 0;
670 createTree(IntervalsSize, 0, EndPoints.size() - 1,
671 0, References.size());
683 : find_iterator(&IntervalsLeft, &IntervalsRight, Root, Point);