1 //===- llvm/ADT/IntervalMap.h - A sorted interval map -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements a coalescing interval map for small objects. 11 // 12 // KeyT objects are mapped to ValT objects. Intervals of keys that map to the 13 // same value are represented in a compressed form. 14 // 15 // Iterators provide ordered access to the compressed intervals rather than the 16 // individual keys, and insert and erase operations use key intervals as well. 17 // 18 // Like SmallVector, IntervalMap will store the first N intervals in the map 19 // object itself without any allocations. When space is exhausted it switches to 20 // a B+-tree representation with very small overhead for small key and value 21 // objects. 22 // 23 // A Traits class specifies how keys are compared. It also allows IntervalMap to 24 // work with both closed and half-open intervals. 25 // 26 // Keys and values are not stored next to each other in a std::pair, so we don't 27 // provide such a value_type. Dereferencing iterators only returns the mapped 28 // value. The interval bounds are accessible through the start() and stop() 29 // iterator methods. 30 // 31 // IntervalMap is optimized for small key and value objects, 4 or 8 bytes each 32 // is the optimal size. For large objects use std::map instead. 33 // 34 //===----------------------------------------------------------------------===// 35 // 36 // Synopsis: 37 // 38 // template <typename KeyT, typename ValT, unsigned N, typename Traits> 39 // class IntervalMap { 40 // public: 41 // typedef KeyT key_type; 42 // typedef ValT mapped_type; 43 // typedef RecyclingAllocator<...> Allocator; 44 // class iterator; 45 // class const_iterator; 46 // 47 // explicit IntervalMap(Allocator&); 48 // ~IntervalMap(): 49 // 50 // bool empty() const; 51 // KeyT start() const; 52 // KeyT stop() const; 53 // ValT lookup(KeyT x, Value NotFound = Value()) const; 54 // 55 // const_iterator begin() const; 56 // const_iterator end() const; 57 // iterator begin(); 58 // iterator end(); 59 // const_iterator find(KeyT x) const; 60 // iterator find(KeyT x); 61 // 62 // void insert(KeyT a, KeyT b, ValT y); 63 // void clear(); 64 // }; 65 // 66 // template <typename KeyT, typename ValT, unsigned N, typename Traits> 67 // class IntervalMap::const_iterator : 68 // public std::iterator<std::bidirectional_iterator_tag, ValT> { 69 // public: 70 // bool operator==(const const_iterator &) const; 71 // bool operator!=(const const_iterator &) const; 72 // bool valid() const; 73 // 74 // const KeyT &start() const; 75 // const KeyT &stop() const; 76 // const ValT &value() const; 77 // const ValT &operator*() const; 78 // const ValT *operator->() const; 79 // 80 // const_iterator &operator++(); 81 // const_iterator &operator++(int); 82 // const_iterator &operator--(); 83 // const_iterator &operator--(int); 84 // void goToBegin(); 85 // void goToEnd(); 86 // void find(KeyT x); 87 // void advanceTo(KeyT x); 88 // }; 89 // 90 // template <typename KeyT, typename ValT, unsigned N, typename Traits> 91 // class IntervalMap::iterator : public const_iterator { 92 // public: 93 // void insert(KeyT a, KeyT b, Value y); 94 // void erase(); 95 // }; 96 // 97 //===----------------------------------------------------------------------===// 98 99 #ifndef LLVM_ADT_INTERVALMAP_H 100 #define LLVM_ADT_INTERVALMAP_H 101 102 #include "llvm/ADT/PointerIntPair.h" 103 #include "llvm/ADT/SmallVector.h" 104 #include "llvm/Support/AlignOf.h" 105 #include "llvm/Support/Allocator.h" 106 #include "llvm/Support/RecyclingAllocator.h" 107 #include <iterator> 108 109 namespace llvm { 110 111 112 //===----------------------------------------------------------------------===// 113 //--- Key traits ---// 114 //===----------------------------------------------------------------------===// 115 // 116 // The IntervalMap works with closed or half-open intervals. 117 // Adjacent intervals that map to the same value are coalesced. 118 // 119 // The IntervalMapInfo traits class is used to determine if a key is contained 120 // in an interval, and if two intervals are adjacent so they can be coalesced. 121 // The provided implementation works for closed integer intervals, other keys 122 // probably need a specialized version. 123 // 124 // The point x is contained in [a;b] when !startLess(x, a) && !stopLess(b, x). 125 // 126 // It is assumed that (a;b] half-open intervals are not used, only [a;b) is 127 // allowed. This is so that stopLess(a, b) can be used to determine if two 128 // intervals overlap. 129 // 130 //===----------------------------------------------------------------------===// 131 132 template <typename T> 133 struct IntervalMapInfo { 134 135 /// startLess - Return true if x is not in [a;b]. 136 /// This is x < a both for closed intervals and for [a;b) half-open intervals. 137 static inline bool startLess(const T &x, const T &a) { 138 return x < a; 139 } 140 141 /// stopLess - Return true if x is not in [a;b]. 142 /// This is b < x for a closed interval, b <= x for [a;b) half-open intervals. 143 static inline bool stopLess(const T &b, const T &x) { 144 return b < x; 145 } 146 147 /// adjacent - Return true when the intervals [x;a] and [b;y] can coalesce. 148 /// This is a+1 == b for closed intervals, a == b for half-open intervals. 149 static inline bool adjacent(const T &a, const T &b) { 150 return a+1 == b; 151 } 152 153 }; 154 155 template <typename T> 156 struct IntervalMapHalfOpenInfo { 157 158 /// startLess - Return true if x is not in [a;b). 159 static inline bool startLess(const T &x, const T &a) { 160 return x < a; 161 } 162 163 /// stopLess - Return true if x is not in [a;b). 164 static inline bool stopLess(const T &b, const T &x) { 165 return b <= x; 166 } 167 168 /// adjacent - Return true when the intervals [x;a) and [b;y) can coalesce. 169 static inline bool adjacent(const T &a, const T &b) { 170 return a == b; 171 } 172 173 }; 174 175 /// IntervalMapImpl - Namespace used for IntervalMap implementation details. 176 /// It should be considered private to the implementation. 177 namespace IntervalMapImpl { 178 179 // Forward declarations. 180 template <typename, typename, unsigned, typename> class LeafNode; 181 template <typename, typename, unsigned, typename> class BranchNode; 182 183 typedef std::pair<unsigned,unsigned> IdxPair; 184 185 186 //===----------------------------------------------------------------------===// 187 //--- IntervalMapImpl::NodeBase ---// 188 //===----------------------------------------------------------------------===// 189 // 190 // Both leaf and branch nodes store vectors of pairs. 191 // Leaves store ((KeyT, KeyT), ValT) pairs, branches use (NodeRef, KeyT). 192 // 193 // Keys and values are stored in separate arrays to avoid padding caused by 194 // different object alignments. This also helps improve locality of reference 195 // when searching the keys. 196 // 197 // The nodes don't know how many elements they contain - that information is 198 // stored elsewhere. Omitting the size field prevents padding and allows a node 199 // to fill the allocated cache lines completely. 200 // 201 // These are typical key and value sizes, the node branching factor (N), and 202 // wasted space when nodes are sized to fit in three cache lines (192 bytes): 203 // 204 // T1 T2 N Waste Used by 205 // 4 4 24 0 Branch<4> (32-bit pointers) 206 // 8 4 16 0 Leaf<4,4>, Branch<4> 207 // 8 8 12 0 Leaf<4,8>, Branch<8> 208 // 16 4 9 12 Leaf<8,4> 209 // 16 8 8 0 Leaf<8,8> 210 // 211 //===----------------------------------------------------------------------===// 212 213 template <typename T1, typename T2, unsigned N> 214 class NodeBase { 215 public: 216 enum { Capacity = N }; 217 218 T1 first[N]; 219 T2 second[N]; 220 221 /// copy - Copy elements from another node. 222 /// @param Other Node elements are copied from. 223 /// @param i Beginning of the source range in other. 224 /// @param j Beginning of the destination range in this. 225 /// @param Count Number of elements to copy. 226 template <unsigned M> 227 void copy(const NodeBase<T1, T2, M> &Other, unsigned i, 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) { 232 first[j] = Other.first[i]; 233 second[j] = Other.second[i]; 234 } 235 } 236 237 /// moveLeft - Move elements to the left. 238 /// @param i Beginning of the source range. 239 /// @param j Beginning of the destination range. 240 /// @param Count Number of elements to copy. 241 void moveLeft(unsigned i, unsigned j, unsigned Count) { 242 assert(j <= i && "Use moveRight shift elements right"); 243 copy(*this, i, j, Count); 244 } 245 246 /// moveRight - Move elements to the right. 247 /// @param i Beginning of the source range. 248 /// @param j Beginning of the destination range. 249 /// @param Count Number of elements to copy. 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"); 253 while (Count--) { 254 first[j + Count] = first[i + Count]; 255 second[j + Count] = second[i + Count]; 256 } 257 } 258 259 /// erase - Erase elements [i;j). 260 /// @param i Beginning of the range to erase. 261 /// @param j End of the range. (Exclusive). 262 /// @param Size Number of elements in node. 263 void erase(unsigned i, unsigned j, unsigned Size) { 264 moveLeft(j, i, Size - j); 265 } 266 267 /// erase - Erase element at i. 268 /// @param i Index of element to erase. 269 /// @param Size Number of elements in node. 270 void erase(unsigned i, unsigned Size) { 271 erase(i, i+1, Size); 272 } 273 274 /// shift - Shift elements [i;size) 1 position to the right. 275 /// @param i Beginning of the range to move. 276 /// @param Size Number of elements in node. 277 void shift(unsigned i, unsigned Size) { 278 moveRight(i, i + 1, Size - i); 279 } 280 281 /// transferToLeftSib - Transfer elements to a left sibling node. 282 /// @param Size Number of elements in this. 283 /// @param Sib Left sibling node. 284 /// @param SSize Number of elements in sib. 285 /// @param Count Number of elements to transfer. 286 void transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, 287 unsigned Count) { 288 Sib.copy(*this, 0, SSize, Count); 289 erase(0, Count, Size); 290 } 291 292 /// transferToRightSib - Transfer elements to a right sibling node. 293 /// @param Size Number of elements in this. 294 /// @param Sib Right sibling node. 295 /// @param SSize Number of elements in sib. 296 /// @param Count Number of elements to transfer. 297 void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize, 298 unsigned Count) { 299 Sib.moveRight(0, Count, SSize); 300 Sib.copy(*this, Size-Count, 0, Count); 301 } 302 303 /// adjustFromLeftSib - Adjust the number if elements in this node by moving 304 /// elements to or from a left sibling node. 305 /// @param Size Number of elements in this. 306 /// @param Sib Right sibling node. 307 /// @param SSize Number of elements in sib. 308 /// @param Add The number of elements to add to this node, possibly < 0. 309 /// @return Number of elements added to this node, possibly negative. 310 int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add) { 311 if (Add > 0) { 312 // We want to grow, copy from sib. 313 unsigned Count = std::min(std::min(unsigned(Add), SSize), N - Size); 314 Sib.transferToRightSib(SSize, *this, Size, Count); 315 return Count; 316 } else { 317 // We want to shrink, copy to sib. 318 unsigned Count = std::min(std::min(unsigned(-Add), Size), N - SSize); 319 transferToLeftSib(Size, Sib, SSize, Count); 320 return -Count; 321 } 322 } 323 }; 324 325 /// IntervalMapImpl::adjustSiblingSizes - Move elements between sibling nodes. 326 /// @param Node Array of pointers to sibling nodes. 327 /// @param Nodes Number of nodes. 328 /// @param CurSize Array of current node sizes, will be overwritten. 329 /// @param NewSize Array of desired node sizes. 330 template <typename NodeT> 331 void adjustSiblingSizes(NodeT *Node[], unsigned Nodes, 332 unsigned CurSize[], const unsigned NewSize[]) { 333 // Move elements right. 334 for (int n = Nodes - 1; n; --n) { 335 if (CurSize[n] == NewSize[n]) 336 continue; 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]); 340 CurSize[m] -= d; 341 CurSize[n] += d; 342 // Keep going if the current node was exhausted. 343 if (CurSize[n] >= NewSize[n]) 344 break; 345 } 346 } 347 348 if (Nodes == 0) 349 return; 350 351 // Move elements left. 352 for (unsigned n = 0; n != Nodes - 1; ++n) { 353 if (CurSize[n] == NewSize[n]) 354 continue; 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]); 358 CurSize[m] += d; 359 CurSize[n] -= d; 360 // Keep going if the current node was exhausted. 361 if (CurSize[n] >= NewSize[n]) 362 break; 363 } 364 } 365 366 #ifndef NDEBUG 367 for (unsigned n = 0; n != Nodes; n++) 368 assert(CurSize[n] == NewSize[n] && "Insufficient element shuffle"); 369 #endif 370 } 371 372 /// IntervalMapImpl::distribute - Compute a new distribution of node elements 373 /// after an overflow or underflow. Reserve space for a new element at Position, 374 /// and compute the node that will hold Position after redistributing node 375 /// elements. 376 /// 377 /// It is required that 378 /// 379 /// Elements == sum(CurSize), and 380 /// Elements + Grow <= Nodes * Capacity. 381 /// 382 /// NewSize[] will be filled in such that: 383 /// 384 /// sum(NewSize) == Elements, and 385 /// NewSize[i] <= Capacity. 386 /// 387 /// The returned index is the node where Position will go, so: 388 /// 389 /// sum(NewSize[0..idx-1]) <= Position 390 /// sum(NewSize[0..idx]) >= Position 391 /// 392 /// The last equality, sum(NewSize[0..idx]) == Position, can only happen when 393 /// Grow is set and NewSize[idx] == Capacity-1. The index points to the node 394 /// before the one holding the Position'th element where there is room for an 395 /// insertion. 396 /// 397 /// @param Nodes The number of nodes. 398 /// @param Elements Total elements in all nodes. 399 /// @param Capacity The capacity of each node. 400 /// @param CurSize Array[Nodes] of current node sizes, or NULL. 401 /// @param NewSize Array[Nodes] to receive the new node sizes. 402 /// @param Position Insert position. 403 /// @param Grow Reserve space for a new element at Position. 404 /// @return (node, offset) for Position. 405 IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity, 406 const unsigned *CurSize, unsigned NewSize[], 407 unsigned Position, bool Grow); 408 409 410 //===----------------------------------------------------------------------===// 411 //--- IntervalMapImpl::NodeSizer ---// 412 //===----------------------------------------------------------------------===// 413 // 414 // Compute node sizes from key and value types. 415 // 416 // The branching factors are chosen to make nodes fit in three cache lines. 417 // This may not be possible if keys or values are very large. Such large objects 418 // are handled correctly, but a std::map would probably give better performance. 419 // 420 //===----------------------------------------------------------------------===// 421 422 enum { 423 // Cache line size. Most architectures have 32 or 64 byte cache lines. 424 // We use 64 bytes here because it provides good branching factors. 425 Log2CacheLine = 6, 426 CacheLineBytes = 1 << Log2CacheLine, 427 DesiredNodeBytes = 3 * CacheLineBytes 428 }; 429 430 template <typename KeyT, typename ValT> 431 struct NodeSizer { 432 enum { 433 // Compute the leaf node branching factor that makes a node fit in three 434 // cache lines. The branching factor must be at least 3, or some B+-tree 435 // balancing algorithms won't work. 436 // LeafSize can't be larger than CacheLineBytes. This is required by the 437 // PointerIntPair used by NodeRef. 438 DesiredLeafSize = DesiredNodeBytes / 439 static_cast<unsigned>(2*sizeof(KeyT)+sizeof(ValT)), 440 MinLeafSize = 3, 441 LeafSize = DesiredLeafSize > MinLeafSize ? DesiredLeafSize : MinLeafSize 442 }; 443 444 typedef NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize> LeafBase; 445 446 enum { 447 // Now that we have the leaf branching factor, compute the actual allocation 448 // unit size by rounding up to a whole number of cache lines. 449 AllocBytes = (sizeof(LeafBase) + CacheLineBytes-1) & ~(CacheLineBytes-1), 450 451 // Determine the branching factor for branch nodes. 452 BranchSize = AllocBytes / 453 static_cast<unsigned>(sizeof(KeyT) + sizeof(void*)) 454 }; 455 456 /// Allocator - The recycling allocator used for both branch and leaf nodes. 457 /// This typedef is very likely to be identical for all IntervalMaps with 458 /// reasonably sized entries, so the same allocator can be shared among 459 /// different kinds of maps. 460 typedef RecyclingAllocator<BumpPtrAllocator, char, 461 AllocBytes, CacheLineBytes> Allocator; 462 463 }; 464 465 466 //===----------------------------------------------------------------------===// 467 //--- IntervalMapImpl::NodeRef ---// 468 //===----------------------------------------------------------------------===// 469 // 470 // B+-tree nodes can be leaves or branches, so we need a polymorphic node 471 // pointer that can point to both kinds. 472 // 473 // All nodes are cache line aligned and the low 6 bits of a node pointer are 474 // always 0. These bits are used to store the number of elements in the 475 // referenced node. Besides saving space, placing node sizes in the parents 476 // allow tree balancing algorithms to run without faulting cache lines for nodes 477 // that may not need to be modified. 478 // 479 // A NodeRef doesn't know whether it references a leaf node or a branch node. 480 // It is the responsibility of the caller to use the correct types. 481 // 482 // Nodes are never supposed to be empty, and it is invalid to store a node size 483 // of 0 in a NodeRef. The valid range of sizes is 1-64. 484 // 485 //===----------------------------------------------------------------------===// 486 487 class NodeRef { 488 struct CacheAlignedPointerTraits { 489 static inline void *getAsVoidPointer(void *P) { return P; } 490 static inline void *getFromVoidPointer(void *P) { return P; } 491 enum { NumLowBitsAvailable = Log2CacheLine }; 492 }; 493 PointerIntPair<void*, Log2CacheLine, unsigned, CacheAlignedPointerTraits> pip; 494 495 public: 496 /// NodeRef - Create a null ref. 497 NodeRef() {} 498 499 /// operator bool - Detect a null ref. 500 explicit operator bool() const { return pip.getOpaqueValue(); } 501 502 /// NodeRef - Create a reference to the node p with n elements. 503 template <typename NodeT> 504 NodeRef(NodeT *p, unsigned n) : pip(p, n - 1) { 505 assert(n <= NodeT::Capacity && "Size too big for node"); 506 } 507 508 /// size - Return the number of elements in the referenced node. 509 unsigned size() const { return pip.getInt() + 1; } 510 511 /// setSize - Update the node size. 512 void setSize(unsigned n) { pip.setInt(n - 1); } 513 514 /// subtree - Access the i'th subtree reference in a branch node. 515 /// This depends on branch nodes storing the NodeRef array as their first 516 /// member. 517 NodeRef &subtree(unsigned i) const { 518 return reinterpret_cast<NodeRef*>(pip.getPointer())[i]; 519 } 520 521 /// get - Dereference as a NodeT reference. 522 template <typename NodeT> 523 NodeT &get() const { 524 return *reinterpret_cast<NodeT*>(pip.getPointer()); 525 } 526 527 bool operator==(const NodeRef &RHS) const { 528 if (pip == RHS.pip) 529 return true; 530 assert(pip.getPointer() != RHS.pip.getPointer() && "Inconsistent NodeRefs"); 531 return false; 532 } 533 534 bool operator!=(const NodeRef &RHS) const { 535 return !operator==(RHS); 536 } 537 }; 538 539 //===----------------------------------------------------------------------===// 540 //--- IntervalMapImpl::LeafNode ---// 541 //===----------------------------------------------------------------------===// 542 // 543 // Leaf nodes store up to N disjoint intervals with corresponding values. 544 // 545 // The intervals are kept sorted and fully coalesced so there are no adjacent 546 // intervals mapping to the same value. 547 // 548 // These constraints are always satisfied: 549 // 550 // - Traits::stopLess(start(i), stop(i)) - Non-empty, sane intervals. 551 // 552 // - Traits::stopLess(stop(i), start(i + 1) - Sorted. 553 // 554 // - value(i) != value(i + 1) || !Traits::adjacent(stop(i), start(i + 1)) 555 // - Fully coalesced. 556 // 557 //===----------------------------------------------------------------------===// 558 559 template <typename KeyT, typename ValT, unsigned N, typename Traits> 560 class LeafNode : public NodeBase<std::pair<KeyT, KeyT>, ValT, N> { 561 public: 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]; } 565 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]; } 569 570 /// findFrom - Find the first interval after i that may contain x. 571 /// @param i Starting index for the search. 572 /// @param Size Number of elements in node. 573 /// @param x Key to search for. 574 /// @return First index with !stopLess(key[i].stop, x), or size. 575 /// This is the first interval that can possibly contain x. 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; 581 return i; 582 } 583 584 /// safeFind - Find an interval that is known to exist. This is the same as 585 /// findFrom except is it assumed that x is at least within range of the last 586 /// interval. 587 /// @param i Starting index for the search. 588 /// @param x Key to search for. 589 /// @return First index with !stopLess(key[i].stop, x), never size. 590 /// This is the first interval that can possibly contain x. 591 unsigned safeFind(unsigned i, KeyT x) const { 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"); 597 return i; 598 } 599 600 /// safeLookup - Lookup mapped value for a safe key. 601 /// It is assumed that x is within range of the last entry. 602 /// @param x Key to search for. 603 /// @param NotFound Value to return if x is not in any interval. 604 /// @return The mapped value at x or NotFound. 605 ValT safeLookup(KeyT x, ValT NotFound) const { 606 unsigned i = safeFind(0, x); 607 return Traits::startLess(x, start(i)) ? NotFound : value(i); 608 } 609 610 unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y); 611 }; 612 613 /// insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as 614 /// possible. This may cause the node to grow by 1, or it may cause the node 615 /// to shrink because of coalescing. 616 /// @param Pos Starting index = insertFrom(0, size, a) 617 /// @param Size Number of elements in node. 618 /// @param a Interval start. 619 /// @param b Interval stop. 620 /// @param y Value be mapped. 621 /// @return (insert position, new size), or (i, Capacity+1) on overflow. 622 template <typename KeyT, typename ValT, unsigned N, typename Traits> 623 unsigned LeafNode<KeyT, ValT, N, Traits>:: 624 insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y) { 625 unsigned i = Pos; 626 assert(i <= Size && Size <= N && "Invalid index"); 627 assert(!Traits::stopLess(b, a) && "Invalid interval"); 628 629 // Verify the findFrom invariant. 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"); 633 634 // Coalesce with previous interval. 635 if (i && value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) { 636 Pos = i - 1; 637 // Also coalesce with next interval? 638 if (i != Size && value(i) == y && Traits::adjacent(b, start(i))) { 639 stop(i - 1) = stop(i); 640 this->erase(i, Size); 641 return Size - 1; 642 } 643 stop(i - 1) = b; 644 return Size; 645 } 646 647 // Detect overflow. 648 if (i == N) 649 return N + 1; 650 651 // Add new interval at end. 652 if (i == Size) { 653 start(i) = a; 654 stop(i) = b; 655 value(i) = y; 656 return Size + 1; 657 } 658 659 // Try to coalesce with following interval. 660 if (value(i) == y && Traits::adjacent(b, start(i))) { 661 start(i) = a; 662 return Size; 663 } 664 665 // We must insert before i. Detect overflow. 666 if (Size == N) 667 return N + 1; 668 669 // Insert before i. 670 this->shift(i, Size); 671 start(i) = a; 672 stop(i) = b; 673 value(i) = y; 674 return Size + 1; 675 } 676 677 678 //===----------------------------------------------------------------------===// 679 //--- IntervalMapImpl::BranchNode ---// 680 //===----------------------------------------------------------------------===// 681 // 682 // A branch node stores references to 1--N subtrees all of the same height. 683 // 684 // The key array in a branch node holds the rightmost stop key of each subtree. 685 // It is redundant to store the last stop key since it can be found in the 686 // parent node, but doing so makes tree balancing a lot simpler. 687 // 688 // It is unusual for a branch node to only have one subtree, but it can happen 689 // in the root node if it is smaller than the normal nodes. 690 // 691 // When all of the leaf nodes from all the subtrees are concatenated, they must 692 // satisfy the same constraints as a single leaf node. They must be sorted, 693 // sane, and fully coalesced. 694 // 695 //===----------------------------------------------------------------------===// 696 697 template <typename KeyT, typename ValT, unsigned N, typename Traits> 698 class BranchNode : public NodeBase<NodeRef, KeyT, N> { 699 public: 700 const KeyT &stop(unsigned i) const { return this->second[i]; } 701 const NodeRef &subtree(unsigned i) const { return this->first[i]; } 702 703 KeyT &stop(unsigned i) { return this->second[i]; } 704 NodeRef &subtree(unsigned i) { return this->first[i]; } 705 706 /// findFrom - Find the first subtree after i that may contain x. 707 /// @param i Starting index for the search. 708 /// @param Size Number of elements in node. 709 /// @param x Key to search for. 710 /// @return First index with !stopLess(key[i], x), or size. 711 /// This is the first subtree that can possibly contain x. 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; 717 return i; 718 } 719 720 /// safeFind - Find a subtree that is known to exist. This is the same as 721 /// findFrom except is it assumed that x is in range. 722 /// @param i Starting index for the search. 723 /// @param x Key to search for. 724 /// @return First index with !stopLess(key[i], x), never size. 725 /// This is the first subtree that can possibly contain x. 726 unsigned safeFind(unsigned i, KeyT x) const { 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"); 732 return i; 733 } 734 735 /// safeLookup - Get the subtree containing x, Assuming that x is in range. 736 /// @param x Key to search for. 737 /// @return Subtree containing x 738 NodeRef safeLookup(KeyT x) const { 739 return subtree(safeFind(0, x)); 740 } 741 742 /// insert - Insert a new (subtree, stop) pair. 743 /// @param i Insert position, following entries will be shifted. 744 /// @param Size Number of elements in node. 745 /// @param Node Subtree to insert. 746 /// @param Stop Last key in subtree. 747 void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop) { 748 assert(Size < N && "branch node overflow"); 749 assert(i <= Size && "Bad insert position"); 750 this->shift(i, Size); 751 subtree(i) = Node; 752 stop(i) = Stop; 753 } 754 }; 755 756 //===----------------------------------------------------------------------===// 757 //--- IntervalMapImpl::Path ---// 758 //===----------------------------------------------------------------------===// 759 // 760 // A Path is used by iterators to represent a position in a B+-tree, and the 761 // path to get there from the root. 762 // 763 // The Path class also contains the tree navigation code that doesn't have to 764 // be templatized. 765 // 766 //===----------------------------------------------------------------------===// 767 768 class Path { 769 /// Entry - Each step in the path is a node pointer and an offset into that 770 /// node. 771 struct Entry { 772 void *node; 773 unsigned size; 774 unsigned offset; 775 776 Entry(void *Node, unsigned Size, unsigned Offset) 777 : node(Node), size(Size), offset(Offset) {} 778 779 Entry(NodeRef Node, unsigned Offset) 780 : node(&Node.subtree(0)), size(Node.size()), offset(Offset) {} 781 782 NodeRef &subtree(unsigned i) const { 783 return reinterpret_cast<NodeRef*>(node)[i]; 784 } 785 }; 786 787 /// path - The path entries, path[0] is the root node, path.back() is a leaf. 788 SmallVector<Entry, 4> path; 789 790 public: 791 // Node accessors. 792 template <typename NodeT> NodeT &node(unsigned Level) const { 793 return *reinterpret_cast<NodeT*>(path[Level].node); 794 } 795 unsigned size(unsigned Level) const { return path[Level].size; } 796 unsigned offset(unsigned Level) const { return path[Level].offset; } 797 unsigned &offset(unsigned Level) { return path[Level].offset; } 798 799 // Leaf accessors. 800 template <typename NodeT> NodeT &leaf() const { 801 return *reinterpret_cast<NodeT*>(path.back().node); 802 } 803 unsigned leafSize() const { return path.back().size; } 804 unsigned leafOffset() const { return path.back().offset; } 805 unsigned &leafOffset() { return path.back().offset; } 806 807 /// valid - Return true if path is at a valid node, not at end(). 808 bool valid() const { 809 return !path.empty() && path.front().offset < path.front().size; 810 } 811 812 /// height - Return the height of the tree corresponding to this path. 813 /// This matches map->height in a full path. 814 unsigned height() const { return path.size() - 1; } 815 816 /// subtree - Get the subtree referenced from Level. When the path is 817 /// consistent, node(Level + 1) == subtree(Level). 818 /// @param Level 0..height-1. The leaves have no subtrees. 819 NodeRef &subtree(unsigned Level) const { 820 return path[Level].subtree(path[Level].offset); 821 } 822 823 /// reset - Reset cached information about node(Level) from subtree(Level -1). 824 /// @param Level 1..height. THe node to update after parent node changed. 825 void reset(unsigned Level) { 826 path[Level] = Entry(subtree(Level - 1), offset(Level)); 827 } 828 829 /// push - Add entry to path. 830 /// @param Node Node to add, should be subtree(path.size()-1). 831 /// @param Offset Offset into Node. 832 void push(NodeRef Node, unsigned Offset) { 833 path.push_back(Entry(Node, Offset)); 834 } 835 836 /// pop - Remove the last path entry. 837 void pop() { 838 path.pop_back(); 839 } 840 841 /// setSize - Set the size of a node both in the path and in the tree. 842 /// @param Level 0..height. Note that setting the root size won't change 843 /// map->rootSize. 844 /// @param Size New node size. 845 void setSize(unsigned Level, unsigned Size) { 846 path[Level].size = Size; 847 if (Level) 848 subtree(Level - 1).setSize(Size); 849 } 850 851 /// setRoot - Clear the path and set a new root node. 852 /// @param Node New root node. 853 /// @param Size New root size. 854 /// @param Offset Offset into root node. 855 void setRoot(void *Node, unsigned Size, unsigned Offset) { 856 path.clear(); 857 path.push_back(Entry(Node, Size, Offset)); 858 } 859 860 /// replaceRoot - Replace the current root node with two new entries after the 861 /// tree height has increased. 862 /// @param Root The new root node. 863 /// @param Size Number of entries in the new root. 864 /// @param Offsets Offsets into the root and first branch nodes. 865 void replaceRoot(void *Root, unsigned Size, IdxPair Offsets); 866 867 /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef. 868 /// @param Level Get the sibling to node(Level). 869 /// @return Left sibling, or NodeRef(). 870 NodeRef getLeftSibling(unsigned Level) const; 871 872 /// moveLeft - Move path to the left sibling at Level. Leave nodes below Level 873 /// unaltered. 874 /// @param Level Move node(Level). 875 void moveLeft(unsigned Level); 876 877 /// fillLeft - Grow path to Height by taking leftmost branches. 878 /// @param Height The target height. 879 void fillLeft(unsigned Height) { 880 while (height() < Height) 881 push(subtree(height()), 0); 882 } 883 884 /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef. 885 /// @param Level Get the sinbling to node(Level). 886 /// @return Left sibling, or NodeRef(). 887 NodeRef getRightSibling(unsigned Level) const; 888 889 /// moveRight - Move path to the left sibling at Level. Leave nodes below 890 /// Level unaltered. 891 /// @param Level Move node(Level). 892 void moveRight(unsigned Level); 893 894 /// atBegin - Return true if path is at begin(). 895 bool atBegin() const { 896 for (unsigned i = 0, e = path.size(); i != e; ++i) 897 if (path[i].offset != 0) 898 return false; 899 return true; 900 } 901 902 /// atLastEntry - Return true if the path is at the last entry of the node at 903 /// Level. 904 /// @param Level Node to examine. 905 bool atLastEntry(unsigned Level) const { 906 return path[Level].offset == path[Level].size - 1; 907 } 908 909 /// legalizeForInsert - Prepare the path for an insertion at Level. When the 910 /// path is at end(), node(Level) may not be a legal node. legalizeForInsert 911 /// ensures that node(Level) is real by moving back to the last node at Level, 912 /// and setting offset(Level) to size(Level) if required. 913 /// @param Level The level where an insertion is about to take place. 914 void legalizeForInsert(unsigned Level) { 915 if (valid()) 916 return; 917 moveLeft(Level); 918 ++path[Level].offset; 919 } 920 }; 921 922 } // namespace IntervalMapImpl 923 924 925 //===----------------------------------------------------------------------===// 926 //--- IntervalMap ----// 927 //===----------------------------------------------------------------------===// 928 929 template <typename KeyT, typename ValT, 930 unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize, 931 typename Traits = IntervalMapInfo<KeyT> > 932 class IntervalMap { 933 typedef IntervalMapImpl::NodeSizer<KeyT, ValT> Sizer; 934 typedef IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits> Leaf; 935 typedef IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits> 936 Branch; 937 typedef IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits> RootLeaf; 938 typedef IntervalMapImpl::IdxPair IdxPair; 939 940 // The RootLeaf capacity is given as a template parameter. We must compute the 941 // corresponding RootBranch capacity. 942 enum { 943 DesiredRootBranchCap = (sizeof(RootLeaf) - sizeof(KeyT)) / 944 (sizeof(KeyT) + sizeof(IntervalMapImpl::NodeRef)), 945 RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1 946 }; 947 948 typedef IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits> 949 RootBranch; 950 951 // When branched, we store a global start key as well as the branch node. 952 struct RootBranchData { 953 KeyT start; 954 RootBranch node; 955 }; 956 957 public: 958 typedef typename Sizer::Allocator Allocator; 959 typedef KeyT KeyType; 960 typedef ValT ValueType; 961 typedef Traits KeyTraits; 962 963 private: 964 // The root data is either a RootLeaf or a RootBranchData instance. 965 AlignedCharArrayUnion<RootLeaf, RootBranchData> data; 966 967 // Tree height. 968 // 0: Leaves in root. 969 // 1: Root points to leaf. 970 // 2: root->branch->leaf ... 971 unsigned height; 972 973 // Number of entries in the root node. 974 unsigned rootSize; 975 976 // Allocator used for creating external nodes. 977 Allocator &allocator; 978 979 /// dataAs - Represent data as a node type without breaking aliasing rules. 980 template <typename T> 981 T &dataAs() const { 982 union { 983 const char *d; 984 T *t; 985 } u; 986 u.d = data.buffer; 987 return *u.t; 988 } 989 990 const RootLeaf &rootLeaf() const { 991 assert(!branched() && "Cannot acces leaf data in branched root"); 992 return dataAs<RootLeaf>(); 993 } 994 RootLeaf &rootLeaf() { 995 assert(!branched() && "Cannot acces leaf data in branched root"); 996 return dataAs<RootLeaf>(); 997 } 998 RootBranchData &rootBranchData() const { 999 assert(branched() && "Cannot access branch data in non-branched root"); 1000 return dataAs<RootBranchData>(); 1001 } 1002 RootBranchData &rootBranchData() { 1003 assert(branched() && "Cannot access branch data in non-branched root"); 1004 return dataAs<RootBranchData>(); 1005 } 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; } 1010 1011 template <typename NodeT> NodeT *newNode() { 1012 return new(allocator.template Allocate<NodeT>()) NodeT(); 1013 } 1014 1015 template <typename NodeT> void deleteNode(NodeT *P) { 1016 P->~NodeT(); 1017 allocator.Deallocate(P); 1018 } 1019 1020 IdxPair branchRoot(unsigned Position); 1021 IdxPair splitRoot(unsigned Position); 1022 1023 void switchRootToBranch() { 1024 rootLeaf().~RootLeaf(); 1025 height = 1; 1026 new (&rootBranchData()) RootBranchData(); 1027 } 1028 1029 void switchRootToLeaf() { 1030 rootBranchData().~RootBranchData(); 1031 height = 0; 1032 new(&rootLeaf()) RootLeaf(); 1033 } 1034 1035 bool branched() const { return height > 0; } 1036 1037 ValT treeSafeLookup(KeyT x, ValT NotFound) const; 1038 void visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef, 1039 unsigned Level)); 1040 void deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level); 1041 1042 public: 1043 explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) { 1044 assert((uintptr_t(data.buffer) & (alignOf<RootLeaf>() - 1)) == 0 && 1045 "Insufficient alignment"); 1046 new(&rootLeaf()) RootLeaf(); 1047 } 1048 1049 ~IntervalMap() { 1050 clear(); 1051 rootLeaf().~RootLeaf(); 1052 } 1053 1054 /// empty - Return true when no intervals are mapped. 1055 bool empty() const { 1056 return rootSize == 0; 1057 } 1058 1059 /// start - Return the smallest mapped key in a non-empty map. 1060 KeyT start() const { 1061 assert(!empty() && "Empty IntervalMap has no start"); 1062 return !branched() ? rootLeaf().start(0) : rootBranchStart(); 1063 } 1064 1065 /// stop - Return the largest mapped key in a non-empty map. 1066 KeyT stop() const { 1067 assert(!empty() && "Empty IntervalMap has no stop"); 1068 return !branched() ? rootLeaf().stop(rootSize - 1) : 1069 rootBranch().stop(rootSize - 1); 1070 } 1071 1072 /// lookup - Return the mapped value at x or NotFound. 1073 ValT lookup(KeyT x, ValT NotFound = ValT()) const { 1074 if (empty() || Traits::startLess(x, start()) || Traits::stopLess(stop(), x)) 1075 return NotFound; 1076 return branched() ? treeSafeLookup(x, NotFound) : 1077 rootLeaf().safeLookup(x, NotFound); 1078 } 1079 1080 /// insert - Add a mapping of [a;b] to y, coalesce with adjacent intervals. 1081 /// It is assumed that no key in the interval is mapped to another value, but 1082 /// overlapping intervals already mapped to y will be coalesced. 1083 void insert(KeyT a, KeyT b, ValT y) { 1084 if (branched() || rootSize == RootLeaf::Capacity) 1085 return find(a).insert(a, b, y); 1086 1087 // Easy insert into root leaf. 1088 unsigned p = rootLeaf().findFrom(0, rootSize, a); 1089 rootSize = rootLeaf().insertFrom(p, rootSize, a, b, y); 1090 } 1091 1092 /// clear - Remove all entries. 1093 void clear(); 1094 1095 class const_iterator; 1096 class iterator; 1097 friend class const_iterator; 1098 friend class iterator; 1099 1100 const_iterator begin() const { 1101 const_iterator I(*this); 1102 I.goToBegin(); 1103 return I; 1104 } 1105 1106 iterator begin() { 1107 iterator I(*this); 1108 I.goToBegin(); 1109 return I; 1110 } 1111 1112 const_iterator end() const { 1113 const_iterator I(*this); 1114 I.goToEnd(); 1115 return I; 1116 } 1117 1118 iterator end() { 1119 iterator I(*this); 1120 I.goToEnd(); 1121 return I; 1122 } 1123 1124 /// find - Return an iterator pointing to the first interval ending at or 1125 /// after x, or end(). 1126 const_iterator find(KeyT x) const { 1127 const_iterator I(*this); 1128 I.find(x); 1129 return I; 1130 } 1131 1132 iterator find(KeyT x) { 1133 iterator I(*this); 1134 I.find(x); 1135 return I; 1136 } 1137 }; 1138 1139 /// treeSafeLookup - Return the mapped value at x or NotFound, assuming a 1140 /// branched root. 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"); 1145 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); 1150 } 1151 1152 1153 // branchRoot - Switch from a leaf root to a branched root. 1154 // Return the new (root offset, node offset) corresponding to Position. 1155 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1156 IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>:: 1157 branchRoot(unsigned Position) { 1158 using namespace IntervalMapImpl; 1159 // How many external leaf nodes to hold RootLeaf+1? 1160 const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1; 1161 1162 // Compute element distribution among new nodes. 1163 unsigned size[Nodes]; 1164 IdxPair NewOffset(0, Position); 1165 1166 // Is is very common for the root node to be smaller than external nodes. 1167 if (Nodes == 1) 1168 size[0] = rootSize; 1169 else 1170 NewOffset = distribute(Nodes, rootSize, Leaf::Capacity, nullptr, size, 1171 Position, true); 1172 1173 // Allocate new nodes. 1174 unsigned pos = 0; 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]); 1180 pos += size[n]; 1181 } 1182 1183 // Destroy the old leaf node, construct branch node instead. 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]; 1188 } 1189 rootBranchStart() = node[0].template get<Leaf>().start(0); 1190 rootSize = Nodes; 1191 return NewOffset; 1192 } 1193 1194 // splitRoot - Split the current BranchRoot into multiple Branch nodes. 1195 // Return the new (root offset, node offset) corresponding to Position. 1196 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1197 IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>:: 1198 splitRoot(unsigned Position) { 1199 using namespace IntervalMapImpl; 1200 // How many external leaf nodes to hold RootBranch+1? 1201 const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1; 1202 1203 // Compute element distribution among new nodes. 1204 unsigned Size[Nodes]; 1205 IdxPair NewOffset(0, Position); 1206 1207 // Is is very common for the root node to be smaller than external nodes. 1208 if (Nodes == 1) 1209 Size[0] = rootSize; 1210 else 1211 NewOffset = distribute(Nodes, rootSize, Leaf::Capacity, nullptr, Size, 1212 Position, true); 1213 1214 // Allocate new nodes. 1215 unsigned Pos = 0; 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]); 1221 Pos += Size[n]; 1222 } 1223 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]; 1227 } 1228 rootSize = Nodes; 1229 ++height; 1230 return NewOffset; 1231 } 1232 1233 /// visitNodes - Visit each external node. 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)) { 1237 if (!branched()) 1238 return; 1239 SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs; 1240 1241 // Collect level 0 nodes from the root. 1242 for (unsigned i = 0; i != rootSize; ++i) 1243 Refs.push_back(rootBranch().subtree(i)); 1244 1245 // Visit all branch nodes. 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); 1251 } 1252 Refs.clear(); 1253 Refs.swap(NextRefs); 1254 } 1255 1256 // Visit all leaf nodes. 1257 for (unsigned i = 0, e = Refs.size(); i != e; ++i) 1258 (this->*f)(Refs[i], 0); 1259 } 1260 1261 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1262 void IntervalMap<KeyT, ValT, N, Traits>:: 1263 deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level) { 1264 if (Level) 1265 deleteNode(&Node.get<Branch>()); 1266 else 1267 deleteNode(&Node.get<Leaf>()); 1268 } 1269 1270 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1271 void IntervalMap<KeyT, ValT, N, Traits>:: 1272 clear() { 1273 if (branched()) { 1274 visitNodes(&IntervalMap::deleteNode); 1275 switchRootToLeaf(); 1276 } 1277 rootSize = 0; 1278 } 1279 1280 //===----------------------------------------------------------------------===// 1281 //--- IntervalMap::const_iterator ----// 1282 //===----------------------------------------------------------------------===// 1283 1284 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1285 class IntervalMap<KeyT, ValT, N, Traits>::const_iterator : 1286 public std::iterator<std::bidirectional_iterator_tag, ValT> { 1287 protected: 1288 friend class IntervalMap; 1289 1290 // The map referred to. 1291 IntervalMap *map; 1292 1293 // We store a full path from the root to the current position. 1294 // The path may be partially filled, but never between iterator calls. 1295 IntervalMapImpl::Path path; 1296 1297 explicit const_iterator(const IntervalMap &map) : 1298 map(const_cast<IntervalMap*>(&map)) {} 1299 1300 bool branched() const { 1301 assert(map && "Invalid iterator"); 1302 return map->branched(); 1303 } 1304 1305 void setRoot(unsigned Offset) { 1306 if (branched()) 1307 path.setRoot(&map->rootBranch(), map->rootSize, Offset); 1308 else 1309 path.setRoot(&map->rootLeaf(), map->rootSize, Offset); 1310 } 1311 1312 void pathFillFind(KeyT x); 1313 void treeFind(KeyT x); 1314 void treeAdvanceTo(KeyT x); 1315 1316 /// unsafeStart - Writable access to start() for iterator. 1317 KeyT &unsafeStart() const { 1318 assert(valid() && "Cannot access invalid iterator"); 1319 return branched() ? path.leaf<Leaf>().start(path.leafOffset()) : 1320 path.leaf<RootLeaf>().start(path.leafOffset()); 1321 } 1322 1323 /// unsafeStop - Writable access to stop() for iterator. 1324 KeyT &unsafeStop() const { 1325 assert(valid() && "Cannot access invalid iterator"); 1326 return branched() ? path.leaf<Leaf>().stop(path.leafOffset()) : 1327 path.leaf<RootLeaf>().stop(path.leafOffset()); 1328 } 1329 1330 /// unsafeValue - Writable access to value() for iterator. 1331 ValT &unsafeValue() const { 1332 assert(valid() && "Cannot access invalid iterator"); 1333 return branched() ? path.leaf<Leaf>().value(path.leafOffset()) : 1334 path.leaf<RootLeaf>().value(path.leafOffset()); 1335 } 1336 1337 public: 1338 /// const_iterator - Create an iterator that isn't pointing anywhere. 1339 const_iterator() : map(nullptr) {} 1340 1341 /// setMap - Change the map iterated over. This call must be followed by a 1342 /// call to goToBegin(), goToEnd(), or find() 1343 void setMap(const IntervalMap &m) { map = const_cast<IntervalMap*>(&m); } 1344 1345 /// valid - Return true if the current position is valid, false for end(). 1346 bool valid() const { return path.valid(); } 1347 1348 /// atBegin - Return true if the current position is the first map entry. 1349 bool atBegin() const { return path.atBegin(); } 1350 1351 /// start - Return the beginning of the current interval. 1352 const KeyT &start() const { return unsafeStart(); } 1353 1354 /// stop - Return the end of the current interval. 1355 const KeyT &stop() const { return unsafeStop(); } 1356 1357 /// value - Return the mapped value at the current interval. 1358 const ValT &value() const { return unsafeValue(); } 1359 1360 const ValT &operator*() const { return value(); } 1361 1362 bool operator==(const const_iterator &RHS) const { 1363 assert(map == RHS.map && "Cannot compare iterators from different maps"); 1364 if (!valid()) 1365 return !RHS.valid(); 1366 if (path.leafOffset() != RHS.path.leafOffset()) 1367 return false; 1368 return &path.template leaf<Leaf>() == &RHS.path.template leaf<Leaf>(); 1369 } 1370 1371 bool operator!=(const const_iterator &RHS) const { 1372 return !operator==(RHS); 1373 } 1374 1375 /// goToBegin - Move to the first interval in map. 1376 void goToBegin() { 1377 setRoot(0); 1378 if (branched()) 1379 path.fillLeft(map->height); 1380 } 1381 1382 /// goToEnd - Move beyond the last interval in map. 1383 void goToEnd() { 1384 setRoot(map->rootSize); 1385 } 1386 1387 /// preincrement - move to the next interval. 1388 const_iterator &operator++() { 1389 assert(valid() && "Cannot increment end()"); 1390 if (++path.leafOffset() == path.leafSize() && branched()) 1391 path.moveRight(map->height); 1392 return *this; 1393 } 1394 1395 /// postincrement - Dont do that! 1396 const_iterator operator++(int) { 1397 const_iterator tmp = *this; 1398 operator++(); 1399 return tmp; 1400 } 1401 1402 /// predecrement - move to the previous interval. 1403 const_iterator &operator--() { 1404 if (path.leafOffset() && (valid() || !branched())) 1405 --path.leafOffset(); 1406 else 1407 path.moveLeft(map->height); 1408 return *this; 1409 } 1410 1411 /// postdecrement - Dont do that! 1412 const_iterator operator--(int) { 1413 const_iterator tmp = *this; 1414 operator--(); 1415 return tmp; 1416 } 1417 1418 /// find - Move to the first interval with stop >= x, or end(). 1419 /// This is a full search from the root, the current position is ignored. 1420 void find(KeyT x) { 1421 if (branched()) 1422 treeFind(x); 1423 else 1424 setRoot(map->rootLeaf().findFrom(0, map->rootSize, x)); 1425 } 1426 1427 /// advanceTo - Move to the first interval with stop >= x, or end(). 1428 /// The search is started from the current position, and no earlier positions 1429 /// can be found. This is much faster than find() for small moves. 1430 void advanceTo(KeyT x) { 1431 if (!valid()) 1432 return; 1433 if (branched()) 1434 treeAdvanceTo(x); 1435 else 1436 path.leafOffset() = 1437 map->rootLeaf().findFrom(path.leafOffset(), map->rootSize, x); 1438 } 1439 1440 }; 1441 1442 /// pathFillFind - Complete path by searching for x. 1443 /// @param x Key to search for. 1444 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1445 void IntervalMap<KeyT, ValT, N, Traits>:: 1446 const_iterator::pathFillFind(KeyT x) { 1447 IntervalMapImpl::NodeRef NR = path.subtree(path.height()); 1448 for (unsigned i = map->height - path.height() - 1; i; --i) { 1449 unsigned p = NR.get<Branch>().safeFind(0, x); 1450 path.push(NR, p); 1451 NR = NR.subtree(p); 1452 } 1453 path.push(NR, NR.get<Leaf>().safeFind(0, x)); 1454 } 1455 1456 /// treeFind - Find in a branched tree. 1457 /// @param x Key to search for. 1458 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1459 void IntervalMap<KeyT, ValT, N, Traits>:: 1460 const_iterator::treeFind(KeyT x) { 1461 setRoot(map->rootBranch().findFrom(0, map->rootSize, x)); 1462 if (valid()) 1463 pathFillFind(x); 1464 } 1465 1466 /// treeAdvanceTo - Find position after the current one. 1467 /// @param x Key to search for. 1468 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1469 void IntervalMap<KeyT, ValT, N, Traits>:: 1470 const_iterator::treeAdvanceTo(KeyT x) { 1471 // Can we stay on the same leaf node? 1472 if (!Traits::stopLess(path.leaf<Leaf>().stop(path.leafSize() - 1), x)) { 1473 path.leafOffset() = path.leaf<Leaf>().safeFind(path.leafOffset(), x); 1474 return; 1475 } 1476 1477 // Drop the current leaf. 1478 path.pop(); 1479 1480 // Search towards the root for a usable subtree. 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)) { 1484 // The branch node at l+1 is usable 1485 path.offset(l + 1) = 1486 path.node<Branch>(l + 1).safeFind(path.offset(l + 1), x); 1487 return pathFillFind(x); 1488 } 1489 path.pop(); 1490 } 1491 // Is the level-1 Branch usable? 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); 1495 } 1496 } 1497 1498 // We reached the root. 1499 setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x)); 1500 if (valid()) 1501 pathFillFind(x); 1502 } 1503 1504 //===----------------------------------------------------------------------===// 1505 //--- IntervalMap::iterator ----// 1506 //===----------------------------------------------------------------------===// 1507 1508 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1509 class IntervalMap<KeyT, ValT, N, Traits>::iterator : public const_iterator { 1510 friend class IntervalMap; 1511 typedef IntervalMapImpl::IdxPair IdxPair; 1512 1513 explicit iterator(IntervalMap &map) : const_iterator(map) {} 1514 1515 void setNodeStop(unsigned Level, KeyT Stop); 1516 bool insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, 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); 1523 1524 public: 1525 /// iterator - Create null iterator. 1526 iterator() {} 1527 1528 /// setStart - Move the start of the current interval. 1529 /// This may cause coalescing with the previous interval. 1530 /// @param a New start key, must not overlap the previous interval. 1531 void setStart(KeyT a); 1532 1533 /// setStop - Move the end of the current interval. 1534 /// This may cause coalescing with the following interval. 1535 /// @param b New stop key, must not overlap the following interval. 1536 void setStop(KeyT b); 1537 1538 /// setValue - Change the mapped value of the current interval. 1539 /// This may cause coalescing with the previous and following intervals. 1540 /// @param x New value. 1541 void setValue(ValT x); 1542 1543 /// setStartUnchecked - Move the start of the current interval without 1544 /// checking for coalescing or overlaps. 1545 /// This should only be used when it is known that coalescing is not required. 1546 /// @param a New start key. 1547 void setStartUnchecked(KeyT a) { this->unsafeStart() = a; } 1548 1549 /// setStopUnchecked - Move the end of the current interval without checking 1550 /// for coalescing or overlaps. 1551 /// This should only be used when it is known that coalescing is not required. 1552 /// @param b New stop key. 1553 void setStopUnchecked(KeyT b) { 1554 this->unsafeStop() = b; 1555 // Update keys in branch nodes as well. 1556 if (this->path.atLastEntry(this->path.height())) 1557 setNodeStop(this->path.height(), b); 1558 } 1559 1560 /// setValueUnchecked - Change the mapped value of the current interval 1561 /// without checking for coalescing. 1562 /// @param x New value. 1563 void setValueUnchecked(ValT x) { this->unsafeValue() = x; } 1564 1565 /// insert - Insert mapping [a;b] -> y before the current position. 1566 void insert(KeyT a, KeyT b, ValT y); 1567 1568 /// erase - Erase the current interval. 1569 void erase(); 1570 1571 iterator &operator++() { 1572 const_iterator::operator++(); 1573 return *this; 1574 } 1575 1576 iterator operator++(int) { 1577 iterator tmp = *this; 1578 operator++(); 1579 return tmp; 1580 } 1581 1582 iterator &operator--() { 1583 const_iterator::operator--(); 1584 return *this; 1585 } 1586 1587 iterator operator--(int) { 1588 iterator tmp = *this; 1589 operator--(); 1590 return tmp; 1591 } 1592 1593 }; 1594 1595 /// canCoalesceLeft - Can the current interval coalesce to the left after 1596 /// changing start or value? 1597 /// @param Start New start of current interval. 1598 /// @param Value New value for current interval. 1599 /// @return True when updating the current interval would enable coalescing. 1600 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1601 bool IntervalMap<KeyT, ValT, N, Traits>:: 1602 iterator::canCoalesceLeft(KeyT Start, ValT Value) { 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); 1610 } 1611 // Branched. 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); 1619 } 1620 return false; 1621 } 1622 1623 /// canCoalesceRight - Can the current interval coalesce to the right after 1624 /// changing stop or value? 1625 /// @param Stop New stop of current interval. 1626 /// @param Value New value for current interval. 1627 /// @return True when updating the current interval would enable coalescing. 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()) 1636 return false; 1637 RootLeaf &Node = P.leaf<RootLeaf>(); 1638 return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i)); 1639 } 1640 // Branched. 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)); 1647 } 1648 return false; 1649 } 1650 1651 /// setNodeStop - Update the stop key of the current node at level and above. 1652 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1653 void IntervalMap<KeyT, ValT, N, Traits>:: 1654 iterator::setNodeStop(unsigned Level, KeyT Stop) { 1655 // There are no references to the root node, so nothing to update. 1656 if (!Level) 1657 return; 1658 IntervalMapImpl::Path &P = this->path; 1659 // Update nodes pointing to the current node. 1660 while (--Level) { 1661 P.node<Branch>(Level).stop(P.offset(Level)) = Stop; 1662 if (!P.atLastEntry(Level)) 1663 return; 1664 } 1665 // Update root separately since it has a different layout. 1666 P.node<RootBranch>(Level).stop(P.offset(Level)) = Stop; 1667 } 1668 1669 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1670 void IntervalMap<KeyT, ValT, N, Traits>:: 1671 iterator::setStart(KeyT a) { 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())) { 1675 CurStart = a; 1676 return; 1677 } 1678 // Coalesce with the interval to the left. 1679 --*this; 1680 a = this->start(); 1681 erase(); 1682 setStartUnchecked(a); 1683 } 1684 1685 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1686 void IntervalMap<KeyT, ValT, N, Traits>:: 1687 iterator::setStop(KeyT b) { 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); 1692 return; 1693 } 1694 // Coalesce with interval to the right. 1695 KeyT a = this->start(); 1696 erase(); 1697 setStartUnchecked(a); 1698 } 1699 1700 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1701 void IntervalMap<KeyT, ValT, N, Traits>:: 1702 iterator::setValue(ValT x) { 1703 setValueUnchecked(x); 1704 if (canCoalesceRight(this->stop(), x)) { 1705 KeyT a = this->start(); 1706 erase(); 1707 setStartUnchecked(a); 1708 } 1709 if (canCoalesceLeft(this->start(), x)) { 1710 --*this; 1711 KeyT a = this->start(); 1712 erase(); 1713 setStartUnchecked(a); 1714 } 1715 } 1716 1717 /// insertNode - insert a node before the current path at level. 1718 /// Leave the current path pointing at the new node. 1719 /// @param Level path index of the node to be inserted. 1720 /// @param Node The node to be inserted. 1721 /// @param Stop The last index in the new node. 1722 /// @return True if the tree height was increased. 1723 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1724 bool IntervalMap<KeyT, ValT, N, Traits>:: 1725 iterator::insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop) { 1726 assert(Level && "Cannot insert next to the root"); 1727 bool SplitRoot = false; 1728 IntervalMap &IM = *this->map; 1729 IntervalMapImpl::Path &P = this->path; 1730 1731 if (Level == 1) { 1732 // Insert into the root branch node. 1733 if (IM.rootSize < RootBranch::Capacity) { 1734 IM.rootBranch().insert(P.offset(0), IM.rootSize, Node, Stop); 1735 P.setSize(0, ++IM.rootSize); 1736 P.reset(Level); 1737 return SplitRoot; 1738 } 1739 1740 // We need to split the root while keeping our position. 1741 SplitRoot = true; 1742 IdxPair Offset = IM.splitRoot(P.offset(0)); 1743 P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset); 1744 1745 // Fall through to insert at the new higher level. 1746 ++Level; 1747 } 1748 1749 // When inserting before end(), make sure we have a valid path. 1750 P.legalizeForInsert(--Level); 1751 1752 // Insert into the branch node at Level-1. 1753 if (P.size(Level) == Branch::Capacity) { 1754 // Branch node is full, handle handle the overflow. 1755 assert(!SplitRoot && "Cannot overflow after splitting the root"); 1756 SplitRoot = overflow<Branch>(Level); 1757 Level += SplitRoot; 1758 } 1759 P.node<Branch>(Level).insert(P.offset(Level), P.size(Level), Node, Stop); 1760 P.setSize(Level, P.size(Level) + 1); 1761 if (P.atLastEntry(Level)) 1762 setNodeStop(Level, Stop); 1763 P.reset(Level + 1); 1764 return SplitRoot; 1765 } 1766 1767 // insert 1768 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1769 void IntervalMap<KeyT, ValT, N, Traits>:: 1770 iterator::insert(KeyT a, KeyT b, ValT y) { 1771 if (this->branched()) 1772 return treeInsert(a, b, y); 1773 IntervalMap &IM = *this->map; 1774 IntervalMapImpl::Path &P = this->path; 1775 1776 // Try simple root leaf insert. 1777 unsigned Size = IM.rootLeaf().insertFrom(P.leafOffset(), IM.rootSize, a, b, y); 1778 1779 // Was the root node insert successful? 1780 if (Size <= RootLeaf::Capacity) { 1781 P.setSize(0, IM.rootSize = Size); 1782 return; 1783 } 1784 1785 // Root leaf node is full, we must branch. 1786 IdxPair Offset = IM.branchRoot(P.leafOffset()); 1787 P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset); 1788 1789 // Now it fits in the new leaf. 1790 treeInsert(a, b, y); 1791 } 1792 1793 1794 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1795 void IntervalMap<KeyT, ValT, N, Traits>:: 1796 iterator::treeInsert(KeyT a, KeyT b, ValT y) { 1797 using namespace IntervalMapImpl; 1798 Path &P = this->path; 1799 1800 if (!P.valid()) 1801 P.legalizeForInsert(this->map->height); 1802 1803 // Check if this insertion will extend the node to the left. 1804 if (P.leafOffset() == 0 && Traits::startLess(a, P.leaf<Leaf>().start(0))) { 1805 // Node is growing to the left, will it affect a left sibling node? 1806 if (NodeRef Sib = P.getLeftSibling(P.height())) { 1807 Leaf &SibLeaf = Sib.get<Leaf>(); 1808 unsigned SibOfs = Sib.size() - 1; 1809 if (SibLeaf.value(SibOfs) == y && 1810 Traits::adjacent(SibLeaf.stop(SibOfs), a)) { 1811 // This insertion will coalesce with the last entry in SibLeaf. We can 1812 // handle it in two ways: 1813 // 1. Extend SibLeaf.stop to b and be done, or 1814 // 2. Extend a to SibLeaf, erase the SibLeaf entry and continue. 1815 // We prefer 1., but need 2 when coalescing to the right as well. 1816 Leaf &CurLeaf = P.leaf<Leaf>(); 1817 P.moveLeft(P.height()); 1818 if (Traits::stopLess(b, CurLeaf.start(0)) && 1819 (y != CurLeaf.value(0) || !Traits::adjacent(b, CurLeaf.start(0)))) { 1820 // Easy, just extend SibLeaf and we're done. 1821 setNodeStop(P.height(), SibLeaf.stop(SibOfs) = b); 1822 return; 1823 } else { 1824 // We have both left and right coalescing. Erase the old SibLeaf entry 1825 // and continue inserting the larger interval. 1826 a = SibLeaf.start(SibOfs); 1827 treeErase(/* UpdateRoot= */false); 1828 } 1829 } 1830 } else { 1831 // No left sibling means we are at begin(). Update cached bound. 1832 this->map->rootBranchStart() = a; 1833 } 1834 } 1835 1836 // When we are inserting at the end of a leaf node, we must update stops. 1837 unsigned Size = P.leafSize(); 1838 bool Grow = P.leafOffset() == Size; 1839 Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), Size, a, b, y); 1840 1841 // Leaf insertion unsuccessful? Overflow and try again. 1842 if (Size > Leaf::Capacity) { 1843 overflow<Leaf>(P.height()); 1844 Grow = P.leafOffset() == P.leafSize(); 1845 Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), P.leafSize(), a, b, y); 1846 assert(Size <= Leaf::Capacity && "overflow() didn't make room"); 1847 } 1848 1849 // Inserted, update offset and leaf size. 1850 P.setSize(P.height(), Size); 1851 1852 // Insert was the last node entry, update stops. 1853 if (Grow) 1854 setNodeStop(P.height(), b); 1855 } 1856 1857 /// erase - erase the current interval and move to the next position. 1858 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1859 void IntervalMap<KeyT, ValT, N, Traits>:: 1860 iterator::erase() { 1861 IntervalMap &IM = *this->map; 1862 IntervalMapImpl::Path &P = this->path; 1863 assert(P.valid() && "Cannot erase end()"); 1864 if (this->branched()) 1865 return treeErase(); 1866 IM.rootLeaf().erase(P.leafOffset(), IM.rootSize); 1867 P.setSize(0, --IM.rootSize); 1868 } 1869 1870 /// treeErase - erase() for a branched tree. 1871 template <typename KeyT, typename ValT, unsigned N, typename Traits> 1872 void IntervalMap<KeyT, ValT, N, Traits>:: 1873 iterator::treeErase(bool UpdateRoot) { 1874 IntervalMap &IM = *this->map; 1875 IntervalMapImpl::Path &P = this->path; 1876 Leaf &Node = P.leaf<Leaf>(); 1877 1878 // Nodes are not allowed to become empty. 1879 if (P.leafSize() == 1) { 1880 IM.deleteNode(&Node); 1881 eraseNode(IM.height); 1882 // Update rootBranchStart if we erased begin(). 1883 if (UpdateRoot && IM.branched() && P.valid() && P.atBegin()) 1884 IM.rootBranchStart() = P.leaf<Leaf>().start(0); 1885 return; 1886 } 1887 1888 // Erase current entry. 1889 Node.erase(P.leafOffset(), P.leafSize()); 1890 unsigned NewSize = P.leafSize() - 1; 1891 P.setSize(IM.height, NewSize); 1892 // When we erase the last entry, update stop and move to a legal position. 1893 if (P.leafOffset() == NewSize) { 1894 setNodeStop(IM.height, Node.stop(NewSize - 1)); 1895 P.moveRight(IM.height); 1896 } else if (UpdateRoot && P.atBegin()) 1897 IM.rootBranchStart() = P.leaf<Leaf>().start(0); 1898 } 1899 1900 /// eraseNode - Erase the current node at Level from its parent and move path to 1901 /// the first entry of the next sibling node. 1902 /// The node must be deallocated by the caller. 1903 /// @param Level 1..height, the root node cannot be erased. 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; 1910 1911 if (--Level == 0) { 1912 IM.rootBranch().erase(P.offset(0), IM.rootSize); 1913 P.setSize(0, --IM.rootSize); 1914 // If this cleared the root, switch to height=0. 1915 if (IM.empty()) { 1916 IM.switchRootToLeaf(); 1917 this->setRoot(0); 1918 return; 1919 } 1920 } else { 1921 // Remove node ref from branch node at Level. 1922 Branch &Parent = P.node<Branch>(Level); 1923 if (P.size(Level) == 1) { 1924 // Branch node became empty, remove it recursively. 1925 IM.deleteNode(&Parent); 1926 eraseNode(Level); 1927 } else { 1928 // Branch node won't become empty. 1929 Parent.erase(P.offset(Level), P.size(Level)); 1930 unsigned NewSize = P.size(Level) - 1; 1931 P.setSize(Level, NewSize); 1932 // If we removed the last branch, update stop and move to a legal pos. 1933 if (P.offset(Level) == NewSize) { 1934 setNodeStop(Level, Parent.stop(NewSize - 1)); 1935 P.moveRight(Level); 1936 } 1937 } 1938 } 1939 // Update path cache for the new right sibling position. 1940 if (P.valid()) { 1941 P.reset(Level + 1); 1942 P.offset(Level + 1) = 0; 1943 } 1944 } 1945 1946 /// overflow - Distribute entries of the current node evenly among 1947 /// its siblings and ensure that the current node is not full. 1948 /// This may require allocating a new node. 1949 /// @tparam NodeT The type of node at Level (Leaf or Branch). 1950 /// @param Level path index of the overflowing node. 1951 /// @return True when the tree height was changed. 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]; 1959 NodeT *Node[4]; 1960 unsigned Nodes = 0; 1961 unsigned Elements = 0; 1962 unsigned Offset = P.offset(Level); 1963 1964 // Do we have a left sibling? 1965 NodeRef LeftSib = P.getLeftSibling(Level); 1966 if (LeftSib) { 1967 Offset += Elements = CurSize[Nodes] = LeftSib.size(); 1968 Node[Nodes++] = &LeftSib.get<NodeT>(); 1969 } 1970 1971 // Current node. 1972 Elements += CurSize[Nodes] = P.size(Level); 1973 Node[Nodes++] = &P.node<NodeT>(Level); 1974 1975 // Do we have a right sibling? 1976 NodeRef RightSib = P.getRightSibling(Level); 1977 if (RightSib) { 1978 Elements += CurSize[Nodes] = RightSib.size(); 1979 Node[Nodes++] = &RightSib.get<NodeT>(); 1980 } 1981 1982 // Do we need to allocate a new node? 1983 unsigned NewNode = 0; 1984 if (Elements + 1 > Nodes * NodeT::Capacity) { 1985 // Insert NewNode at the penultimate position, or after a single node. 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>(); 1991 ++Nodes; 1992 } 1993 1994 // Compute the new element distribution. 1995 unsigned NewSize[4]; 1996 IdxPair NewOffset = distribute(Nodes, Elements, NodeT::Capacity, 1997 CurSize, NewSize, Offset, true); 1998 adjustSiblingSizes(Node, Nodes, CurSize, NewSize); 1999 2000 // Move current location to the leftmost node. 2001 if (LeftSib) 2002 P.moveLeft(Level); 2003 2004 // Elements have been rearranged, now update node sizes and stops. 2005 bool SplitRoot = false; 2006 unsigned Pos = 0; 2007 for (;;) { 2008 KeyT Stop = Node[Pos]->stop(NewSize[Pos]-1); 2009 if (NewNode && Pos == NewNode) { 2010 SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop); 2011 Level += SplitRoot; 2012 } else { 2013 P.setSize(Level, NewSize[Pos]); 2014 setNodeStop(Level, Stop); 2015 } 2016 if (Pos + 1 == Nodes) 2017 break; 2018 P.moveRight(Level); 2019 ++Pos; 2020 } 2021 2022 // Where was I? Find NewOffset. 2023 while(Pos != NewOffset.first) { 2024 P.moveLeft(Level); 2025 --Pos; 2026 } 2027 P.offset(Level) = NewOffset.second; 2028 return SplitRoot; 2029 } 2030 2031 //===----------------------------------------------------------------------===// 2032 //--- IntervalMapOverlaps ----// 2033 //===----------------------------------------------------------------------===// 2034 2035 /// IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two 2036 /// IntervalMaps. The maps may be different, but the KeyT and Traits types 2037 /// should be the same. 2038 /// 2039 /// Typical uses: 2040 /// 2041 /// 1. Test for overlap: 2042 /// bool overlap = IntervalMapOverlaps(a, b).valid(); 2043 /// 2044 /// 2. Enumerate overlaps: 2045 /// for (IntervalMapOverlaps I(a, b); I.valid() ; ++I) { ... } 2046 /// 2047 template <typename MapA, typename MapB> 2048 class IntervalMapOverlaps { 2049 typedef typename MapA::KeyType KeyType; 2050 typedef typename MapA::KeyTraits Traits; 2051 typename MapA::const_iterator posA; 2052 typename MapB::const_iterator posB; 2053 2054 /// advance - Move posA and posB forward until reaching an overlap, or until 2055 /// either meets end. 2056 /// Don't move the iterators if they are already overlapping. 2057 void advance() { 2058 if (!valid()) 2059 return; 2060 2061 if (Traits::stopLess(posA.stop(), posB.start())) { 2062 // A ends before B begins. Catch up. 2063 posA.advanceTo(posB.start()); 2064 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start())) 2065 return; 2066 } else if (Traits::stopLess(posB.stop(), posA.start())) { 2067 // B ends before A begins. Catch up. 2068 posB.advanceTo(posA.start()); 2069 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start())) 2070 return; 2071 } else 2072 // Already overlapping. 2073 return; 2074 2075 for (;;) { 2076 // Make a.end > b.start. 2077 posA.advanceTo(posB.start()); 2078 if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start())) 2079 return; 2080 // Make b.end > a.start. 2081 posB.advanceTo(posA.start()); 2082 if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start())) 2083 return; 2084 } 2085 } 2086 2087 public: 2088 /// IntervalMapOverlaps - Create an iterator for the overlaps of a and b. 2089 IntervalMapOverlaps(const MapA &a, const MapB &b) 2090 : posA(b.empty() ? a.end() : a.find(b.start())), 2091 posB(posA.valid() ? b.find(posA.start()) : b.end()) { advance(); } 2092 2093 /// valid - Return true if iterator is at an overlap. 2094 bool valid() const { 2095 return posA.valid() && posB.valid(); 2096 } 2097 2098 /// a - access the left hand side in the overlap. 2099 const typename MapA::const_iterator &a() const { return posA; } 2100 2101 /// b - access the right hand side in the overlap. 2102 const typename MapB::const_iterator &b() const { return posB; } 2103 2104 /// start - Beginning of the overlapping interval. 2105 KeyType start() const { 2106 KeyType ak = a().start(); 2107 KeyType bk = b().start(); 2108 return Traits::startLess(ak, bk) ? bk : ak; 2109 } 2110 2111 /// stop - End of the overlapping interval. 2112 KeyType stop() const { 2113 KeyType ak = a().stop(); 2114 KeyType bk = b().stop(); 2115 return Traits::startLess(ak, bk) ? ak : bk; 2116 } 2117 2118 /// skipA - Move to the next overlap that doesn't involve a(). 2119 void skipA() { 2120 ++posA; 2121 advance(); 2122 } 2123 2124 /// skipB - Move to the next overlap that doesn't involve b(). 2125 void skipB() { 2126 ++posB; 2127 advance(); 2128 } 2129 2130 /// Preincrement - Move to the next overlap. 2131 IntervalMapOverlaps &operator++() { 2132 // Bump the iterator that ends first. The other one may have more overlaps. 2133 if (Traits::startLess(posB.stop(), posA.stop())) 2134 skipB(); 2135 else 2136 skipA(); 2137 return *this; 2138 } 2139 2140 /// advanceTo - Move to the first overlapping interval with 2141 /// stopLess(x, stop()). 2142 void advanceTo(KeyType x) { 2143 if (!valid()) 2144 return; 2145 // Make sure advanceTo sees monotonic keys. 2146 if (Traits::stopLess(posA.stop(), x)) 2147 posA.advanceTo(x); 2148 if (Traits::stopLess(posB.stop(), x)) 2149 posB.advanceTo(x); 2150 advance(); 2151 } 2152 }; 2153 2154 } // namespace llvm 2155 2156 #endif 2157