File indexing completed on 2026-05-10 08:43:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 #ifndef LLVM_ADT_INTERVALMAP_H
0105 #define LLVM_ADT_INTERVALMAP_H
0106
0107 #include "llvm/ADT/PointerIntPair.h"
0108 #include "llvm/ADT/SmallVector.h"
0109 #include "llvm/Support/Allocator.h"
0110 #include "llvm/Support/RecyclingAllocator.h"
0111 #include <algorithm>
0112 #include <cassert>
0113 #include <iterator>
0114 #include <new>
0115 #include <utility>
0116
0117 namespace llvm {
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 template <typename T>
0140 struct IntervalMapInfo {
0141
0142
0143 static inline bool startLess(const T &x, const T &a) {
0144 return x < a;
0145 }
0146
0147
0148
0149 static inline bool stopLess(const T &b, const T &x) {
0150 return b < x;
0151 }
0152
0153
0154
0155 static inline bool adjacent(const T &a, const T &b) {
0156 return a+1 == b;
0157 }
0158
0159
0160
0161 static inline bool nonEmpty(const T &a, const T &b) {
0162 return a <= b;
0163 }
0164 };
0165
0166 template <typename T>
0167 struct IntervalMapHalfOpenInfo {
0168
0169 static inline bool startLess(const T &x, const T &a) {
0170 return x < a;
0171 }
0172
0173
0174 static inline bool stopLess(const T &b, const T &x) {
0175 return b <= x;
0176 }
0177
0178
0179 static inline bool adjacent(const T &a, const T &b) {
0180 return a == b;
0181 }
0182
0183
0184 static inline bool nonEmpty(const T &a, const T &b) {
0185 return a < b;
0186 }
0187 };
0188
0189
0190
0191 namespace IntervalMapImpl {
0192
0193 using IdxPair = std::pair<unsigned,unsigned>;
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 template <typename T1, typename T2, unsigned N>
0223 class NodeBase {
0224 public:
0225 static constexpr unsigned Capacity = N;
0226
0227 T1 first[N];
0228 T2 second[N];
0229
0230
0231
0232
0233
0234
0235 template <unsigned M>
0236 void copy(const NodeBase<T1, T2, M> &Other, unsigned i,
0237 unsigned j, unsigned Count) {
0238 assert(i + Count <= M && "Invalid source range");
0239 assert(j + Count <= N && "Invalid dest range");
0240 for (unsigned e = i + Count; i != e; ++i, ++j) {
0241 first[j] = Other.first[i];
0242 second[j] = Other.second[i];
0243 }
0244 }
0245
0246
0247
0248
0249
0250 void moveLeft(unsigned i, unsigned j, unsigned Count) {
0251 assert(j <= i && "Use moveRight shift elements right");
0252 copy(*this, i, j, Count);
0253 }
0254
0255
0256
0257
0258
0259 void moveRight(unsigned i, unsigned j, unsigned Count) {
0260 assert(i <= j && "Use moveLeft shift elements left");
0261 assert(j + Count <= N && "Invalid range");
0262 while (Count--) {
0263 first[j + Count] = first[i + Count];
0264 second[j + Count] = second[i + Count];
0265 }
0266 }
0267
0268
0269
0270
0271
0272 void erase(unsigned i, unsigned j, unsigned Size) {
0273 moveLeft(j, i, Size - j);
0274 }
0275
0276
0277
0278
0279 void erase(unsigned i, unsigned Size) {
0280 erase(i, i+1, Size);
0281 }
0282
0283
0284
0285
0286 void shift(unsigned i, unsigned Size) {
0287 moveRight(i, i + 1, Size - i);
0288 }
0289
0290
0291
0292
0293
0294
0295 void transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize,
0296 unsigned Count) {
0297 Sib.copy(*this, 0, SSize, Count);
0298 erase(0, Count, Size);
0299 }
0300
0301
0302
0303
0304
0305
0306 void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize,
0307 unsigned Count) {
0308 Sib.moveRight(0, Count, SSize);
0309 Sib.copy(*this, Size-Count, 0, Count);
0310 }
0311
0312
0313
0314
0315
0316
0317
0318
0319 int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add) {
0320 if (Add > 0) {
0321
0322 unsigned Count = std::min(std::min(unsigned(Add), SSize), N - Size);
0323 Sib.transferToRightSib(SSize, *this, Size, Count);
0324 return Count;
0325 } else {
0326
0327 unsigned Count = std::min(std::min(unsigned(-Add), Size), N - SSize);
0328 transferToLeftSib(Size, Sib, SSize, Count);
0329 return -Count;
0330 }
0331 }
0332 };
0333
0334
0335
0336
0337
0338
0339 template <typename NodeT>
0340 void adjustSiblingSizes(NodeT *Node[], unsigned Nodes,
0341 unsigned CurSize[], const unsigned NewSize[]) {
0342
0343 for (int n = Nodes - 1; n; --n) {
0344 if (CurSize[n] == NewSize[n])
0345 continue;
0346 for (int m = n - 1; m != -1; --m) {
0347 int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
0348 NewSize[n] - CurSize[n]);
0349 CurSize[m] -= d;
0350 CurSize[n] += d;
0351
0352 if (CurSize[n] >= NewSize[n])
0353 break;
0354 }
0355 }
0356
0357 if (Nodes == 0)
0358 return;
0359
0360
0361 for (unsigned n = 0; n != Nodes - 1; ++n) {
0362 if (CurSize[n] == NewSize[n])
0363 continue;
0364 for (unsigned m = n + 1; m != Nodes; ++m) {
0365 int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
0366 CurSize[n] - NewSize[n]);
0367 CurSize[m] += d;
0368 CurSize[n] -= d;
0369
0370 if (CurSize[n] >= NewSize[n])
0371 break;
0372 }
0373 }
0374
0375 #ifndef NDEBUG
0376 for (unsigned n = 0; n != Nodes; n++)
0377 assert(CurSize[n] == NewSize[n] && "Insufficient element shuffle");
0378 #endif
0379 }
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
0415 const unsigned *CurSize, unsigned NewSize[],
0416 unsigned Position, bool Grow);
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430 enum {
0431
0432
0433 Log2CacheLine = 6,
0434 CacheLineBytes = 1 << Log2CacheLine,
0435 DesiredNodeBytes = 3 * CacheLineBytes
0436 };
0437
0438 template <typename KeyT, typename ValT>
0439 struct NodeSizer {
0440 enum {
0441
0442
0443
0444
0445
0446 DesiredLeafSize = DesiredNodeBytes /
0447 static_cast<unsigned>(2*sizeof(KeyT)+sizeof(ValT)),
0448 MinLeafSize = 3,
0449 LeafSize = DesiredLeafSize > MinLeafSize ? DesiredLeafSize : MinLeafSize
0450 };
0451
0452 using LeafBase = NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize>;
0453
0454 enum {
0455
0456
0457 AllocBytes = (sizeof(LeafBase) + CacheLineBytes-1) & ~(CacheLineBytes-1),
0458
0459
0460 BranchSize = AllocBytes /
0461 static_cast<unsigned>(sizeof(KeyT) + sizeof(void*))
0462 };
0463
0464
0465
0466
0467
0468 using Allocator =
0469 RecyclingAllocator<BumpPtrAllocator, char, AllocBytes, CacheLineBytes>;
0470 };
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 class NodeRef {
0494 struct CacheAlignedPointerTraits {
0495 static inline void *getAsVoidPointer(void *P) { return P; }
0496 static inline void *getFromVoidPointer(void *P) { return P; }
0497 static constexpr int NumLowBitsAvailable = Log2CacheLine;
0498 };
0499 PointerIntPair<void*, Log2CacheLine, unsigned, CacheAlignedPointerTraits> pip;
0500
0501 public:
0502
0503 NodeRef() = default;
0504
0505
0506 explicit operator bool() const { return pip.getOpaqueValue(); }
0507
0508
0509 template <typename NodeT>
0510 NodeRef(NodeT *p, unsigned n) : pip(p, n - 1) {
0511 assert(n <= NodeT::Capacity && "Size too big for node");
0512 }
0513
0514
0515 unsigned size() const { return pip.getInt() + 1; }
0516
0517
0518 void setSize(unsigned n) { pip.setInt(n - 1); }
0519
0520
0521
0522
0523 NodeRef &subtree(unsigned i) const {
0524 return reinterpret_cast<NodeRef*>(pip.getPointer())[i];
0525 }
0526
0527
0528 template <typename NodeT>
0529 NodeT &get() const {
0530 return *reinterpret_cast<NodeT*>(pip.getPointer());
0531 }
0532
0533 bool operator==(const NodeRef &RHS) const {
0534 if (pip == RHS.pip)
0535 return true;
0536 assert(pip.getPointer() != RHS.pip.getPointer() && "Inconsistent NodeRefs");
0537 return false;
0538 }
0539
0540 bool operator!=(const NodeRef &RHS) const {
0541 return !operator==(RHS);
0542 }
0543 };
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565 template <typename KeyT, typename ValT, unsigned N, typename Traits>
0566 class LeafNode : public NodeBase<std::pair<KeyT, KeyT>, ValT, N> {
0567 public:
0568 const KeyT &start(unsigned i) const { return this->first[i].first; }
0569 const KeyT &stop(unsigned i) const { return this->first[i].second; }
0570 const ValT &value(unsigned i) const { return this->second[i]; }
0571
0572 KeyT &start(unsigned i) { return this->first[i].first; }
0573 KeyT &stop(unsigned i) { return this->first[i].second; }
0574 ValT &value(unsigned i) { return this->second[i]; }
0575
0576
0577
0578
0579
0580
0581
0582 unsigned findFrom(unsigned i, unsigned Size, KeyT x) const {
0583 assert(i <= Size && Size <= N && "Bad indices");
0584 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
0585 "Index is past the needed point");
0586 while (i != Size && Traits::stopLess(stop(i), x)) ++i;
0587 return i;
0588 }
0589
0590
0591
0592
0593
0594
0595
0596
0597 unsigned safeFind(unsigned i, KeyT x) const {
0598 assert(i < N && "Bad index");
0599 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
0600 "Index is past the needed point");
0601 while (Traits::stopLess(stop(i), x)) ++i;
0602 assert(i < N && "Unsafe intervals");
0603 return i;
0604 }
0605
0606
0607
0608
0609
0610
0611 ValT safeLookup(KeyT x, ValT NotFound) const {
0612 unsigned i = safeFind(0, x);
0613 return Traits::startLess(x, start(i)) ? NotFound : value(i);
0614 }
0615
0616 unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y);
0617 };
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628 template <typename KeyT, typename ValT, unsigned N, typename Traits>
0629 unsigned LeafNode<KeyT, ValT, N, Traits>::
0630 insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y) {
0631 unsigned i = Pos;
0632 assert(i <= Size && Size <= N && "Invalid index");
0633 assert(!Traits::stopLess(b, a) && "Invalid interval");
0634
0635
0636 assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
0637 assert((i == Size || !Traits::stopLess(stop(i), a)));
0638 assert((i == Size || Traits::stopLess(b, start(i))) && "Overlapping insert");
0639
0640
0641 if (i && value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
0642 Pos = i - 1;
0643
0644 if (i != Size && value(i) == y && Traits::adjacent(b, start(i))) {
0645 stop(i - 1) = stop(i);
0646 this->erase(i, Size);
0647 return Size - 1;
0648 }
0649 stop(i - 1) = b;
0650 return Size;
0651 }
0652
0653
0654 if (i == N)
0655 return N + 1;
0656
0657
0658 if (i == Size) {
0659 start(i) = a;
0660 stop(i) = b;
0661 value(i) = y;
0662 return Size + 1;
0663 }
0664
0665
0666 if (value(i) == y && Traits::adjacent(b, start(i))) {
0667 start(i) = a;
0668 return Size;
0669 }
0670
0671
0672 if (Size == N)
0673 return N + 1;
0674
0675
0676 this->shift(i, Size);
0677 start(i) = a;
0678 stop(i) = b;
0679 value(i) = y;
0680 return Size + 1;
0681 }
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702 template <typename KeyT, typename ValT, unsigned N, typename Traits>
0703 class BranchNode : public NodeBase<NodeRef, KeyT, N> {
0704 public:
0705 const KeyT &stop(unsigned i) const { return this->second[i]; }
0706 const NodeRef &subtree(unsigned i) const { return this->first[i]; }
0707
0708 KeyT &stop(unsigned i) { return this->second[i]; }
0709 NodeRef &subtree(unsigned i) { return this->first[i]; }
0710
0711
0712
0713
0714
0715
0716
0717 unsigned findFrom(unsigned i, unsigned Size, KeyT x) const {
0718 assert(i <= Size && Size <= N && "Bad indices");
0719 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
0720 "Index to findFrom is past the needed point");
0721 while (i != Size && Traits::stopLess(stop(i), x)) ++i;
0722 return i;
0723 }
0724
0725
0726
0727
0728
0729
0730
0731 unsigned safeFind(unsigned i, KeyT x) const {
0732 assert(i < N && "Bad index");
0733 assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
0734 "Index is past the needed point");
0735 while (Traits::stopLess(stop(i), x)) ++i;
0736 assert(i < N && "Unsafe intervals");
0737 return i;
0738 }
0739
0740
0741
0742
0743 NodeRef safeLookup(KeyT x) const {
0744 return subtree(safeFind(0, x));
0745 }
0746
0747
0748
0749
0750
0751
0752 void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop) {
0753 assert(Size < N && "branch node overflow");
0754 assert(i <= Size && "Bad insert position");
0755 this->shift(i, Size);
0756 subtree(i) = Node;
0757 stop(i) = Stop;
0758 }
0759 };
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773 class Path {
0774
0775
0776 struct Entry {
0777 void *node;
0778 unsigned size;
0779 unsigned offset;
0780
0781 Entry(void *Node, unsigned Size, unsigned Offset)
0782 : node(Node), size(Size), offset(Offset) {}
0783
0784 Entry(NodeRef Node, unsigned Offset)
0785 : node(&Node.subtree(0)), size(Node.size()), offset(Offset) {}
0786
0787 NodeRef &subtree(unsigned i) const {
0788 return reinterpret_cast<NodeRef*>(node)[i];
0789 }
0790 };
0791
0792
0793 SmallVector<Entry, 4> path;
0794
0795 public:
0796
0797 template <typename NodeT> NodeT &node(unsigned Level) const {
0798 return *reinterpret_cast<NodeT*>(path[Level].node);
0799 }
0800 unsigned size(unsigned Level) const { return path[Level].size; }
0801 unsigned offset(unsigned Level) const { return path[Level].offset; }
0802 unsigned &offset(unsigned Level) { return path[Level].offset; }
0803
0804
0805 template <typename NodeT> NodeT &leaf() const {
0806 return *reinterpret_cast<NodeT*>(path.back().node);
0807 }
0808 unsigned leafSize() const { return path.back().size; }
0809 unsigned leafOffset() const { return path.back().offset; }
0810 unsigned &leafOffset() { return path.back().offset; }
0811
0812
0813 bool valid() const {
0814 return !path.empty() && path.front().offset < path.front().size;
0815 }
0816
0817
0818
0819 unsigned height() const { return path.size() - 1; }
0820
0821
0822
0823
0824 NodeRef &subtree(unsigned Level) const {
0825 return path[Level].subtree(path[Level].offset);
0826 }
0827
0828
0829
0830 void reset(unsigned Level) {
0831 path[Level] = Entry(subtree(Level - 1), offset(Level));
0832 }
0833
0834
0835
0836
0837 void push(NodeRef Node, unsigned Offset) {
0838 path.push_back(Entry(Node, Offset));
0839 }
0840
0841
0842 void pop() {
0843 path.pop_back();
0844 }
0845
0846
0847
0848
0849
0850 void setSize(unsigned Level, unsigned Size) {
0851 path[Level].size = Size;
0852 if (Level)
0853 subtree(Level - 1).setSize(Size);
0854 }
0855
0856
0857
0858
0859
0860 void setRoot(void *Node, unsigned Size, unsigned Offset) {
0861 path.clear();
0862 path.push_back(Entry(Node, Size, Offset));
0863 }
0864
0865
0866
0867
0868
0869
0870 void replaceRoot(void *Root, unsigned Size, IdxPair Offsets);
0871
0872
0873
0874
0875 NodeRef getLeftSibling(unsigned Level) const;
0876
0877
0878
0879
0880 void moveLeft(unsigned Level);
0881
0882
0883
0884 void fillLeft(unsigned Height) {
0885 while (height() < Height)
0886 push(subtree(height()), 0);
0887 }
0888
0889
0890
0891
0892 NodeRef getRightSibling(unsigned Level) const;
0893
0894
0895
0896
0897 void moveRight(unsigned Level);
0898
0899
0900 bool atBegin() const {
0901 for (unsigned i = 0, e = path.size(); i != e; ++i)
0902 if (path[i].offset != 0)
0903 return false;
0904 return true;
0905 }
0906
0907
0908
0909
0910 bool atLastEntry(unsigned Level) const {
0911 return path[Level].offset == path[Level].size - 1;
0912 }
0913
0914
0915
0916
0917
0918
0919 void legalizeForInsert(unsigned Level) {
0920 if (valid())
0921 return;
0922 moveLeft(Level);
0923 ++path[Level].offset;
0924 }
0925 };
0926
0927 }
0928
0929
0930
0931
0932
0933 template <typename KeyT, typename ValT,
0934 unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
0935 typename Traits = IntervalMapInfo<KeyT>>
0936 class IntervalMap {
0937 using Sizer = IntervalMapImpl::NodeSizer<KeyT, ValT>;
0938 using Leaf = IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits>;
0939 using Branch =
0940 IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits>;
0941 using RootLeaf = IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits>;
0942 using IdxPair = IntervalMapImpl::IdxPair;
0943
0944
0945
0946 enum {
0947 DesiredRootBranchCap = (sizeof(RootLeaf) - sizeof(KeyT)) /
0948 (sizeof(KeyT) + sizeof(IntervalMapImpl::NodeRef)),
0949 RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
0950 };
0951
0952 using RootBranch =
0953 IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits>;
0954
0955
0956 struct RootBranchData {
0957 KeyT start;
0958 RootBranch node;
0959 };
0960
0961 public:
0962 using Allocator = typename Sizer::Allocator;
0963 using KeyType = KeyT;
0964 using ValueType = ValT;
0965 using KeyTraits = Traits;
0966
0967 private:
0968
0969 union {
0970 RootLeaf leaf;
0971 RootBranchData branchData;
0972 };
0973
0974
0975
0976
0977
0978 unsigned height = 0;
0979
0980
0981 unsigned rootSize = 0;
0982
0983
0984 Allocator *allocator = nullptr;
0985
0986 const RootLeaf &rootLeaf() const {
0987 assert(!branched() && "Cannot acces leaf data in branched root");
0988 return leaf;
0989 }
0990 RootLeaf &rootLeaf() {
0991 assert(!branched() && "Cannot acces leaf data in branched root");
0992 return leaf;
0993 }
0994
0995 const RootBranchData &rootBranchData() const {
0996 assert(branched() && "Cannot access branch data in non-branched root");
0997 return branchData;
0998 }
0999 RootBranchData &rootBranchData() {
1000 assert(branched() && "Cannot access branch data in non-branched root");
1001 return branchData;
1002 }
1003
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; }
1008
1009 template <typename NodeT> NodeT *newNode() {
1010 return new (allocator->template Allocate<NodeT>()) NodeT();
1011 }
1012
1013 template <typename NodeT> void deleteNode(NodeT *P) {
1014 P->~NodeT();
1015 allocator->Deallocate(P);
1016 }
1017
1018 IdxPair branchRoot(unsigned Position);
1019 IdxPair splitRoot(unsigned Position);
1020
1021 void switchRootToBranch() {
1022 rootLeaf().~RootLeaf();
1023 height = 1;
1024 new (&rootBranchData()) RootBranchData();
1025 }
1026
1027 void switchRootToLeaf() {
1028 rootBranchData().~RootBranchData();
1029 height = 0;
1030 new(&rootLeaf()) RootLeaf();
1031 }
1032
1033 bool branched() const { return height > 0; }
1034
1035 ValT treeSafeLookup(KeyT x, ValT NotFound) const;
1036 void visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
1037 unsigned Level));
1038 void deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level);
1039
1040 public:
1041 explicit IntervalMap(Allocator &a) : allocator(&a) {
1042 new (&rootLeaf()) RootLeaf();
1043 }
1044
1045
1046
1047
1048
1049 IntervalMap(IntervalMap const &RHS) : IntervalMap(*RHS.allocator) {
1050
1051
1052 assert(empty() && "Expected emptry tree");
1053 *this = RHS;
1054 }
1055 IntervalMap &operator=(IntervalMap const &RHS) {
1056 clear();
1057 allocator = RHS.allocator;
1058 for (auto It = RHS.begin(), End = RHS.end(); It != End; ++It)
1059 insert(It.start(), It.stop(), It.value());
1060 return *this;
1061 }
1062
1063 IntervalMap(IntervalMap &&RHS) : IntervalMap(*RHS.allocator) {
1064
1065
1066 assert(empty() && "Expected emptry tree");
1067 *this = std::move(RHS);
1068 }
1069 IntervalMap &operator=(IntervalMap &&RHS) {
1070
1071 clear();
1072
1073 rootLeaf().~RootLeaf();
1074
1075 height = RHS.height;
1076 rootSize = RHS.rootSize;
1077 allocator = RHS.allocator;
1078
1079
1080
1081 if (RHS.branched()) {
1082 rootBranch() = std::move(RHS.rootBranch());
1083
1084
1085 RHS.rootBranch().~RootBranch();
1086 RHS.height = 0;
1087 new (&RHS.rootLeaf()) RootLeaf();
1088 } else {
1089 rootLeaf() = std::move(RHS.rootLeaf());
1090 }
1091 return *this;
1092 }
1093
1094
1095 ~IntervalMap() {
1096 clear();
1097 rootLeaf().~RootLeaf();
1098 }
1099
1100
1101 bool empty() const {
1102 return rootSize == 0;
1103 }
1104
1105
1106 KeyT start() const {
1107 assert(!empty() && "Empty IntervalMap has no start");
1108 return !branched() ? rootLeaf().start(0) : rootBranchStart();
1109 }
1110
1111
1112 KeyT stop() const {
1113 assert(!empty() && "Empty IntervalMap has no stop");
1114 return !branched() ? rootLeaf().stop(rootSize - 1) :
1115 rootBranch().stop(rootSize - 1);
1116 }
1117
1118
1119 ValT lookup(KeyT x, ValT NotFound = ValT()) const {
1120 if (empty() || Traits::startLess(x, start()) || Traits::stopLess(stop(), x))
1121 return NotFound;
1122 return branched() ? treeSafeLookup(x, NotFound) :
1123 rootLeaf().safeLookup(x, NotFound);
1124 }
1125
1126
1127
1128
1129 void insert(KeyT a, KeyT b, ValT y) {
1130 if (branched() || rootSize == RootLeaf::Capacity)
1131 return find(a).insert(a, b, y);
1132
1133
1134 unsigned p = rootLeaf().findFrom(0, rootSize, a);
1135 rootSize = rootLeaf().insertFrom(p, rootSize, a, b, y);
1136 }
1137
1138
1139 void clear();
1140
1141 class const_iterator;
1142 class iterator;
1143 friend class const_iterator;
1144 friend class iterator;
1145
1146 const_iterator begin() const {
1147 const_iterator I(*this);
1148 I.goToBegin();
1149 return I;
1150 }
1151
1152 iterator begin() {
1153 iterator I(*this);
1154 I.goToBegin();
1155 return I;
1156 }
1157
1158 const_iterator end() const {
1159 const_iterator I(*this);
1160 I.goToEnd();
1161 return I;
1162 }
1163
1164 iterator end() {
1165 iterator I(*this);
1166 I.goToEnd();
1167 return I;
1168 }
1169
1170
1171
1172 const_iterator find(KeyT x) const {
1173 const_iterator I(*this);
1174 I.find(x);
1175 return I;
1176 }
1177
1178 iterator find(KeyT x) {
1179 iterator I(*this);
1180 I.find(x);
1181 return I;
1182 }
1183
1184
1185
1186 bool overlaps(KeyT a, KeyT b) const {
1187 assert(Traits::nonEmpty(a, b));
1188 const_iterator I = find(a);
1189 if (!I.valid())
1190 return false;
1191
1192
1193
1194 return !Traits::stopLess(b, I.start());
1195 }
1196 };
1197
1198
1199
1200 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1201 ValT IntervalMap<KeyT, ValT, N, Traits>::
1202 treeSafeLookup(KeyT x, ValT NotFound) const {
1203 assert(branched() && "treeLookup assumes a branched root");
1204
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);
1209 }
1210
1211
1212
1213 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1214 IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>::
1215 branchRoot(unsigned Position) {
1216 using namespace IntervalMapImpl;
1217
1218 const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
1219
1220
1221 unsigned size[Nodes];
1222 IdxPair NewOffset(0, Position);
1223
1224
1225 if (Nodes == 1)
1226 size[0] = rootSize;
1227 else
1228 NewOffset = distribute(Nodes, rootSize, Leaf::Capacity, nullptr, size,
1229 Position, true);
1230
1231
1232 unsigned pos = 0;
1233 NodeRef node[Nodes];
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]);
1238 pos += size[n];
1239 }
1240
1241
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];
1246 }
1247 rootBranchStart() = node[0].template get<Leaf>().start(0);
1248 rootSize = Nodes;
1249 return NewOffset;
1250 }
1251
1252
1253
1254 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1255 IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>::
1256 splitRoot(unsigned Position) {
1257 using namespace IntervalMapImpl;
1258
1259 const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
1260
1261
1262 unsigned Size[Nodes];
1263 IdxPair NewOffset(0, Position);
1264
1265
1266 if (Nodes == 1)
1267 Size[0] = rootSize;
1268 else
1269 NewOffset = distribute(Nodes, rootSize, Leaf::Capacity, nullptr, Size,
1270 Position, true);
1271
1272
1273 unsigned Pos = 0;
1274 NodeRef Node[Nodes];
1275 for (unsigned n = 0; n != Nodes; ++n) {
1276 Branch *B = newNode<Branch>();
1277 B->copy(rootBranch(), Pos, 0, Size[n]);
1278 Node[n] = NodeRef(B, Size[n]);
1279 Pos += Size[n];
1280 }
1281
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];
1285 }
1286 rootSize = Nodes;
1287 ++height;
1288 return NewOffset;
1289 }
1290
1291
1292 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1293 void IntervalMap<KeyT, ValT, N, Traits>::
1294 visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef, unsigned Height)) {
1295 if (!branched())
1296 return;
1297 SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
1298
1299
1300 for (unsigned i = 0; i != rootSize; ++i)
1301 Refs.push_back(rootBranch().subtree(i));
1302
1303
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);
1309 }
1310 Refs.clear();
1311 Refs.swap(NextRefs);
1312 }
1313
1314
1315 for (unsigned i = 0, e = Refs.size(); i != e; ++i)
1316 (this->*f)(Refs[i], 0);
1317 }
1318
1319 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1320 void IntervalMap<KeyT, ValT, N, Traits>::
1321 deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level) {
1322 if (Level)
1323 deleteNode(&Node.get<Branch>());
1324 else
1325 deleteNode(&Node.get<Leaf>());
1326 }
1327
1328 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1329 void IntervalMap<KeyT, ValT, N, Traits>::
1330 clear() {
1331 if (branched()) {
1332 visitNodes(&IntervalMap::deleteNode);
1333 switchRootToLeaf();
1334 }
1335 rootSize = 0;
1336 }
1337
1338
1339
1340
1341
1342 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1343 class IntervalMap<KeyT, ValT, N, Traits>::const_iterator {
1344 friend class IntervalMap;
1345
1346 public:
1347 using iterator_category = std::bidirectional_iterator_tag;
1348 using value_type = ValT;
1349 using difference_type = std::ptrdiff_t;
1350 using pointer = value_type *;
1351 using reference = value_type &;
1352
1353 protected:
1354
1355 IntervalMap *map = nullptr;
1356
1357
1358
1359 IntervalMapImpl::Path path;
1360
1361 explicit const_iterator(const IntervalMap &map) :
1362 map(const_cast<IntervalMap*>(&map)) {}
1363
1364 bool branched() const {
1365 assert(map && "Invalid iterator");
1366 return map->branched();
1367 }
1368
1369 void setRoot(unsigned Offset) {
1370 if (branched())
1371 path.setRoot(&map->rootBranch(), map->rootSize, Offset);
1372 else
1373 path.setRoot(&map->rootLeaf(), map->rootSize, Offset);
1374 }
1375
1376 void pathFillFind(KeyT x);
1377 void treeFind(KeyT x);
1378 void treeAdvanceTo(KeyT x);
1379
1380
1381 KeyT &unsafeStart() const {
1382 assert(valid() && "Cannot access invalid iterator");
1383 return branched() ? path.leaf<Leaf>().start(path.leafOffset()) :
1384 path.leaf<RootLeaf>().start(path.leafOffset());
1385 }
1386
1387
1388 KeyT &unsafeStop() const {
1389 assert(valid() && "Cannot access invalid iterator");
1390 return branched() ? path.leaf<Leaf>().stop(path.leafOffset()) :
1391 path.leaf<RootLeaf>().stop(path.leafOffset());
1392 }
1393
1394
1395 ValT &unsafeValue() const {
1396 assert(valid() && "Cannot access invalid iterator");
1397 return branched() ? path.leaf<Leaf>().value(path.leafOffset()) :
1398 path.leaf<RootLeaf>().value(path.leafOffset());
1399 }
1400
1401 public:
1402
1403 const_iterator() = default;
1404
1405
1406
1407 void setMap(const IntervalMap &m) { map = const_cast<IntervalMap*>(&m); }
1408
1409
1410 bool valid() const { return path.valid(); }
1411
1412
1413 bool atBegin() const { return path.atBegin(); }
1414
1415
1416 const KeyT &start() const { return unsafeStart(); }
1417
1418
1419 const KeyT &stop() const { return unsafeStop(); }
1420
1421
1422 const ValT &value() const { return unsafeValue(); }
1423
1424 const ValT &operator*() const { return value(); }
1425
1426 bool operator==(const const_iterator &RHS) const {
1427 assert(map == RHS.map && "Cannot compare iterators from different maps");
1428 if (!valid())
1429 return !RHS.valid();
1430 if (path.leafOffset() != RHS.path.leafOffset())
1431 return false;
1432 return &path.template leaf<Leaf>() == &RHS.path.template leaf<Leaf>();
1433 }
1434
1435 bool operator!=(const const_iterator &RHS) const {
1436 return !operator==(RHS);
1437 }
1438
1439
1440 void goToBegin() {
1441 setRoot(0);
1442 if (branched())
1443 path.fillLeft(map->height);
1444 }
1445
1446
1447 void goToEnd() {
1448 setRoot(map->rootSize);
1449 }
1450
1451
1452 const_iterator &operator++() {
1453 assert(valid() && "Cannot increment end()");
1454 if (++path.leafOffset() == path.leafSize() && branched())
1455 path.moveRight(map->height);
1456 return *this;
1457 }
1458
1459
1460 const_iterator operator++(int) {
1461 const_iterator tmp = *this;
1462 operator++();
1463 return tmp;
1464 }
1465
1466
1467 const_iterator &operator--() {
1468 if (path.leafOffset() && (valid() || !branched()))
1469 --path.leafOffset();
1470 else
1471 path.moveLeft(map->height);
1472 return *this;
1473 }
1474
1475
1476 const_iterator operator--(int) {
1477 const_iterator tmp = *this;
1478 operator--();
1479 return tmp;
1480 }
1481
1482
1483
1484 void find(KeyT x) {
1485 if (branched())
1486 treeFind(x);
1487 else
1488 setRoot(map->rootLeaf().findFrom(0, map->rootSize, x));
1489 }
1490
1491
1492
1493
1494 void advanceTo(KeyT x) {
1495 if (!valid())
1496 return;
1497 if (branched())
1498 treeAdvanceTo(x);
1499 else
1500 path.leafOffset() =
1501 map->rootLeaf().findFrom(path.leafOffset(), map->rootSize, x);
1502 }
1503 };
1504
1505
1506
1507 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1508 void IntervalMap<KeyT, ValT, N, Traits>::
1509 const_iterator::pathFillFind(KeyT x) {
1510 IntervalMapImpl::NodeRef NR = path.subtree(path.height());
1511 for (unsigned i = map->height - path.height() - 1; i; --i) {
1512 unsigned p = NR.get<Branch>().safeFind(0, x);
1513 path.push(NR, p);
1514 NR = NR.subtree(p);
1515 }
1516 path.push(NR, NR.get<Leaf>().safeFind(0, x));
1517 }
1518
1519
1520
1521 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1522 void IntervalMap<KeyT, ValT, N, Traits>::
1523 const_iterator::treeFind(KeyT x) {
1524 setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
1525 if (valid())
1526 pathFillFind(x);
1527 }
1528
1529
1530
1531 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1532 void IntervalMap<KeyT, ValT, N, Traits>::
1533 const_iterator::treeAdvanceTo(KeyT x) {
1534
1535 if (!Traits::stopLess(path.leaf<Leaf>().stop(path.leafSize() - 1), x)) {
1536 path.leafOffset() = path.leaf<Leaf>().safeFind(path.leafOffset(), x);
1537 return;
1538 }
1539
1540
1541 path.pop();
1542
1543
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)) {
1547
1548 path.offset(l + 1) =
1549 path.node<Branch>(l + 1).safeFind(path.offset(l + 1), x);
1550 return pathFillFind(x);
1551 }
1552 path.pop();
1553 }
1554
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);
1558 }
1559 }
1560
1561
1562 setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
1563 if (valid())
1564 pathFillFind(x);
1565 }
1566
1567
1568
1569
1570
1571 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1572 class IntervalMap<KeyT, ValT, N, Traits>::iterator : public const_iterator {
1573 friend class IntervalMap;
1574
1575 using IdxPair = IntervalMapImpl::IdxPair;
1576
1577 explicit iterator(IntervalMap &map) : const_iterator(map) {}
1578
1579 void setNodeStop(unsigned Level, KeyT Stop);
1580 bool insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop);
1581 template <typename NodeT> bool overflow(unsigned Level);
1582 void treeInsert(KeyT a, KeyT b, ValT y);
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);
1587
1588 public:
1589
1590 iterator() = default;
1591
1592
1593
1594
1595 void setStart(KeyT a);
1596
1597
1598
1599
1600 void setStop(KeyT b);
1601
1602
1603
1604
1605 void setValue(ValT x);
1606
1607
1608
1609
1610
1611 void setStartUnchecked(KeyT a) { this->unsafeStart() = a; }
1612
1613
1614
1615
1616
1617 void setStopUnchecked(KeyT b) {
1618 this->unsafeStop() = b;
1619
1620 if (this->path.atLastEntry(this->path.height()))
1621 setNodeStop(this->path.height(), b);
1622 }
1623
1624
1625
1626
1627 void setValueUnchecked(ValT x) { this->unsafeValue() = x; }
1628
1629
1630 void insert(KeyT a, KeyT b, ValT y);
1631
1632
1633 void erase();
1634
1635 iterator &operator++() {
1636 const_iterator::operator++();
1637 return *this;
1638 }
1639
1640 iterator operator++(int) {
1641 iterator tmp = *this;
1642 operator++();
1643 return tmp;
1644 }
1645
1646 iterator &operator--() {
1647 const_iterator::operator--();
1648 return *this;
1649 }
1650
1651 iterator operator--(int) {
1652 iterator tmp = *this;
1653 operator--();
1654 return tmp;
1655 }
1656 };
1657
1658
1659
1660
1661
1662
1663 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1664 bool IntervalMap<KeyT, ValT, N, Traits>::
1665 iterator::canCoalesceLeft(KeyT Start, ValT Value) {
1666 using namespace IntervalMapImpl;
1667 Path &P = this->path;
1668 if (!this->branched()) {
1669 unsigned i = P.leafOffset();
1670 RootLeaf &Node = P.leaf<RootLeaf>();
1671 return i && Node.value(i-1) == Value &&
1672 Traits::adjacent(Node.stop(i-1), Start);
1673 }
1674
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);
1682 }
1683 return false;
1684 }
1685
1686
1687
1688
1689
1690
1691 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1692 bool IntervalMap<KeyT, ValT, N, Traits>::
1693 iterator::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())
1699 return false;
1700 RootLeaf &Node = P.leaf<RootLeaf>();
1701 return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
1702 }
1703
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));
1710 }
1711 return false;
1712 }
1713
1714
1715 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1716 void IntervalMap<KeyT, ValT, N, Traits>::
1717 iterator::setNodeStop(unsigned Level, KeyT Stop) {
1718
1719 if (!Level)
1720 return;
1721 IntervalMapImpl::Path &P = this->path;
1722
1723 while (--Level) {
1724 P.node<Branch>(Level).stop(P.offset(Level)) = Stop;
1725 if (!P.atLastEntry(Level))
1726 return;
1727 }
1728
1729 P.node<RootBranch>(Level).stop(P.offset(Level)) = Stop;
1730 }
1731
1732 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1733 void IntervalMap<KeyT, ValT, N, Traits>::
1734 iterator::setStart(KeyT a) {
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())) {
1738 CurStart = a;
1739 return;
1740 }
1741
1742 --*this;
1743 a = this->start();
1744 erase();
1745 setStartUnchecked(a);
1746 }
1747
1748 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1749 void IntervalMap<KeyT, ValT, N, Traits>::
1750 iterator::setStop(KeyT b) {
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);
1755 return;
1756 }
1757
1758 KeyT a = this->start();
1759 erase();
1760 setStartUnchecked(a);
1761 }
1762
1763 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1764 void IntervalMap<KeyT, ValT, N, Traits>::
1765 iterator::setValue(ValT x) {
1766 setValueUnchecked(x);
1767 if (canCoalesceRight(this->stop(), x)) {
1768 KeyT a = this->start();
1769 erase();
1770 setStartUnchecked(a);
1771 }
1772 if (canCoalesceLeft(this->start(), x)) {
1773 --*this;
1774 KeyT a = this->start();
1775 erase();
1776 setStartUnchecked(a);
1777 }
1778 }
1779
1780
1781
1782
1783
1784
1785
1786 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1787 bool IntervalMap<KeyT, ValT, N, Traits>::
1788 iterator::insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop) {
1789 assert(Level && "Cannot insert next to the root");
1790 bool SplitRoot = false;
1791 IntervalMap &IM = *this->map;
1792 IntervalMapImpl::Path &P = this->path;
1793
1794 if (Level == 1) {
1795
1796 if (IM.rootSize < RootBranch::Capacity) {
1797 IM.rootBranch().insert(P.offset(0), IM.rootSize, Node, Stop);
1798 P.setSize(0, ++IM.rootSize);
1799 P.reset(Level);
1800 return SplitRoot;
1801 }
1802
1803
1804 SplitRoot = true;
1805 IdxPair Offset = IM.splitRoot(P.offset(0));
1806 P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
1807
1808
1809 ++Level;
1810 }
1811
1812
1813 P.legalizeForInsert(--Level);
1814
1815
1816 if (P.size(Level) == Branch::Capacity) {
1817
1818 assert(!SplitRoot && "Cannot overflow after splitting the root");
1819 SplitRoot = overflow<Branch>(Level);
1820 Level += SplitRoot;
1821 }
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);
1826 P.reset(Level + 1);
1827 return SplitRoot;
1828 }
1829
1830
1831 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1832 void IntervalMap<KeyT, ValT, N, Traits>::
1833 iterator::insert(KeyT a, KeyT b, ValT y) {
1834 if (this->branched())
1835 return treeInsert(a, b, y);
1836 IntervalMap &IM = *this->map;
1837 IntervalMapImpl::Path &P = this->path;
1838
1839
1840 unsigned Size = IM.rootLeaf().insertFrom(P.leafOffset(), IM.rootSize, a, b, y);
1841
1842
1843 if (Size <= RootLeaf::Capacity) {
1844 P.setSize(0, IM.rootSize = Size);
1845 return;
1846 }
1847
1848
1849 IdxPair Offset = IM.branchRoot(P.leafOffset());
1850 P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
1851
1852
1853 treeInsert(a, b, y);
1854 }
1855
1856 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1857 void IntervalMap<KeyT, ValT, N, Traits>::
1858 iterator::treeInsert(KeyT a, KeyT b, ValT y) {
1859 using namespace IntervalMapImpl;
1860 Path &P = this->path;
1861
1862 if (!P.valid())
1863 P.legalizeForInsert(this->map->height);
1864
1865
1866 if (P.leafOffset() == 0 && Traits::startLess(a, P.leaf<Leaf>().start(0))) {
1867
1868 if (NodeRef Sib = P.getLeftSibling(P.height())) {
1869 Leaf &SibLeaf = Sib.get<Leaf>();
1870 unsigned SibOfs = Sib.size() - 1;
1871 if (SibLeaf.value(SibOfs) == y &&
1872 Traits::adjacent(SibLeaf.stop(SibOfs), a)) {
1873
1874
1875
1876
1877
1878 Leaf &CurLeaf = P.leaf<Leaf>();
1879 P.moveLeft(P.height());
1880 if (Traits::stopLess(b, CurLeaf.start(0)) &&
1881 (y != CurLeaf.value(0) || !Traits::adjacent(b, CurLeaf.start(0)))) {
1882
1883 setNodeStop(P.height(), SibLeaf.stop(SibOfs) = b);
1884 return;
1885 } else {
1886
1887
1888 a = SibLeaf.start(SibOfs);
1889 treeErase(false);
1890 }
1891 }
1892 } else {
1893
1894 this->map->rootBranchStart() = a;
1895 }
1896 }
1897
1898
1899 unsigned Size = P.leafSize();
1900 bool Grow = P.leafOffset() == Size;
1901 Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), Size, a, b, y);
1902
1903
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");
1909 }
1910
1911
1912 P.setSize(P.height(), Size);
1913
1914
1915 if (Grow)
1916 setNodeStop(P.height(), b);
1917 }
1918
1919
1920 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1921 void IntervalMap<KeyT, ValT, N, Traits>::
1922 iterator::erase() {
1923 IntervalMap &IM = *this->map;
1924 IntervalMapImpl::Path &P = this->path;
1925 assert(P.valid() && "Cannot erase end()");
1926 if (this->branched())
1927 return treeErase();
1928 IM.rootLeaf().erase(P.leafOffset(), IM.rootSize);
1929 P.setSize(0, --IM.rootSize);
1930 }
1931
1932
1933 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1934 void IntervalMap<KeyT, ValT, N, Traits>::
1935 iterator::treeErase(bool UpdateRoot) {
1936 IntervalMap &IM = *this->map;
1937 IntervalMapImpl::Path &P = this->path;
1938 Leaf &Node = P.leaf<Leaf>();
1939
1940
1941 if (P.leafSize() == 1) {
1942 IM.deleteNode(&Node);
1943 eraseNode(IM.height);
1944
1945 if (UpdateRoot && IM.branched() && P.valid() && P.atBegin())
1946 IM.rootBranchStart() = P.leaf<Leaf>().start(0);
1947 return;
1948 }
1949
1950
1951 Node.erase(P.leafOffset(), P.leafSize());
1952 unsigned NewSize = P.leafSize() - 1;
1953 P.setSize(IM.height, NewSize);
1954
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);
1960 }
1961
1962
1963
1964
1965
1966 template <typename KeyT, typename ValT, unsigned N, typename Traits>
1967 void IntervalMap<KeyT, ValT, N, Traits>::
1968 iterator::eraseNode(unsigned Level) {
1969 assert(Level && "Cannot erase root node");
1970 IntervalMap &IM = *this->map;
1971 IntervalMapImpl::Path &P = this->path;
1972
1973 if (--Level == 0) {
1974 IM.rootBranch().erase(P.offset(0), IM.rootSize);
1975 P.setSize(0, --IM.rootSize);
1976
1977 if (IM.empty()) {
1978 IM.switchRootToLeaf();
1979 this->setRoot(0);
1980 return;
1981 }
1982 } else {
1983
1984 Branch &Parent = P.node<Branch>(Level);
1985 if (P.size(Level) == 1) {
1986
1987 IM.deleteNode(&Parent);
1988 eraseNode(Level);
1989 } else {
1990
1991 Parent.erase(P.offset(Level), P.size(Level));
1992 unsigned NewSize = P.size(Level) - 1;
1993 P.setSize(Level, NewSize);
1994
1995 if (P.offset(Level) == NewSize) {
1996 setNodeStop(Level, Parent.stop(NewSize - 1));
1997 P.moveRight(Level);
1998 }
1999 }
2000 }
2001
2002 if (P.valid()) {
2003 P.reset(Level + 1);
2004 P.offset(Level + 1) = 0;
2005 }
2006 }
2007
2008
2009
2010
2011
2012
2013
2014 template <typename KeyT, typename ValT, unsigned N, typename Traits>
2015 template <typename NodeT>
2016 bool IntervalMap<KeyT, ValT, N, Traits>::
2017 iterator::overflow(unsigned Level) {
2018 using namespace IntervalMapImpl;
2019 Path &P = this->path;
2020 unsigned CurSize[4];
2021 NodeT *Node[4];
2022 unsigned Nodes = 0;
2023 unsigned Elements = 0;
2024 unsigned Offset = P.offset(Level);
2025
2026
2027 NodeRef LeftSib = P.getLeftSibling(Level);
2028 if (LeftSib) {
2029 Offset += Elements = CurSize[Nodes] = LeftSib.size();
2030 Node[Nodes++] = &LeftSib.get<NodeT>();
2031 }
2032
2033
2034 Elements += CurSize[Nodes] = P.size(Level);
2035 Node[Nodes++] = &P.node<NodeT>(Level);
2036
2037
2038 NodeRef RightSib = P.getRightSibling(Level);
2039 if (RightSib) {
2040 Elements += CurSize[Nodes] = RightSib.size();
2041 Node[Nodes++] = &RightSib.get<NodeT>();
2042 }
2043
2044
2045 unsigned NewNode = 0;
2046 if (Elements + 1 > Nodes * NodeT::Capacity) {
2047
2048 NewNode = Nodes == 1 ? 1 : Nodes - 1;
2049 CurSize[Nodes] = CurSize[NewNode];
2050 Node[Nodes] = Node[NewNode];
2051 CurSize[NewNode] = 0;
2052 Node[NewNode] = this->map->template newNode<NodeT>();
2053 ++Nodes;
2054 }
2055
2056
2057 unsigned NewSize[4];
2058 IdxPair NewOffset = distribute(Nodes, Elements, NodeT::Capacity,
2059 CurSize, NewSize, Offset, true);
2060 adjustSiblingSizes(Node, Nodes, CurSize, NewSize);
2061
2062
2063 if (LeftSib)
2064 P.moveLeft(Level);
2065
2066
2067 bool SplitRoot = false;
2068 unsigned Pos = 0;
2069 while (true) {
2070 KeyT Stop = Node[Pos]->stop(NewSize[Pos]-1);
2071 if (NewNode && Pos == NewNode) {
2072 SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
2073 Level += SplitRoot;
2074 } else {
2075 P.setSize(Level, NewSize[Pos]);
2076 setNodeStop(Level, Stop);
2077 }
2078 if (Pos + 1 == Nodes)
2079 break;
2080 P.moveRight(Level);
2081 ++Pos;
2082 }
2083
2084
2085 while(Pos != NewOffset.first) {
2086 P.moveLeft(Level);
2087 --Pos;
2088 }
2089 P.offset(Level) = NewOffset.second;
2090 return SplitRoot;
2091 }
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109 template <typename MapA, typename MapB>
2110 class IntervalMapOverlaps {
2111 using KeyType = typename MapA::KeyType;
2112 using Traits = typename MapA::KeyTraits;
2113
2114 typename MapA::const_iterator posA;
2115 typename MapB::const_iterator posB;
2116
2117
2118
2119
2120 void advance() {
2121 if (!valid())
2122 return;
2123
2124 if (Traits::stopLess(posA.stop(), posB.start())) {
2125
2126 posA.advanceTo(posB.start());
2127 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2128 return;
2129 } else if (Traits::stopLess(posB.stop(), posA.start())) {
2130
2131 posB.advanceTo(posA.start());
2132 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2133 return;
2134 } else
2135
2136 return;
2137
2138 while (true) {
2139
2140 posA.advanceTo(posB.start());
2141 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
2142 return;
2143
2144 posB.advanceTo(posA.start());
2145 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
2146 return;
2147 }
2148 }
2149
2150 public:
2151
2152 IntervalMapOverlaps(const MapA &a, const MapB &b)
2153 : posA(b.empty() ? a.end() : a.find(b.start())),
2154 posB(posA.valid() ? b.find(posA.start()) : b.end()) { advance(); }
2155
2156
2157 bool valid() const {
2158 return posA.valid() && posB.valid();
2159 }
2160
2161
2162 const typename MapA::const_iterator &a() const { return posA; }
2163
2164
2165 const typename MapB::const_iterator &b() const { return posB; }
2166
2167
2168 KeyType start() const {
2169 KeyType ak = a().start();
2170 KeyType bk = b().start();
2171 return Traits::startLess(ak, bk) ? bk : ak;
2172 }
2173
2174
2175 KeyType stop() const {
2176 KeyType ak = a().stop();
2177 KeyType bk = b().stop();
2178 return Traits::startLess(ak, bk) ? ak : bk;
2179 }
2180
2181
2182 void skipA() {
2183 ++posA;
2184 advance();
2185 }
2186
2187
2188 void skipB() {
2189 ++posB;
2190 advance();
2191 }
2192
2193
2194 IntervalMapOverlaps &operator++() {
2195
2196 if (Traits::startLess(posB.stop(), posA.stop()))
2197 skipB();
2198 else
2199 skipA();
2200 return *this;
2201 }
2202
2203
2204
2205 void advanceTo(KeyType x) {
2206 if (!valid())
2207 return;
2208
2209 if (Traits::stopLess(posA.stop(), x))
2210 posA.advanceTo(x);
2211 if (Traits::stopLess(posB.stop(), x))
2212 posB.advanceTo(x);
2213 advance();
2214 }
2215 };
2216
2217 }
2218
2219 #endif