99 #ifndef LLVM_ADT_INTERVALMAP_H
100 #define LLVM_ADT_INTERVALMAP_H
132 template <
typename T>
155 template <
typename T>
177 namespace IntervalMapImpl {
180 template <
typename,
typename,
unsigned,
typename>
class LeafNode;
181 template <
typename,
typename,
unsigned,
typename>
class BranchNode;
183 typedef std::pair<unsigned,unsigned>
IdxPair;
213 template <
typename T1,
typename T2,
unsigned N>
226 template <
unsigned M>
228 unsigned j,
unsigned Count) {
229 assert(i + Count <= M &&
"Invalid source range");
230 assert(j + Count <=
N &&
"Invalid dest range");
231 for (
unsigned e = i + Count; i != e; ++i, ++j) {
241 void moveLeft(
unsigned i,
unsigned j,
unsigned Count) {
242 assert(j <= i &&
"Use moveRight shift elements right");
243 copy(*
this, i, j, Count);
250 void moveRight(
unsigned i,
unsigned j,
unsigned Count) {
251 assert(i <= j &&
"Use moveLeft shift elements left");
252 assert(j + Count <=
N &&
"Invalid range");
263 void erase(
unsigned i,
unsigned j,
unsigned Size) {
270 void erase(
unsigned i,
unsigned Size) {
277 void shift(
unsigned i,
unsigned Size) {
288 Sib.
copy(*
this, 0, SSize, Count);
289 erase(0, Count, Size);
300 Sib.
copy(*
this, Size-Count, 0, Count);
330 template <
typename NodeT>
332 unsigned CurSize[],
const unsigned NewSize[]) {
334 for (
int n = Nodes - 1; n; --n) {
335 if (CurSize[n] == NewSize[n])
337 for (
int m = n - 1; m != -1; --m) {
338 int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
339 NewSize[n] - CurSize[n]);
343 if (CurSize[n] >= NewSize[n])
352 for (
unsigned n = 0; n != Nodes - 1; ++n) {
353 if (CurSize[n] == NewSize[n])
355 for (
unsigned m = n + 1; m != Nodes; ++m) {
356 int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
357 CurSize[n] - NewSize[n]);
361 if (CurSize[n] >= NewSize[n])
367 for (
unsigned n = 0; n != Nodes; n++)
368 assert(CurSize[n] == NewSize[n] &&
"Insufficient element shuffle");
406 const unsigned *CurSize,
unsigned NewSize[],
407 unsigned Position,
bool Grow);
430 template <
typename KeyT,
typename ValT>
439 static_cast<unsigned>(2*
sizeof(KeyT)+
sizeof(
ValT)),
453 static_cast<unsigned>(
sizeof(KeyT) +
sizeof(
void*))
488 struct CacheAlignedPointerTraits {
489 static inline void *getAsVoidPointer(
void *
P) {
return P; }
490 static inline void *getFromVoidPointer(
void *P) {
return P; }
500 explicit operator bool()
const {
return pip.getOpaqueValue(); }
503 template <
typename NodeT>
504 NodeRef(NodeT *p,
unsigned n) : pip(p, n - 1) {
505 assert(n <= NodeT::Capacity &&
"Size too big for node");
509 unsigned size()
const {
return pip.getInt() + 1; }
512 void setSize(
unsigned n) { pip.setInt(n - 1); }
518 return reinterpret_cast<NodeRef*
>(pip.getPointer())[i];
522 template <
typename NodeT>
524 return *
reinterpret_cast<NodeT*
>(pip.getPointer());
530 assert(pip.getPointer() != RHS.pip.
getPointer() &&
"Inconsistent NodeRefs");
559 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
560 class LeafNode :
public NodeBase<std::pair<KeyT, KeyT>, ValT, N> {
562 const KeyT &
start(
unsigned i)
const {
return this->first[i].first; }
563 const KeyT &
stop(
unsigned i)
const {
return this->first[i].second; }
564 const ValT &
value(
unsigned i)
const {
return this->second[i]; }
566 KeyT &
start(
unsigned i) {
return this->first[i].first; }
567 KeyT &
stop(
unsigned i) {
return this->first[i].second; }
568 ValT &
value(
unsigned i) {
return this->second[i]; }
576 unsigned findFrom(
unsigned i,
unsigned Size, KeyT x)
const {
577 assert(i <= Size && Size <=
N &&
"Bad indices");
578 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
579 "Index is past the needed point");
580 while (i != Size && Traits::stopLess(stop(i), x)) ++i;
592 assert(i <
N &&
"Bad index");
593 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
594 "Index is past the needed point");
595 while (Traits::stopLess(stop(i), x)) ++i;
596 assert(i <
N &&
"Unsafe intervals");
606 unsigned i = safeFind(0, x);
607 return Traits::startLess(x, start(i)) ? NotFound : value(i);
610 unsigned insertFrom(
unsigned &Pos,
unsigned Size, KeyT a, KeyT b, ValT y);
622 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
624 insertFrom(
unsigned &Pos,
unsigned Size, KeyT a, KeyT b, ValT y) {
626 assert(i <= Size && Size <=
N &&
"Invalid index");
627 assert(!Traits::stopLess(b, a) &&
"Invalid interval");
630 assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
631 assert((i == Size || !Traits::stopLess(stop(i), a)));
632 assert((i == Size || Traits::stopLess(b, start(i))) &&
"Overlapping insert");
635 if (i && value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
638 if (i != Size && value(i) == y && Traits::adjacent(b, start(i))) {
639 stop(i - 1) = stop(i);
640 this->erase(i, Size);
660 if (value(i) == y && Traits::adjacent(b, start(i))) {
670 this->shift(i, Size);
697 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
700 const KeyT &
stop(
unsigned i)
const {
return this->second[i]; }
703 KeyT &
stop(
unsigned i) {
return this->second[i]; }
712 unsigned findFrom(
unsigned i,
unsigned Size, KeyT x)
const {
713 assert(i <= Size && Size <=
N &&
"Bad indices");
714 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
715 "Index to findFrom is past the needed point");
716 while (i != Size && Traits::stopLess(stop(i), x)) ++i;
727 assert(i <
N &&
"Bad index");
728 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
729 "Index is past the needed point");
730 while (Traits::stopLess(stop(i), x)) ++i;
731 assert(i <
N &&
"Unsafe intervals");
739 return subtree(safeFind(0, x));
748 assert(Size <
N &&
"branch node overflow");
749 assert(i <= Size &&
"Bad insert position");
750 this->shift(i, Size);
776 Entry(
void *Node,
unsigned Size,
unsigned Offset)
777 : node(Node),
size(Size), offset(Offset) {}
779 Entry(
NodeRef Node,
unsigned Offset)
782 NodeRef &subtree(
unsigned i)
const {
783 return reinterpret_cast<NodeRef*
>(node)[i];
792 template <
typename NodeT> NodeT &
node(
unsigned Level)
const {
793 return *
reinterpret_cast<NodeT*
>(path[
Level].node);
800 template <
typename NodeT> NodeT &
leaf()
const {
801 return *
reinterpret_cast<NodeT*
>(path.back().node);
803 unsigned leafSize()
const {
return path.back().size; }
809 return !path.empty() && path.front().offset < path.front().size;
814 unsigned height()
const {
return path.size() - 1; }
826 path[
Level] = Entry(subtree(Level - 1), offset(Level));
833 path.push_back(Entry(Node, Offset));
846 path[
Level].size = Size;
848 subtree(Level - 1).setSize(Size);
855 void setRoot(
void *Node,
unsigned Size,
unsigned Offset) {
857 path.push_back(Entry(Node, Size, Offset));
875 void moveLeft(
unsigned Level);
880 while (height() < Height)
881 push(subtree(height()), 0);
892 void moveRight(
unsigned Level);
896 for (
unsigned i = 0, e = path.size(); i != e; ++i)
897 if (path[i].offset != 0)
906 return path[
Level].offset == path[
Level].size - 1;
918 ++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>();
998 RootBranchData &rootBranchData()
const {
999 assert(branched() &&
"Cannot access branch data in non-branched root");
1000 return dataAs<RootBranchData>();
1002 RootBranchData &rootBranchData() {
1003 assert(branched() &&
"Cannot access branch data in non-branched root");
1004 return dataAs<RootBranchData>();
1006 const RootBranch &rootBranch()
const {
return rootBranchData().node; }
1007 RootBranch &rootBranch() {
return rootBranchData().node; }
1008 KeyT rootBranchStart()
const {
return rootBranchData().start; }
1009 KeyT &rootBranchStart() {
return rootBranchData().start; }
1011 template <
typename NodeT> NodeT *newNode() {
1012 return new(allocator.template Allocate<NodeT>()) NodeT();
1015 template <
typename NodeT>
void deleteNode(NodeT *
P) {
1017 allocator.Deallocate(P);
1020 IdxPair branchRoot(
unsigned Position);
1021 IdxPair splitRoot(
unsigned Position);
1023 void switchRootToBranch() {
1024 rootLeaf().~RootLeaf();
1026 new (&rootBranchData()) RootBranchData();
1029 void switchRootToLeaf() {
1030 rootBranchData().~RootBranchData();
1032 new(&rootLeaf()) RootLeaf();
1035 bool branched()
const {
return height > 0; }
1037 ValT treeSafeLookup(KeyT x, ValT NotFound)
const;
1038 void visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
1040 void deleteNode(IntervalMapImpl::NodeRef Node,
unsigned Level);
1044 assert((uintptr_t(data.buffer) & (alignOf<RootLeaf>() - 1)) == 0 &&
1045 "Insufficient alignment");
1051 rootLeaf().~RootLeaf();
1056 return rootSize == 0;
1061 assert(!empty() &&
"Empty IntervalMap has no start");
1062 return !branched() ? rootLeaf().start(0) : rootBranchStart();
1067 assert(!empty() &&
"Empty IntervalMap has no stop");
1068 return !branched() ? rootLeaf().stop(rootSize - 1) :
1069 rootBranch().stop(rootSize - 1);
1073 ValT
lookup(KeyT x, ValT NotFound = ValT())
const {
1074 if (empty() || Traits::startLess(x, start()) || Traits::stopLess(stop(), x))
1076 return branched() ? treeSafeLookup(x, NotFound) :
1077 rootLeaf().safeLookup(x, NotFound);
1084 if (branched() || rootSize == RootLeaf::Capacity)
1085 return find(a).insert(a, b, y);
1088 unsigned p = rootLeaf().findFrom(0, rootSize, a);
1089 rootSize = rootLeaf().insertFrom(p, rootSize, a, b, y);
1095 class const_iterator;
1097 friend class const_iterator;
1098 friend class iterator;
1101 const_iterator
I(*
this);
1113 const_iterator
I(*
this);
1126 const_iterator
find(KeyT x)
const {
1127 const_iterator
I(*
this);
1141 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1142 ValT IntervalMap<KeyT, ValT, N, Traits>::
1143 treeSafeLookup(KeyT x, ValT NotFound)
const {
1144 assert(branched() &&
"treeLookup assumes a branched root");
1146 IntervalMapImpl::NodeRef NR = rootBranch().safeLookup(x);
1147 for (
unsigned h = height-1; h; --h)
1148 NR = NR.get<
Branch>().safeLookup(x);
1149 return NR.get<Leaf>().safeLookup(x, NotFound);
1155 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1157 branchRoot(
unsigned Position) {
1158 using namespace IntervalMapImpl;
1160 const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
1163 unsigned size[Nodes];
1164 IdxPair NewOffset(0, Position);
1170 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity,
nullptr,
size,
1175 NodeRef node[Nodes];
1176 for (
unsigned n = 0; n != Nodes; ++n) {
1177 Leaf *L = newNode<Leaf>();
1178 L->copy(rootLeaf(), pos, 0,
size[n]);
1179 node[n] = NodeRef(L,
size[n]);
1184 switchRootToBranch();
1185 for (
unsigned n = 0; n != Nodes; ++n) {
1186 rootBranch().stop(n) = node[n].template get<Leaf>().stop(
size[n]-1);
1187 rootBranch().subtree(n) = node[n];
1189 rootBranchStart() = node[0].template get<Leaf>().start(0);
1196 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1198 splitRoot(
unsigned Position) {
1199 using namespace IntervalMapImpl;
1201 const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
1204 unsigned Size[Nodes];
1205 IdxPair NewOffset(0, Position);
1211 NewOffset =
distribute(Nodes, rootSize, Leaf::Capacity,
nullptr, Size,
1216 NodeRef Node[Nodes];
1217 for (
unsigned n = 0; n != Nodes; ++n) {
1218 Branch *B = newNode<Branch>();
1219 B->copy(rootBranch(), Pos, 0, Size[n]);
1220 Node[n] = NodeRef(B, Size[n]);
1224 for (
unsigned n = 0; n != Nodes; ++n) {
1225 rootBranch().stop(n) = Node[n].template get<Branch>().stop(Size[n]-1);
1226 rootBranch().subtree(n) = Node[n];
1234 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1235 void IntervalMap<KeyT, ValT, N, Traits>::
1236 visitNodes(
void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
unsigned Height)) {
1239 SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
1242 for (
unsigned i = 0; i != rootSize; ++i)
1243 Refs.push_back(rootBranch().subtree(i));
1246 for (
unsigned h = height - 1; h; --h) {
1247 for (
unsigned i = 0, e = Refs.size(); i != e; ++i) {
1248 for (
unsigned j = 0, s = Refs[i].
size(); j != s; ++j)
1249 NextRefs.push_back(Refs[i].subtree(j));
1250 (this->*f)(Refs[i], h);
1253 Refs.swap(NextRefs);
1257 for (
unsigned i = 0, e = Refs.size(); i != e; ++i)
1258 (this->*f)(Refs[i], 0);
1261 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1262 void IntervalMap<KeyT, ValT, N, Traits>::
1263 deleteNode(IntervalMapImpl::NodeRef Node,
unsigned Level) {
1265 deleteNode(&Node.get<
Branch>());
1267 deleteNode(&Node.get<Leaf>());
1270 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1274 visitNodes(&IntervalMap::deleteNode);
1284 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1286 public std::iterator<std::bidirectional_iterator_tag, ValT> {
1301 assert(map &&
"Invalid iterator");
1302 return map->branched();
1307 path.setRoot(&map->rootBranch(), map->rootSize, Offset);
1309 path.setRoot(&map->rootLeaf(), map->rootSize, Offset);
1312 void pathFillFind(KeyT x);
1313 void treeFind(KeyT x);
1314 void treeAdvanceTo(KeyT x);
1318 assert(valid() &&
"Cannot access invalid iterator");
1319 return branched() ? path.leaf<
Leaf>().start(path.leafOffset()) :
1325 assert(valid() &&
"Cannot access invalid iterator");
1326 return branched() ? path.leaf<
Leaf>().stop(path.leafOffset()) :
1332 assert(valid() &&
"Cannot access invalid iterator");
1333 return branched() ? path.leaf<
Leaf>().value(path.leafOffset()) :
1346 bool valid()
const {
return path.valid(); }
1352 const KeyT &
start()
const {
return unsafeStart(); }
1355 const KeyT &
stop()
const {
return unsafeStop(); }
1358 const ValT &
value()
const {
return unsafeValue(); }
1363 assert(map == RHS.
map &&
"Cannot compare iterators from different maps");
1365 return !RHS.
valid();
1368 return &path.template leaf<Leaf>() == &RHS.
path.template leaf<Leaf>();
1379 path.fillLeft(map->height);
1384 setRoot(map->rootSize);
1389 assert(valid() &&
"Cannot increment end()");
1390 if (++path.leafOffset() == path.leafSize() && branched())
1391 path.moveRight(map->height);
1404 if (path.leafOffset() && (valid() || !branched()))
1405 --path.leafOffset();
1407 path.moveLeft(map->height);
1424 setRoot(map->rootLeaf().findFrom(0, map->rootSize, x));
1437 map->rootLeaf().findFrom(path.leafOffset(), map->rootSize, x);
1444 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1448 for (
unsigned i = map->height - path.height() - 1; i; --i) {
1449 unsigned p = NR.
get<
Branch>().safeFind(0, x);
1458 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1461 setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
1468 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1472 if (!Traits::stopLess(path.leaf<
Leaf>().
stop(path.leafSize() - 1), x)) {
1473 path.leafOffset() = path.leaf<
Leaf>().safeFind(path.leafOffset(), x);
1481 if (path.height()) {
1482 for (
unsigned l = path.height() - 1; l; --l) {
1483 if (!Traits::stopLess(path.node<
Branch>(l).
stop(path.offset(l)), x)) {
1485 path.offset(l + 1) =
1486 path.node<
Branch>(l + 1).safeFind(path.offset(l + 1), x);
1487 return pathFillFind(x);
1492 if (!Traits::stopLess(map->rootBranch().stop(path.offset(0)), x)) {
1493 path.offset(1) = path.node<
Branch>(1).safeFind(path.offset(1), x);
1494 return pathFillFind(x);
1499 setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
1508 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1515 void setNodeStop(
unsigned Level, KeyT Stop);
1517 template <
typename NodeT>
bool overflow(
unsigned Level);
1518 void treeInsert(KeyT a, KeyT b, ValT y);
1519 void eraseNode(
unsigned Level);
1520 void treeErase(
bool UpdateRoot =
true);
1521 bool canCoalesceLeft(KeyT Start, ValT x);
1522 bool canCoalesceRight(KeyT Stop, ValT x);
1531 void setStart(KeyT a);
1536 void setStop(KeyT b);
1541 void setValue(ValT x);
1554 this->unsafeStop() = b;
1556 if (this->path.atLastEntry(this->path.height()))
1557 setNodeStop(this->path.height(), b);
1566 void insert(KeyT a, KeyT b, ValT y);
1572 const_iterator::operator++();
1583 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::stopLess(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::stopLess(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);
1743 P.
replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
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());
1787 P.
replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
1790 treeInsert(a, b, y);
1794 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1797 using namespace IntervalMapImpl;
1798 Path &P = this->path;
1808 unsigned SibOfs = Sib.size() - 1;
1809 if (SibLeaf.
value(SibOfs) == y &&
1810 Traits::adjacent(SibLeaf.
stop(SibOfs), a)) {
1818 if (Traits::stopLess(b, CurLeaf.
start(0)) &&
1819 (y != CurLeaf.
value(0) || !Traits::adjacent(b, CurLeaf.
start(0)))) {
1821 setNodeStop(P.
height(), SibLeaf.
stop(SibOfs) = b);
1826 a = SibLeaf.
start(SibOfs);
1832 this->map->rootBranchStart() = a;
1842 if (Size > Leaf::Capacity) {
1843 overflow<Leaf>(P.
height());
1846 assert(Size <= Leaf::Capacity &&
"overflow() didn't make room");
1854 setNodeStop(P.
height(), b);
1858 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1863 assert(P.
valid() &&
"Cannot erase end()");
1864 if (this->branched())
1871 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1880 IM.deleteNode(&Node);
1881 eraseNode(IM.height);
1883 if (UpdateRoot && IM.branched() && P.
valid() && P.
atBegin())
1884 IM.rootBranchStart() = P.
leaf<
Leaf>().start(0);
1890 unsigned NewSize = P.
leafSize() - 1;
1891 P.
setSize(IM.height, NewSize);
1894 setNodeStop(IM.height, Node.
stop(NewSize - 1));
1896 }
else if (UpdateRoot && P.
atBegin())
1897 IM.rootBranchStart() = P.
leaf<Leaf>().start(0);
1904 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1905 void IntervalMap<KeyT, ValT, N, Traits>::
1906 iterator::eraseNode(
unsigned Level) {
1907 assert(Level &&
"Cannot erase root node");
1908 IntervalMap &IM = *this->map;
1909 IntervalMapImpl::Path &P = this->path;
1912 IM.rootBranch().erase(P.offset(0), IM.rootSize);
1916 IM.switchRootToLeaf();
1923 if (P.size(Level) == 1) {
1925 IM.deleteNode(&Parent);
1929 Parent.erase(P.offset(Level), P.size(Level));
1930 unsigned NewSize = P.size(Level) - 1;
1931 P.setSize(Level, NewSize);
1933 if (P.offset(Level) == NewSize) {
1934 setNodeStop(Level, Parent.stop(NewSize - 1));
1942 P.offset(Level + 1) = 0;
1952 template <
typename KeyT,
typename ValT,
unsigned N,
typename Traits>
1953 template <
typename NodeT>
1954 bool IntervalMap<KeyT, ValT, N, Traits>::
1955 iterator::overflow(
unsigned Level) {
1956 using namespace IntervalMapImpl;
1957 Path &P = this->path;
1958 unsigned CurSize[4];
1961 unsigned Elements = 0;
1962 unsigned Offset = P.offset(Level);
1965 NodeRef LeftSib = P.getLeftSibling(Level);
1967 Offset += Elements = CurSize[Nodes] = LeftSib.size();
1968 Node[Nodes++] = &LeftSib.get<NodeT>();
1972 Elements += CurSize[Nodes] = P.size(Level);
1973 Node[Nodes++] = &P.node<NodeT>(
Level);
1976 NodeRef RightSib = P.getRightSibling(Level);
1978 Elements += CurSize[Nodes] = RightSib.size();
1979 Node[Nodes++] = &RightSib.get<NodeT>();
1983 unsigned NewNode = 0;
1984 if (Elements + 1 > Nodes * NodeT::Capacity) {
1986 NewNode = Nodes == 1 ? 1 : Nodes - 1;
1987 CurSize[Nodes] = CurSize[NewNode];
1988 Node[Nodes] = Node[NewNode];
1989 CurSize[NewNode] = 0;
1990 Node[NewNode] = this->map->template newNode<NodeT>();
1995 unsigned NewSize[4];
1997 CurSize, NewSize, Offset,
true);
2005 bool SplitRoot =
false;
2008 KeyT Stop = Node[Pos]->
stop(NewSize[Pos]-1);
2009 if (NewNode && Pos == NewNode) {
2010 SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
2013 P.setSize(Level, NewSize[Pos]);
2014 setNodeStop(Level, Stop);
2016 if (Pos + 1 == Nodes)
2023 while(Pos != NewOffset.first) {
2027 P.offset(Level) = NewOffset.second;
2047 template <
typename MapA,
typename MapB>
2049 typedef typename MapA::KeyType KeyType;
2050 typedef typename MapA::KeyTraits Traits;
2051 typename MapA::const_iterator posA;
2052 typename MapB::const_iterator posB;
2061 if (Traits::stopLess(posA.stop(), posB.start())) {
2063 posA.advanceTo(posB.start());
2064 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2066 }
else if (Traits::stopLess(posB.stop(), posA.start())) {
2068 posB.advanceTo(posA.start());
2069 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2077 posA.advanceTo(posB.start());
2078 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2081 posB.advanceTo(posA.start());
2082 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2090 : posA(b.empty() ? a.
end() : a.find(b.start())),
2091 posB(posA.valid() ? b.find(posA.start()) : b.
end()) {
advance(); }
2095 return posA.valid() && posB.valid();
2099 const typename MapA::const_iterator &
a()
const {
return posA; }
2102 const typename MapB::const_iterator &
b()
const {
return posB; }
2106 KeyType ak = a().start();
2107 KeyType bk = b().start();
2108 return Traits::startLess(ak, bk) ? bk : ak;
2113 KeyType ak = a().stop();
2114 KeyType bk = b().stop();
2115 return Traits::startLess(ak, bk) ? ak : bk;
2133 if (Traits::startLess(posB.stop(), posA.stop()))
2146 if (Traits::stopLess(posA.stop(), x))
2148 if (Traits::stopLess(posB.stop(), x))
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.
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find an interval that is known to exist.
void legalizeForInsert(unsigned Level)
legalizeForInsert - Prepare the path for an insertion at Level.
IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two IntervalMaps.
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first subtree after i that may contain x.
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)
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.
NodeRef()
NodeRef - Create a null ref.
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.
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.
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
const KeyT & stop(unsigned i) const
void setRoot(unsigned Offset)
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.
NodeRef safeLookup(KeyT x) const
safeLookup - Get the subtree containing x, Assuming that x is in range.
const KeyT & start(unsigned i) const
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().
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
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).
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
subtree - Access the i'th subtree reference in a branch node.
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...
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.
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first interval after i that may contain x.
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().
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.
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().
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.
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find a subtree that is known to exist.
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)
moveLeft - Move elements to the left.
NodeT & node(unsigned Level) const
void goToEnd()
goToEnd - Move beyond the last interval in map.
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...
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.
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
std::pair< unsigned, unsigned > IdxPair
NodeT & get() const
get - Dereference as a NodeT reference.
void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop)
insert - Insert a new (subtree, stop) pair.
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
safeLookup - Lookup mapped value for a safe key.
void setStopUnchecked(KeyT b)
setStopUnchecked - Move the end of the current interval without checking for coalescing or overlaps...
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.
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)
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.