249 "PointT must be a fundamental type");
251 "ValueT must be a fundamental or pointer type");
268 IntervalNode *
Left =
nullptr;
269 IntervalNode *
Right =
nullptr;
270 unsigned BucketIntervalsStart = 0;
271 unsigned BucketIntervalsSize = 0;
274 PointType middle()
const {
return MiddlePoint; }
275 unsigned start()
const {
return BucketIntervalsStart; }
276 unsigned size()
const {
return BucketIntervalsSize; }
278 IntervalNode(
PointType Point,
unsigned Start)
279 : MiddlePoint(Point), BucketIntervalsStart(Start) {}
285 IntervalNode *Root =
nullptr;
286 IntervalVector Intervals;
288 PointsVector EndPoints;
306 void deleteTree(IntervalNode *
Node) {
308 deleteTree(
Node->Left);
309 deleteTree(
Node->Right);
310 Node->~IntervalNode();
311 NodeAllocator.Deallocate(
Node);
317 unsigned Start,
unsigned Size,
bool HexFormat =
true) {
319 "Start + Size must be in bounds of the IntervalSet");
320 const char *
Format = HexFormat ?
"[0x%08x,0x%08x] " :
"[%2d,%2d] ";
322 for (
unsigned Position = Start; Position <
Start +
Size; ++Position)
324 IntervalSet[Position]->right());
332 void printNode(raw_ostream &OS,
unsigned Level, IntervalNode *Node,
333 bool HexFormat =
true) {
334 const char *
Format = HexFormat ?
"MP:0x%08x " :
"MP:%2d ";
336 OS <<
format(
"%5d: ", Level);
337 OS.indent(Level * 2);
339 printList(OS, IntervalSet,
Node->start(),
Node->size(), HexFormat);
342 PrintNodeData(
"IR", IntervalsRight);
343 PrintNodeData(
"IL", IntervalsLeft);
347 void printTree(raw_ostream &OS,
unsigned Level, IntervalNode *Node,
348 bool HexFormat =
true) {
350 printNode(OS, Level, Node, HexFormat);
352 printTree(OS, Level,
Node->Left, HexFormat);
353 printTree(OS, Level,
Node->Right, HexFormat);
364 IntervalNode *createTree(
unsigned &IntervalsSize,
int PointsBeginIndex,
365 int PointsEndIndex,
int ReferencesBeginIndex,
366 int ReferencesSize) {
377 if (PointsBeginIndex > PointsEndIndex ||
378 ReferencesBeginIndex >= ReferencesSize)
381 int MiddleIndex = (PointsBeginIndex + PointsEndIndex) / 2;
382 PointType MiddlePoint = EndPoints[MiddleIndex];
384 unsigned NewBucketStart = IntervalsSize;
385 unsigned NewBucketSize = 0;
386 int ReferencesRightIndex = ReferencesSize;
389 new (NodeAllocator) IntervalNode(MiddlePoint, NewBucketStart);
394 for (
int Index = ReferencesBeginIndex;
Index < ReferencesRightIndex;) {
397 if (References[Index]->
contains(MiddlePoint)) {
398 IntervalsLeft[IntervalsSize] = References[
Index];
399 IntervalsRight[IntervalsSize] = References[
Index];
401 Root->BucketIntervalsSize = ++NewBucketSize;
403 if (Index < --ReferencesRightIndex)
404 std::swap(References[Index], References[ReferencesRightIndex]);
405 if (ReferencesRightIndex < --ReferencesSize)
406 std::swap(References[ReferencesRightIndex],
407 References[ReferencesSize]);
411 if (References[Index]->left() > MiddlePoint) {
412 if (Index < --ReferencesRightIndex)
413 std::swap(References[Index], References[ReferencesRightIndex]);
420 if (NewBucketSize > 1) {
422 std::stable_sort(IntervalsLeft.begin() + NewBucketStart,
423 IntervalsLeft.begin() + NewBucketStart + NewBucketSize,
425 return LHS->left() < RHS->left();
428 std::stable_sort(IntervalsRight.begin() + NewBucketStart,
429 IntervalsRight.begin() + NewBucketStart + NewBucketSize,
431 return LHS->right() > RHS->right();
435 if (PointsBeginIndex <= MiddleIndex - 1) {
436 Root->Left = createTree(IntervalsSize, PointsBeginIndex, MiddleIndex - 1,
437 ReferencesBeginIndex, ReferencesRightIndex);
440 if (MiddleIndex + 1 <= PointsEndIndex) {
441 Root->Right = createTree(IntervalsSize, MiddleIndex + 1, PointsEndIndex,
442 ReferencesRightIndex, ReferencesSize);
449 class find_iterator {
463 IntervalNode *Node =
nullptr;
475 if (Point ==
Node->middle()) {
476 if (
Node->size() == 0) {
483 if (Point < Node->middle()) {
487 if (
Node->size() && (*AscendingBuckets)[
Node->start()]->left(Point)) {
493 (*DescendingBuckets)[Node->start()]->right(Point)) {
505 void nextInterval() {
509 if (++Index < Node->
size()) {
510 if (Node->middle() == Point)
512 if (Point < Node->middle()) {
514 if (!(*AscendingBuckets)[Node->start() + Index]->left(Point)) {
522 if (!(*DescendingBuckets)[Node->start() + Index]->right(Point)) {
531 if (Point == Node->middle()) {
537 Node = Point < Node->middle() ? Node->Left : Node->Right;
542 find_iterator() =
default;
546 : AscendingBuckets(
Left), DescendingBuckets(
Right), Node(Node),
547 Point(Point), Index(0) {
552 return (Point <= Node->middle())
553 ? (*AscendingBuckets)[Node->start() + Index]
554 : (*DescendingBuckets)[Node->start() + Index];
564 find_iterator Iter(*
this);
575 return (!
LHS.Node && !
RHS.Node && !
LHS.Index && !
RHS.Index) ||
591 : NodeAllocator(NodeAllocator) {}
595 bool empty()
const {
return Root ==
nullptr; }
602 IntervalsLeft.clear();
603 IntervalsRight.clear();
609 assert(
empty() &&
"Invalid insertion. Interval tree already constructed.");
616 assert(!
empty() &&
"Interval tree it is not constructed.");
618 for (find_iterator Iter =
find(Point),
E =
find_end(); Iter !=
E; ++Iter)
627 std::stable_sort(IntervalSet.
begin(), IntervalSet.
end(),
629 return Sort == Sorting::Ascending
630 ? (LHS->right() - LHS->left()) >
631 (RHS->right() - RHS->left())
632 : (LHS->right() - LHS->left()) <
633 (RHS->right() - RHS->left());
641 printTree(OS, 0, Root, HexFormat);
646 assert(
empty() &&
"Interval tree already constructed.");
653 References.push_back(std::addressof(
Data));
655 std::stable_sort(Points.
begin(), Points.
end());
659 EndPoints.assign(Points.
begin(), Points.
end());
661 IntervalsLeft.resize(Intervals.size());
662 IntervalsRight.resize(Intervals.size());
667 unsigned IntervalsSize = 0;
669 createTree(IntervalsSize, 0, EndPoints.size() - 1,
670 0, References.size());
682 : find_iterator(&IntervalsLeft, &IntervalsRight, Root, Point);