104#ifndef LLVM_ADT_INTERVALMAP_H
105#define LLVM_ADT_INTERVALMAP_H
191namespace IntervalMapImpl {
222template <
typename T1,
typename T2,
unsigned N>
235 template <
unsigned M>
237 unsigned j,
unsigned Count) {
238 assert(i + Count <= M &&
"Invalid source range");
239 assert(j + Count <=
N &&
"Invalid dest range");
240 for (
unsigned e = i + Count; i != e; ++i, ++j) {
250 void moveLeft(
unsigned i,
unsigned j,
unsigned Count) {
251 assert(j <= i &&
"Use moveRight shift elements right");
252 copy(*
this, i, j, Count);
259 void moveRight(
unsigned i,
unsigned j,
unsigned Count) {
260 assert(i <= j &&
"Use moveLeft shift elements left");
261 assert(j + Count <=
N &&
"Invalid range");
297 Sib.
copy(*
this, 0, SSize, Count);
309 Sib.
copy(*
this,
Size-Count, 0, Count);
322 unsigned Count = std::min(std::min(
unsigned(
Add), SSize),
N -
Size);
327 unsigned Count = std::min(std::min(
unsigned(-
Add),
Size),
N - SSize);
339template <
typename NodeT>
341 unsigned CurSize[],
const unsigned NewSize[]) {
343 for (
int n = Nodes - 1; n; --n) {
344 if (CurSize[n] == NewSize[n])
346 for (
int m = n - 1; m != -1; --m) {
347 int d =
Node[n]->adjustFromLeftSib(CurSize[n], *
Node[m], CurSize[m],
348 NewSize[n] - CurSize[n]);
352 if (CurSize[n] >= NewSize[n])
361 for (
unsigned n = 0; n != Nodes - 1; ++n) {
362 if (CurSize[n] == NewSize[n])
364 for (
unsigned m = n + 1; m != Nodes; ++m) {
365 int d =
Node[m]->adjustFromLeftSib(CurSize[m], *
Node[n], CurSize[n],
366 CurSize[n] - NewSize[n]);
370 if (CurSize[n] >= NewSize[n])
376 for (
unsigned n = 0; n != Nodes; n++)
377 assert(CurSize[n] == NewSize[n] &&
"Insufficient element shuffle");
415 const unsigned *CurSize,
unsigned NewSize[],
416 unsigned Position,
bool Grow);
438template <
typename KeyT,
typename ValT>
447 static_cast<unsigned>(2*
sizeof(
KeyT)+
sizeof(
ValT)),
461 static_cast<unsigned>(
sizeof(
KeyT) +
sizeof(
void*))
494 struct CacheAlignedPointerTraits {
495 static inline void *getAsVoidPointer(
void *
P) {
return P; }
496 static inline void *getFromVoidPointer(
void *
P) {
return P; }
509 template <
typename NodeT>
510 NodeRef(NodeT *p,
unsigned n) : pip(p, n - 1) {
511 assert(n <= NodeT::Capacity &&
"Size too big for node");
528 template <
typename NodeT>
530 return *
reinterpret_cast<NodeT*
>(pip.
getPointer());
565template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
584 assert((i == 0 || Traits::stopLess(
stop(i - 1), x)) &&
585 "Index is past the needed point");
586 while (i !=
Size && Traits::stopLess(
stop(i), x)) ++i;
599 assert((i == 0 || Traits::stopLess(
stop(i - 1), x)) &&
600 "Index is past the needed point");
601 while (Traits::stopLess(
stop(i), x)) ++i;
602 assert(i <
N &&
"Unsafe intervals");
613 return Traits::startLess(x,
start(i)) ? NotFound :
value(i);
628template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
633 assert(!Traits::stopLess(b, a) &&
"Invalid interval");
636 assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
637 assert((i ==
Size || !Traits::stopLess(stop(i), a)));
638 assert((i ==
Size || Traits::stopLess(b, start(i))) &&
"Overlapping insert");
641 if (i &&
value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
644 if (i !=
Size &&
value(i) == y && Traits::adjacent(b, start(i))) {
645 stop(i - 1) = stop(i);
666 if (
value(i) == y && Traits::adjacent(b, start(i))) {
676 this->shift(i,
Size);
702template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
719 assert((i == 0 || Traits::stopLess(
stop(i - 1), x)) &&
720 "Index to findFrom is past the needed point");
721 while (i !=
Size && Traits::stopLess(
stop(i), x)) ++i;
733 assert((i == 0 || Traits::stopLess(
stop(i - 1), x)) &&
734 "Index is past the needed point");
735 while (Traits::stopLess(
stop(i), x)) ++i;
736 assert(i <
N &&
"Unsafe intervals");
787 NodeRef &subtree(
unsigned i)
const {
788 return reinterpret_cast<NodeRef*
>(node)[i];
797 template <
typename NodeT> NodeT &
node(
unsigned Level)
const {
798 return *
reinterpret_cast<NodeT*
>(path[Level].node);
800 unsigned size(
unsigned Level)
const {
return path[Level].
size; }
801 unsigned offset(
unsigned Level)
const {
return path[Level].offset; }
802 unsigned &
offset(
unsigned Level) {
return path[Level].offset; }
805 template <
typename NodeT> NodeT &
leaf()
const {
806 return *
reinterpret_cast<NodeT*
>(path.
back().node);
825 return path[Level].subtree(path[Level].
offset);
901 for (
unsigned i = 0, e = path.
size(); i != e; ++i)
911 return path[Level].offset == path[Level].
size - 1;
923 ++path[Level].offset;
933template <
typename KeyT,
typename ValT,
934 unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
935 typename Traits = IntervalMapInfo<KeyT>>
947 DesiredRootBranchCap = (
sizeof(
RootLeaf) -
sizeof(
KeyT)) /
949 RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
956 struct RootBranchData {
981 unsigned rootSize = 0;
986 const RootLeaf &rootLeaf()
const {
987 assert(!branched() &&
"Cannot acces leaf data in branched root");
990 RootLeaf &rootLeaf() {
991 assert(!branched() &&
"Cannot acces leaf data in branched root");
995 const RootBranchData &rootBranchData()
const {
996 assert(branched() &&
"Cannot access branch data in non-branched root");
999 RootBranchData &rootBranchData() {
1000 assert(branched() &&
"Cannot access branch data in non-branched root");
1004 const RootBranch &rootBranch()
const {
return rootBranchData().node; }
1005 RootBranch &rootBranch() {
return rootBranchData().node; }
1006 KeyT rootBranchStart()
const {
return rootBranchData().start; }
1007 KeyT &rootBranchStart() {
return rootBranchData().start; }
1009 template <
typename NodeT> NodeT *newNode() {
1010 return new (
allocator->template Allocate<NodeT>()) NodeT();
1013 template <
typename NodeT>
void deleteNode(NodeT *
P) {
1018 IdxPair branchRoot(
unsigned Position);
1019 IdxPair splitRoot(
unsigned Position);
1021 void switchRootToBranch() {
1022 rootLeaf().~RootLeaf();
1024 new (&rootBranchData()) RootBranchData();
1027 void switchRootToLeaf() {
1028 rootBranchData().~RootBranchData();
1030 new(&rootLeaf()) RootLeaf();
1033 bool branched()
const {
return height > 0; }
1036 void visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
1038 void deleteNode(IntervalMapImpl::NodeRef
Node,
unsigned Level);
1058 for (
auto It =
RHS.begin(),
End =
RHS.end(); It !=
End; ++It)
1059 insert(It.start(), It.stop(), It.value());
1067 *
this = std::move(
RHS);
1073 rootLeaf().~RootLeaf();
1075 height =
RHS.height;
1076 rootSize =
RHS.rootSize;
1081 if (
RHS.branched()) {
1082 rootBranch() = std::move(
RHS.rootBranch());
1085 RHS.rootBranch().~RootBranch();
1089 rootLeaf() = std::move(
RHS.rootLeaf());
1097 rootLeaf().~RootLeaf();
1102 return rootSize == 0;
1107 assert(!
empty() &&
"Empty IntervalMap has no start");
1108 return !branched() ? rootLeaf().
start(0) : rootBranchStart();
1113 assert(!
empty() &&
"Empty IntervalMap has no stop");
1114 return !branched() ? rootLeaf().
stop(rootSize - 1) :
1115 rootBranch().
stop(rootSize - 1);
1120 if (
empty() || Traits::startLess(x,
start()) || Traits::stopLess(
stop(), x))
1122 return branched() ? treeSafeLookup(x, NotFound) :
1131 return find(a).insert(a, b, y);
1134 unsigned p = rootLeaf().
findFrom(0, rootSize, a);
1135 rootSize = rootLeaf().
insertFrom(p, rootSize, a, b, y);
1187 assert(Traits::nonEmpty(a, b));
1194 return !Traits::stopLess(b,
I.start());
1200template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1201ValT IntervalMap<KeyT, ValT, N, Traits>::
1202treeSafeLookup(
KeyT x,
ValT NotFound)
const {
1203 assert(branched() &&
"treeLookup assumes a branched root");
1205 IntervalMapImpl::NodeRef NR = rootBranch().safeLookup(x);
1206 for (
unsigned h = height-1; h; --h)
1207 NR = NR.get<Branch>().safeLookup(x);
1208 return NR.get<Leaf>().safeLookup(x, NotFound);
1213template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1215branchRoot(
unsigned Position) {
1216 using namespace IntervalMapImpl;
1218 const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
1221 unsigned size[Nodes];
1222 IdxPair NewOffset(0, Position);
1228 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity,
nullptr, size,
1234 for (
unsigned n = 0; n != Nodes; ++n) {
1235 Leaf *
L = newNode<Leaf>();
1236 L->copy(rootLeaf(), pos, 0, size[n]);
1237 node[n] =
NodeRef(L, size[n]);
1242 switchRootToBranch();
1243 for (
unsigned n = 0; n != Nodes; ++n) {
1244 rootBranch().stop(n) = node[n].template get<Leaf>().stop(size[n]-1);
1245 rootBranch().subtree(n) = node[n];
1247 rootBranchStart() = node[0].template get<Leaf>().start(0);
1254template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1256splitRoot(
unsigned Position) {
1257 using namespace IntervalMapImpl;
1259 const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
1262 unsigned Size[Nodes];
1263 IdxPair NewOffset(0, Position);
1269 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity,
nullptr,
Size,
1275 for (
unsigned n = 0; n != Nodes; ++n) {
1276 Branch *
B = newNode<Branch>();
1277 B->copy(rootBranch(), Pos, 0,
Size[n]);
1282 for (
unsigned n = 0; n != Nodes; ++n) {
1283 rootBranch().stop(n) =
Node[n].template get<Branch>().stop(
Size[n]-1);
1284 rootBranch().subtree(n) =
Node[n];
1292template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1293void IntervalMap<KeyT, ValT, N, Traits>::
1294visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
unsigned Height)) {
1297 SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
1300 for (
unsigned i = 0; i != rootSize; ++i)
1301 Refs.push_back(rootBranch().subtree(i));
1304 for (
unsigned h = height - 1; h; --h) {
1305 for (
unsigned i = 0, e = Refs.size(); i != e; ++i) {
1306 for (
unsigned j = 0, s = Refs[i].
size();
j != s; ++
j)
1307 NextRefs.push_back(Refs[i].subtree(j));
1308 (this->*f)(Refs[i], h);
1311 Refs.swap(NextRefs);
1315 for (
unsigned i = 0, e = Refs.size(); i !=
e; ++i)
1316 (this->*f)(Refs[i], 0);
1319template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1320void IntervalMap<KeyT, ValT, N, Traits>::
1321deleteNode(IntervalMapImpl::NodeRef
Node,
unsigned Level) {
1323 deleteNode(&
Node.get<Branch>());
1325 deleteNode(&
Node.get<Leaf>());
1328template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1332 visitNodes(&IntervalMap::deleteNode);
1342template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1365 assert(map &&
"Invalid iterator");
1366 return map->branched();
1382 assert(valid() &&
"Cannot access invalid iterator");
1389 assert(valid() &&
"Cannot access invalid iterator");
1396 assert(valid() &&
"Cannot access invalid iterator");
1427 assert(map ==
RHS.map &&
"Cannot compare iterators from different maps");
1429 return !
RHS.valid();
1432 return &path.template leaf<Leaf>() == &
RHS.path.template leaf<Leaf>();
1448 setRoot(map->rootSize);
1453 assert(valid() &&
"Cannot increment end()");
1468 if (path.
leafOffset() && (valid() || !branched()))
1488 setRoot(map->rootLeaf().
findFrom(0, map->rootSize, x));
1507template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1511 for (
unsigned i = map->height - path.height() - 1; i; --i) {
1512 unsigned p = NR.
get<
Branch>().safeFind(0, x);
1521template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1524 setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
1531template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1535 if (!Traits::stopLess(path.leaf<
Leaf>().
stop(path.leafSize() - 1), x)) {
1536 path.leafOffset() = path.leaf<
Leaf>().safeFind(path.leafOffset(), x);
1544 if (path.height()) {
1545 for (
unsigned l = path.height() - 1; l; --l) {
1546 if (!Traits::stopLess(path.node<
Branch>(l).
stop(path.offset(l)), x)) {
1548 path.offset(l + 1) =
1549 path.node<
Branch>(l + 1).safeFind(path.offset(l + 1), x);
1550 return pathFillFind(x);
1555 if (!Traits::stopLess(map->rootBranch().stop(path.offset(0)), x)) {
1556 path.offset(1) = path.node<
Branch>(1).safeFind(path.offset(1), x);
1557 return pathFillFind(x);
1562 setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
1571template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1579 void setNodeStop(
unsigned Level,
KeyT Stop);
1581 template <
typename NodeT>
bool overflow(
unsigned Level);
1583 void eraseNode(
unsigned Level);
1584 void treeErase(
bool UpdateRoot =
true);
1585 bool canCoalesceLeft(
KeyT Start,
ValT x);
1586 bool canCoalesceRight(
KeyT Stop,
ValT x);
1618 this->unsafeStop() = b;
1620 if (this->path.atLastEntry(this->path.height()))
1621 setNodeStop(this->path.height(), b);
1663template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1666 using namespace IntervalMapImpl;
1667 Path &
P = this->path;
1668 if (!this->branched()) {
1669 unsigned i =
P.leafOffset();
1670 RootLeaf &
Node =
P.leaf<RootLeaf>();
1672 Traits::adjacent(
Node.stop(i-1), Start);
1675 if (
unsigned i =
P.leafOffset()) {
1676 Leaf &
Node =
P.leaf<Leaf>();
1677 return Node.value(i-1) == Value && Traits::adjacent(
Node.stop(i-1), Start);
1678 }
else if (NodeRef NR =
P.getLeftSibling(
P.height())) {
1679 unsigned i = NR.size() - 1;
1680 Leaf &
Node = NR.get<Leaf>();
1681 return Node.value(i) ==
Value && Traits::adjacent(
Node.stop(i), Start);
1691template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1692bool IntervalMap<KeyT, ValT, N, Traits>::
1693iterator::canCoalesceRight(
KeyT Stop,
ValT Value) {
1694 using namespace IntervalMapImpl;
1695 Path &
P = this->path;
1696 unsigned i =
P.leafOffset() + 1;
1697 if (!this->branched()) {
1698 if (i >=
P.leafSize())
1700 RootLeaf &
Node =
P.leaf<RootLeaf>();
1701 return Node.value(i) ==
Value && Traits::adjacent(Stop,
Node.start(i));
1704 if (i <
P.leafSize()) {
1705 Leaf &
Node =
P.leaf<Leaf>();
1706 return Node.value(i) ==
Value && Traits::adjacent(Stop,
Node.start(i));
1707 }
else if (NodeRef NR =
P.getRightSibling(
P.height())) {
1708 Leaf &
Node = NR.get<Leaf>();
1709 return Node.value(0) ==
Value && Traits::adjacent(Stop,
Node.start(0));
1715template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1716void IntervalMap<KeyT, ValT, N, Traits>::
1717iterator::setNodeStop(
unsigned Level,
KeyT Stop) {
1721 IntervalMapImpl::Path &
P = this->path;
1724 P.node<
Branch>(Level).stop(
P.offset(Level)) = Stop;
1725 if (!
P.atLastEntry(Level))
1729 P.node<RootBranch>(Level).stop(
P.offset(Level)) = Stop;
1732template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1735 assert(Traits::nonEmpty(a, this->stop()) &&
"Cannot move start beyond stop");
1736 KeyT &CurStart = this->unsafeStart();
1737 if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->
value())) {
1745 setStartUnchecked(a);
1748template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1751 assert(Traits::nonEmpty(this->start(), b) &&
"Cannot move stop beyond start");
1752 if (Traits::startLess(b, this->stop()) ||
1753 !canCoalesceRight(b, this->
value())) {
1754 setStopUnchecked(b);
1758 KeyT a = this->start();
1760 setStartUnchecked(a);
1763template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1766 setValueUnchecked(x);
1767 if (canCoalesceRight(this->stop(), x)) {
1768 KeyT a = this->start();
1770 setStartUnchecked(a);
1772 if (canCoalesceLeft(this->start(), x)) {
1774 KeyT a = this->start();
1776 setStartUnchecked(a);
1786template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1789 assert(Level &&
"Cannot insert next to the root");
1790 bool SplitRoot =
false;
1796 if (IM.rootSize < RootBranch::Capacity) {
1797 IM.rootBranch().
insert(
P.offset(0), IM.rootSize,
Node, Stop);
1798 P.setSize(0, ++IM.rootSize);
1805 IdxPair
Offset = IM.splitRoot(
P.offset(0));
1806 P.replaceRoot(&IM.rootBranch(), IM.rootSize,
Offset);
1813 P.legalizeForInsert(--Level);
1816 if (
P.size(Level) == Branch::Capacity) {
1818 assert(!SplitRoot &&
"Cannot overflow after splitting the root");
1819 SplitRoot = overflow<Branch>(Level);
1822 P.node<
Branch>(Level).insert(
P.offset(Level),
P.size(Level),
Node, Stop);
1823 P.setSize(Level,
P.size(Level) + 1);
1824 if (
P.atLastEntry(Level))
1825 setNodeStop(Level, Stop);
1831template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1834 if (this->branched())
1835 return treeInsert(a, b, y);
1840 unsigned Size = IM.rootLeaf().
insertFrom(
P.leafOffset(), IM.rootSize, a, b, y);
1843 if (
Size <= RootLeaf::Capacity) {
1844 P.setSize(0, IM.rootSize =
Size);
1849 IdxPair
Offset = IM.branchRoot(
P.leafOffset());
1850 P.replaceRoot(&IM.rootBranch(), IM.rootSize,
Offset);
1853 treeInsert(a, b, y);
1856template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1859 using namespace IntervalMapImpl;
1860 Path &
P = this->path;
1863 P.legalizeForInsert(this->map->height);
1866 if (
P.leafOffset() == 0 && Traits::startLess(a,
P.leaf<
Leaf>().
start(0))) {
1868 if (NodeRef Sib =
P.getLeftSibling(
P.height())) {
1870 unsigned SibOfs = Sib.size() - 1;
1871 if (SibLeaf.
value(SibOfs) == y &&
1872 Traits::adjacent(SibLeaf.
stop(SibOfs), a)) {
1879 P.moveLeft(
P.height());
1880 if (Traits::stopLess(b, CurLeaf.
start(0)) &&
1881 (y != CurLeaf.
value(0) || !Traits::adjacent(b, CurLeaf.
start(0)))) {
1883 setNodeStop(
P.height(), SibLeaf.
stop(SibOfs) = b);
1888 a = SibLeaf.
start(SibOfs);
1894 this->map->rootBranchStart() = a;
1899 unsigned Size =
P.leafSize();
1900 bool Grow =
P.leafOffset() ==
Size;
1901 Size =
P.leaf<Leaf>().insertFrom(
P.leafOffset(),
Size, a,
b,
y);
1904 if (
Size > Leaf::Capacity) {
1905 overflow<Leaf>(
P.height());
1906 Grow =
P.leafOffset() ==
P.leafSize();
1907 Size =
P.leaf<Leaf>().insertFrom(
P.leafOffset(),
P.leafSize(), a,
b,
y);
1908 assert(
Size <= Leaf::Capacity &&
"overflow() didn't make room");
1912 P.setSize(
P.height(),
Size);
1916 setNodeStop(
P.height(), b);
1920template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1925 assert(
P.valid() &&
"Cannot erase end()");
1926 if (this->branched())
1928 IM.rootLeaf().
erase(
P.leafOffset(), IM.rootSize);
1929 P.setSize(0, --IM.rootSize);
1933template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1941 if (
P.leafSize() == 1) {
1942 IM.deleteNode(&
Node);
1943 eraseNode(IM.height);
1945 if (UpdateRoot && IM.branched() &&
P.valid() &&
P.atBegin())
1946 IM.rootBranchStart() =
P.leaf<
Leaf>().start(0);
1951 Node.erase(
P.leafOffset(),
P.leafSize());
1952 unsigned NewSize =
P.leafSize() - 1;
1953 P.setSize(IM.height, NewSize);
1955 if (
P.leafOffset() == NewSize) {
1956 setNodeStop(IM.height,
Node.stop(NewSize - 1));
1957 P.moveRight(IM.height);
1958 }
else if (UpdateRoot &&
P.atBegin())
1959 IM.rootBranchStart() =
P.leaf<Leaf>().start(0);
1966template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1967void IntervalMap<KeyT, ValT, N, Traits>::
1968iterator::eraseNode(
unsigned Level) {
1969 assert(Level &&
"Cannot erase root node");
1970 IntervalMap &IM = *this->map;
1971 IntervalMapImpl::Path &
P = this->path;
1974 IM.rootBranch().erase(
P.offset(0), IM.rootSize);
1975 P.setSize(0, --IM.rootSize);
1978 IM.switchRootToLeaf();
1985 if (
P.size(Level) == 1) {
1987 IM.deleteNode(&Parent);
1991 Parent.erase(
P.offset(Level),
P.size(Level));
1992 unsigned NewSize =
P.size(Level) - 1;
1993 P.setSize(Level, NewSize);
1995 if (
P.offset(Level) == NewSize) {
1996 setNodeStop(Level, Parent.stop(NewSize - 1));
2004 P.offset(Level + 1) = 0;
2014template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
2015template <
typename NodeT>
2016bool IntervalMap<KeyT, ValT, N, Traits>::
2017iterator::overflow(
unsigned Level) {
2018 using namespace IntervalMapImpl;
2019 Path &
P = this->path;
2020 unsigned CurSize[4];
2024 unsigned Offset =
P.offset(Level);
2027 NodeRef LeftSib =
P.getLeftSibling(Level);
2030 Node[Nodes++] = &LeftSib.get<NodeT>();
2034 Elements += CurSize[Nodes] =
P.size(Level);
2035 Node[Nodes++] = &
P.node<NodeT>(Level);
2038 NodeRef RightSib =
P.getRightSibling(Level);
2040 Elements += CurSize[Nodes] = RightSib.size();
2041 Node[Nodes++] = &RightSib.get<NodeT>();
2045 unsigned NewNode = 0;
2046 if (Elements + 1 > Nodes * NodeT::Capacity) {
2048 NewNode = Nodes == 1 ? 1 : Nodes - 1;
2049 CurSize[Nodes] = CurSize[NewNode];
2051 CurSize[NewNode] = 0;
2052 Node[NewNode] = this->map->template newNode<NodeT>();
2057 unsigned NewSize[4];
2059 CurSize, NewSize,
Offset,
true);
2067 bool SplitRoot =
false;
2070 KeyT Stop =
Node[Pos]->stop(NewSize[Pos]-1);
2071 if (NewNode && Pos == NewNode) {
2072 SplitRoot = insertNode(Level,
NodeRef(
Node[Pos], NewSize[Pos]), Stop);
2075 P.setSize(Level, NewSize[Pos]);
2076 setNodeStop(Level, Stop);
2078 if (Pos + 1 == Nodes)
2085 while(Pos != NewOffset.first) {
2089 P.offset(Level) = NewOffset.second;
2109template <
typename MapA,
typename MapB>
2111 using KeyType =
typename MapA::KeyType;
2112 using Traits =
typename MapA::KeyTraits;
2114 typename MapA::const_iterator posA;
2115 typename MapB::const_iterator posB;
2124 if (Traits::stopLess(posA.stop(), posB.start())) {
2127 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2129 }
else if (Traits::stopLess(posB.stop(), posA.start())) {
2131 posB.advanceTo(posA.start());
2132 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2140 posA.advanceTo(posB.start());
2141 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2144 posB.advanceTo(posA.start());
2145 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2158 return posA.valid() && posB.valid();
2162 const typename MapA::const_iterator &
a()
const {
return posA; }
2165 const typename MapB::const_iterator &
b()
const {
return posB; }
2169 KeyType ak =
a().start();
2170 KeyType bk =
b().start();
2171 return Traits::startLess(ak, bk) ? bk : ak;
2176 KeyType ak =
a().stop();
2177 KeyType bk =
b().stop();
2178 return Traits::startLess(ak, bk) ? ak : bk;
2196 if (Traits::startLess(posB.stop(), posA.stop()))
2209 if (Traits::stopLess(posA.stop(), x))
2211 if (Traits::stopLess(posB.stop(), x))
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Given that RA is a live value
This file defines the PointerIntPair class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
const NodeRef & subtree(unsigned i) const
NodeRef & subtree(unsigned i)
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find a subtree that is known to exist.
const KeyT & stop(unsigned i) const
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first subtree after i that may contain x.
NodeRef safeLookup(KeyT x) const
safeLookup - Get the subtree containing x, Assuming that x is in range.
void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop)
insert - Insert a new (subtree, stop) pair.
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find an interval that is known to exist.
const KeyT & stop(unsigned i) const
const ValT & value(unsigned i) const
ValT safeLookup(KeyT x, ValT NotFound) const
safeLookup - Lookup mapped value for a safe key.
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.
const KeyT & start(unsigned i) const
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first interval after i that may contain x.
void erase(unsigned i, unsigned j, unsigned Size)
erase - Erase elements [i;j).
void moveLeft(unsigned i, unsigned j, unsigned Count)
moveLeft - Move elements to the left.
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.
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...
void shift(unsigned i, unsigned Size)
shift - Shift elements [i;size) 1 position to the right.
void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
transferToRightSib - Transfer elements to a right sibling node.
void erase(unsigned i, unsigned Size)
erase - Erase element at i.
void moveRight(unsigned i, unsigned j, unsigned Count)
moveRight - Move elements to the right.
unsigned size() const
size - Return the number of elements in the referenced node.
bool operator!=(const NodeRef &RHS) const
void setSize(unsigned n)
setSize - Update the node size.
bool operator==(const NodeRef &RHS) const
NodeT & get() const
get - Dereference as a NodeT reference.
NodeRef(NodeT *p, unsigned n)
NodeRef - Create a reference to the node p with n elements.
NodeRef & subtree(unsigned i) const
subtree - Access the i'th subtree reference in a branch node.
NodeRef()=default
NodeRef - Create a null ref.
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 & offset(unsigned Level)
bool valid() const
valid - Return true if path is at a valid node, not at end().
void reset(unsigned Level)
reset - Reset cached information about node(Level) from subtree(Level -1).
NodeRef getLeftSibling(unsigned Level) const
getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
void setRoot(void *Node, unsigned Size, unsigned Offset)
setRoot - Clear the path and set a new root node.
unsigned offset(unsigned Level) const
unsigned leafOffset() const
NodeT & node(unsigned Level) const
bool atLastEntry(unsigned Level) const
atLastEntry - Return true if the path is at the last entry of the node at Level.
unsigned leafSize() const
bool atBegin() const
atBegin - Return true if path is at begin().
unsigned height() const
height - Return the height of the tree corresponding to this path.
void moveRight(unsigned Level)
moveRight - Move path to the left sibling at Level.
void pop()
pop - Remove the last path entry.
void setSize(unsigned Level, unsigned Size)
setSize - Set the size of a node both in the path and in the tree.
NodeRef getRightSibling(unsigned Level) const
getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
void fillLeft(unsigned Height)
fillLeft - Grow path to Height by taking leftmost branches.
void legalizeForInsert(unsigned Level)
legalizeForInsert - Prepare the path for an insertion at Level.
unsigned size(unsigned Level) const
void moveLeft(unsigned Level)
moveLeft - Move path to the left sibling at Level.
void push(NodeRef Node, unsigned Offset)
push - Add entry to path.
NodeRef & subtree(unsigned Level) const
subtree - Get the subtree referenced from Level.
IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two IntervalMaps.
IntervalMapOverlaps & operator++()
Preincrement - Move to the next overlap.
void skipB()
skipB - Move to the next overlap that doesn't involve b().
void skipA()
skipA - Move to the next overlap that doesn't involve a().
IntervalMapOverlaps(const MapA &a, const MapB &b)
IntervalMapOverlaps - Create an iterator for the overlaps of a and b.
KeyType start() const
start - Beginning of the overlapping interval.
const MapA::const_iterator & a() const
a - access the left hand side in the overlap.
void advanceTo(KeyType x)
advanceTo - Move to the first overlapping interval with stopLess(x, stop()).
bool valid() const
valid - Return true if iterator is at an overlap.
const MapB::const_iterator & b() const
b - access the right hand side in the overlap.
KeyType stop() const
stop - End of the overlapping interval.
void setMap(const IntervalMap &m)
setMap - Change the map iterated over.
const_iterator(const IntervalMap &map)
const_iterator()=default
const_iterator - Create an iterator that isn't pointing anywhere.
void advanceTo(KeyT x)
advanceTo - Move to the first interval with stop >= x, or end().
void pathFillFind(KeyT x)
pathFillFind - Complete path by searching for x.
bool operator==(const const_iterator &RHS) const
bool operator!=(const const_iterator &RHS) const
void goToEnd()
goToEnd - Move beyond the last interval in map.
const KeyT & stop() const
stop - Return the end of the current interval.
KeyT & unsafeStop() const
unsafeStop - Writable access to stop() for iterator.
const_iterator & operator++()
preincrement - Move to the next interval.
bool valid() const
valid - Return true if the current position is valid, false for end().
const KeyT & start() const
start - Return the beginning of the current interval.
void treeAdvanceTo(KeyT x)
treeAdvanceTo - Find position after the current one.
ValT & unsafeValue() const
unsafeValue - Writable access to value() for iterator.
const ValT & operator*() const
std::bidirectional_iterator_tag iterator_category
const ValT & value() const
value - Return the mapped value at the current interval.
const_iterator operator--(int)
postdecrement - Don't do that!
IntervalMapImpl::Path path
void setRoot(unsigned Offset)
void treeFind(KeyT x)
treeFind - Find in a branched tree.
bool atBegin() const
atBegin - Return true if the current position is the first map entry.
std::ptrdiff_t difference_type
void find(KeyT x)
find - Move to the first interval with stop >= x, or end().
const_iterator & operator--()
predecrement - Move to the previous interval.
KeyT & unsafeStart() const
unsafeStart - Writable access to start() for iterator.
void goToBegin()
goToBegin - Move to the first interval in map.
const_iterator operator++(int)
postincrement - Don't do that!
void insert(KeyT a, KeyT b, ValT y)
insert - Insert mapping [a;b] -> y before the current position.
void setValueUnchecked(ValT x)
setValueUnchecked - Change the mapped value of the current interval without checking for coalescing.
iterator()=default
iterator - Create null iterator.
void setStart(KeyT a)
setStart - Move the start of the current interval.
void erase()
erase - Erase the current interval.
void setValue(ValT x)
setValue - Change the mapped value of the current interval.
void setStartUnchecked(KeyT a)
setStartUnchecked - Move the start of the current interval without checking for coalescing or overlap...
void setStop(KeyT b)
setStop - Move the end of the current interval.
void setStopUnchecked(KeyT b)
setStopUnchecked - Move the end of the current interval without checking for coalescing or overlaps.
const_iterator begin() const
void insert(KeyT a, KeyT b, ValT y)
insert - Add a mapping of [a;b] to y, coalesce with adjacent intervals.
ValT lookup(KeyT x, ValT NotFound=ValT()) const
lookup - Return the mapped value at x or NotFound.
KeyT stop() const
stop - Return the largest mapped key in a non-empty map.
IntervalMap & operator=(IntervalMap const &RHS)
typename Sizer::Allocator Allocator
IntervalMap & operator=(IntervalMap &&RHS)
IntervalMap(IntervalMap &&RHS)
const_iterator find(KeyT x) const
find - Return an iterator pointing to the first interval ending at or after x, or end().
RootBranchData branchData
IntervalMap(IntervalMap const &RHS)
bool overlaps(KeyT a, KeyT b) const
overlaps(a, b) - Return true if the intervals in this map overlap with the interval [a;b].
bool empty() const
empty - Return true when no intervals are mapped.
const_iterator end() const
KeyT start() const
start - Return the smallest mapped key in a non-empty map.
void clear()
clear - Remove all entries.
IntervalMap(Allocator &a)
PointerIntPair - This class implements a pair of a pointer and small integer.
void setInt(IntType IntVal) &
void * getOpaqueValue() const
PointerTy getPointer() const
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
std::pair< unsigned, unsigned > IdxPair
void adjustSiblingSizes(NodeT *Node[], unsigned Nodes, unsigned CurSize[], const unsigned NewSize[])
IntervalMapImpl::adjustSiblingSizes - Move elements between sibling nodes.
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...
std::pair< NodeId, LaneBitmask > NodeRef
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
static bool startLess(const T &x, const T &a)
startLess - Return true if x is not in [a;b).
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
static bool stopLess(const T &b, const T &x)
stopLess - Return true if x is not in [a;b).
static bool nonEmpty(const T &a, const T &b)
nonEmpty - Return true if [a;b) is non-empty.
NodeBase< std::pair< KeyT, KeyT >, ValT, LeafSize > LeafBase
RecyclingAllocator< BumpPtrAllocator, char, AllocBytes, CacheLineBytes > Allocator
Allocator - The recycling allocator used for both branch and leaf nodes.
static bool startLess(const T &x, const T &a)
startLess - Return true if x is not in [a;b].
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a] and [b;y] can coalesce.
static bool nonEmpty(const T &a, const T &b)
nonEmpty - Return true if [a;b] is non-empty.
static bool stopLess(const T &b, const T &x)
stopLess - Return true if x is not in [a;b].