LLVM  3.7.0
IntervalMap.h
Go to the documentation of this file.
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"
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>
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>
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 
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.
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.
439  static_cast<unsigned>(2*sizeof(KeyT)+sizeof(ValT)),
442  };
443 
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.
450 
451  // Determine the branching factor for branch nodes.
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,
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  };
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>
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.
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 {
936  Branch;
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 
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.
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 
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>
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.
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.
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.
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!
1397  const_iterator tmp = *this;
1398  operator++();
1399  return tmp;
1400  }
1401 
1402  /// predecrement - move to the previous interval.
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!
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>
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>
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>
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;
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.
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 
1572  const_iterator::operator++();
1573  return *this;
1574  }
1575 
1577  iterator tmp = *this;
1578  operator++();
1579  return tmp;
1580  }
1581 
1583  const_iterator::operator--();
1584  return *this;
1585  }
1586 
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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.
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
KeyT & unsafeStop() const
unsafeStop - Writable access to stop() for iterator.
Definition: IntervalMap.h:1324
void setValueUnchecked(ValT x)
setValueUnchecked - Change the mapped value of the current interval without checking for coalescing...
Definition: IntervalMap.h:1563
ValT lookup(KeyT x, ValT NotFound=ValT()) const
lookup - Return the mapped value at x or NotFound.
Definition: IntervalMap.h:1073
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:240
void setValue(ValT x)
setValue - Change the mapped value of the current interval.
Definition: IntervalMap.h:1702
void transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
transferToLeftSib - Transfer elements to a left sibling node.
Definition: IntervalMap.h:286
iterator find(KeyT x)
Definition: IntervalMap.h:1132
void copy(const NodeBase< T1, T2, M > &Other, unsigned i, unsigned j, unsigned Count)
copy - Copy elements from another node.
Definition: IntervalMap.h:227
NodeRef getLeftSibling(unsigned Level) const
getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
Definition: IntervalMap.cpp:25
const_iterator begin() const
Definition: IntervalMap.h:1100
void adjustSiblingSizes(NodeT *Node[], unsigned Nodes, unsigned CurSize[], const unsigned NewSize[])
IntervalMapImpl::adjustSiblingSizes - Move elements between sibling nodes.
Definition: IntervalMap.h:331
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find an interval that is known to exist.
Definition: IntervalMap.h:591
void legalizeForInsert(unsigned Level)
legalizeForInsert - Prepare the path for an insertion at Level.
Definition: IntervalMap.h:914
IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two IntervalMaps.
Definition: IntervalMap.h:2048
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first subtree after i that may contain x.
Definition: IntervalMap.h:712
KeyT & unsafeStart() const
unsafeStart - Writable access to start() for iterator.
Definition: IntervalMap.h:1317
bool atBegin() const
atBegin - Return true if the current position is the first map entry.
Definition: IntervalMap.h:1349
IntervalMapOverlaps & operator++()
Preincrement - Move to the next overlap.
Definition: IntervalMap.h:2131
void skipA()
skipA - Move to the next overlap that doesn't involve a().
Definition: IntervalMap.h:2119
const_iterator(const IntervalMap &map)
Definition: IntervalMap.h:1297
void moveLeft(unsigned Level)
moveLeft - Move path to the left sibling at Level.
Definition: IntervalMap.cpp:48
const_iterator find(KeyT x) const
find - Return an iterator pointing to the first interval ending at or after x, or end()...
Definition: IntervalMap.h:1126
KeyT stop() const
stop - Return the largest mapped key in a non-empty map.
Definition: IntervalMap.h:1066
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:378
void pop()
pop - Remove the last path entry.
Definition: IntervalMap.h:837
KeyType stop() const
stop - End of the overlapping interval.
Definition: IntervalMap.h:2112
NodeRef()
NodeRef - Create a null ref.
Definition: IntervalMap.h:497
int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add)
adjustFromLeftSib - Adjust the number if elements in this node by moving elements to or from a left s...
Definition: IntervalMap.h:310
unsigned & offset(unsigned Level)
Definition: IntervalMap.h:797
void setMap(const IntervalMap &m)
setMap - Change the map iterated over.
Definition: IntervalMap.h:1343
const_iterator end() const
Definition: IntervalMap.h:1112
void fillLeft(unsigned Height)
fillLeft - Grow path to Height by taking leftmost branches.
Definition: IntervalMap.h:879
iterator()
iterator - Create null iterator.
Definition: IntervalMap.h:1526
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
Definition: IntervalMap.h:169
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
const KeyT & stop(unsigned i) const
Definition: IntervalMap.h:700
void setRoot(unsigned Offset)
Definition: IntervalMap.h:1305
static bool stopLess(const T &b, const T &x)
stopLess - Return true if x is not in [a;b].
Definition: IntervalMap.h:143
const_iterator & operator++()
preincrement - move to the next interval.
Definition: IntervalMap.h:1388
NodeRef safeLookup(KeyT x) const
safeLookup - Get the subtree containing x, Assuming that x is in range.
Definition: IntervalMap.h:738
const KeyT & start(unsigned i) const
Definition: IntervalMap.h:562
ValT & unsafeValue() const
unsafeValue - Writable access to value() for iterator.
Definition: IntervalMap.h:1331
static void advance(T &it, size_t Val)
bool valid() const
valid - Return true if iterator is at an overlap.
Definition: IntervalMap.h:2094
void advanceTo(KeyT x)
advanceTo - Move to the first interval with stop >= x, or end().
Definition: IntervalMap.h:1430
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
void treeAdvanceTo(KeyT x)
treeAdvanceTo - Find position after the current one.
Definition: IntervalMap.h:1470
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:591
bool operator==(const NodeRef &RHS) const
Definition: IntervalMap.h:527
bool operator!=(const NodeRef &RHS) const
Definition: IntervalMap.h:534
bool empty() const
empty - Return true when no intervals are mapped.
Definition: IntervalMap.h:1055
static bool startLess(const T &x, const T &a)
startLess - Return true if x is not in [a;b).
Definition: IntervalMap.h:159
const KeyT & stop(unsigned i) const
Definition: IntervalMap.h:563
const MapA::const_iterator & a() const
a - access the left hand side in the overlap.
Definition: IntervalMap.h:2099
void erase()
erase - Erase the current interval.
Definition: IntervalMap.h:1860
NodeBase< std::pair< KeyT, KeyT >, ValT, LeafSize > LeafBase
Definition: IntervalMap.h:444
void clear()
clear - Remove all entries.
Definition: IntervalMap.h:1272
IntervalMap(Allocator &a)
Definition: IntervalMap.h:1043
NodeRef & subtree(unsigned i) const
subtree - Access the i'th subtree reference in a branch node.
Definition: IntervalMap.h:517
KeyType start() const
start - Beginning of the overlapping interval.
Definition: IntervalMap.h:2105
void erase(unsigned i, unsigned j, unsigned Size)
erase - Erase elements [i;j).
Definition: IntervalMap.h:263
void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize, unsigned Count)
transferToRightSib - Transfer elements to a right sibling node.
Definition: IntervalMap.h:297
void setStartUnchecked(KeyT a)
setStartUnchecked - Move the start of the current interval without checking for coalescing or overlap...
Definition: IntervalMap.h:1547
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template paramaters.
Definition: Allocator.h:342
#define P(N)
unsigned size() const
size - Return the number of elements in the referenced node.
Definition: IntervalMap.h:509
const KeyT & start() const
start - Return the beginning of the current interval.
Definition: IntervalMap.h:1352
unsigned findFrom(unsigned i, unsigned Size, KeyT x) const
findFrom - Find the first interval after i that may contain x.
Definition: IntervalMap.h:576
IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity, const unsigned *CurSize, unsigned NewSize[], unsigned Position, bool Grow)
IntervalMapImpl::distribute - Compute a new distribution of node elements after an overflow or underf...
void replaceRoot(void *Root, unsigned Size, IdxPair Offsets)
replaceRoot - Replace the current root node with two new entries after the tree height has increased...
Definition: IntervalMap.cpp:19
unsigned size(unsigned Level) const
Definition: IntervalMap.h:795
void moveRight(unsigned i, unsigned j, unsigned Count)
moveRight - Move elements to the right.
Definition: IntervalMap.h:250
void find(KeyT x)
find - Move to the first interval with stop >= x, or end().
Definition: IntervalMap.h:1420
const_iterator & operator--()
predecrement - move to the previous interval.
Definition: IntervalMap.h:1403
void goToBegin()
goToBegin - Move to the first interval in map.
Definition: IntervalMap.h:1376
bool operator!=(const const_iterator &RHS) const
Definition: IntervalMap.h:1371
const MapB::const_iterator & b() const
b - access the right hand side in the overlap.
Definition: IntervalMap.h:2102
void setStop(KeyT b)
setStop - Move the end of the current interval.
Definition: IntervalMap.h:1687
static bool startLess(const T &x, const T &a)
startLess - Return true if x is not in [a;b].
Definition: IntervalMap.h:137
IntervalMapOverlaps(const MapA &a, const MapB &b)
IntervalMapOverlaps - Create an iterator for the overlaps of a and b.
Definition: IntervalMap.h:2089
unsigned leafOffset() const
Definition: IntervalMap.h:804
const_iterator operator++(int)
postincrement - Dont do that!
Definition: IntervalMap.h:1396
NodeRef & subtree(unsigned Level) const
subtree - Get the subtree referenced from Level.
Definition: IntervalMap.h:819
const NodeRef & subtree(unsigned i) const
Definition: IntervalMap.h:701
static bool stopLess(const T &b, const T &x)
stopLess - Return true if x is not in [a;b).
Definition: IntervalMap.h:164
void skipB()
skipB - Move to the next overlap that doesn't involve b().
Definition: IntervalMap.h:2125
unsigned height() const
height - Return the height of the tree corresponding to this path.
Definition: IntervalMap.h:814
void insert(KeyT a, KeyT b, ValT y)
insert - Add a mapping of [a;b] to y, coalesce with adjacent intervals.
Definition: IntervalMap.h:1083
unsigned safeFind(unsigned i, KeyT x) const
safeFind - Find a subtree that is known to exist.
Definition: IntervalMap.h:726
PointerTy getPointer() const
const_iterator()
const_iterator - Create an iterator that isn't pointing anywhere.
Definition: IntervalMap.h:1339
KeyT start() const
start - Return the smallest mapped key in a non-empty map.
Definition: IntervalMap.h:1060
void moveLeft(unsigned i, unsigned j, unsigned Count)
moveLeft - Move elements to the left.
Definition: IntervalMap.h:241
iterator begin()
Definition: IntervalMap.h:1106
NodeT & node(unsigned Level) const
Definition: IntervalMap.h:792
void goToEnd()
goToEnd - Move beyond the last interval in map.
Definition: IntervalMap.h:1383
RecyclingAllocator< BumpPtrAllocator, char, AllocBytes, CacheLineBytes > Allocator
Allocator - The recycling allocator used for both branch and leaf nodes.
Definition: IntervalMap.h:461
void setStart(KeyT a)
setStart - Move the start of the current interval.
Definition: IntervalMap.h:1671
bool valid() const
valid - Return true if path is at a valid node, not at end().
Definition: IntervalMap.h:808
bool valid() const
valid - Return true if the current position is valid, false for end().
Definition: IntervalMap.h:1346
void advanceTo(KeyType x)
advanceTo - Move to the first overlapping interval with stopLess(x, stop()).
Definition: IntervalMap.h:2142
void reset(unsigned Level)
reset - Reset cached information about node(Level) from subtree(Level -1).
Definition: IntervalMap.h:825
void erase(unsigned i, unsigned Size)
erase - Erase element at i.
Definition: IntervalMap.h:270
This union template exposes a suitably aligned and sized character array member which can hold elemen...
Definition: AlignOf.h:224
void pathFillFind(KeyT x)
pathFillFind - Complete path by searching for x.
Definition: IntervalMap.h:1446
const KeyT & stop() const
stop - Return the end of the current interval.
Definition: IntervalMap.h:1355
void push(NodeRef Node, unsigned Offset)
push - Add entry to path.
Definition: IntervalMap.h:832
void moveRight(unsigned Level)
moveRight - Move path to the left sibling at Level.
Definition: IntervalMap.cpp:98
void insert(KeyT a, KeyT b, ValT y)
insert - Insert mapping [a;b] -> y before the current position.
Definition: IntervalMap.h:1770
void treeFind(KeyT x)
treeFind - Find in a branched tree.
Definition: IntervalMap.h:1460
IntervalMapImpl::Path path
Definition: IntervalMap.h:1295
unsigned leafSize() const
Definition: IntervalMap.h:803
unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y)
insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as possible.
Definition: IntervalMap.h:624
Sizer::Allocator Allocator
Definition: IntervalMap.h:958
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
void size_t size
std::pair< unsigned, unsigned > IdxPair
Definition: IntervalMap.h:181
NodeT & get() const
get - Dereference as a NodeT reference.
Definition: IntervalMap.h:523
void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop)
insert - Insert a new (subtree, stop) pair.
Definition: IntervalMap.h:747
const_iterator operator--(int)
postdecrement - Dont do that!
Definition: IntervalMap.h:1412
bool atBegin() const
atBegin - Return true if path is at begin().
Definition: IntervalMap.h:895
unsigned offset(unsigned Level) const
Definition: IntervalMap.h:796
ValT safeLookup(KeyT x, ValT NotFound) const
safeLookup - Lookup mapped value for a safe key.
Definition: IntervalMap.h:605
void setStopUnchecked(KeyT b)
setStopUnchecked - Move the end of the current interval without checking for coalescing or overlaps...
Definition: IntervalMap.h:1553
void setRoot(void *Node, unsigned Size, unsigned Offset)
setRoot - Clear the path and set a new root node.
Definition: IntervalMap.h:855
void setSize(unsigned n)
setSize - Update the node size.
Definition: IntervalMap.h:512
static bool adjacent(const T &a, const T &b)
adjacent - Return true when the intervals [x;a] and [b;y] can coalesce.
Definition: IntervalMap.h:149
LLVM Value Representation.
Definition: Value.h:69
void shift(unsigned i, unsigned Size)
shift - Shift elements [i;size) 1 position to the right.
Definition: IntervalMap.h:277
NodeRef & subtree(unsigned i)
Definition: IntervalMap.h:704
bool operator==(const const_iterator &RHS) const
Definition: IntervalMap.h:1362
const ValT & operator*() const
Definition: IntervalMap.h:1360
const ValT & value(unsigned i) const
Definition: IntervalMap.h:564
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1734
const ValT & value() const
value - Return the mapped value at the current interval.
Definition: IntervalMap.h:1358
void setSize(unsigned Level, unsigned Size)
setSize - Set the size of a node both in the path and in the tree.
Definition: IntervalMap.h:845
#define T1
NodeRef(NodeT *p, unsigned n)
NodeRef - Create a reference to the node p with n elements.
Definition: IntervalMap.h:504
bool atLastEntry(unsigned Level) const
atLastEntry - Return true if the path is at the last entry of the node at Level.
Definition: IntervalMap.h:905