99 #ifndef LLVM_ADT_INTERVALMAP_H
100 #define LLVM_ADT_INTERVALMAP_H
131 template <
typename T>
154 template <
typename T>
176 namespace IntervalMapImpl {
179 template <
typename,
typename,
unsigned,
typename>
class LeafNode;
180 template <
typename,
typename,
unsigned,
typename>
class BranchNode;
182 typedef std::pair<unsigned,unsigned>
IdxPair;
212 template <
typename T1,
typename T2,
unsigned N>
225 template <
unsigned M>
227 unsigned j,
unsigned Count) {
228 assert(i + Count <= M &&
"Invalid source range");
229 assert(j + Count <=
N &&
"Invalid dest range");
230 for (
unsigned e = i + Count; i != e; ++i, ++j) {
240 void moveLeft(
unsigned i,
unsigned j,
unsigned Count) {
241 assert(j <= i &&
"Use moveRight shift elements right");
242 copy(*
this, i, j, Count);
249 void moveRight(
unsigned i,
unsigned j,
unsigned Count) {
250 assert(i <= j &&
"Use moveLeft shift elements left");
251 assert(j + Count <=
N &&
"Invalid range");
262 void erase(
unsigned i,
unsigned j,
unsigned Size) {
269 void erase(
unsigned i,
unsigned Size) {
276 void shift(
unsigned i,
unsigned Size) {
287 Sib.
copy(*
this, 0, SSize, Count);
288 erase(0, Count, Size);
299 Sib.
copy(*
this, Size-Count, 0, Count);
312 unsigned Count = std::min(std::min(
unsigned(Add), SSize),
N - Size);
317 unsigned Count = std::min(std::min(
unsigned(-Add), Size),
N - SSize);
329 template <
typename NodeT>
331 unsigned CurSize[],
const unsigned NewSize[]) {
333 for (
int n = Nodes - 1; n; --n) {
334 if (CurSize[n] == NewSize[n])
336 for (
int m = n - 1; m != -1; --m) {
337 int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
338 NewSize[n] - CurSize[n]);
342 if (CurSize[n] >= NewSize[n])
351 for (
unsigned n = 0; n != Nodes - 1; ++n) {
352 if (CurSize[n] == NewSize[n])
354 for (
unsigned m = n + 1; m != Nodes; ++m) {
355 int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
356 CurSize[n] - NewSize[n]);
360 if (CurSize[n] >= NewSize[n])
366 for (
unsigned n = 0; n != Nodes; n++)
367 assert(CurSize[n] == NewSize[n] &&
"Insufficient element shuffle");
405 const unsigned *CurSize,
unsigned NewSize[],
406 unsigned Position,
bool Grow);
429 template <
typename KeyT,
typename ValT>
438 static_cast<unsigned>(2*
sizeof(
KeyT)+
sizeof(
ValT)),
452 static_cast<unsigned>(
sizeof(
KeyT) +
sizeof(
void*))
487 struct CacheAlignedPointerTraits {
488 static inline void *getAsVoidPointer(
void *
P) {
return P; }
489 static inline void *getFromVoidPointer(
void *P) {
return P; }
502 template <
typename NodeT>
503 NodeRef(NodeT *p,
unsigned n) : pip(p, n - 1) {
504 assert(n <= NodeT::Capacity &&
"Size too big for node");
508 unsigned size()
const {
return pip.getInt() + 1; }
511 void setSize(
unsigned n) { pip.setInt(n - 1); }
517 return reinterpret_cast<NodeRef*
>(pip.getPointer())[i];
521 template <
typename NodeT>
523 return *
reinterpret_cast<NodeT*
>(pip.getPointer());
529 assert(pip.getPointer() != RHS.pip.
getPointer() &&
"Inconsistent NodeRefs");
558 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
559 class LeafNode :
public NodeBase<std::pair<KeyT, KeyT>, ValT, N> {
561 const KeyT &
start(
unsigned i)
const {
return this->first[i].first; }
562 const KeyT &
stop(
unsigned i)
const {
return this->first[i].second; }
563 const ValT &
value(
unsigned i)
const {
return this->second[i]; }
565 KeyT &
start(
unsigned i) {
return this->first[i].first; }
566 KeyT &
stop(
unsigned i) {
return this->first[i].second; }
567 ValT &
value(
unsigned i) {
return this->second[i]; }
576 assert(i <= Size && Size <=
N &&
"Bad indices");
577 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
578 "Index is past the needed point");
579 while (i != Size && Traits::stopLess(stop(i), x)) ++i;
591 assert(i <
N &&
"Bad index");
592 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
593 "Index is past the needed point");
594 while (Traits::stopLess(stop(i), x)) ++i;
595 assert(i <
N &&
"Unsafe intervals");
605 unsigned i = safeFind(0, x);
606 return Traits::startLess(x, start(i)) ? NotFound : value(i);
609 unsigned insertFrom(
unsigned &Pos,
unsigned Size,
KeyT a,
KeyT b, ValT y);
621 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
625 assert(i <= Size && Size <=
N &&
"Invalid index");
626 assert(!Traits::stopLess(b, a) &&
"Invalid interval");
629 assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
630 assert((i == Size || !Traits::stopLess(stop(i), a)));
631 assert((i == Size || Traits::stopLess(b, start(i))) &&
"Overlapping insert");
634 if (i && value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
637 if (i != Size && value(i) == y && Traits::adjacent(b, start(i))) {
638 stop(i - 1) = stop(i);
639 this->erase(i, Size);
659 if (value(i) == y && Traits::adjacent(b, start(i))) {
669 this->shift(i, Size);
696 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
699 const KeyT &
stop(
unsigned i)
const {
return this->second[i]; }
712 assert(i <= Size && Size <=
N &&
"Bad indices");
713 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
714 "Index to findFrom is past the needed point");
715 while (i != Size && Traits::stopLess(stop(i), x)) ++i;
726 assert(i <
N &&
"Bad index");
727 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
728 "Index is past the needed point");
729 while (Traits::stopLess(stop(i), x)) ++i;
730 assert(i <
N &&
"Unsafe intervals");
738 return subtree(safeFind(0, x));
747 assert(Size <
N &&
"branch node overflow");
748 assert(i <= Size &&
"Bad insert position");
749 this->shift(i, Size);
775 Entry(
void *Node,
unsigned Size,
unsigned Offset)
776 : node(Node), size(Size), offset(Offset) {}
778 Entry(
NodeRef Node,
unsigned Offset)
779 : node(&Node.
subtree(0)), size(Node.
size()), offset(Offset) {}
781 NodeRef &subtree(
unsigned i)
const {
782 return reinterpret_cast<NodeRef*
>(node)[i];
791 template <
typename NodeT> NodeT &
node(
unsigned Level)
const {
792 return *
reinterpret_cast<NodeT*
>(path[
Level].node);
799 template <
typename NodeT> NodeT &
leaf()
const {
800 return *
reinterpret_cast<NodeT*
>(path.back().node);
802 unsigned leafSize()
const {
return path.back().size; }
808 return !path.empty() && path.front().offset < path.front().size;
813 unsigned height()
const {
return path.size() - 1; }
825 path[
Level] = Entry(subtree(Level - 1), offset(Level));
832 path.push_back(Entry(Node, Offset));
845 path[
Level].size = Size;
847 subtree(Level - 1).setSize(Size);
854 void setRoot(
void *Node,
unsigned Size,
unsigned Offset) {
856 path.push_back(Entry(Node, Size, Offset));
864 void replaceRoot(
void *Root,
unsigned Size,
IdxPair Offsets);
874 void moveLeft(
unsigned Level);
879 while (height() < Height)
880 push(subtree(height()), 0);
891 void moveRight(
unsigned Level);
895 for (
unsigned i = 0, e = path.size(); i != e; ++i)
896 if (path[i].offset != 0)
905 return path[
Level].offset == path[
Level].size - 1;
917 ++path[
Level].offset;
928 template <
typename KeyT,
typename ValT,
929 unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
930 typename Traits = IntervalMapInfo<KeyT> >
942 DesiredRootBranchCap = (
sizeof(
RootLeaf) -
sizeof(
KeyT)) /
944 RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
951 struct RootBranchData {
957 RootDataSize =
sizeof(RootBranchData) >
sizeof(
RootLeaf) ?
958 sizeof(RootBranchData) :
sizeof(
RootLeaf)
975 char data[RootDataSize];
990 template <
typename T>
1000 const RootLeaf &rootLeaf()
const {
1001 assert(!branched() &&
"Cannot acces leaf data in branched root");
1002 return dataAs<RootLeaf>();
1004 RootLeaf &rootLeaf() {
1005 assert(!branched() &&
"Cannot acces leaf data in branched root");
1006 return dataAs<RootLeaf>();
1008 RootBranchData &rootBranchData()
const {
1009 assert(branched() &&
"Cannot access branch data in non-branched root");
1010 return dataAs<RootBranchData>();
1012 RootBranchData &rootBranchData() {
1013 assert(branched() &&
"Cannot access branch data in non-branched root");
1014 return dataAs<RootBranchData>();
1016 const RootBranch &rootBranch()
const {
return rootBranchData().node; }
1017 RootBranch &rootBranch() {
return rootBranchData().node; }
1018 KeyT rootBranchStart()
const {
return rootBranchData().start; }
1019 KeyT &rootBranchStart() {
return rootBranchData().start; }
1021 template <
typename NodeT> NodeT *newNode() {
1022 return new(allocator.template Allocate<NodeT>()) NodeT();
1025 template <
typename NodeT>
void deleteNode(NodeT *
P) {
1027 allocator.Deallocate(P);
1030 IdxPair branchRoot(
unsigned Position);
1031 IdxPair splitRoot(
unsigned Position);
1033 void switchRootToBranch() {
1034 rootLeaf().~RootLeaf();
1036 new (&rootBranchData()) RootBranchData();
1039 void switchRootToLeaf() {
1040 rootBranchData().~RootBranchData();
1042 new(&rootLeaf()) RootLeaf();
1045 bool branched()
const {
return height > 0; }
1047 ValT treeSafeLookup(
KeyT x, ValT NotFound)
const;
1048 void visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
1050 void deleteNode(IntervalMapImpl::NodeRef Node,
unsigned Level);
1054 assert((uintptr_t(data) & (alignOf<RootLeaf>() - 1)) == 0 &&
1055 "Insufficient alignment");
1061 rootLeaf().~RootLeaf();
1066 return rootSize == 0;
1071 assert(!empty() &&
"Empty IntervalMap has no start");
1072 return !branched() ? rootLeaf().start(0) : rootBranchStart();
1077 assert(!empty() &&
"Empty IntervalMap has no stop");
1078 return !branched() ? rootLeaf().stop(rootSize - 1) :
1079 rootBranch().stop(rootSize - 1);
1084 if (empty() || Traits::startLess(x, start()) || Traits::stopLess(stop(), x))
1086 return branched() ? treeSafeLookup(x, NotFound) :
1087 rootLeaf().safeLookup(x, NotFound);
1094 if (branched() || rootSize == RootLeaf::Capacity)
1095 return find(a).insert(a, b, y);
1098 unsigned p = rootLeaf().findFrom(0, rootSize, a);
1099 rootSize = rootLeaf().insertFrom(p, rootSize, a, b, y);
1105 class const_iterator;
1107 friend class const_iterator;
1108 friend class iterator;
1111 const_iterator
I(*
this);
1123 const_iterator
I(*
this);
1137 const_iterator
I(*
this);
1151 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1152 ValT IntervalMap<KeyT, ValT, N, Traits>::
1153 treeSafeLookup(
KeyT x, ValT NotFound)
const {
1154 assert(branched() &&
"treeLookup assumes a branched root");
1156 IntervalMapImpl::NodeRef NR = rootBranch().safeLookup(x);
1157 for (
unsigned h = height-1; h; --h)
1158 NR = NR.get<
Branch>().safeLookup(x);
1159 return NR.get<Leaf>().safeLookup(x, NotFound);
1165 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1167 branchRoot(
unsigned Position) {
1168 using namespace IntervalMapImpl;
1170 const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
1173 unsigned size[Nodes];
1174 IdxPair NewOffset(0, Position);
1180 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity, NULL, size,
1185 NodeRef node[Nodes];
1186 for (
unsigned n = 0; n != Nodes; ++n) {
1187 Leaf *L = newNode<Leaf>();
1188 L->copy(rootLeaf(), pos, 0, size[n]);
1189 node[n] = NodeRef(L, size[n]);
1194 switchRootToBranch();
1195 for (
unsigned n = 0; n != Nodes; ++n) {
1196 rootBranch().stop(n) = node[n].template get<Leaf>().stop(size[n]-1);
1197 rootBranch().subtree(n) = node[n];
1199 rootBranchStart() = node[0].template get<Leaf>().start(0);
1206 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1208 splitRoot(
unsigned Position) {
1209 using namespace IntervalMapImpl;
1211 const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
1214 unsigned Size[Nodes];
1215 IdxPair NewOffset(0, Position);
1221 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity, NULL, Size,
1226 NodeRef Node[Nodes];
1227 for (
unsigned n = 0; n != Nodes; ++n) {
1228 Branch *B = newNode<Branch>();
1229 B->copy(rootBranch(), Pos, 0, Size[n]);
1230 Node[n] = NodeRef(B, Size[n]);
1234 for (
unsigned n = 0; n != Nodes; ++n) {
1235 rootBranch().stop(n) = Node[n].template get<Branch>().stop(Size[n]-1);
1236 rootBranch().subtree(n) = Node[n];
1244 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1245 void IntervalMap<KeyT, ValT, N, Traits>::
1246 visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
unsigned Height)) {
1249 SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
1252 for (
unsigned i = 0; i != rootSize; ++i)
1253 Refs.push_back(rootBranch().subtree(i));
1256 for (
unsigned h = height - 1; h; --h) {
1257 for (
unsigned i = 0, e = Refs.size(); i != e; ++i) {
1258 for (
unsigned j = 0, s = Refs[i].size(); j != s; ++j)
1259 NextRefs.push_back(Refs[i].subtree(j));
1260 (this->*f)(Refs[i], h);
1263 Refs.swap(NextRefs);
1267 for (
unsigned i = 0, e = Refs.size(); i != e; ++i)
1268 (this->*f)(Refs[i], 0);
1271 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1272 void IntervalMap<KeyT, ValT, N, Traits>::
1273 deleteNode(IntervalMapImpl::NodeRef Node,
unsigned Level) {
1275 deleteNode(&Node.get<
Branch>());
1277 deleteNode(&Node.get<Leaf>());
1280 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1284 visitNodes(&IntervalMap::deleteNode);
1294 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1296 public std::iterator<std::bidirectional_iterator_tag, ValT> {
1311 assert(map &&
"Invalid iterator");
1312 return map->branched();
1317 path.setRoot(&map->rootBranch(), map->rootSize, Offset);
1319 path.setRoot(&map->rootLeaf(), map->rootSize, Offset);
1322 void pathFillFind(
KeyT x);
1323 void treeFind(
KeyT x);
1324 void treeAdvanceTo(
KeyT x);
1328 assert(valid() &&
"Cannot access invalid iterator");
1329 return branched() ? path.leaf<
Leaf>().start(path.leafOffset()) :
1335 assert(valid() &&
"Cannot access invalid iterator");
1336 return branched() ? path.leaf<
Leaf>().stop(path.leafOffset()) :
1342 assert(valid() &&
"Cannot access invalid iterator");
1343 return branched() ? path.leaf<
Leaf>().value(path.leafOffset()) :
1356 bool valid()
const {
return path.valid(); }
1368 const ValT &
value()
const {
return unsafeValue(); }
1373 assert(map == RHS.
map &&
"Cannot compare iterators from different maps");
1375 return !RHS.
valid();
1378 return &path.template leaf<Leaf>() == &RHS.
path.template leaf<Leaf>();
1389 path.fillLeft(map->height);
1394 setRoot(map->rootSize);
1399 assert(valid() &&
"Cannot increment end()");
1400 if (++path.leafOffset() == path.leafSize() && branched())
1401 path.moveRight(map->height);
1414 if (path.leafOffset() && (valid() || !branched()))
1415 --path.leafOffset();
1417 path.moveLeft(map->height);
1434 setRoot(map->rootLeaf().findFrom(0, map->rootSize, x));
1447 map->rootLeaf().findFrom(path.leafOffset(), map->rootSize, x);
1454 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1458 for (
unsigned i = map->height - path.height() - 1; i; --i) {
1459 unsigned p = NR.
get<
Branch>().safeFind(0, x);
1468 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1471 setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
1478 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1482 if (!Traits::stopLess(path.leaf<
Leaf>().
stop(path.leafSize() - 1), x)) {
1483 path.leafOffset() = path.leaf<
Leaf>().safeFind(path.leafOffset(), x);
1491 if (path.height()) {
1492 for (
unsigned l = path.height() - 1; l; --l) {
1493 if (!Traits::stopLess(path.node<
Branch>(l).
stop(path.offset(l)), x)) {
1495 path.offset(l + 1) =
1496 path.node<
Branch>(l + 1).safeFind(path.offset(l + 1), x);
1497 return pathFillFind(x);
1502 if (!Traits::stopLess(map->rootBranch().stop(path.offset(0)), x)) {
1503 path.offset(1) = path.node<
Branch>(1).safeFind(path.offset(1), x);
1504 return pathFillFind(x);
1509 setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
1518 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1525 void setNodeStop(
unsigned Level,
KeyT Stop);
1527 template <
typename NodeT>
bool overflow(
unsigned Level);
1528 void treeInsert(
KeyT a,
KeyT b, ValT y);
1529 void eraseNode(
unsigned Level);
1530 void treeErase(
bool UpdateRoot =
true);
1531 bool canCoalesceLeft(
KeyT Start, ValT x);
1532 bool canCoalesceRight(
KeyT Stop, ValT x);
1541 void setStart(
KeyT a);
1546 void setStop(
KeyT b);
1551 void setValue(ValT x);
1564 this->unsafeStop() = b;
1566 if (this->path.atLastEntry(this->path.height()))
1567 setNodeStop(this->path.height(), b);
1576 void insert(
KeyT a,
KeyT b, ValT y);
1582 const_iterator::operator++();
1593 const_iterator::operator--();
1610 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1613 using namespace IntervalMapImpl;
1614 Path &P = this->path;
1615 if (!this->branched()) {
1616 unsigned i = P.leafOffset();
1617 RootLeaf &Node = P.leaf<RootLeaf>();
1618 return i && Node.value(i-1) == Value &&
1619 Traits::adjacent(Node.stop(i-1), Start);
1622 if (
unsigned i = P.leafOffset()) {
1623 Leaf &Node = P.leaf<Leaf>();
1624 return Node.value(i-1) == Value && Traits::adjacent(Node.stop(i-1), Start);
1625 }
else if (NodeRef NR = P.getLeftSibling(P.height())) {
1626 unsigned i = NR.size() - 1;
1627 Leaf &Node = NR.get<Leaf>();
1628 return Node.value(i) == Value && Traits::adjacent(Node.stop(i), Start);
1638 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1639 bool IntervalMap<KeyT, ValT, N, Traits>::
1640 iterator::canCoalesceRight(
KeyT Stop, ValT Value) {
1641 using namespace IntervalMapImpl;
1642 Path &P = this->path;
1643 unsigned i = P.leafOffset() + 1;
1644 if (!this->branched()) {
1645 if (i >= P.leafSize())
1647 RootLeaf &Node = P.leaf<RootLeaf>();
1648 return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
1651 if (i < P.leafSize()) {
1652 Leaf &Node = P.leaf<Leaf>();
1653 return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
1654 }
else if (NodeRef NR = P.getRightSibling(P.height())) {
1655 Leaf &Node = NR.get<Leaf>();
1656 return Node.value(0) == Value && Traits::adjacent(Stop, Node.start(0));
1662 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1663 void IntervalMap<KeyT, ValT, N, Traits>::
1664 iterator::setNodeStop(
unsigned Level,
KeyT Stop) {
1668 IntervalMapImpl::Path &P = this->path;
1671 P.node<
Branch>(
Level).stop(P.offset(Level)) = Stop;
1672 if (!P.atLastEntry(Level))
1676 P.node<RootBranch>(
Level).stop(P.offset(Level)) = Stop;
1679 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1682 assert(Traits::stopLess(a, this->stop()) &&
"Cannot move start beyond stop");
1683 KeyT &CurStart = this->unsafeStart();
1684 if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->value())) {
1692 setStartUnchecked(a);
1695 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1698 assert(Traits::stopLess(this->start(), b) &&
"Cannot move stop beyond start");
1699 if (Traits::startLess(b, this->stop()) ||
1700 !canCoalesceRight(b, this->value())) {
1701 setStopUnchecked(b);
1705 KeyT a = this->start();
1707 setStartUnchecked(a);
1710 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1713 setValueUnchecked(x);
1714 if (canCoalesceRight(this->stop(), x)) {
1715 KeyT a = this->start();
1717 setStartUnchecked(a);
1719 if (canCoalesceLeft(this->start(), x)) {
1721 KeyT a = this->start();
1723 setStartUnchecked(a);
1733 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1736 assert(Level &&
"Cannot insert next to the root");
1737 bool SplitRoot =
false;
1743 if (IM.rootSize < RootBranch::Capacity) {
1744 IM.rootBranch().
insert(P.
offset(0), IM.rootSize, Node, Stop);
1753 P.
replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
1763 if (P.
size(Level) == Branch::Capacity) {
1765 assert(!SplitRoot &&
"Cannot overflow after splitting the root");
1766 SplitRoot = overflow<Branch>(
Level);
1772 setNodeStop(Level, Stop);
1778 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1781 if (this->branched())
1782 return treeInsert(a, b, y);
1790 if (Size <= RootLeaf::Capacity) {
1791 P.
setSize(0, IM.rootSize = Size);
1796 IdxPair Offset = IM.branchRoot(P.
leafOffset());
1797 P.
replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
1800 treeInsert(a, b, y);
1804 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1807 using namespace IntervalMapImpl;
1808 Path &P = this->path;
1818 unsigned SibOfs = Sib.size() - 1;
1819 if (SibLeaf.
value(SibOfs) == y &&
1820 Traits::adjacent(SibLeaf.
stop(SibOfs), a)) {
1828 if (Traits::stopLess(b, CurLeaf.
start(0)) &&
1829 (y != CurLeaf.
value(0) || !Traits::adjacent(b, CurLeaf.
start(0)))) {
1831 setNodeStop(P.
height(), SibLeaf.
stop(SibOfs) = b);
1836 a = SibLeaf.
start(SibOfs);
1842 this->map->rootBranchStart() = a;
1852 if (Size > Leaf::Capacity) {
1853 overflow<Leaf>(P.
height());
1856 assert(Size <= Leaf::Capacity &&
"overflow() didn't make room");
1864 setNodeStop(P.
height(), b);
1868 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1873 assert(P.
valid() &&
"Cannot erase end()");
1874 if (this->branched())
1881 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1890 IM.deleteNode(&Node);
1891 eraseNode(IM.height);
1893 if (UpdateRoot && IM.branched() && P.
valid() && P.
atBegin())
1894 IM.rootBranchStart() = P.
leaf<
Leaf>().start(0);
1900 unsigned NewSize = P.
leafSize() - 1;
1901 P.
setSize(IM.height, NewSize);
1904 setNodeStop(IM.height, Node.
stop(NewSize - 1));
1906 }
else if (UpdateRoot && P.
atBegin())
1907 IM.rootBranchStart() = P.
leaf<Leaf>().start(0);
1914 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1915 void IntervalMap<KeyT, ValT, N, Traits>::
1916 iterator::eraseNode(
unsigned Level) {
1917 assert(Level &&
"Cannot erase root node");
1918 IntervalMap &IM = *this->map;
1919 IntervalMapImpl::Path &P = this->path;
1922 IM.rootBranch().erase(P.offset(0), IM.rootSize);
1926 IM.switchRootToLeaf();
1933 if (P.size(Level) == 1) {
1935 IM.deleteNode(&Parent);
1939 Parent.erase(P.offset(Level), P.size(Level));
1940 unsigned NewSize = P.size(Level) - 1;
1941 P.setSize(Level, NewSize);
1943 if (P.offset(Level) == NewSize) {
1944 setNodeStop(Level, Parent.stop(NewSize - 1));
1952 P.offset(Level + 1) = 0;
1962 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1963 template <
typename NodeT>
1964 bool IntervalMap<KeyT, ValT, N, Traits>::
1965 iterator::overflow(
unsigned Level) {
1966 using namespace IntervalMapImpl;
1967 Path &P = this->path;
1968 unsigned CurSize[4];
1971 unsigned Elements = 0;
1972 unsigned Offset = P.offset(Level);
1975 NodeRef LeftSib = P.getLeftSibling(Level);
1977 Offset += Elements = CurSize[Nodes] = LeftSib.size();
1978 Node[Nodes++] = &LeftSib.get<NodeT>();
1982 Elements += CurSize[Nodes] = P.size(Level);
1983 Node[Nodes++] = &P.node<NodeT>(
Level);
1986 NodeRef RightSib = P.getRightSibling(Level);
1988 Elements += CurSize[Nodes] = RightSib.size();
1989 Node[Nodes++] = &RightSib.get<NodeT>();
1993 unsigned NewNode = 0;
1994 if (Elements + 1 > Nodes * NodeT::Capacity) {
1996 NewNode = Nodes == 1 ? 1 : Nodes - 1;
1997 CurSize[Nodes] = CurSize[NewNode];
1998 Node[Nodes] = Node[NewNode];
1999 CurSize[NewNode] = 0;
2000 Node[NewNode] = this->map->template newNode<NodeT>();
2005 unsigned NewSize[4];
2007 CurSize, NewSize, Offset,
true);
2015 bool SplitRoot =
false;
2018 KeyT Stop = Node[Pos]->
stop(NewSize[Pos]-1);
2019 if (NewNode && Pos == NewNode) {
2020 SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
2023 P.setSize(Level, NewSize[Pos]);
2024 setNodeStop(Level, Stop);
2026 if (Pos + 1 == Nodes)
2033 while(Pos != NewOffset.first) {
2037 P.offset(Level) = NewOffset.second;
2057 template <
typename MapA,
typename MapB>
2059 typedef typename MapA::KeyType KeyType;
2060 typedef typename MapA::KeyTraits Traits;
2061 typename MapA::const_iterator posA;
2062 typename MapB::const_iterator posB;
2071 if (Traits::stopLess(posA.stop(), posB.start())) {
2073 posA.advanceTo(posB.start());
2074 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2076 }
else if (Traits::stopLess(posB.stop(), posA.start())) {
2078 posB.advanceTo(posA.start());
2079 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2087 posA.advanceTo(posB.start());
2088 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2091 posB.advanceTo(posA.start());
2092 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2100 : posA(b.empty() ? a.
end() : a.find(b.start())),
2101 posB(posA.valid() ? b.find(posA.start()) : b.
end()) {
advance(); }
2105 return posA.valid() && posB.valid();
2109 const typename MapA::const_iterator &
a()
const {
return posA; }
2112 const typename MapB::const_iterator &
b()
const {
return posB; }
2116 KeyType ak = a().start();
2117 KeyType bk = b().start();
2118 return Traits::startLess(ak, bk) ? bk : ak;
2123 KeyType ak = a().stop();
2124 KeyType bk = b().stop();
2125 return Traits::startLess(ak, bk) ? ak : bk;
2143 if (Traits::startLess(posB.stop(), posA.stop()))
2156 if (Traits::stopLess(posA.stop(), x))
2158 if (Traits::stopLess(posB.stop(), x))
KeyT & unsafeStop() const
unsafeStop - Writable access to stop() for iterator.
void setValueUnchecked(ValT x)
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 transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
void copy(const NodeBase< T1, T2, M > &Other, unsigned i, unsigned j, unsigned Count)
NodeRef getLeftSibling(unsigned Level) const
const_iterator begin() const
void adjustSiblingSizes(NodeT *Node[], unsigned Nodes, unsigned CurSize[], const unsigned NewSize[])
unsigned safeFind(unsigned i, KeyT x) const
void legalizeForInsert(unsigned Level)
unsigned findFrom(unsigned i, unsigned Size, KeyT x) 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.
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)
const_iterator find(KeyT x) const
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.
NodeRef()
NodeRef - Create a null ref.
int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add)
unsigned & offset(unsigned Level)
void setMap(const IntervalMap &m)
const_iterator end() const
void fillLeft(unsigned Height)
iterator()
iterator - Create null iterator.
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
const KeyT & stop(unsigned i) const
void setRoot(unsigned Offset)
static error_code advance(T &it, size_t Val)
static bool stopLess(const T &b, const T &x)
const_iterator & operator++()
preincrement - move to the next interval.
NodeRef safeLookup(KeyT x) const
const KeyT & start(unsigned i) const
ValT & unsafeValue() const
unsafeValue - Writable access to value() for iterator.
bool valid() const
valid - Return true if iterator is at an overlap.
void treeAdvanceTo(KeyT x)
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).
const KeyT & stop(unsigned i) 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.
IntervalMap(Allocator &a)
NodeRef & subtree(unsigned i) const
KeyType start() const
start - Beginning of the overlapping interval.
void erase(unsigned i, unsigned j, unsigned Size)
void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
void setStartUnchecked(KeyT a)
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.
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity, const unsigned *CurSize, unsigned NewSize[], unsigned Position, bool Grow)
void replaceRoot(void *Root, unsigned Size, IdxPair Offsets)
unsigned size(unsigned Level) const
void moveRight(unsigned i, unsigned j, unsigned Count)
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.
static bool startLess(const T &x, const T &a)
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
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).
void skipB()
skipB - Move to the next overlap that doesn't involve b().
void insert(KeyT a, KeyT b, ValT y)
unsigned safeFind(unsigned i, KeyT x) const
PointerTy getPointer() const
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)
NodeT & node(unsigned Level) const
void goToEnd()
goToEnd - Move beyond the last interval in map.
RecyclingAllocator< BumpPtrAllocator, char, AllocBytes, CacheLineBytes > Allocator
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)
void reset(unsigned Level)
void erase(unsigned i, unsigned Size)
void pathFillFind(KeyT x)
const KeyT & stop() const
stop - Return the end of the current interval.
void push(NodeRef Node, unsigned Offset)
void moveRight(unsigned Level)
void insert(KeyT a, KeyT b, ValT y)
insert - Insert mapping [a;b] -> y before the current position.
#define LLVM_EXPLICIT
Expands to explicit on compilers which support explicit conversion operators. Otherwise expands to no...
IntervalMapImpl::Path path
unsigned leafSize() const
unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y)
Sizer::Allocator Allocator
std::pair< unsigned, unsigned > IdxPair
NodeT & get() const
get - Dereference as a NodeT reference.
void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop)
const_iterator operator--(int)
postdecrement - Dont do that!
bool atBegin() const
atBegin - Return true if path is at begin().
unsigned offset(unsigned Level) const
ValT safeLookup(KeyT x, ValT NotFound) const
void setStopUnchecked(KeyT b)
void setRoot(void *Node, unsigned Size, unsigned Offset)
void setSize(unsigned n)
setSize - Update the node size.
static bool adjacent(const T &a, const T &b)
LLVM Value Representation.
void shift(unsigned i, unsigned Size)
NodeRef & subtree(unsigned i)
bool operator==(const const_iterator &RHS) const
const ValT & operator*() const
const ValT & value(unsigned i) const
bool operator==(uint64_t V1, const APInt &V2)
const ValT & value() const
value - Return the mapped value at the current interval.
void setSize(unsigned Level, unsigned Size)
NodeRef(NodeT *p, unsigned n)
NodeRef - Create a reference to the node p with n elements.
bool atLastEntry(unsigned Level) const