github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/util/interval/range_group.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package interval
    12  
    13  import (
    14  	"bytes"
    15  	"container/list"
    16  	"fmt"
    17  )
    18  
    19  // RangeGroup represents a set of possibly disjointed Ranges. The
    20  // interface exposes methods to manipulate the group by adding and
    21  // subtracting Ranges. All methods requiring a Range will panic
    22  // if the provided range is inverted or empty.
    23  //
    24  // One use case of the interface is to add ranges to the group and
    25  // observe whether the addition increases the size of the group or
    26  // not, indicating whether the new range's interval is redundant, or
    27  // if it is needed for the full composition of the group. Because
    28  // the RangeGroup builds as more ranges are added, insertion order of
    29  // the ranges is critical. For instance, if two identical ranges are
    30  // added, only the first to be added with Add will return true, as it
    31  // will be the only one to expand the group.
    32  //
    33  // Another use case of the interface is to add and subtract ranges as
    34  // needed to the group, allowing the internals of the implementation
    35  // to coalesce and split ranges when needed to factor the group to
    36  // its minimum number of disjoint ranges.
    37  type RangeGroup interface {
    38  	// Add will attempt to add the provided Range to the RangeGroup,
    39  	// returning whether the addition increased the range of the group
    40  	// or not.
    41  	Add(Range) bool
    42  	// Sub will attempt to remove the provided Range from the RangeGroup,
    43  	// returning whether the subtraction reduced the range of the group
    44  	// or not.
    45  	Sub(Range) bool
    46  	// Clear clears all ranges from the RangeGroup, resetting it to be
    47  	// used again.
    48  	Clear()
    49  	// Overlaps returns whether the provided Range is partially contained
    50  	// within the group of Ranges in the RangeGroup.
    51  	Overlaps(Range) bool
    52  	// Encloses returns whether the provided Range is fully contained
    53  	// within the group of Ranges in the RangeGroup.
    54  	Encloses(Range) bool
    55  	// ForEach calls the provided function with each Range stored in
    56  	// the group. An error is returned indicating whether the callback
    57  	// function saw an error, whereupon the Range iteration will halt
    58  	// (potentially prematurely) and the error will be returned from ForEach
    59  	// itself. If no error is returned from the callback, the method
    60  	// will visit all Ranges in the group before returning a nil error.
    61  	ForEach(func(Range) error) error
    62  	// Iterator returns an iterator to visit each Range stored in the
    63  	// group, in-order. It is not safe to mutate the RangeGroup while
    64  	// iteration is being performed.
    65  	Iterator() RangeGroupIterator
    66  	// Len returns the number of Ranges currently within the RangeGroup.
    67  	// This will always be equal to or less than the number of ranges added,
    68  	// as ranges that overlap will merge to produce a single larger range.
    69  	Len() int
    70  	fmt.Stringer
    71  }
    72  
    73  // RangeGroupIterator is an iterator that walks in-order over a RangeGroup.
    74  type RangeGroupIterator interface {
    75  	// Next returns the next Range in the RangeGroup. It returns false
    76  	// if there are no more Ranges.
    77  	Next() (Range, bool)
    78  }
    79  
    80  const rangeListNodeBucketSize = 8
    81  
    82  type rangeListNode struct {
    83  	slots [rangeListNodeBucketSize]Range // ordered, non-overlapping
    84  	len   int
    85  }
    86  
    87  func newRangeListNodeWithRange(r Range) *rangeListNode {
    88  	var n rangeListNode
    89  	n.push(r)
    90  	return &n
    91  }
    92  
    93  func (n *rangeListNode) push(r Range) {
    94  	n.slots[n.len] = r
    95  	n.len++
    96  }
    97  
    98  func (n *rangeListNode) full() bool {
    99  	return n.len == len(n.slots)
   100  }
   101  
   102  func (n *rangeListNode) min() Comparable {
   103  	return n.slots[0].Start
   104  }
   105  
   106  func (n *rangeListNode) max() Comparable {
   107  	return n.slots[n.len-1].End
   108  }
   109  
   110  // findIdx finds the upper-bound slot index that the provided range should fit
   111  // in the rangeListNode. It also returns whether the slot is currently occupied
   112  // by an overlapping range.
   113  func (n *rangeListNode) findIdx(r Range, inclusive bool) (int, bool) {
   114  	overlapFn := overlapsExclusive
   115  	passedCmp := 0
   116  	if inclusive {
   117  		overlapFn = overlapsInclusive
   118  		passedCmp = -1
   119  	}
   120  	for i, nr := range n.slots[:n.len] {
   121  		switch {
   122  		case overlapFn(nr, r):
   123  			return i, true
   124  		case r.End.Compare(nr.Start) <= passedCmp:
   125  			// Past where overlapping ranges would be.
   126  			return i, false
   127  		}
   128  	}
   129  	return n.len, false
   130  }
   131  
   132  // rangeList is an implementation of a RangeGroup using a bucketted linked list
   133  // to sequentially order non-overlapping ranges.
   134  //
   135  // rangeList is not safe for concurrent use by multiple goroutines.
   136  type rangeList struct {
   137  	ll  list.List
   138  	len int
   139  }
   140  
   141  // NewRangeList constructs a linked-list backed RangeGroup.
   142  func NewRangeList() RangeGroup {
   143  	var rl rangeList
   144  	rl.ll.Init()
   145  	rl.ll.PushFront(&rangeListNode{})
   146  	return &rl
   147  }
   148  
   149  // findNode returns the upper-bound node that the range would be bucketted in,
   150  // along with that node's previous element. It also returns whether the range
   151  // overlaps with the bounds of the node.
   152  func (rl *rangeList) findNode(r Range, inclusive bool) (prev, cur *list.Element, inCur bool) {
   153  	if err := rangeError(r); err != nil {
   154  		panic(err)
   155  	}
   156  	reachedCmp := 1
   157  	passedCmp := 0
   158  	if inclusive {
   159  		reachedCmp = 0
   160  		passedCmp = -1
   161  	}
   162  	for e := rl.ll.Front(); e != nil; e = e.Next() {
   163  		n := e.Value.(*rangeListNode)
   164  		if n.len == 0 {
   165  			// The node is empty. This must be the last node in the list.
   166  			return prev, e, false
   167  		}
   168  		// Check if the range starts at a value less than (or equal to, for
   169  		// inclusive) the maximum value in this node. This is what we want.
   170  		if n.max().Compare(r.Start) >= reachedCmp {
   171  			// Determine whether the range overlap the node's bounds.
   172  			inCur := n.min().Compare(r.End) <= passedCmp
   173  			return prev, e, inCur
   174  		}
   175  		prev = e
   176  	}
   177  	return prev, nil, false
   178  }
   179  
   180  // insertAtIdx inserts the provided range at the specified index in the node.
   181  // It performs any necessary slot movement to keep the ranges ordered.
   182  //
   183  // Note: e.Value is expected to be n, but we want to avoid repeated type
   184  // assertions so both are taken as arguments.
   185  func (rl *rangeList) insertAtIdx(e *list.Element, n *rangeListNode, r Range, i int) {
   186  	if n.full() {
   187  		// If the current node is full, we're going to need to shift off a range
   188  		// from one of the slots into a different node. If i is not pointing
   189  		// past the end of the range, we need to shift off the range currently
   190  		// in the last slot in this node. If i is pointing past the end of the
   191  		// range, we can just shift the new range to a different node without
   192  		// making any changes to this node.
   193  		toShift := n.slots[n.len-1]
   194  		noLocalChanges := false
   195  		if i == n.len {
   196  			toShift = r
   197  
   198  			// We're going to add range r to a different node, so there will be
   199  			// no local changes to this node.
   200  			noLocalChanges = true
   201  		}
   202  
   203  		// Check if the next node has room. Note that we only call insertAtIdx
   204  		// recursively on the next node if it is not full. We don't want to
   205  		// shift recursively all the way down the list. Instead, we'll just pay
   206  		// the constant cost below of inserting a fresh node in-between the
   207  		// current and next node.
   208  		next := e.Next()
   209  		insertedInNext := false
   210  		if next != nil {
   211  			nextN := next.Value.(*rangeListNode)
   212  			if !nextN.full() {
   213  				rl.insertAtIdx(next, nextN, toShift, 0)
   214  				insertedInNext = true
   215  			}
   216  		}
   217  		if !insertedInNext {
   218  			newN := newRangeListNodeWithRange(toShift)
   219  			rl.ll.InsertAfter(newN, e)
   220  			rl.len++
   221  		}
   222  
   223  		if noLocalChanges {
   224  			return
   225  		}
   226  	} else {
   227  		n.len++
   228  		rl.len++
   229  	}
   230  	// Shift all others over and copy the new range in. Because of
   231  	// the n.full check, we know that we'll have at least one free
   232  	// slot open at the end.
   233  	copy(n.slots[i+1:n.len], n.slots[i:n.len-1])
   234  	n.slots[i] = r
   235  }
   236  
   237  // Add implements RangeGroup. It iterates over the current ranges in the
   238  // rangeList to find which overlap with the new range. If there is no
   239  // overlap, the new range will be added and the function will return true.
   240  // If there is some overlap, the function will return true if the new
   241  // range increases the range of the rangeList, in which case it will be
   242  // added to the list, and false if it does not increase the range, in which
   243  // case it won't be added. If the range is added, the function will also attempt
   244  // to merge any ranges within the list that now overlap.
   245  func (rl *rangeList) Add(r Range) bool {
   246  	prev, cur, inCur := rl.findNode(r, true /* inclusive */)
   247  
   248  	var prevN *rangeListNode
   249  	if prev != nil {
   250  		prevN = prev.Value.(*rangeListNode)
   251  	}
   252  	if !inCur && prevN != nil && !prevN.full() {
   253  		// There is a previous node. Add the range to the end of that node.
   254  		prevN.push(r)
   255  		rl.len++
   256  		return true
   257  	}
   258  
   259  	if cur != nil {
   260  		n := cur.Value.(*rangeListNode)
   261  		i, ok := n.findIdx(r, true /* inclusive */)
   262  		if !ok {
   263  			// The range can't be merged with any existing ranges, but should
   264  			// instead be inserted at slot i. This may force us to shift over
   265  			// other slots.
   266  			rl.insertAtIdx(cur, n, r, i)
   267  			return true
   268  		}
   269  
   270  		// If a current range fully contains the new range, no need to add it.
   271  		nr := n.slots[i]
   272  		if contains(nr, r) {
   273  			return false
   274  		}
   275  
   276  		// Merge as many ranges as possible and replace old range. All merges
   277  		// will be made into n.slots[i] because adding a range to the RangeGroup
   278  		// can result in only at most one group of ranges being merged.
   279  		//
   280  		// For example:
   281  		//  existing ranges :  ---- -----    ----  ----  ----
   282  		//  new range       :          --------------
   283  		//  resulting ranges:  ---- -------------------  ----
   284  		//
   285  		// In this example, n.slots[i] is the first existing range that overlaps
   286  		// with the new range.
   287  		newR := merge(nr, r)
   288  		n.slots[i] = newR
   289  
   290  		// Each iteration attempts to merge all of the ranges in a rangeListNode.
   291  		mergeElem := cur
   292  		origNode := true
   293  		for {
   294  			mergeN := mergeElem.Value.(*rangeListNode)
   295  			origLen := mergeN.len
   296  
   297  			// mergeState is the slot index to begin merging from
   298  			mergeStart := 0
   299  			if origNode {
   300  				mergeStart = i + 1
   301  			}
   302  
   303  			// Each iteration attempts to merge a single range into the current
   304  			// merge batch.
   305  			j := mergeStart
   306  			for ; j < origLen; j++ {
   307  				mergeR := mergeN.slots[j]
   308  
   309  				if overlapsInclusive(newR, mergeR) {
   310  					newR = merge(newR, mergeR)
   311  					n.slots[i] = newR
   312  					mergeN.len--
   313  					rl.len--
   314  				} else {
   315  					// If the ranges don't overlap, that means index j and up
   316  					// are still needed in the current node. Shift these over.
   317  					copy(mergeN.slots[mergeStart:mergeStart+origLen-j], mergeN.slots[j:origLen])
   318  					return true
   319  				}
   320  			}
   321  
   322  			// If we didn't break, that means that all of the slots including
   323  			// and after mergeStart in the current node were merged. Continue
   324  			// onto the next node.
   325  			nextE := mergeElem.Next()
   326  			if !origNode {
   327  				// If this is not the current node, we can delete it
   328  				// completely.
   329  				rl.ll.Remove(mergeElem)
   330  			}
   331  			if nextE == nil {
   332  				return true
   333  			}
   334  			mergeElem = nextE
   335  			origNode = false
   336  		}
   337  	}
   338  
   339  	// The new range couldn't be added to the previous or the current node.
   340  	// We'll have to create a new node for the range.
   341  	n := newRangeListNodeWithRange(r)
   342  	if prevN != nil {
   343  		// There is a previous node and it is full.
   344  		rl.ll.InsertAfter(n, prev)
   345  	} else {
   346  		// There is no previous node. Add the range to a new node in the front
   347  		// of the list.
   348  		rl.ll.PushFront(n)
   349  	}
   350  	rl.len++
   351  	return true
   352  }
   353  
   354  // Sub implements RangeGroup. It iterates over the current ranges in the
   355  // rangeList to find which overlap with the range to subtract. For all
   356  // ranges that overlap with the provided range, the overlapping segment of
   357  // the range is removed. If the provided range fully contains a range in
   358  // the rangeList, the range in the rangeList will be removed. The method
   359  // returns whether the subtraction resulted in any decrease to the size
   360  // of the RangeGroup.
   361  func (rl *rangeList) Sub(r Range) bool {
   362  	_, cur, inCur := rl.findNode(r, false /* inclusive */)
   363  	if !inCur {
   364  		// The range does not overlap any nodes. Nothing to do.
   365  		return false
   366  	}
   367  
   368  	n := cur.Value.(*rangeListNode)
   369  	i, ok := n.findIdx(r, false /* inclusive */)
   370  	if !ok {
   371  		// The range does not overlap any ranges in the node. Nothing to do.
   372  		return false
   373  	}
   374  
   375  	for {
   376  		nr := n.slots[i]
   377  		if !overlapsExclusive(nr, r) {
   378  			// The range does not overlap nr so stop trying to subtract. The
   379  			// findIdx check above guarantees that this will never be the case
   380  			// for the first iteration of this loop.
   381  			return true
   382  		}
   383  
   384  		sCmp := nr.Start.Compare(r.Start)
   385  		eCmp := nr.End.Compare(r.End)
   386  		delStart := sCmp >= 0
   387  		delEnd := eCmp <= 0
   388  
   389  		switch {
   390  		case delStart && delEnd:
   391  			// Remove the entire range.
   392  			n.len--
   393  			rl.len--
   394  			if n.len == 0 {
   395  				// Move to the next node, removing the current node as long as
   396  				// it's not the only one in the list.
   397  				i = 0
   398  				next := cur.Next()
   399  				if rl.len > 0 {
   400  					rl.ll.Remove(cur)
   401  				}
   402  				if next == nil {
   403  					return true
   404  				}
   405  				cur = next
   406  				n = cur.Value.(*rangeListNode)
   407  				continue
   408  			} else {
   409  				// Replace the current Range.
   410  				copy(n.slots[i:n.len], n.slots[i+1:n.len+1])
   411  			}
   412  			// Don't increment i.
   413  		case delStart:
   414  			// Remove the start of the range by truncating. Can return after.
   415  			n.slots[i].Start = r.End
   416  			return true
   417  		case delEnd:
   418  			// Remove the end of the range by truncating.
   419  			n.slots[i].End = r.Start
   420  			i++
   421  		default:
   422  			// Remove the middle of the range by splitting and truncating.
   423  			oldEnd := nr.End
   424  			n.slots[i].End = r.Start
   425  
   426  			// Create right side of split. Can return after.
   427  			rSplit := Range{Start: r.End, End: oldEnd}
   428  			rl.insertAtIdx(cur, n, rSplit, i+1)
   429  			return true
   430  		}
   431  
   432  		// Move to the next node, if necessary.
   433  		if i >= n.len {
   434  			i = 0
   435  			cur = cur.Next()
   436  			if cur == nil {
   437  				return true
   438  			}
   439  			n = cur.Value.(*rangeListNode)
   440  		}
   441  	}
   442  }
   443  
   444  // Clear implements RangeGroup. It clears all ranges from the
   445  // rangeList.
   446  func (rl *rangeList) Clear() {
   447  	// Empty the first node, but keep it in the list.
   448  	f := rl.ll.Front().Value.(*rangeListNode)
   449  	*f = rangeListNode{}
   450  
   451  	// If the list has more than one node in it, remove all but the first.
   452  	if rl.ll.Len() > 1 {
   453  		rl.ll.Init()
   454  		rl.ll.PushBack(f)
   455  	}
   456  	rl.len = 0
   457  }
   458  
   459  // Overlaps implements RangeGroup. It returns whether the provided
   460  // Range is partially contained within the group of Ranges in the rangeList.
   461  func (rl *rangeList) Overlaps(r Range) bool {
   462  	if _, cur, inCur := rl.findNode(r, false /* inclusive */); inCur {
   463  		n := cur.Value.(*rangeListNode)
   464  		if _, ok := n.findIdx(r, false /* inclusive */); ok {
   465  			return true
   466  		}
   467  	}
   468  	return false
   469  }
   470  
   471  // Encloses implements RangeGroup. It returns whether the provided
   472  // Range is fully contained within the group of Ranges in the rangeList.
   473  func (rl *rangeList) Encloses(r Range) bool {
   474  	if _, cur, inCur := rl.findNode(r, false /* inclusive */); inCur {
   475  		n := cur.Value.(*rangeListNode)
   476  		if i, ok := n.findIdx(r, false /* inclusive */); ok {
   477  			return contains(n.slots[i], r)
   478  		}
   479  	}
   480  	return false
   481  }
   482  
   483  // ForEach implements RangeGroup. It calls the provided function f
   484  // with each Range stored in the rangeList.
   485  func (rl *rangeList) ForEach(f func(Range) error) error {
   486  	it := rangeListIterator{e: rl.ll.Front()}
   487  	for r, ok := it.Next(); ok; r, ok = it.Next() {
   488  		if err := f(r); err != nil {
   489  			return err
   490  		}
   491  	}
   492  	return nil
   493  }
   494  
   495  // rangeListIterator is an in-order iterator operating over a rangeList.
   496  type rangeListIterator struct {
   497  	e   *list.Element
   498  	idx int // next slot index
   499  }
   500  
   501  // Next implements RangeGroupIterator. It returns the next Range in the
   502  // rangeList, or false.
   503  func (rli *rangeListIterator) Next() (r Range, ok bool) {
   504  	if rli.e != nil {
   505  		n := rli.e.Value.(*rangeListNode)
   506  
   507  		// Get current index, return if invalid.
   508  		curIdx := rli.idx
   509  		if curIdx >= n.len {
   510  			return Range{}, false
   511  		}
   512  
   513  		// Move index and Element pointer forwards.
   514  		rli.idx = curIdx + 1
   515  		if rli.idx >= n.len {
   516  			rli.idx = 0
   517  			rli.e = rli.e.Next()
   518  		}
   519  
   520  		return n.slots[curIdx], true
   521  	}
   522  	return Range{}, false
   523  }
   524  
   525  // Iterator implements RangeGroup. It returns an iterator to iterate over
   526  // the group of ranges.
   527  func (rl *rangeList) Iterator() RangeGroupIterator {
   528  	return &rangeListIterator{e: rl.ll.Front()}
   529  }
   530  
   531  // Len implements RangeGroup. It returns the number of ranges in
   532  // the rangeList.
   533  func (rl *rangeList) Len() int {
   534  	return rl.len
   535  }
   536  
   537  func (rl *rangeList) String() string {
   538  	return rgString(rl)
   539  }
   540  
   541  // rangeTree is an implementation of a RangeGroup using an interval
   542  // tree to efficiently store and search for non-overlapping ranges.
   543  //
   544  // rangeTree is not safe for concurrent use by multiple goroutines.
   545  type rangeTree struct {
   546  	t       Tree
   547  	idCount uintptr
   548  }
   549  
   550  // NewRangeTree constructs an interval tree backed RangeGroup.
   551  func NewRangeTree() RangeGroup {
   552  	return &rangeTree{
   553  		t: NewTree(InclusiveOverlapper),
   554  	}
   555  }
   556  
   557  // rangeKey implements Interface and can be inserted into a Tree. It
   558  // provides uniqueness as well as a key interval.
   559  type rangeKey struct {
   560  	r  Range
   561  	id uintptr
   562  }
   563  
   564  var _ Interface = rangeKey{}
   565  
   566  // makeKey creates a new rangeKey defined by the provided range.
   567  func (rt *rangeTree) makeKey(r Range) rangeKey {
   568  	rt.idCount++
   569  	return rangeKey{
   570  		r:  r,
   571  		id: rt.idCount,
   572  	}
   573  }
   574  
   575  // Range implements Interface.
   576  func (rk rangeKey) Range() Range {
   577  	return rk.r
   578  }
   579  
   580  // ID implements Interface.
   581  func (rk rangeKey) ID() uintptr {
   582  	return rk.id
   583  }
   584  
   585  func (rk rangeKey) String() string {
   586  	return fmt.Sprintf("%d: %q-%q", rk.id, rk.r.Start, rk.r.End)
   587  }
   588  
   589  // Add implements RangeGroup. It first uses the interval tree to lookup
   590  // the current ranges which overlap with the new range. If there is no
   591  // overlap, the new range will be added and the function will return true.
   592  // If there is some overlap, the function will return true if the new
   593  // range increases the range of the rangeTree, in which case it will be
   594  // added to the tree, and false if it does not increase the range, in which
   595  // case it won't be added. If the range is added, the function will also attempt
   596  // to merge any ranges within the tree that now overlap.
   597  func (rt *rangeTree) Add(r Range) bool {
   598  	if err := rangeError(r); err != nil {
   599  		panic(err)
   600  	}
   601  	overlaps := rt.t.Get(r)
   602  	if len(overlaps) == 0 {
   603  		key := rt.makeKey(r)
   604  		if err := rt.t.Insert(&key, false /* fast */); err != nil {
   605  			panic(err)
   606  		}
   607  		return true
   608  	}
   609  	first := overlaps[0].(*rangeKey)
   610  
   611  	// If a current range fully contains the new range, no
   612  	// need to add it.
   613  	if contains(first.r, r) {
   614  		return false
   615  	}
   616  
   617  	// Merge as many ranges as possible, and replace old range.
   618  	first.r = merge(first.r, r)
   619  	for _, o := range overlaps[1:] {
   620  		other := o.(*rangeKey)
   621  		first.r = merge(first.r, other.r)
   622  		if err := rt.t.Delete(o, true /* fast */); err != nil {
   623  			panic(err)
   624  		}
   625  	}
   626  	rt.t.AdjustRanges()
   627  	return true
   628  }
   629  
   630  // Sub implements RangeGroup. It first uses the interval tree to lookup
   631  // the current ranges which overlap with the range to subtract. For all
   632  // ranges that overlap with the provided range, the overlapping segment of
   633  // the range is removed. If the provided range fully contains a range in
   634  // the rangeTree, the range in the rangeTree will be removed. The method
   635  // returns whether the subtraction resulted in any decrease to the size
   636  // of the RangeGroup.
   637  func (rt *rangeTree) Sub(r Range) bool {
   638  	if err := rangeError(r); err != nil {
   639  		panic(err)
   640  	}
   641  	overlaps := rt.t.GetWithOverlapper(r, ExclusiveOverlapper)
   642  	if len(overlaps) == 0 {
   643  		return false
   644  	}
   645  
   646  	for _, o := range overlaps {
   647  		rk := o.(*rangeKey)
   648  		sCmp := rk.r.Start.Compare(r.Start)
   649  		eCmp := rk.r.End.Compare(r.End)
   650  
   651  		delStart := sCmp >= 0
   652  		delEnd := eCmp <= 0
   653  
   654  		switch {
   655  		case delStart && delEnd:
   656  			// Remove the entire range.
   657  			if err := rt.t.Delete(o, true /* fast */); err != nil {
   658  				panic(err)
   659  			}
   660  		case delStart:
   661  			// Remove the start of the range by truncating.
   662  			rk.r.Start = r.End
   663  		case delEnd:
   664  			// Remove the end of the range by truncating.
   665  			rk.r.End = r.Start
   666  		default:
   667  			// Remove the middle of the range by splitting.
   668  			oldEnd := rk.r.End
   669  			rk.r.End = r.Start
   670  
   671  			rSplit := Range{Start: r.End, End: oldEnd}
   672  			rKey := rt.makeKey(rSplit)
   673  			if err := rt.t.Insert(&rKey, true /* fast */); err != nil {
   674  				panic(err)
   675  			}
   676  		}
   677  	}
   678  	rt.t.AdjustRanges()
   679  	return true
   680  }
   681  
   682  // Clear implements RangeGroup. It clears all rangeKeys from the rangeTree.
   683  func (rt *rangeTree) Clear() {
   684  	rt.t.Clear()
   685  }
   686  
   687  // Overlaps implements RangeGroup. It returns whether the provided
   688  // Range is partially contained within the group of Ranges in the rangeTree.
   689  func (rt *rangeTree) Overlaps(r Range) bool {
   690  	if err := rangeError(r); err != nil {
   691  		panic(err)
   692  	}
   693  	overlaps := rt.t.GetWithOverlapper(r, ExclusiveOverlapper)
   694  	return len(overlaps) > 0
   695  }
   696  
   697  // Encloses implements RangeGroup. It returns whether the provided
   698  // Range is fully contained within the group of Ranges in the rangeTree.
   699  func (rt *rangeTree) Encloses(r Range) bool {
   700  	if err := rangeError(r); err != nil {
   701  		panic(err)
   702  	}
   703  	overlaps := rt.t.GetWithOverlapper(r, ExclusiveOverlapper)
   704  	if len(overlaps) != 1 {
   705  		return false
   706  	}
   707  	first := overlaps[0].(*rangeKey)
   708  	return contains(first.r, r)
   709  }
   710  
   711  // ForEach implements RangeGroup. It calls the provided function f
   712  // with each Range stored in the rangeTree.
   713  func (rt *rangeTree) ForEach(f func(Range) error) error {
   714  	var err error
   715  	rt.t.Do(func(i Interface) bool {
   716  		err = f(i.Range())
   717  		return err != nil
   718  	})
   719  	return err
   720  }
   721  
   722  // rangeListIterator is an in-order iterator operating over a rangeTree.
   723  type rangeTreeIterator struct {
   724  	it TreeIterator
   725  }
   726  
   727  // Next implements RangeGroupIterator. It returns the next Range in the
   728  // rangeTree, or false.
   729  func (rti *rangeTreeIterator) Next() (r Range, ok bool) {
   730  	i, ok := rti.it.Next()
   731  	if !ok {
   732  		return Range{}, false
   733  	}
   734  	return i.Range(), true
   735  }
   736  
   737  // Iterator implements RangeGroup. It returns an iterator to iterate over
   738  // the group of ranges.
   739  func (rt *rangeTree) Iterator() RangeGroupIterator {
   740  	return &rangeTreeIterator{it: rt.t.Iterator()}
   741  }
   742  
   743  // Len implements RangeGroup. It returns the number of rangeKeys in
   744  // the rangeTree.
   745  func (rt *rangeTree) Len() int {
   746  	return rt.t.Len()
   747  }
   748  
   749  func (rt *rangeTree) String() string {
   750  	return rgString(rt)
   751  }
   752  
   753  // contains returns if the range in the out range fully contains the
   754  // in range.
   755  func contains(out, in Range) bool {
   756  	return in.Start.Compare(out.Start) >= 0 && out.End.Compare(in.End) >= 0
   757  }
   758  
   759  // merge merges the provided ranges together into their union range. The
   760  // ranges must overlap or the function will not produce the correct output.
   761  func merge(l, r Range) Range {
   762  	start := l.Start
   763  	if r.Start.Compare(start) < 0 {
   764  		start = r.Start
   765  	}
   766  	end := l.End
   767  	if r.End.Compare(end) > 0 {
   768  		end = r.End
   769  	}
   770  	return Range{Start: start, End: end}
   771  }
   772  
   773  // rgString returns a string representation of the ranges in a RangeGroup.
   774  func rgString(rg RangeGroup) string {
   775  	var buffer bytes.Buffer
   776  	buffer.WriteRune('[')
   777  	space := false
   778  	if err := rg.ForEach(func(r Range) error {
   779  		if space {
   780  			buffer.WriteRune(' ')
   781  		}
   782  		buffer.WriteString(r.String())
   783  		space = true
   784  		return nil
   785  	}); err != nil {
   786  		panic(err)
   787  	}
   788  	buffer.WriteRune(']')
   789  	return buffer.String()
   790  }
   791  
   792  // RangeGroupsOverlap determines if two RangeGroups contain any overlapping
   793  // Ranges or if they are fully disjoint. It does so by iterating over the
   794  // RangeGroups together and comparing subsequent ranges.
   795  func RangeGroupsOverlap(rg1, rg2 RangeGroup) bool {
   796  	it1, it2 := rg1.Iterator(), rg2.Iterator()
   797  	r1, ok1 := it1.Next()
   798  	r2, ok2 := it2.Next()
   799  	if !ok1 || !ok2 {
   800  		return false
   801  	}
   802  	for {
   803  		// Check if the current pair of Ranges overlap.
   804  		if overlapsExclusive(r1, r2) {
   805  			return true
   806  		}
   807  
   808  		// If not, advance the Range further behind.
   809  		var ok bool
   810  		if r1.Start.Compare(r2.Start) < 0 {
   811  			r1, ok = it1.Next()
   812  		} else {
   813  			r2, ok = it2.Next()
   814  		}
   815  		if !ok {
   816  			return false
   817  		}
   818  	}
   819  }