99 #ifndef LLVM_ADT_INTERVALMAP_H
100 #define LLVM_ADT_INTERVALMAP_H
135 template <
typename T>
162 template <
typename T>
187 namespace IntervalMapImpl {
218 template <
typename T1,
typename T2,
unsigned N>
231 template <
unsigned M>
233 unsigned j,
unsigned Count) {
234 assert(i + Count <= M &&
"Invalid source range");
235 assert(j + Count <=
N &&
"Invalid dest range");
236 for (
unsigned e = i + Count; i != e; ++
i, ++j) {
247 assert(j <= i &&
"Use moveRight shift elements right");
248 copy(*
this, i, j, Count);
256 assert(i <= j &&
"Use moveLeft shift elements left");
257 assert(j + Count <=
N &&
"Invalid range");
268 void erase(
unsigned i,
unsigned j,
unsigned Size) {
293 Sib.
copy(*
this, 0, SSize, Count);
294 erase(0, Count, Size);
305 Sib.
copy(*
this, Size-Count, 0, Count);
335 template <
typename NodeT>
337 unsigned CurSize[],
const unsigned NewSize[]) {
339 for (
int n = Nodes - 1; n; --n) {
340 if (CurSize[n] == NewSize[n])
342 for (
int m = n - 1; m != -1; --m) {
343 int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
344 NewSize[n] - CurSize[n]);
348 if (CurSize[n] >= NewSize[n])
357 for (
unsigned n = 0; n != Nodes - 1; ++n) {
358 if (CurSize[n] == NewSize[n])
360 for (
unsigned m = n + 1; m != Nodes; ++m) {
361 int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
362 CurSize[n] - NewSize[n]);
366 if (CurSize[n] >= NewSize[n])
372 for (
unsigned n = 0; n != Nodes; n++)
373 assert(CurSize[n] == NewSize[n] &&
"Insufficient element shuffle");
411 const unsigned *CurSize,
unsigned NewSize[],
412 unsigned Position,
bool Grow);
434 template <
typename KeyT,
typename ValT>
443 static_cast<unsigned>(2*
sizeof(KeyT)+
sizeof(
ValT)),
457 static_cast<unsigned>(
sizeof(KeyT) +
sizeof(
void*))
490 struct CacheAlignedPointerTraits {
491 static inline void *getAsVoidPointer(
void *
P) {
return P; }
492 static inline void *getFromVoidPointer(
void *P) {
return P; }
502 explicit operator bool()
const {
return pip.getOpaqueValue(); }
505 template <
typename NodeT>
506 NodeRef(NodeT *p,
unsigned n) : pip(p, n - 1) {
507 assert(n <= NodeT::Capacity &&
"Size too big for node");
511 unsigned size()
const {
return pip.getInt() + 1; }
514 void setSize(
unsigned n) { pip.setInt(n - 1); }
520 return reinterpret_cast<NodeRef*
>(pip.getPointer())[i];
524 template <
typename NodeT>
526 return *
reinterpret_cast<NodeT*
>(pip.getPointer());
532 assert(pip.getPointer() != RHS.pip.
getPointer() &&
"Inconsistent NodeRefs");
561 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
564 const KeyT &
start(
unsigned i)
const {
return this->first[
i].first; }
565 const KeyT &
stop(
unsigned i)
const {
return this->first[
i].second; }
566 const ValT &
value(
unsigned i)
const {
return this->second[
i]; }
568 KeyT &
start(
unsigned i) {
return this->first[
i].first; }
569 KeyT &
stop(
unsigned i) {
return this->first[
i].second; }
570 ValT &
value(
unsigned i) {
return this->second[
i]; }
578 unsigned findFrom(
unsigned i,
unsigned Size, KeyT x)
const {
579 assert(i <= Size && Size <=
N &&
"Bad indices");
580 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
581 "Index is past the needed point");
582 while (i != Size && Traits::stopLess(stop(i), x)) ++
i;
595 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
596 "Index is past the needed point");
597 while (Traits::stopLess(stop(i), x)) ++
i;
598 assert(i <
N &&
"Unsafe intervals");
608 unsigned i = safeFind(0, x);
609 return Traits::startLess(x, start(i)) ? NotFound : value(i);
612 unsigned insertFrom(
unsigned &Pos,
unsigned Size, KeyT a, KeyT b, ValT y);
624 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
626 insertFrom(
unsigned &Pos,
unsigned Size, KeyT a, KeyT b, ValT y) {
628 assert(i <= Size && Size <=
N &&
"Invalid index");
629 assert(!Traits::stopLess(b, a) &&
"Invalid interval");
632 assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
633 assert((i == Size || !Traits::stopLess(stop(i), a)));
634 assert((i == Size || Traits::stopLess(b, start(i))) &&
"Overlapping insert");
637 if (i && value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
640 if (i != Size && value(i) == y && Traits::adjacent(b, start(i))) {
641 stop(i - 1) = stop(i);
642 this->erase(i, Size);
662 if (value(i) == y && Traits::adjacent(b, start(i))) {
672 this->shift(i, Size);
698 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
701 const KeyT &
stop(
unsigned i)
const {
return this->second[
i]; }
704 KeyT &
stop(
unsigned i) {
return this->second[
i]; }
713 unsigned findFrom(
unsigned i,
unsigned Size, KeyT x)
const {
714 assert(i <= Size && Size <=
N &&
"Bad indices");
715 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
716 "Index to findFrom is past the needed point");
717 while (i != Size && Traits::stopLess(stop(i), x)) ++
i;
729 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
730 "Index is past the needed point");
731 while (Traits::stopLess(stop(i), x)) ++
i;
732 assert(i <
N &&
"Unsafe intervals");
740 return subtree(safeFind(0, x));
749 assert(Size <
N &&
"branch node overflow");
750 assert(i <= Size &&
"Bad insert position");
751 this->shift(i, Size);
777 Entry(
void *Node,
unsigned Size,
unsigned Offset)
778 : node(Node), size(Size), offset(Offset) {}
780 Entry(
NodeRef Node,
unsigned Offset)
781 : node(&Node.
subtree(0)), size(Node.
size()), offset(Offset) {}
783 NodeRef &subtree(
unsigned i)
const {
784 return reinterpret_cast<NodeRef*
>(node)[i];
793 template <
typename NodeT> NodeT &
node(
unsigned Level)
const {
794 return *
reinterpret_cast<NodeT*
>(path[
Level].node);
801 template <
typename NodeT> NodeT &
leaf()
const {
802 return *
reinterpret_cast<NodeT*
>(path.back().node);
804 unsigned leafSize()
const {
return path.back().size; }
810 return !path.empty() && path.front().offset < path.front().size;
815 unsigned height()
const {
return path.size() - 1; }
827 path[
Level] = Entry(subtree(Level - 1), offset(Level));
834 path.push_back(Entry(Node, Offset));
847 path[
Level].size = Size;
849 subtree(Level - 1).setSize(Size);
858 path.push_back(Entry(Node, Size, Offset));
876 void moveLeft(
unsigned Level);
881 while (height() < Height)
882 push(subtree(height()), 0);
893 void moveRight(
unsigned Level);
897 for (
unsigned i = 0, e = path.size();
i != e; ++
i)
898 if (path[
i].offset != 0)
907 return path[
Level].offset == path[
Level].size - 1;
919 ++path[
Level].offset;
929 template <
typename KeyT,
typename ValT,
930 unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
931 typename Traits = IntervalMapInfo<KeyT>>
943 DesiredRootBranchCap = (
sizeof(
RootLeaf) -
sizeof(KeyT)) /
945 RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
952 struct RootBranchData {
980 template <
typename T>
990 const RootLeaf &rootLeaf()
const {
991 assert(!branched() &&
"Cannot acces leaf data in branched root");
992 return dataAs<RootLeaf>();
994 RootLeaf &rootLeaf() {
995 assert(!branched() &&
"Cannot acces leaf data in branched root");
996 return dataAs<RootLeaf>();
999 RootBranchData &rootBranchData()
const {
1000 assert(branched() &&
"Cannot access branch data in non-branched root");
1001 return dataAs<RootBranchData>();
1003 RootBranchData &rootBranchData() {
1004 assert(branched() &&
"Cannot access branch data in non-branched root");
1005 return dataAs<RootBranchData>();
1008 const RootBranch &rootBranch()
const {
return rootBranchData().node; }
1009 RootBranch &rootBranch() {
return rootBranchData().node; }
1010 KeyT rootBranchStart()
const {
return rootBranchData().start; }
1011 KeyT &rootBranchStart() {
return rootBranchData().start; }
1013 template <
typename NodeT> NodeT *newNode() {
1014 return new(allocator.template Allocate<NodeT>()) NodeT();
1017 template <
typename NodeT>
void deleteNode(NodeT *
P) {
1019 allocator.Deallocate(P);
1022 IdxPair branchRoot(
unsigned Position);
1023 IdxPair splitRoot(
unsigned Position);
1025 void switchRootToBranch() {
1026 rootLeaf().~RootLeaf();
1028 new (&rootBranchData()) RootBranchData();
1031 void switchRootToLeaf() {
1032 rootBranchData().~RootBranchData();
1034 new(&rootLeaf()) RootLeaf();
1037 bool branched()
const {
return height > 0; }
1039 ValT treeSafeLookup(KeyT x, ValT NotFound)
const;
1040 void visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
1042 void deleteNode(IntervalMapImpl::NodeRef Node,
unsigned Level);
1046 assert((uintptr_t(data.buffer) & (
alignof(
RootLeaf) - 1)) == 0 &&
1047 "Insufficient alignment");
1053 rootLeaf().~RootLeaf();
1058 return rootSize == 0;
1063 assert(!empty() &&
"Empty IntervalMap has no start");
1064 return !branched() ? rootLeaf().start(0) : rootBranchStart();
1069 assert(!empty() &&
"Empty IntervalMap has no stop");
1070 return !branched() ? rootLeaf().stop(rootSize - 1) :
1071 rootBranch().stop(rootSize - 1);
1075 ValT
lookup(KeyT x, ValT NotFound = ValT())
const {
1076 if (empty() || Traits::startLess(x, start()) || Traits::stopLess(stop(), x))
1078 return branched() ? treeSafeLookup(x, NotFound) :
1079 rootLeaf().safeLookup(x, NotFound);
1086 if (branched() || rootSize == RootLeaf::Capacity)
1087 return find(a).insert(a, b, y);
1090 unsigned p = rootLeaf().findFrom(0, rootSize, a);
1091 rootSize = rootLeaf().insertFrom(p, rootSize, a, b, y);
1097 class const_iterator;
1099 friend class const_iterator;
1100 friend class iterator;
1103 const_iterator
I(*
this);
1115 const_iterator
I(*
this);
1128 const_iterator
find(KeyT x)
const {
1129 const_iterator
I(*
this);
1143 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1144 ValT IntervalMap<KeyT, ValT, N, Traits>::
1145 treeSafeLookup(KeyT x, ValT NotFound)
const {
1146 assert(branched() &&
"treeLookup assumes a branched root");
1148 IntervalMapImpl::NodeRef NR = rootBranch().safeLookup(x);
1149 for (
unsigned h = height-1; h; --h)
1150 NR = NR.get<
Branch>().safeLookup(x);
1151 return NR.get<Leaf>().safeLookup(x, NotFound);
1156 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1158 branchRoot(
unsigned Position) {
1159 using namespace IntervalMapImpl;
1161 const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
1164 unsigned size[Nodes];
1165 IdxPair NewOffset(0, Position);
1171 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity,
nullptr, size,
1176 NodeRef node[Nodes];
1177 for (
unsigned n = 0; n != Nodes; ++n) {
1178 Leaf *
L = newNode<Leaf>();
1179 L->copy(rootLeaf(), pos, 0, size[n]);
1180 node[n] = NodeRef(L, size[n]);
1185 switchRootToBranch();
1186 for (
unsigned n = 0; n != Nodes; ++n) {
1187 rootBranch().stop(n) = node[n].template get<Leaf>().stop(size[n]-1);
1188 rootBranch().subtree(n) = node[n];
1190 rootBranchStart() = node[0].template get<Leaf>().start(0);
1197 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1199 splitRoot(
unsigned Position) {
1200 using namespace IntervalMapImpl;
1202 const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
1205 unsigned Size[Nodes];
1206 IdxPair NewOffset(0, Position);
1212 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity,
nullptr, Size,
1217 NodeRef Node[Nodes];
1218 for (
unsigned n = 0; n != Nodes; ++n) {
1219 Branch *
B = newNode<Branch>();
1220 B->copy(rootBranch(), Pos, 0, Size[n]);
1221 Node[n] = NodeRef(B, Size[n]);
1225 for (
unsigned n = 0; n != Nodes; ++n) {
1226 rootBranch().stop(n) = Node[n].template get<Branch>().stop(Size[n]-1);
1227 rootBranch().subtree(n) = Node[n];
1235 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1236 void IntervalMap<KeyT, ValT, N, Traits>::
1237 visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
unsigned Height)) {
1240 SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
1243 for (
unsigned i = 0;
i != rootSize; ++
i)
1244 Refs.push_back(rootBranch().subtree(
i));
1247 for (
unsigned h = height - 1; h; --h) {
1248 for (
unsigned i = 0, e = Refs.size();
i != e; ++
i) {
1249 for (
unsigned j = 0, s = Refs[
i].size(); j != s; ++j)
1250 NextRefs.push_back(Refs[
i].subtree(j));
1251 (this->*f)(Refs[
i], h);
1254 Refs.swap(NextRefs);
1258 for (
unsigned i = 0, e = Refs.size();
i != e; ++
i)
1259 (this->*f)(Refs[
i], 0);
1262 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1263 void IntervalMap<KeyT, ValT, N, Traits>::
1264 deleteNode(IntervalMapImpl::NodeRef Node,
unsigned Level) {
1266 deleteNode(&Node.get<
Branch>());
1268 deleteNode(&Node.get<Leaf>());
1271 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1275 visitNodes(&IntervalMap::deleteNode);
1285 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1287 public std::iterator<std::bidirectional_iterator_tag, ValT> {
1303 assert(map &&
"Invalid iterator");
1304 return map->branched();
1309 path.setRoot(&map->rootBranch(), map->rootSize,
Offset);
1311 path.setRoot(&map->rootLeaf(), map->rootSize,
Offset);
1314 void pathFillFind(KeyT x);
1315 void treeFind(KeyT x);
1316 void treeAdvanceTo(KeyT x);
1320 assert(valid() &&
"Cannot access invalid iterator");
1321 return branched() ? path.leaf<
Leaf>().start(path.leafOffset()) :
1327 assert(valid() &&
"Cannot access invalid iterator");
1328 return branched() ? path.leaf<
Leaf>().stop(path.leafOffset()) :
1334 assert(valid() &&
"Cannot access invalid iterator");
1335 return branched() ? path.leaf<
Leaf>().value(path.leafOffset()) :
1348 bool valid()
const {
return path.valid(); }
1354 const KeyT &
start()
const {
return unsafeStart(); }
1357 const KeyT &
stop()
const {
return unsafeStop(); }
1360 const ValT &
value()
const {
return unsafeValue(); }
1365 assert(map == RHS.
map &&
"Cannot compare iterators from different maps");
1367 return !RHS.
valid();
1370 return &path.template leaf<Leaf>() == &RHS.
path.template leaf<Leaf>();
1381 path.fillLeft(map->height);
1386 setRoot(map->rootSize);
1391 assert(valid() &&
"Cannot increment end()");
1392 if (++path.leafOffset() == path.leafSize() && branched())
1393 path.moveRight(map->height);
1406 if (path.leafOffset() && (valid() || !branched()))
1407 --path.leafOffset();
1409 path.moveLeft(map->height);
1426 setRoot(map->rootLeaf().findFrom(0, map->rootSize, x));
1439 map->rootLeaf().findFrom(path.leafOffset(), map->rootSize, x);
1445 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1449 for (
unsigned i = map->height - path.height() - 1;
i; --
i) {
1450 unsigned p = NR.
get<
Branch>().safeFind(0, x);
1459 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1462 setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
1469 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1473 if (!Traits::stopLess(path.leaf<
Leaf>().
stop(path.leafSize() - 1), x)) {
1474 path.leafOffset() = path.leaf<
Leaf>().safeFind(path.leafOffset(), x);
1482 if (path.height()) {
1483 for (
unsigned l = path.height() - 1; l; --l) {
1484 if (!Traits::stopLess(path.node<
Branch>(l).
stop(path.offset(l)), x)) {
1486 path.offset(l + 1) =
1487 path.node<
Branch>(l + 1).safeFind(path.offset(l + 1), x);
1488 return pathFillFind(x);
1493 if (!Traits::stopLess(map->rootBranch().stop(path.offset(0)), x)) {
1494 path.offset(1) = path.node<
Branch>(1).safeFind(path.offset(1), x);
1495 return pathFillFind(x);
1500 setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
1509 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1516 void setNodeStop(
unsigned Level, KeyT Stop);
1518 template <
typename NodeT>
bool overflow(
unsigned Level);
1519 void treeInsert(KeyT a, KeyT b, ValT y);
1520 void eraseNode(
unsigned Level);
1521 void treeErase(
bool UpdateRoot =
true);
1522 bool canCoalesceLeft(KeyT Start, ValT x);
1523 bool canCoalesceRight(KeyT Stop, ValT x);
1532 void setStart(KeyT a);
1537 void setStop(KeyT b);
1542 void setValue(ValT x);
1555 this->unsafeStop() = b;
1557 if (this->path.atLastEntry(this->path.height()))
1558 setNodeStop(this->path.height(), b);
1567 void insert(KeyT a, KeyT b, ValT y);
1573 const_iterator::operator++();
1584 const_iterator::operator--();
1600 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1603 using namespace IntervalMapImpl;
1604 Path &P = this->path;
1605 if (!this->branched()) {
1606 unsigned i = P.leafOffset();
1607 RootLeaf &Node = P.leaf<RootLeaf>();
1608 return i && Node.value(i-1) == Value &&
1609 Traits::adjacent(Node.stop(i-1), Start);
1612 if (
unsigned i = P.leafOffset()) {
1613 Leaf &Node = P.leaf<Leaf>();
1614 return Node.value(i-1) == Value && Traits::adjacent(Node.stop(i-1), Start);
1615 }
else if (NodeRef NR = P.getLeftSibling(P.height())) {
1616 unsigned i = NR.size() - 1;
1617 Leaf &Node = NR.get<Leaf>();
1618 return Node.value(i) == Value && Traits::adjacent(Node.stop(i), Start);
1628 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1629 bool IntervalMap<KeyT, ValT, N, Traits>::
1630 iterator::canCoalesceRight(KeyT Stop, ValT Value) {
1631 using namespace IntervalMapImpl;
1632 Path &P = this->path;
1633 unsigned i = P.leafOffset() + 1;
1634 if (!this->branched()) {
1635 if (i >= P.leafSize())
1637 RootLeaf &Node = P.leaf<RootLeaf>();
1638 return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
1641 if (i < P.leafSize()) {
1642 Leaf &Node = P.leaf<Leaf>();
1643 return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
1644 }
else if (NodeRef NR = P.getRightSibling(P.height())) {
1645 Leaf &Node = NR.get<Leaf>();
1646 return Node.value(0) == Value && Traits::adjacent(Stop, Node.start(0));
1652 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1653 void IntervalMap<KeyT, ValT, N, Traits>::
1654 iterator::setNodeStop(
unsigned Level, KeyT Stop) {
1658 IntervalMapImpl::Path &P = this->path;
1661 P.node<
Branch>(
Level).stop(P.offset(Level)) = Stop;
1662 if (!P.atLastEntry(Level))
1666 P.node<RootBranch>(
Level).stop(P.offset(Level)) = Stop;
1669 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1672 assert(Traits::nonEmpty(a, this->stop()) &&
"Cannot move start beyond stop");
1673 KeyT &CurStart = this->unsafeStart();
1674 if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->value())) {
1682 setStartUnchecked(a);
1685 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1688 assert(Traits::nonEmpty(this->start(), b) &&
"Cannot move stop beyond start");
1689 if (Traits::startLess(b, this->stop()) ||
1690 !canCoalesceRight(b, this->value())) {
1691 setStopUnchecked(b);
1695 KeyT a = this->start();
1697 setStartUnchecked(a);
1700 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1703 setValueUnchecked(x);
1704 if (canCoalesceRight(this->stop(), x)) {
1705 KeyT a = this->start();
1707 setStartUnchecked(a);
1709 if (canCoalesceLeft(this->start(), x)) {
1711 KeyT a = this->start();
1713 setStartUnchecked(a);
1723 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1726 assert(Level &&
"Cannot insert next to the root");
1727 bool SplitRoot =
false;
1733 if (IM.rootSize < RootBranch::Capacity) {
1734 IM.rootBranch().
insert(P.
offset(0), IM.rootSize, Node, Stop);
1753 if (P.
size(Level) == Branch::Capacity) {
1755 assert(!SplitRoot &&
"Cannot overflow after splitting the root");
1756 SplitRoot = overflow<Branch>(
Level);
1762 setNodeStop(Level, Stop);
1768 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1771 if (this->branched())
1772 return treeInsert(a, b, y);
1780 if (Size <= RootLeaf::Capacity) {
1781 P.
setSize(0, IM.rootSize = Size);
1786 IdxPair Offset = IM.branchRoot(P.
leafOffset());
1790 treeInsert(a, b, y);
1793 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1796 using namespace IntervalMapImpl;
1797 Path &P = this->path;
1807 unsigned SibOfs = Sib.size() - 1;
1808 if (SibLeaf.
value(SibOfs) == y &&
1809 Traits::adjacent(SibLeaf.
stop(SibOfs), a)) {
1817 if (Traits::stopLess(b, CurLeaf.
start(0)) &&
1818 (y != CurLeaf.
value(0) || !Traits::adjacent(b, CurLeaf.
start(0)))) {
1820 setNodeStop(P.
height(), SibLeaf.
stop(SibOfs) = b);
1825 a = SibLeaf.
start(SibOfs);
1831 this->map->rootBranchStart() = a;
1841 if (Size > Leaf::Capacity) {
1842 overflow<Leaf>(P.
height());
1845 assert(Size <= Leaf::Capacity &&
"overflow() didn't make room");
1853 setNodeStop(P.
height(), b);
1857 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1863 if (this->branched())
1870 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1879 IM.deleteNode(&Node);
1880 eraseNode(IM.height);
1882 if (UpdateRoot && IM.branched() && P.
valid() && P.
atBegin())
1883 IM.rootBranchStart() = P.
leaf<
Leaf>().start(0);
1889 unsigned NewSize = P.
leafSize() - 1;
1890 P.
setSize(IM.height, NewSize);
1893 setNodeStop(IM.height, Node.
stop(NewSize - 1));
1895 }
else if (UpdateRoot && P.
atBegin())
1896 IM.rootBranchStart() = P.
leaf<Leaf>().start(0);
1903 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1904 void IntervalMap<KeyT, ValT, N, Traits>::
1905 iterator::eraseNode(
unsigned Level) {
1906 assert(Level &&
"Cannot erase root node");
1907 IntervalMap &IM = *this->map;
1908 IntervalMapImpl::Path &P = this->path;
1911 IM.rootBranch().erase(P.offset(0), IM.rootSize);
1915 IM.switchRootToLeaf();
1922 if (P.size(Level) == 1) {
1924 IM.deleteNode(&Parent);
1928 Parent.erase(P.offset(Level), P.size(Level));
1929 unsigned NewSize = P.size(Level) - 1;
1930 P.setSize(Level, NewSize);
1932 if (P.offset(Level) == NewSize) {
1933 setNodeStop(Level, Parent.stop(NewSize - 1));
1941 P.offset(Level + 1) = 0;
1951 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1952 template <
typename NodeT>
1953 bool IntervalMap<KeyT, ValT, N, Traits>::
1954 iterator::overflow(
unsigned Level) {
1955 using namespace IntervalMapImpl;
1956 Path &P = this->path;
1957 unsigned CurSize[4];
1960 unsigned Elements = 0;
1961 unsigned Offset = P.offset(Level);
1964 NodeRef LeftSib = P.getLeftSibling(Level);
1966 Offset += Elements = CurSize[Nodes] = LeftSib.size();
1967 Node[Nodes++] = &LeftSib.get<NodeT>();
1971 Elements += CurSize[Nodes] = P.size(Level);
1972 Node[Nodes++] = &P.node<NodeT>(
Level);
1975 NodeRef RightSib = P.getRightSibling(Level);
1977 Elements += CurSize[Nodes] = RightSib.size();
1978 Node[Nodes++] = &RightSib.get<NodeT>();
1982 unsigned NewNode = 0;
1983 if (Elements + 1 > Nodes * NodeT::Capacity) {
1985 NewNode = Nodes == 1 ? 1 : Nodes - 1;
1986 CurSize[Nodes] = CurSize[NewNode];
1987 Node[Nodes] = Node[NewNode];
1988 CurSize[NewNode] = 0;
1989 Node[NewNode] = this->map->template newNode<NodeT>();
1994 unsigned NewSize[4];
1996 CurSize, NewSize, Offset,
true);
2004 bool SplitRoot =
false;
2007 KeyT Stop = Node[Pos]->
stop(NewSize[Pos]-1);
2008 if (NewNode && Pos == NewNode) {
2009 SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
2012 P.setSize(Level, NewSize[Pos]);
2013 setNodeStop(Level, Stop);
2015 if (Pos + 1 == Nodes)
2022 while(Pos != NewOffset.first) {
2026 P.offset(Level) = NewOffset.second;
2046 template <
typename MapA,
typename MapB>
2048 typedef typename MapA::KeyType KeyType;
2049 typedef typename MapA::KeyTraits Traits;
2050 typename MapA::const_iterator posA;
2051 typename MapB::const_iterator posB;
2060 if (Traits::stopLess(posA.stop(), posB.start())) {
2062 posA.advanceTo(posB.start());
2063 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2065 }
else if (Traits::stopLess(posB.stop(), posA.start())) {
2067 posB.advanceTo(posA.start());
2068 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2076 posA.advanceTo(posB.start());
2077 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2080 posB.advanceTo(posA.start());
2081 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2089 : posA(b.empty() ? a.
end() : a.
find(b.start())),
2090 posB(posA.valid() ? b.
find(posA.start()) : b.
end()) {
advance(); }
2094 return posA.valid() && posB.valid();
2098 const typename MapA::const_iterator &
a()
const {
return posA; }
2101 const typename MapB::const_iterator &
b()
const {
return posB; }
2105 KeyType ak = a().start();
2106 KeyType bk = b().start();
2107 return Traits::startLess(ak, bk) ? bk : ak;
2112 KeyType ak = a().stop();
2113 KeyType bk = b().stop();
2114 return Traits::startLess(ak, bk) ? ak : bk;
2132 if (Traits::startLess(posB.stop(), posA.stop()))
2145 if (Traits::stopLess(posA.stop(), x))
2147 if (Traits::stopLess(posB.stop(), x))
2155 #endif // LLVM_ADT_INTERVALMAP_H
KeyT & unsafeStop() const
unsafeStop - Writable access to stop() for iterator.
void setValueUnchecked(ValT x)
setValueUnchecked - Change the mapped value of the current interval without checking for coalescing...
ValT lookup(KeyT x, ValT NotFound=ValT()) const
lookup - Return the mapped value at x or NotFound.
const_iterator end(StringRef path)
Get end iterator over path.
void setValue(ValT x)
setValue - Change the mapped value of the current interval.
void transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
transferToLeftSib - Transfer elements to a left sibling node.
void copy(const NodeBase< T1, T2, M > &Other, unsigned i, unsigned j, unsigned Count)
copy - Copy elements from another node.
NodeRef getLeftSibling(unsigned Level) const
getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
const_iterator begin() const
void adjustSiblingSizes(NodeT *Node[], unsigned Nodes, unsigned CurSize[], const unsigned NewSize[])
IntervalMapImpl::adjustSiblingSizes - Move elements between sibling nodes.
void legalizeForInsert(unsigned Level)
legalizeForInsert - Prepare the path for an insertion at Level.
IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two IntervalMaps.
const KeyT & stop(unsigned i) const
KeyT & unsafeStart() const
unsafeStart - Writable access to start() for iterator.
bool atBegin() const
atBegin - Return true if the current position is the first map entry.
const KeyT & stop(unsigned i) const
IntervalMapOverlaps & operator++()
Preincrement - Move to the next overlap.
void skipA()
skipA - Move to the next overlap that doesn't involve a().
const_iterator(const IntervalMap &map)
void moveLeft(unsigned Level)
moveLeft - Move path to the left sibling at Level.
const_iterator find(KeyT x) const
find - Return an iterator pointing to the first interval ending at or after x, or end()...
KeyT stop() const
stop - Return the largest mapped key in a non-empty map.
void pop()
pop - Remove the last path entry.
KeyType stop() const
stop - End of the overlapping interval.
int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add)
adjustFromLeftSib - Adjust the number if elements in this node by moving elements to or from a left s...
unsigned & offset(unsigned Level)
void setMap(const IntervalMap &m)
setMap - Change the map iterated over.
const_iterator end() const
void fillLeft(unsigned Height)
fillLeft - Grow path to Height by taking leftmost branches.
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
ValT safeLookup(KeyT x, ValT NotFound) const
safeLookup - Lookup mapped value for a safe key.
const KeyT & start(unsigned i) const
void setRoot(unsigned Offset)
const NodeRef & subtree(unsigned i) const
static bool stopLess(const T &b, const T &x)
stopLess - Return true if x is not in [a;b].
const_iterator & operator++()
preincrement - move to the next interval.
ValT & unsafeValue() const
unsafeValue - Writable access to value() for iterator.
static void advance(T &it, size_t Val)
bool valid() const
valid - Return true if iterator is at an overlap.
void advanceTo(KeyT x)
advanceTo - Move to the first interval with stop >= x, or end().
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
void treeAdvanceTo(KeyT x)
treeAdvanceTo - Find position after the current one.
bool operator==(const NodeRef &RHS) const
bool operator!=(const NodeRef &RHS) const
bool empty() const
empty - Return true when no intervals are mapped.
static bool startLess(const T &x, const T &a)
startLess - Return true if x is not in [a;b).
PointerTy getPointer() const
const MapA::const_iterator & a() const
a - access the left hand side in the overlap.
void erase()
erase - Erase the current interval.
NodeBase< std::pair< KeyT, KeyT >, ValT, LeafSize > LeafBase
void clear()
clear - Remove all entries.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
IntervalMap(Allocator &a)
NodeRef & subtree(unsigned i) const
subtree - Access the i'th subtree reference in a branch node.
void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop)
insert - Insert a new (subtree, stop) pair.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
KeyType start() const
start - Beginning of the overlapping interval.
void erase(unsigned i, unsigned j, unsigned Size)
erase - Erase elements [i;j).
void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
transferToRightSib - Transfer elements to a right sibling node.
void setStartUnchecked(KeyT a)
setStartUnchecked - Move the start of the current interval without checking for coalescing or overlap...
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find an interval that is known to exist.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template paramaters.
unsigned size() const
size - Return the number of elements in the referenced node.
const KeyT & start() const
start - Return the beginning of the current interval.
IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity, const unsigned *CurSize, unsigned NewSize[], unsigned Position, bool Grow)
IntervalMapImpl::distribute - Compute a new distribution of node elements after an overflow or underf...
void replaceRoot(void *Root, unsigned Size, IdxPair Offsets)
replaceRoot - Replace the current root node with two new entries after the tree height has increased...
unsigned size(unsigned Level) const
void moveRight(unsigned i, unsigned j, unsigned Count)
moveRight - Move elements to the right.
void find(KeyT x)
find - Move to the first interval with stop >= x, or end().
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first interval after i that may contain x.
const_iterator & operator--()
predecrement - move to the previous interval.
void goToBegin()
goToBegin - Move to the first interval in map.
bool operator!=(const const_iterator &RHS) const
const MapB::const_iterator & b() const
b - access the right hand side in the overlap.
void setStop(KeyT b)
setStop - Move the end of the current interval.
static bool startLess(const T &x, const T &a)
startLess - Return true if x is not in [a;b].
IntervalMapOverlaps(const MapA &a, const MapB &b)
IntervalMapOverlaps - Create an iterator for the overlaps of a and b.
unsigned leafOffset() const
const_iterator operator++(int)
postincrement - Dont do that!
NodeRef & subtree(unsigned Level) const
subtree - Get the subtree referenced from Level.
static bool stopLess(const T &b, const T &x)
stopLess - Return true if x is not in [a;b).
void skipB()
skipB - Move to the next overlap that doesn't involve b().
const ValT & value(unsigned i) const
unsigned height() const
height - Return the height of the tree corresponding to this path.
void insert(KeyT a, KeyT b, ValT y)
insert - Add a mapping of [a;b] to y, coalesce with adjacent intervals.
const_iterator()
const_iterator - Create an iterator that isn't pointing anywhere.
KeyT start() const
start - Return the smallest mapped key in a non-empty map.
void moveLeft(unsigned i, unsigned j, unsigned Count)
moveLeft - Move elements to the left.
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
NodeT & node(unsigned Level) const
void goToEnd()
goToEnd - Move beyond the last interval in map.
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find a subtree that is known to exist.
RecyclingAllocator< BumpPtrAllocator, char, AllocBytes, CacheLineBytes > Allocator
Allocator - The recycling allocator used for both branch and leaf nodes.
void setStart(KeyT a)
setStart - Move the start of the current interval.
bool valid() const
valid - Return true if path is at a valid node, not at end().
bool valid() const
valid - Return true if the current position is valid, false for end().
void advanceTo(KeyType x)
advanceTo - Move to the first overlapping interval with stopLess(x, stop()).
void reset(unsigned Level)
reset - Reset cached information about node(Level) from subtree(Level -1).
void erase(unsigned i, unsigned Size)
erase - Erase element at i.
This union template exposes a suitably aligned and sized character array member which can hold elemen...
static void clear(coro::Shape &Shape)
void pathFillFind(KeyT x)
pathFillFind - Complete path by searching for x.
const KeyT & stop() const
stop - Return the end of the current interval.
void push(NodeRef Node, unsigned Offset)
push - Add entry to path.
void moveRight(unsigned Level)
moveRight - Move path to the left sibling at Level.
void insert(KeyT a, KeyT b, ValT y)
insert - Insert mapping [a;b] -> y before the current position.
static bool nonEmpty(const T &a, const T &b)
nonEmpty - Return true if [a;b] is non-empty.
void treeFind(KeyT x)
treeFind - Find in a branched tree.
IntervalMapImpl::Path path
unsigned leafSize() const
unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y)
insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as possible.
Sizer::Allocator Allocator
NodeRef & subtree(unsigned i)
std::pair< unsigned, unsigned > IdxPair
NodeT & get() const
get - Dereference as a NodeT reference.
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first subtree after i that may contain x.
const_iterator operator--(int)
postdecrement - Dont do that!
bool atBegin() const
atBegin - Return true if path is at begin().
unsigned offset(unsigned Level) const
void setStopUnchecked(KeyT b)
setStopUnchecked - Move the end of the current interval without checking for coalescing or overlaps...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
NodeRef safeLookup(KeyT x) const
safeLookup - Get the subtree containing x, Assuming that x is in range.
void setRoot(void *Node, unsigned Size, unsigned Offset)
setRoot - Clear the path and set a new root node.
void setSize(unsigned n)
setSize - Update the node size.
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a] and [b;y] can coalesce.
LLVM Value Representation.
void shift(unsigned i, unsigned Size)
shift - Shift elements [i;size) 1 position to the right.
bool operator==(const const_iterator &RHS) const
const ValT & operator*() const
bool operator==(uint64_t V1, const APInt &V2)
const ValT & value() const
value - Return the mapped value at the current interval.
static bool nonEmpty(const T &a, const T &b)
nonEmpty - Return true if [a;b) is non-empty.
void setSize(unsigned Level, unsigned Size)
setSize - Set the size of a node both in the path and in the tree.
NodeRef(NodeT *p, unsigned n)
NodeRef - Create a reference to the node p with n elements.
bool atLastEntry(unsigned Level) const
atLastEntry - Return true if the path is at the last entry of the node at Level.