github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/pgalloc/evictable_range_set.go (about)

     1  package pgalloc
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  )
     8  
     9  // trackGaps is an optional parameter.
    10  //
    11  // If trackGaps is 1, the Set will track maximum gap size recursively,
    12  // enabling the GapIterator.{Prev,Next}LargeEnoughGap functions. In this
    13  // case, Key must be an unsigned integer.
    14  //
    15  // trackGaps must be 0 or 1.
    16  const evictableRangetrackGaps = 0
    17  
    18  var _ = uint8(evictableRangetrackGaps << 7) // Will fail if not zero or one.
    19  
    20  // dynamicGap is a type that disappears if trackGaps is 0.
    21  type evictableRangedynamicGap [evictableRangetrackGaps]uint64
    22  
    23  // Get returns the value of the gap.
    24  //
    25  // Precondition: trackGaps must be non-zero.
    26  func (d *evictableRangedynamicGap) Get() uint64 {
    27  	return d[:][0]
    28  }
    29  
    30  // Set sets the value of the gap.
    31  //
    32  // Precondition: trackGaps must be non-zero.
    33  func (d *evictableRangedynamicGap) Set(v uint64) {
    34  	d[:][0] = v
    35  }
    36  
    37  const (
    38  	// minDegree is the minimum degree of an internal node in a Set B-tree.
    39  	//
    40  	//	- Any non-root node has at least minDegree-1 segments.
    41  	//
    42  	//	- Any non-root internal (non-leaf) node has at least minDegree children.
    43  	//
    44  	//	- The root node may have fewer than minDegree-1 segments, but it may
    45  	// only have 0 segments if the tree is empty.
    46  	//
    47  	// Our implementation requires minDegree >= 3. Higher values of minDegree
    48  	// usually improve performance, but increase memory usage for small sets.
    49  	evictableRangeminDegree = 3
    50  
    51  	evictableRangemaxDegree = 2 * evictableRangeminDegree
    52  )
    53  
    54  // A Set is a mapping of segments with non-overlapping Range keys. The zero
    55  // value for a Set is an empty set. Set values are not safely movable nor
    56  // copyable. Set is thread-compatible.
    57  //
    58  // +stateify savable
    59  type evictableRangeSet struct {
    60  	root evictableRangenode `state:".([]evictableRangeFlatSegment)"`
    61  }
    62  
    63  // IsEmpty returns true if the set contains no segments.
    64  func (s *evictableRangeSet) IsEmpty() bool {
    65  	return s.root.nrSegments == 0
    66  }
    67  
    68  // IsEmptyRange returns true iff no segments in the set overlap the given
    69  // range. This is semantically equivalent to s.SpanRange(r) == 0, but may be
    70  // more efficient.
    71  func (s *evictableRangeSet) IsEmptyRange(r EvictableRange) bool {
    72  	switch {
    73  	case r.Length() < 0:
    74  		panic(fmt.Sprintf("invalid range %v", r))
    75  	case r.Length() == 0:
    76  		return true
    77  	}
    78  	_, gap := s.Find(r.Start)
    79  	if !gap.Ok() {
    80  		return false
    81  	}
    82  	return r.End <= gap.End()
    83  }
    84  
    85  // Span returns the total size of all segments in the set.
    86  func (s *evictableRangeSet) Span() uint64 {
    87  	var sz uint64
    88  	for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
    89  		sz += seg.Range().Length()
    90  	}
    91  	return sz
    92  }
    93  
    94  // SpanRange returns the total size of the intersection of segments in the set
    95  // with the given range.
    96  func (s *evictableRangeSet) SpanRange(r EvictableRange) uint64 {
    97  	switch {
    98  	case r.Length() < 0:
    99  		panic(fmt.Sprintf("invalid range %v", r))
   100  	case r.Length() == 0:
   101  		return 0
   102  	}
   103  	var sz uint64
   104  	for seg := s.LowerBoundSegment(r.Start); seg.Ok() && seg.Start() < r.End; seg = seg.NextSegment() {
   105  		sz += seg.Range().Intersect(r).Length()
   106  	}
   107  	return sz
   108  }
   109  
   110  // FirstSegment returns the first segment in the set. If the set is empty,
   111  // FirstSegment returns a terminal iterator.
   112  func (s *evictableRangeSet) FirstSegment() evictableRangeIterator {
   113  	if s.root.nrSegments == 0 {
   114  		return evictableRangeIterator{}
   115  	}
   116  	return s.root.firstSegment()
   117  }
   118  
   119  // LastSegment returns the last segment in the set. If the set is empty,
   120  // LastSegment returns a terminal iterator.
   121  func (s *evictableRangeSet) LastSegment() evictableRangeIterator {
   122  	if s.root.nrSegments == 0 {
   123  		return evictableRangeIterator{}
   124  	}
   125  	return s.root.lastSegment()
   126  }
   127  
   128  // FirstGap returns the first gap in the set.
   129  func (s *evictableRangeSet) FirstGap() evictableRangeGapIterator {
   130  	n := &s.root
   131  	for n.hasChildren {
   132  		n = n.children[0]
   133  	}
   134  	return evictableRangeGapIterator{n, 0}
   135  }
   136  
   137  // LastGap returns the last gap in the set.
   138  func (s *evictableRangeSet) LastGap() evictableRangeGapIterator {
   139  	n := &s.root
   140  	for n.hasChildren {
   141  		n = n.children[n.nrSegments]
   142  	}
   143  	return evictableRangeGapIterator{n, n.nrSegments}
   144  }
   145  
   146  // Find returns the segment or gap whose range contains the given key. If a
   147  // segment is found, the returned Iterator is non-terminal and the
   148  // returned GapIterator is terminal. Otherwise, the returned Iterator is
   149  // terminal and the returned GapIterator is non-terminal.
   150  func (s *evictableRangeSet) Find(key uint64) (evictableRangeIterator, evictableRangeGapIterator) {
   151  	n := &s.root
   152  	for {
   153  
   154  		lower := 0
   155  		upper := n.nrSegments
   156  		for lower < upper {
   157  			i := lower + (upper-lower)/2
   158  			if r := n.keys[i]; key < r.End {
   159  				if key >= r.Start {
   160  					return evictableRangeIterator{n, i}, evictableRangeGapIterator{}
   161  				}
   162  				upper = i
   163  			} else {
   164  				lower = i + 1
   165  			}
   166  		}
   167  		i := lower
   168  		if !n.hasChildren {
   169  			return evictableRangeIterator{}, evictableRangeGapIterator{n, i}
   170  		}
   171  		n = n.children[i]
   172  	}
   173  }
   174  
   175  // FindSegment returns the segment whose range contains the given key. If no
   176  // such segment exists, FindSegment returns a terminal iterator.
   177  func (s *evictableRangeSet) FindSegment(key uint64) evictableRangeIterator {
   178  	seg, _ := s.Find(key)
   179  	return seg
   180  }
   181  
   182  // LowerBoundSegment returns the segment with the lowest range that contains a
   183  // key greater than or equal to min. If no such segment exists,
   184  // LowerBoundSegment returns a terminal iterator.
   185  func (s *evictableRangeSet) LowerBoundSegment(min uint64) evictableRangeIterator {
   186  	seg, gap := s.Find(min)
   187  	if seg.Ok() {
   188  		return seg
   189  	}
   190  	return gap.NextSegment()
   191  }
   192  
   193  // UpperBoundSegment returns the segment with the highest range that contains a
   194  // key less than or equal to max. If no such segment exists, UpperBoundSegment
   195  // returns a terminal iterator.
   196  func (s *evictableRangeSet) UpperBoundSegment(max uint64) evictableRangeIterator {
   197  	seg, gap := s.Find(max)
   198  	if seg.Ok() {
   199  		return seg
   200  	}
   201  	return gap.PrevSegment()
   202  }
   203  
   204  // FindGap returns the gap containing the given key. If no such gap exists
   205  // (i.e. the set contains a segment containing that key), FindGap returns a
   206  // terminal iterator.
   207  func (s *evictableRangeSet) FindGap(key uint64) evictableRangeGapIterator {
   208  	_, gap := s.Find(key)
   209  	return gap
   210  }
   211  
   212  // LowerBoundGap returns the gap with the lowest range that is greater than or
   213  // equal to min.
   214  func (s *evictableRangeSet) LowerBoundGap(min uint64) evictableRangeGapIterator {
   215  	seg, gap := s.Find(min)
   216  	if gap.Ok() {
   217  		return gap
   218  	}
   219  	return seg.NextGap()
   220  }
   221  
   222  // UpperBoundGap returns the gap with the highest range that is less than or
   223  // equal to max.
   224  func (s *evictableRangeSet) UpperBoundGap(max uint64) evictableRangeGapIterator {
   225  	seg, gap := s.Find(max)
   226  	if gap.Ok() {
   227  		return gap
   228  	}
   229  	return seg.PrevGap()
   230  }
   231  
   232  // FirstLargeEnoughGap returns the first gap in the set with at least the given
   233  // length. If no such gap exists, FirstLargeEnoughGap returns a terminal
   234  // iterator.
   235  //
   236  // Precondition: trackGaps must be 1.
   237  func (s *evictableRangeSet) FirstLargeEnoughGap(minSize uint64) evictableRangeGapIterator {
   238  	if evictableRangetrackGaps != 1 {
   239  		panic("set is not tracking gaps")
   240  	}
   241  	gap := s.FirstGap()
   242  	if gap.Range().Length() >= minSize {
   243  		return gap
   244  	}
   245  	return gap.NextLargeEnoughGap(minSize)
   246  }
   247  
   248  // LastLargeEnoughGap returns the last gap in the set with at least the given
   249  // length. If no such gap exists, LastLargeEnoughGap returns a terminal
   250  // iterator.
   251  //
   252  // Precondition: trackGaps must be 1.
   253  func (s *evictableRangeSet) LastLargeEnoughGap(minSize uint64) evictableRangeGapIterator {
   254  	if evictableRangetrackGaps != 1 {
   255  		panic("set is not tracking gaps")
   256  	}
   257  	gap := s.LastGap()
   258  	if gap.Range().Length() >= minSize {
   259  		return gap
   260  	}
   261  	return gap.PrevLargeEnoughGap(minSize)
   262  }
   263  
   264  // LowerBoundLargeEnoughGap returns the first gap in the set with at least the
   265  // given length and whose range contains a key greater than or equal to min. If
   266  // no such gap exists, LowerBoundLargeEnoughGap returns a terminal iterator.
   267  //
   268  // Precondition: trackGaps must be 1.
   269  func (s *evictableRangeSet) LowerBoundLargeEnoughGap(min, minSize uint64) evictableRangeGapIterator {
   270  	if evictableRangetrackGaps != 1 {
   271  		panic("set is not tracking gaps")
   272  	}
   273  	gap := s.LowerBoundGap(min)
   274  	if gap.Range().Length() >= minSize {
   275  		return gap
   276  	}
   277  	return gap.NextLargeEnoughGap(minSize)
   278  }
   279  
   280  // UpperBoundLargeEnoughGap returns the last gap in the set with at least the
   281  // given length and whose range contains a key less than or equal to max. If no
   282  // such gap exists, UpperBoundLargeEnoughGap returns a terminal iterator.
   283  //
   284  // Precondition: trackGaps must be 1.
   285  func (s *evictableRangeSet) UpperBoundLargeEnoughGap(max, minSize uint64) evictableRangeGapIterator {
   286  	if evictableRangetrackGaps != 1 {
   287  		panic("set is not tracking gaps")
   288  	}
   289  	gap := s.UpperBoundGap(max)
   290  	if gap.Range().Length() >= minSize {
   291  		return gap
   292  	}
   293  	return gap.PrevLargeEnoughGap(minSize)
   294  }
   295  
   296  // Insert inserts the given segment into the given gap. If the new segment can
   297  // be merged with adjacent segments, Insert will do so. Insert returns an
   298  // iterator to the segment containing the inserted value (which may have been
   299  // merged with other values). All existing iterators (including gap, but not
   300  // including the returned iterator) are invalidated.
   301  //
   302  // If the gap cannot accommodate the segment, or if r is invalid, Insert panics.
   303  //
   304  // Insert is semantically equivalent to a InsertWithoutMerging followed by a
   305  // Merge, but may be more efficient. Note that there is no unchecked variant of
   306  // Insert since Insert must retrieve and inspect gap's predecessor and
   307  // successor segments regardless.
   308  func (s *evictableRangeSet) Insert(gap evictableRangeGapIterator, r EvictableRange, val evictableRangeSetValue) evictableRangeIterator {
   309  	if r.Length() <= 0 {
   310  		panic(fmt.Sprintf("invalid segment range %v", r))
   311  	}
   312  	prev, next := gap.PrevSegment(), gap.NextSegment()
   313  	if prev.Ok() && prev.End() > r.Start {
   314  		panic(fmt.Sprintf("new segment %v overlaps predecessor %v", r, prev.Range()))
   315  	}
   316  	if next.Ok() && next.Start() < r.End {
   317  		panic(fmt.Sprintf("new segment %v overlaps successor %v", r, next.Range()))
   318  	}
   319  	if prev.Ok() && prev.End() == r.Start {
   320  		if mval, ok := (evictableRangeSetFunctions{}).Merge(prev.Range(), prev.Value(), r, val); ok {
   321  			shrinkMaxGap := evictableRangetrackGaps != 0 && gap.Range().Length() == gap.node.maxGap.Get()
   322  			prev.SetEndUnchecked(r.End)
   323  			prev.SetValue(mval)
   324  			if shrinkMaxGap {
   325  				gap.node.updateMaxGapLeaf()
   326  			}
   327  			if next.Ok() && next.Start() == r.End {
   328  				val = mval
   329  				if mval, ok := (evictableRangeSetFunctions{}).Merge(prev.Range(), val, next.Range(), next.Value()); ok {
   330  					prev.SetEndUnchecked(next.End())
   331  					prev.SetValue(mval)
   332  					return s.Remove(next).PrevSegment()
   333  				}
   334  			}
   335  			return prev
   336  		}
   337  	}
   338  	if next.Ok() && next.Start() == r.End {
   339  		if mval, ok := (evictableRangeSetFunctions{}).Merge(r, val, next.Range(), next.Value()); ok {
   340  			shrinkMaxGap := evictableRangetrackGaps != 0 && gap.Range().Length() == gap.node.maxGap.Get()
   341  			next.SetStartUnchecked(r.Start)
   342  			next.SetValue(mval)
   343  			if shrinkMaxGap {
   344  				gap.node.updateMaxGapLeaf()
   345  			}
   346  			return next
   347  		}
   348  	}
   349  
   350  	return s.InsertWithoutMergingUnchecked(gap, r, val)
   351  }
   352  
   353  // InsertWithoutMerging inserts the given segment into the given gap and
   354  // returns an iterator to the inserted segment. All existing iterators
   355  // (including gap, but not including the returned iterator) are invalidated.
   356  //
   357  // If the gap cannot accommodate the segment, or if r is invalid,
   358  // InsertWithoutMerging panics.
   359  func (s *evictableRangeSet) InsertWithoutMerging(gap evictableRangeGapIterator, r EvictableRange, val evictableRangeSetValue) evictableRangeIterator {
   360  	if r.Length() <= 0 {
   361  		panic(fmt.Sprintf("invalid segment range %v", r))
   362  	}
   363  	if gr := gap.Range(); !gr.IsSupersetOf(r) {
   364  		panic(fmt.Sprintf("cannot insert segment range %v into gap range %v", r, gr))
   365  	}
   366  	return s.InsertWithoutMergingUnchecked(gap, r, val)
   367  }
   368  
   369  // InsertWithoutMergingUnchecked inserts the given segment into the given gap
   370  // and returns an iterator to the inserted segment. All existing iterators
   371  // (including gap, but not including the returned iterator) are invalidated.
   372  //
   373  // Preconditions:
   374  //   - r.Start >= gap.Start().
   375  //   - r.End <= gap.End().
   376  func (s *evictableRangeSet) InsertWithoutMergingUnchecked(gap evictableRangeGapIterator, r EvictableRange, val evictableRangeSetValue) evictableRangeIterator {
   377  	gap = gap.node.rebalanceBeforeInsert(gap)
   378  	splitMaxGap := evictableRangetrackGaps != 0 && (gap.node.nrSegments == 0 || gap.Range().Length() == gap.node.maxGap.Get())
   379  	copy(gap.node.keys[gap.index+1:], gap.node.keys[gap.index:gap.node.nrSegments])
   380  	copy(gap.node.values[gap.index+1:], gap.node.values[gap.index:gap.node.nrSegments])
   381  	gap.node.keys[gap.index] = r
   382  	gap.node.values[gap.index] = val
   383  	gap.node.nrSegments++
   384  	if splitMaxGap {
   385  		gap.node.updateMaxGapLeaf()
   386  	}
   387  	return evictableRangeIterator{gap.node, gap.index}
   388  }
   389  
   390  // InsertRange inserts the given segment into the set. If the new segment can
   391  // be merged with adjacent segments, InsertRange will do so. InsertRange
   392  // returns an iterator to the segment containing the inserted value (which may
   393  // have been merged with other values). All existing iterators (excluding the
   394  // returned iterator) are invalidated.
   395  //
   396  // If the new segment would overlap an existing segment, or if r is invalid,
   397  // InsertRange panics.
   398  //
   399  // InsertRange searches the set to find the gap to insert into. If the caller
   400  // already has the appropriate GapIterator, or if the caller needs to do
   401  // additional work between finding the gap and insertion, use Insert instead.
   402  func (s *evictableRangeSet) InsertRange(r EvictableRange, val evictableRangeSetValue) evictableRangeIterator {
   403  	if r.Length() <= 0 {
   404  		panic(fmt.Sprintf("invalid segment range %v", r))
   405  	}
   406  	seg, gap := s.Find(r.Start)
   407  	if seg.Ok() {
   408  		panic(fmt.Sprintf("new segment %v overlaps existing segment %v", r, seg.Range()))
   409  	}
   410  	if gap.End() < r.End {
   411  		panic(fmt.Sprintf("new segment %v overlaps existing segment %v", r, gap.NextSegment().Range()))
   412  	}
   413  	return s.Insert(gap, r, val)
   414  }
   415  
   416  // InsertWithoutMergingRange inserts the given segment into the set and returns
   417  // an iterator to the inserted segment. All existing iterators (excluding the
   418  // returned iterator) are invalidated.
   419  //
   420  // If the new segment would overlap an existing segment, or if r is invalid,
   421  // InsertWithoutMergingRange panics.
   422  //
   423  // InsertWithoutMergingRange searches the set to find the gap to insert into.
   424  // If the caller already has the appropriate GapIterator, or if the caller
   425  // needs to do additional work between finding the gap and insertion, use
   426  // InsertWithoutMerging instead.
   427  func (s *evictableRangeSet) InsertWithoutMergingRange(r EvictableRange, val evictableRangeSetValue) evictableRangeIterator {
   428  	if r.Length() <= 0 {
   429  		panic(fmt.Sprintf("invalid segment range %v", r))
   430  	}
   431  	seg, gap := s.Find(r.Start)
   432  	if seg.Ok() {
   433  		panic(fmt.Sprintf("new segment %v overlaps existing segment %v", r, seg.Range()))
   434  	}
   435  	if gap.End() < r.End {
   436  		panic(fmt.Sprintf("new segment %v overlaps existing segment %v", r, gap.NextSegment().Range()))
   437  	}
   438  	return s.InsertWithoutMerging(gap, r, val)
   439  }
   440  
   441  // TryInsertRange attempts to insert the given segment into the set. If the new
   442  // segment can be merged with adjacent segments, TryInsertRange will do so.
   443  // TryInsertRange returns an iterator to the segment containing the inserted
   444  // value (which may have been merged with other values). All existing iterators
   445  // (excluding the returned iterator) are invalidated.
   446  //
   447  // If the new segment would overlap an existing segment, TryInsertRange does
   448  // nothing and returns a terminal iterator.
   449  //
   450  // TryInsertRange searches the set to find the gap to insert into. If the
   451  // caller already has the appropriate GapIterator, or if the caller needs to do
   452  // additional work between finding the gap and insertion, use Insert instead.
   453  func (s *evictableRangeSet) TryInsertRange(r EvictableRange, val evictableRangeSetValue) evictableRangeIterator {
   454  	if r.Length() <= 0 {
   455  		panic(fmt.Sprintf("invalid segment range %v", r))
   456  	}
   457  	seg, gap := s.Find(r.Start)
   458  	if seg.Ok() {
   459  		return evictableRangeIterator{}
   460  	}
   461  	if gap.End() < r.End {
   462  		return evictableRangeIterator{}
   463  	}
   464  	return s.Insert(gap, r, val)
   465  }
   466  
   467  // TryInsertWithoutMergingRange attempts to insert the given segment into the
   468  // set. If successful, it returns an iterator to the inserted segment; all
   469  // existing iterators (excluding the returned iterator) are invalidated. If the
   470  // new segment would overlap an existing segment, TryInsertWithoutMergingRange
   471  // does nothing and returns a terminal iterator.
   472  //
   473  // TryInsertWithoutMergingRange searches the set to find the gap to insert
   474  // into. If the caller already has the appropriate GapIterator, or if the
   475  // caller needs to do additional work between finding the gap and insertion,
   476  // use InsertWithoutMerging instead.
   477  func (s *evictableRangeSet) TryInsertWithoutMergingRange(r EvictableRange, val evictableRangeSetValue) evictableRangeIterator {
   478  	if r.Length() <= 0 {
   479  		panic(fmt.Sprintf("invalid segment range %v", r))
   480  	}
   481  	seg, gap := s.Find(r.Start)
   482  	if seg.Ok() {
   483  		return evictableRangeIterator{}
   484  	}
   485  	if gap.End() < r.End {
   486  		return evictableRangeIterator{}
   487  	}
   488  	return s.InsertWithoutMerging(gap, r, val)
   489  }
   490  
   491  // Remove removes the given segment and returns an iterator to the vacated gap.
   492  // All existing iterators (including seg, but not including the returned
   493  // iterator) are invalidated.
   494  func (s *evictableRangeSet) Remove(seg evictableRangeIterator) evictableRangeGapIterator {
   495  
   496  	if seg.node.hasChildren {
   497  
   498  		victim := seg.PrevSegment()
   499  
   500  		seg.SetRangeUnchecked(victim.Range())
   501  		seg.SetValue(victim.Value())
   502  
   503  		nextAdjacentNode := seg.NextSegment().node
   504  		if evictableRangetrackGaps != 0 {
   505  			nextAdjacentNode.updateMaxGapLeaf()
   506  		}
   507  		return s.Remove(victim).NextGap()
   508  	}
   509  	copy(seg.node.keys[seg.index:], seg.node.keys[seg.index+1:seg.node.nrSegments])
   510  	copy(seg.node.values[seg.index:], seg.node.values[seg.index+1:seg.node.nrSegments])
   511  	evictableRangeSetFunctions{}.ClearValue(&seg.node.values[seg.node.nrSegments-1])
   512  	seg.node.nrSegments--
   513  	if evictableRangetrackGaps != 0 {
   514  		seg.node.updateMaxGapLeaf()
   515  	}
   516  	return seg.node.rebalanceAfterRemove(evictableRangeGapIterator{seg.node, seg.index})
   517  }
   518  
   519  // RemoveAll removes all segments from the set. All existing iterators are
   520  // invalidated.
   521  func (s *evictableRangeSet) RemoveAll() {
   522  	s.root = evictableRangenode{}
   523  }
   524  
   525  // RemoveRange removes all segments in the given range. An iterator to the
   526  // newly formed gap is returned, and all existing iterators are invalidated.
   527  //
   528  // RemoveRange searches the set to find segments to remove. If the caller
   529  // already has an iterator to either end of the range of segments to remove, or
   530  // if the caller needs to do additional work before removing each segment,
   531  // iterate segments and call Remove in a loop instead.
   532  func (s *evictableRangeSet) RemoveRange(r EvictableRange) evictableRangeGapIterator {
   533  	seg, gap := s.Find(r.Start)
   534  	if seg.Ok() {
   535  		seg = s.Isolate(seg, r)
   536  		gap = s.Remove(seg)
   537  	}
   538  	for seg = gap.NextSegment(); seg.Ok() && seg.Start() < r.End; seg = gap.NextSegment() {
   539  		seg = s.SplitAfter(seg, r.End)
   540  		gap = s.Remove(seg)
   541  	}
   542  	return gap
   543  }
   544  
   545  // RemoveFullRange is equivalent to RemoveRange, except that if any key in the
   546  // given range does not correspond to a segment, RemoveFullRange panics.
   547  func (s *evictableRangeSet) RemoveFullRange(r EvictableRange) evictableRangeGapIterator {
   548  	seg := s.FindSegment(r.Start)
   549  	if !seg.Ok() {
   550  		panic(fmt.Sprintf("missing segment at %v", r.Start))
   551  	}
   552  	seg = s.SplitBefore(seg, r.Start)
   553  	for {
   554  		seg = s.SplitAfter(seg, r.End)
   555  		end := seg.End()
   556  		gap := s.Remove(seg)
   557  		if r.End <= end {
   558  			return gap
   559  		}
   560  		seg = gap.NextSegment()
   561  		if !seg.Ok() || seg.Start() != end {
   562  			panic(fmt.Sprintf("missing segment at %v", end))
   563  		}
   564  	}
   565  }
   566  
   567  // Merge attempts to merge two neighboring segments. If successful, Merge
   568  // returns an iterator to the merged segment, and all existing iterators are
   569  // invalidated. Otherwise, Merge returns a terminal iterator.
   570  //
   571  // If first is not the predecessor of second, Merge panics.
   572  func (s *evictableRangeSet) Merge(first, second evictableRangeIterator) evictableRangeIterator {
   573  	if first.NextSegment() != second {
   574  		panic(fmt.Sprintf("attempt to merge non-neighboring segments %v, %v", first.Range(), second.Range()))
   575  	}
   576  	return s.MergeUnchecked(first, second)
   577  }
   578  
   579  // MergeUnchecked attempts to merge two neighboring segments. If successful,
   580  // MergeUnchecked returns an iterator to the merged segment, and all existing
   581  // iterators are invalidated. Otherwise, MergeUnchecked returns a terminal
   582  // iterator.
   583  //
   584  // Precondition: first is the predecessor of second: first.NextSegment() ==
   585  // second, first == second.PrevSegment().
   586  func (s *evictableRangeSet) MergeUnchecked(first, second evictableRangeIterator) evictableRangeIterator {
   587  	if first.End() == second.Start() {
   588  		if mval, ok := (evictableRangeSetFunctions{}).Merge(first.Range(), first.Value(), second.Range(), second.Value()); ok {
   589  
   590  			first.SetEndUnchecked(second.End())
   591  			first.SetValue(mval)
   592  
   593  			return s.Remove(second).PrevSegment()
   594  		}
   595  	}
   596  	return evictableRangeIterator{}
   597  }
   598  
   599  // MergePrev attempts to merge the given segment with its predecessor if
   600  // possible, and returns an updated iterator to the extended segment. All
   601  // existing iterators (including seg, but not including the returned iterator)
   602  // are invalidated.
   603  //
   604  // MergePrev is usually used when mutating segments while iterating them in
   605  // order of increasing keys, to attempt merging of each mutated segment with
   606  // its previously-mutated predecessor. In such cases, merging a mutated segment
   607  // with its unmutated successor would incorrectly cause the latter to be
   608  // skipped.
   609  func (s *evictableRangeSet) MergePrev(seg evictableRangeIterator) evictableRangeIterator {
   610  	if prev := seg.PrevSegment(); prev.Ok() {
   611  		if mseg := s.MergeUnchecked(prev, seg); mseg.Ok() {
   612  			seg = mseg
   613  		}
   614  	}
   615  	return seg
   616  }
   617  
   618  // MergeNext attempts to merge the given segment with its successor if
   619  // possible, and returns an updated iterator to the extended segment. All
   620  // existing iterators (including seg, but not including the returned iterator)
   621  // are invalidated.
   622  //
   623  // MergeNext is usually used when mutating segments while iterating them in
   624  // order of decreasing keys, to attempt merging of each mutated segment with
   625  // its previously-mutated successor. In such cases, merging a mutated segment
   626  // with its unmutated predecessor would incorrectly cause the latter to be
   627  // skipped.
   628  func (s *evictableRangeSet) MergeNext(seg evictableRangeIterator) evictableRangeIterator {
   629  	if next := seg.NextSegment(); next.Ok() {
   630  		if mseg := s.MergeUnchecked(seg, next); mseg.Ok() {
   631  			seg = mseg
   632  		}
   633  	}
   634  	return seg
   635  }
   636  
   637  // Unisolate attempts to merge the given segment with its predecessor and
   638  // successor if possible, and returns an updated iterator to the extended
   639  // segment. All existing iterators (including seg, but not including the
   640  // returned iterator) are invalidated.
   641  //
   642  // Unisolate is usually used in conjunction with Isolate when mutating part of
   643  // a single segment in a way that may affect its mergeability. For the reasons
   644  // described by MergePrev and MergeNext, it is usually incorrect to use the
   645  // return value of Unisolate in a loop variable.
   646  func (s *evictableRangeSet) Unisolate(seg evictableRangeIterator) evictableRangeIterator {
   647  	if prev := seg.PrevSegment(); prev.Ok() {
   648  		if mseg := s.MergeUnchecked(prev, seg); mseg.Ok() {
   649  			seg = mseg
   650  		}
   651  	}
   652  	if next := seg.NextSegment(); next.Ok() {
   653  		if mseg := s.MergeUnchecked(seg, next); mseg.Ok() {
   654  			seg = mseg
   655  		}
   656  	}
   657  	return seg
   658  }
   659  
   660  // MergeAll merges all mergeable adjacent segments in the set. All existing
   661  // iterators are invalidated.
   662  func (s *evictableRangeSet) MergeAll() {
   663  	seg := s.FirstSegment()
   664  	if !seg.Ok() {
   665  		return
   666  	}
   667  	next := seg.NextSegment()
   668  	for next.Ok() {
   669  		if mseg := s.MergeUnchecked(seg, next); mseg.Ok() {
   670  			seg, next = mseg, mseg.NextSegment()
   671  		} else {
   672  			seg, next = next, next.NextSegment()
   673  		}
   674  	}
   675  }
   676  
   677  // MergeInsideRange attempts to merge all adjacent segments that contain a key
   678  // in the specific range. All existing iterators are invalidated.
   679  //
   680  // MergeInsideRange only makes sense after mutating the set in a way that may
   681  // change the mergeability of modified segments; callers should prefer to use
   682  // MergePrev or MergeNext during the mutating loop instead (depending on the
   683  // direction of iteration), in order to avoid a redundant search.
   684  func (s *evictableRangeSet) MergeInsideRange(r EvictableRange) {
   685  	seg := s.LowerBoundSegment(r.Start)
   686  	if !seg.Ok() {
   687  		return
   688  	}
   689  	next := seg.NextSegment()
   690  	for next.Ok() && next.Start() < r.End {
   691  		if mseg := s.MergeUnchecked(seg, next); mseg.Ok() {
   692  			seg, next = mseg, mseg.NextSegment()
   693  		} else {
   694  			seg, next = next, next.NextSegment()
   695  		}
   696  	}
   697  }
   698  
   699  // MergeOutsideRange attempts to merge the segment containing r.Start with its
   700  // predecessor, and the segment containing r.End-1 with its successor.
   701  //
   702  // MergeOutsideRange only makes sense after mutating the set in a way that may
   703  // change the mergeability of modified segments; callers should prefer to use
   704  // MergePrev or MergeNext during the mutating loop instead (depending on the
   705  // direction of iteration), in order to avoid two redundant searches.
   706  func (s *evictableRangeSet) MergeOutsideRange(r EvictableRange) {
   707  	first := s.FindSegment(r.Start)
   708  	if first.Ok() {
   709  		if prev := first.PrevSegment(); prev.Ok() {
   710  			s.Merge(prev, first)
   711  		}
   712  	}
   713  	last := s.FindSegment(r.End - 1)
   714  	if last.Ok() {
   715  		if next := last.NextSegment(); next.Ok() {
   716  			s.Merge(last, next)
   717  		}
   718  	}
   719  }
   720  
   721  // Split splits the given segment at the given key and returns iterators to the
   722  // two resulting segments. All existing iterators (including seg, but not
   723  // including the returned iterators) are invalidated.
   724  //
   725  // If the segment cannot be split at split (because split is at the start or
   726  // end of the segment's range, so splitting would produce a segment with zero
   727  // length, or because split falls outside the segment's range altogether),
   728  // Split panics.
   729  func (s *evictableRangeSet) Split(seg evictableRangeIterator, split uint64) (evictableRangeIterator, evictableRangeIterator) {
   730  	if !seg.Range().CanSplitAt(split) {
   731  		panic(fmt.Sprintf("can't split %v at %v", seg.Range(), split))
   732  	}
   733  	return s.SplitUnchecked(seg, split)
   734  }
   735  
   736  // SplitUnchecked splits the given segment at the given key and returns
   737  // iterators to the two resulting segments. All existing iterators (including
   738  // seg, but not including the returned iterators) are invalidated.
   739  //
   740  // Preconditions: seg.Start() < key < seg.End().
   741  func (s *evictableRangeSet) SplitUnchecked(seg evictableRangeIterator, split uint64) (evictableRangeIterator, evictableRangeIterator) {
   742  	val1, val2 := (evictableRangeSetFunctions{}).Split(seg.Range(), seg.Value(), split)
   743  	end2 := seg.End()
   744  	seg.SetEndUnchecked(split)
   745  	seg.SetValue(val1)
   746  	seg2 := s.InsertWithoutMergingUnchecked(seg.NextGap(), EvictableRange{split, end2}, val2)
   747  
   748  	return seg2.PrevSegment(), seg2
   749  }
   750  
   751  // SplitBefore ensures that the given segment's start is at least start by
   752  // splitting at start if necessary, and returns an updated iterator to the
   753  // bounded segment. All existing iterators (including seg, but not including
   754  // the returned iterator) are invalidated.
   755  //
   756  // SplitBefore is usually when mutating segments in a range. In such cases,
   757  // when iterating segments in order of increasing keys, the first segment may
   758  // extend beyond the start of the range to be mutated, and needs to be
   759  // SplitBefore to ensure that only the part of the segment within the range is
   760  // mutated. When iterating segments in order of decreasing keys, SplitBefore
   761  // and SplitAfter; i.e. SplitBefore needs to be invoked on each segment, while
   762  // SplitAfter only needs to be invoked on the first.
   763  //
   764  // Preconditions: start < seg.End().
   765  func (s *evictableRangeSet) SplitBefore(seg evictableRangeIterator, start uint64) evictableRangeIterator {
   766  	if seg.Range().CanSplitAt(start) {
   767  		_, seg = s.SplitUnchecked(seg, start)
   768  	}
   769  	return seg
   770  }
   771  
   772  // SplitAfter ensures that the given segment's end is at most end by splitting
   773  // at end if necessary, and returns an updated iterator to the bounded segment.
   774  // All existing iterators (including seg, but not including the returned
   775  // iterator) are invalidated.
   776  //
   777  // SplitAfter is usually used when mutating segments in a range. In such cases,
   778  // when iterating segments in order of increasing keys, each iterated segment
   779  // may extend beyond the end of the range to be mutated, and needs to be
   780  // SplitAfter to ensure that only the part of the segment within the range is
   781  // mutated. When iterating segments in order of decreasing keys, SplitBefore
   782  // and SplitAfter exchange roles; i.e. SplitBefore needs to be invoked on each
   783  // segment, while SplitAfter only needs to be invoked on the first.
   784  //
   785  // Preconditions: seg.Start() < end.
   786  func (s *evictableRangeSet) SplitAfter(seg evictableRangeIterator, end uint64) evictableRangeIterator {
   787  	if seg.Range().CanSplitAt(end) {
   788  		seg, _ = s.SplitUnchecked(seg, end)
   789  	}
   790  	return seg
   791  }
   792  
   793  // Isolate ensures that the given segment's range is a subset of r by splitting
   794  // at r.Start and r.End if necessary, and returns an updated iterator to the
   795  // bounded segment. All existing iterators (including seg, but not including
   796  // the returned iterators) are invalidated.
   797  //
   798  // Isolate is usually used when mutating part of a single segment, or when
   799  // mutating segments in a range where the first segment is not necessarily
   800  // split, making use of SplitBefore/SplitAfter complex.
   801  //
   802  // Preconditions: seg.Range().Overlaps(r).
   803  func (s *evictableRangeSet) Isolate(seg evictableRangeIterator, r EvictableRange) evictableRangeIterator {
   804  	if seg.Range().CanSplitAt(r.Start) {
   805  		_, seg = s.SplitUnchecked(seg, r.Start)
   806  	}
   807  	if seg.Range().CanSplitAt(r.End) {
   808  		seg, _ = s.SplitUnchecked(seg, r.End)
   809  	}
   810  	return seg
   811  }
   812  
   813  // LowerBoundSegmentSplitBefore combines LowerBoundSegment and SplitBefore.
   814  //
   815  // LowerBoundSegmentSplitBefore is usually used when mutating segments in a
   816  // range while iterating them in order of increasing keys. In such cases,
   817  // LowerBoundSegmentSplitBefore provides an iterator to the first segment to be
   818  // mutated, suitable as the initial value for a loop variable.
   819  func (s *evictableRangeSet) LowerBoundSegmentSplitBefore(min uint64) evictableRangeIterator {
   820  	seg := s.LowerBoundSegment(min)
   821  	if seg.Ok() {
   822  		seg = s.SplitBefore(seg, min)
   823  	}
   824  	return seg
   825  }
   826  
   827  // UpperBoundSegmentSplitAfter combines UpperBoundSegment and SplitAfter.
   828  //
   829  // UpperBoundSegmentSplitAfter is usually used when mutating segments in a
   830  // range while iterating them in order of decreasing keys. In such cases,
   831  // UpperBoundSegmentSplitAfter provides an iterator to the first segment to be
   832  // mutated, suitable as the initial value for a loop variable.
   833  func (s *evictableRangeSet) UpperBoundSegmentSplitAfter(max uint64) evictableRangeIterator {
   834  	seg := s.UpperBoundSegment(max)
   835  	if seg.Ok() {
   836  		seg = s.SplitAfter(seg, max)
   837  	}
   838  	return seg
   839  }
   840  
   841  // VisitRange applies the function f to all segments intersecting the range r,
   842  // in order of ascending keys. Segments will not be split, so f may be called
   843  // on segments lying partially outside r. Non-empty gaps between segments are
   844  // skipped. If a call to f returns false, VisitRange stops iteration
   845  // immediately.
   846  //
   847  // N.B. f must not invalidate iterators into s.
   848  func (s *evictableRangeSet) VisitRange(r EvictableRange, f func(seg evictableRangeIterator) bool) {
   849  	for seg := s.LowerBoundSegment(r.Start); seg.Ok() && seg.Start() < r.End; seg = seg.NextSegment() {
   850  		if !f(seg) {
   851  			return
   852  		}
   853  	}
   854  }
   855  
   856  // VisitFullRange is equivalent to VisitRange, except that if any key in r that
   857  // is visited before f returns false does not correspond to a segment,
   858  // VisitFullRange panics.
   859  func (s *evictableRangeSet) VisitFullRange(r EvictableRange, f func(seg evictableRangeIterator) bool) {
   860  	pos := r.Start
   861  	seg := s.FindSegment(r.Start)
   862  	for {
   863  		if !seg.Ok() {
   864  			panic(fmt.Sprintf("missing segment at %v", pos))
   865  		}
   866  		if !f(seg) {
   867  			return
   868  		}
   869  		pos = seg.End()
   870  		if r.End <= pos {
   871  			return
   872  		}
   873  		seg, _ = seg.NextNonEmpty()
   874  	}
   875  }
   876  
   877  // MutateRange applies the function f to all segments intersecting the range r,
   878  // in order of ascending keys. Segments that lie partially outside r are split
   879  // before f is called, such that f only observes segments entirely within r.
   880  // Iterated segments are merged again after f is called. Non-empty gaps between
   881  // segments are skipped. If a call to f returns false, MutateRange stops
   882  // iteration immediately.
   883  //
   884  // MutateRange invalidates all existing iterators.
   885  //
   886  // N.B. f must not invalidate iterators into s.
   887  func (s *evictableRangeSet) MutateRange(r EvictableRange, f func(seg evictableRangeIterator) bool) {
   888  	seg := s.LowerBoundSegmentSplitBefore(r.Start)
   889  	for seg.Ok() && seg.Start() < r.End {
   890  		seg = s.SplitAfter(seg, r.End)
   891  		cont := f(seg)
   892  		seg = s.MergePrev(seg)
   893  		if !cont {
   894  			s.MergeNext(seg)
   895  			return
   896  		}
   897  		seg = seg.NextSegment()
   898  	}
   899  	if seg.Ok() {
   900  		s.MergePrev(seg)
   901  	}
   902  }
   903  
   904  // MutateFullRange is equivalent to MutateRange, except that if any key in r
   905  // that is visited before f returns false does not correspond to a segment,
   906  // MutateFullRange panics.
   907  func (s *evictableRangeSet) MutateFullRange(r EvictableRange, f func(seg evictableRangeIterator) bool) {
   908  	seg := s.FindSegment(r.Start)
   909  	if !seg.Ok() {
   910  		panic(fmt.Sprintf("missing segment at %v", r.Start))
   911  	}
   912  	seg = s.SplitBefore(seg, r.Start)
   913  	for {
   914  		seg = s.SplitAfter(seg, r.End)
   915  		cont := f(seg)
   916  		end := seg.End()
   917  		seg = s.MergePrev(seg)
   918  		if !cont || r.End <= end {
   919  			s.MergeNext(seg)
   920  			return
   921  		}
   922  		seg = seg.NextSegment()
   923  		if !seg.Ok() || seg.Start() != end {
   924  			panic(fmt.Sprintf("missing segment at %v", end))
   925  		}
   926  	}
   927  }
   928  
   929  // +stateify savable
   930  type evictableRangenode struct {
   931  	// An internal binary tree node looks like:
   932  	//
   933  	//   K
   934  	//  / \
   935  	// Cl Cr
   936  	//
   937  	// where all keys in the subtree rooted by Cl (the left subtree) are less
   938  	// than K (the key of the parent node), and all keys in the subtree rooted
   939  	// by Cr (the right subtree) are greater than K.
   940  	//
   941  	// An internal B-tree node's indexes work out to look like:
   942  	//
   943  	//   K0 K1 K2  ...   Kn-1
   944  	//  / \/ \/ \  ...  /  \
   945  	// C0 C1 C2 C3 ... Cn-1 Cn
   946  	//
   947  	// where n is nrSegments.
   948  	nrSegments int
   949  
   950  	// parent is a pointer to this node's parent. If this node is root, parent
   951  	// is nil.
   952  	parent *evictableRangenode
   953  
   954  	// parentIndex is the index of this node in parent.children.
   955  	parentIndex int
   956  
   957  	// Flag for internal nodes that is technically redundant with "children[0]
   958  	// != nil", but is stored in the first cache line. "hasChildren" rather
   959  	// than "isLeaf" because false must be the correct value for an empty root.
   960  	hasChildren bool
   961  
   962  	// The longest gap within this node. If the node is a leaf, it's simply the
   963  	// maximum gap among all the (nrSegments+1) gaps formed by its nrSegments keys
   964  	// including the 0th and nrSegments-th gap possibly shared with its upper-level
   965  	// nodes; if it's a non-leaf node, it's the max of all children's maxGap.
   966  	maxGap evictableRangedynamicGap
   967  
   968  	// Nodes store keys and values in separate arrays to maximize locality in
   969  	// the common case (scanning keys for lookup).
   970  	keys     [evictableRangemaxDegree - 1]EvictableRange
   971  	values   [evictableRangemaxDegree - 1]evictableRangeSetValue
   972  	children [evictableRangemaxDegree]*evictableRangenode
   973  }
   974  
   975  // firstSegment returns the first segment in the subtree rooted by n.
   976  //
   977  // Preconditions: n.nrSegments != 0.
   978  func (n *evictableRangenode) firstSegment() evictableRangeIterator {
   979  	for n.hasChildren {
   980  		n = n.children[0]
   981  	}
   982  	return evictableRangeIterator{n, 0}
   983  }
   984  
   985  // lastSegment returns the last segment in the subtree rooted by n.
   986  //
   987  // Preconditions: n.nrSegments != 0.
   988  func (n *evictableRangenode) lastSegment() evictableRangeIterator {
   989  	for n.hasChildren {
   990  		n = n.children[n.nrSegments]
   991  	}
   992  	return evictableRangeIterator{n, n.nrSegments - 1}
   993  }
   994  
   995  func (n *evictableRangenode) prevSibling() *evictableRangenode {
   996  	if n.parent == nil || n.parentIndex == 0 {
   997  		return nil
   998  	}
   999  	return n.parent.children[n.parentIndex-1]
  1000  }
  1001  
  1002  func (n *evictableRangenode) nextSibling() *evictableRangenode {
  1003  	if n.parent == nil || n.parentIndex == n.parent.nrSegments {
  1004  		return nil
  1005  	}
  1006  	return n.parent.children[n.parentIndex+1]
  1007  }
  1008  
  1009  // rebalanceBeforeInsert splits n and its ancestors if they are full, as
  1010  // required for insertion, and returns an updated iterator to the position
  1011  // represented by gap.
  1012  func (n *evictableRangenode) rebalanceBeforeInsert(gap evictableRangeGapIterator) evictableRangeGapIterator {
  1013  	if n.nrSegments < evictableRangemaxDegree-1 {
  1014  		return gap
  1015  	}
  1016  	if n.parent != nil {
  1017  		gap = n.parent.rebalanceBeforeInsert(gap)
  1018  	}
  1019  	if n.parent == nil {
  1020  
  1021  		left := &evictableRangenode{
  1022  			nrSegments:  evictableRangeminDegree - 1,
  1023  			parent:      n,
  1024  			parentIndex: 0,
  1025  			hasChildren: n.hasChildren,
  1026  		}
  1027  		right := &evictableRangenode{
  1028  			nrSegments:  evictableRangeminDegree - 1,
  1029  			parent:      n,
  1030  			parentIndex: 1,
  1031  			hasChildren: n.hasChildren,
  1032  		}
  1033  		copy(left.keys[:evictableRangeminDegree-1], n.keys[:evictableRangeminDegree-1])
  1034  		copy(left.values[:evictableRangeminDegree-1], n.values[:evictableRangeminDegree-1])
  1035  		copy(right.keys[:evictableRangeminDegree-1], n.keys[evictableRangeminDegree:])
  1036  		copy(right.values[:evictableRangeminDegree-1], n.values[evictableRangeminDegree:])
  1037  		n.keys[0], n.values[0] = n.keys[evictableRangeminDegree-1], n.values[evictableRangeminDegree-1]
  1038  		evictableRangezeroValueSlice(n.values[1:])
  1039  		if n.hasChildren {
  1040  			copy(left.children[:evictableRangeminDegree], n.children[:evictableRangeminDegree])
  1041  			copy(right.children[:evictableRangeminDegree], n.children[evictableRangeminDegree:])
  1042  			evictableRangezeroNodeSlice(n.children[2:])
  1043  			for i := 0; i < evictableRangeminDegree; i++ {
  1044  				left.children[i].parent = left
  1045  				left.children[i].parentIndex = i
  1046  				right.children[i].parent = right
  1047  				right.children[i].parentIndex = i
  1048  			}
  1049  		}
  1050  		n.nrSegments = 1
  1051  		n.hasChildren = true
  1052  		n.children[0] = left
  1053  		n.children[1] = right
  1054  
  1055  		if evictableRangetrackGaps != 0 {
  1056  			left.updateMaxGapLocal()
  1057  			right.updateMaxGapLocal()
  1058  		}
  1059  		if gap.node != n {
  1060  			return gap
  1061  		}
  1062  		if gap.index < evictableRangeminDegree {
  1063  			return evictableRangeGapIterator{left, gap.index}
  1064  		}
  1065  		return evictableRangeGapIterator{right, gap.index - evictableRangeminDegree}
  1066  	}
  1067  
  1068  	copy(n.parent.keys[n.parentIndex+1:], n.parent.keys[n.parentIndex:n.parent.nrSegments])
  1069  	copy(n.parent.values[n.parentIndex+1:], n.parent.values[n.parentIndex:n.parent.nrSegments])
  1070  	n.parent.keys[n.parentIndex], n.parent.values[n.parentIndex] = n.keys[evictableRangeminDegree-1], n.values[evictableRangeminDegree-1]
  1071  	copy(n.parent.children[n.parentIndex+2:], n.parent.children[n.parentIndex+1:n.parent.nrSegments+1])
  1072  	for i := n.parentIndex + 2; i < n.parent.nrSegments+2; i++ {
  1073  		n.parent.children[i].parentIndex = i
  1074  	}
  1075  	sibling := &evictableRangenode{
  1076  		nrSegments:  evictableRangeminDegree - 1,
  1077  		parent:      n.parent,
  1078  		parentIndex: n.parentIndex + 1,
  1079  		hasChildren: n.hasChildren,
  1080  	}
  1081  	n.parent.children[n.parentIndex+1] = sibling
  1082  	n.parent.nrSegments++
  1083  	copy(sibling.keys[:evictableRangeminDegree-1], n.keys[evictableRangeminDegree:])
  1084  	copy(sibling.values[:evictableRangeminDegree-1], n.values[evictableRangeminDegree:])
  1085  	evictableRangezeroValueSlice(n.values[evictableRangeminDegree-1:])
  1086  	if n.hasChildren {
  1087  		copy(sibling.children[:evictableRangeminDegree], n.children[evictableRangeminDegree:])
  1088  		evictableRangezeroNodeSlice(n.children[evictableRangeminDegree:])
  1089  		for i := 0; i < evictableRangeminDegree; i++ {
  1090  			sibling.children[i].parent = sibling
  1091  			sibling.children[i].parentIndex = i
  1092  		}
  1093  	}
  1094  	n.nrSegments = evictableRangeminDegree - 1
  1095  
  1096  	if evictableRangetrackGaps != 0 {
  1097  		n.updateMaxGapLocal()
  1098  		sibling.updateMaxGapLocal()
  1099  	}
  1100  
  1101  	if gap.node != n {
  1102  		return gap
  1103  	}
  1104  	if gap.index < evictableRangeminDegree {
  1105  		return gap
  1106  	}
  1107  	return evictableRangeGapIterator{sibling, gap.index - evictableRangeminDegree}
  1108  }
  1109  
  1110  // rebalanceAfterRemove "unsplits" n and its ancestors if they are deficient
  1111  // (contain fewer segments than required by B-tree invariants), as required for
  1112  // removal, and returns an updated iterator to the position represented by gap.
  1113  //
  1114  // Precondition: n is the only node in the tree that may currently violate a
  1115  // B-tree invariant.
  1116  func (n *evictableRangenode) rebalanceAfterRemove(gap evictableRangeGapIterator) evictableRangeGapIterator {
  1117  	for {
  1118  		if n.nrSegments >= evictableRangeminDegree-1 {
  1119  			return gap
  1120  		}
  1121  		if n.parent == nil {
  1122  
  1123  			return gap
  1124  		}
  1125  
  1126  		if sibling := n.prevSibling(); sibling != nil && sibling.nrSegments >= evictableRangeminDegree {
  1127  			copy(n.keys[1:], n.keys[:n.nrSegments])
  1128  			copy(n.values[1:], n.values[:n.nrSegments])
  1129  			n.keys[0] = n.parent.keys[n.parentIndex-1]
  1130  			n.values[0] = n.parent.values[n.parentIndex-1]
  1131  			n.parent.keys[n.parentIndex-1] = sibling.keys[sibling.nrSegments-1]
  1132  			n.parent.values[n.parentIndex-1] = sibling.values[sibling.nrSegments-1]
  1133  			evictableRangeSetFunctions{}.ClearValue(&sibling.values[sibling.nrSegments-1])
  1134  			if n.hasChildren {
  1135  				copy(n.children[1:], n.children[:n.nrSegments+1])
  1136  				n.children[0] = sibling.children[sibling.nrSegments]
  1137  				sibling.children[sibling.nrSegments] = nil
  1138  				n.children[0].parent = n
  1139  				n.children[0].parentIndex = 0
  1140  				for i := 1; i < n.nrSegments+2; i++ {
  1141  					n.children[i].parentIndex = i
  1142  				}
  1143  			}
  1144  			n.nrSegments++
  1145  			sibling.nrSegments--
  1146  
  1147  			if evictableRangetrackGaps != 0 {
  1148  				n.updateMaxGapLocal()
  1149  				sibling.updateMaxGapLocal()
  1150  			}
  1151  			if gap.node == sibling && gap.index == sibling.nrSegments {
  1152  				return evictableRangeGapIterator{n, 0}
  1153  			}
  1154  			if gap.node == n {
  1155  				return evictableRangeGapIterator{n, gap.index + 1}
  1156  			}
  1157  			return gap
  1158  		}
  1159  		if sibling := n.nextSibling(); sibling != nil && sibling.nrSegments >= evictableRangeminDegree {
  1160  			n.keys[n.nrSegments] = n.parent.keys[n.parentIndex]
  1161  			n.values[n.nrSegments] = n.parent.values[n.parentIndex]
  1162  			n.parent.keys[n.parentIndex] = sibling.keys[0]
  1163  			n.parent.values[n.parentIndex] = sibling.values[0]
  1164  			copy(sibling.keys[:sibling.nrSegments-1], sibling.keys[1:])
  1165  			copy(sibling.values[:sibling.nrSegments-1], sibling.values[1:])
  1166  			evictableRangeSetFunctions{}.ClearValue(&sibling.values[sibling.nrSegments-1])
  1167  			if n.hasChildren {
  1168  				n.children[n.nrSegments+1] = sibling.children[0]
  1169  				copy(sibling.children[:sibling.nrSegments], sibling.children[1:])
  1170  				sibling.children[sibling.nrSegments] = nil
  1171  				n.children[n.nrSegments+1].parent = n
  1172  				n.children[n.nrSegments+1].parentIndex = n.nrSegments + 1
  1173  				for i := 0; i < sibling.nrSegments; i++ {
  1174  					sibling.children[i].parentIndex = i
  1175  				}
  1176  			}
  1177  			n.nrSegments++
  1178  			sibling.nrSegments--
  1179  
  1180  			if evictableRangetrackGaps != 0 {
  1181  				n.updateMaxGapLocal()
  1182  				sibling.updateMaxGapLocal()
  1183  			}
  1184  			if gap.node == sibling {
  1185  				if gap.index == 0 {
  1186  					return evictableRangeGapIterator{n, n.nrSegments}
  1187  				}
  1188  				return evictableRangeGapIterator{sibling, gap.index - 1}
  1189  			}
  1190  			return gap
  1191  		}
  1192  
  1193  		p := n.parent
  1194  		if p.nrSegments == 1 {
  1195  
  1196  			left, right := p.children[0], p.children[1]
  1197  			p.nrSegments = left.nrSegments + right.nrSegments + 1
  1198  			p.hasChildren = left.hasChildren
  1199  			p.keys[left.nrSegments] = p.keys[0]
  1200  			p.values[left.nrSegments] = p.values[0]
  1201  			copy(p.keys[:left.nrSegments], left.keys[:left.nrSegments])
  1202  			copy(p.values[:left.nrSegments], left.values[:left.nrSegments])
  1203  			copy(p.keys[left.nrSegments+1:], right.keys[:right.nrSegments])
  1204  			copy(p.values[left.nrSegments+1:], right.values[:right.nrSegments])
  1205  			if left.hasChildren {
  1206  				copy(p.children[:left.nrSegments+1], left.children[:left.nrSegments+1])
  1207  				copy(p.children[left.nrSegments+1:], right.children[:right.nrSegments+1])
  1208  				for i := 0; i < p.nrSegments+1; i++ {
  1209  					p.children[i].parent = p
  1210  					p.children[i].parentIndex = i
  1211  				}
  1212  			} else {
  1213  				p.children[0] = nil
  1214  				p.children[1] = nil
  1215  			}
  1216  
  1217  			if gap.node == left {
  1218  				return evictableRangeGapIterator{p, gap.index}
  1219  			}
  1220  			if gap.node == right {
  1221  				return evictableRangeGapIterator{p, gap.index + left.nrSegments + 1}
  1222  			}
  1223  			return gap
  1224  		}
  1225  		// Merge n and either sibling, along with the segment separating the
  1226  		// two, into whichever of the two nodes comes first. This is the
  1227  		// reverse of the non-root splitting case in
  1228  		// node.rebalanceBeforeInsert.
  1229  		var left, right *evictableRangenode
  1230  		if n.parentIndex > 0 {
  1231  			left = n.prevSibling()
  1232  			right = n
  1233  		} else {
  1234  			left = n
  1235  			right = n.nextSibling()
  1236  		}
  1237  
  1238  		if gap.node == right {
  1239  			gap = evictableRangeGapIterator{left, gap.index + left.nrSegments + 1}
  1240  		}
  1241  		left.keys[left.nrSegments] = p.keys[left.parentIndex]
  1242  		left.values[left.nrSegments] = p.values[left.parentIndex]
  1243  		copy(left.keys[left.nrSegments+1:], right.keys[:right.nrSegments])
  1244  		copy(left.values[left.nrSegments+1:], right.values[:right.nrSegments])
  1245  		if left.hasChildren {
  1246  			copy(left.children[left.nrSegments+1:], right.children[:right.nrSegments+1])
  1247  			for i := left.nrSegments + 1; i < left.nrSegments+right.nrSegments+2; i++ {
  1248  				left.children[i].parent = left
  1249  				left.children[i].parentIndex = i
  1250  			}
  1251  		}
  1252  		left.nrSegments += right.nrSegments + 1
  1253  		copy(p.keys[left.parentIndex:], p.keys[left.parentIndex+1:p.nrSegments])
  1254  		copy(p.values[left.parentIndex:], p.values[left.parentIndex+1:p.nrSegments])
  1255  		evictableRangeSetFunctions{}.ClearValue(&p.values[p.nrSegments-1])
  1256  		copy(p.children[left.parentIndex+1:], p.children[left.parentIndex+2:p.nrSegments+1])
  1257  		for i := 0; i < p.nrSegments; i++ {
  1258  			p.children[i].parentIndex = i
  1259  		}
  1260  		p.children[p.nrSegments] = nil
  1261  		p.nrSegments--
  1262  
  1263  		if evictableRangetrackGaps != 0 {
  1264  			left.updateMaxGapLocal()
  1265  		}
  1266  
  1267  		n = p
  1268  	}
  1269  }
  1270  
  1271  // updateMaxGapLeaf updates maxGap bottom-up from the calling leaf until no
  1272  // necessary update.
  1273  //
  1274  // Preconditions: n must be a leaf node, trackGaps must be 1.
  1275  func (n *evictableRangenode) updateMaxGapLeaf() {
  1276  	if n.hasChildren {
  1277  		panic(fmt.Sprintf("updateMaxGapLeaf should always be called on leaf node: %v", n))
  1278  	}
  1279  	max := n.calculateMaxGapLeaf()
  1280  	if max == n.maxGap.Get() {
  1281  
  1282  		return
  1283  	}
  1284  	oldMax := n.maxGap.Get()
  1285  	n.maxGap.Set(max)
  1286  	if max > oldMax {
  1287  
  1288  		for p := n.parent; p != nil; p = p.parent {
  1289  			if p.maxGap.Get() >= max {
  1290  
  1291  				break
  1292  			}
  1293  
  1294  			p.maxGap.Set(max)
  1295  		}
  1296  		return
  1297  	}
  1298  
  1299  	for p := n.parent; p != nil; p = p.parent {
  1300  		if p.maxGap.Get() > oldMax {
  1301  
  1302  			break
  1303  		}
  1304  
  1305  		parentNewMax := p.calculateMaxGapInternal()
  1306  		if p.maxGap.Get() == parentNewMax {
  1307  
  1308  			break
  1309  		}
  1310  
  1311  		p.maxGap.Set(parentNewMax)
  1312  	}
  1313  }
  1314  
  1315  // updateMaxGapLocal updates maxGap of the calling node solely with no
  1316  // propagation to ancestor nodes.
  1317  //
  1318  // Precondition: trackGaps must be 1.
  1319  func (n *evictableRangenode) updateMaxGapLocal() {
  1320  	if !n.hasChildren {
  1321  
  1322  		n.maxGap.Set(n.calculateMaxGapLeaf())
  1323  	} else {
  1324  
  1325  		n.maxGap.Set(n.calculateMaxGapInternal())
  1326  	}
  1327  }
  1328  
  1329  // calculateMaxGapLeaf iterates the gaps within a leaf node and calculate the
  1330  // max.
  1331  //
  1332  // Preconditions: n must be a leaf node.
  1333  func (n *evictableRangenode) calculateMaxGapLeaf() uint64 {
  1334  	max := evictableRangeGapIterator{n, 0}.Range().Length()
  1335  	for i := 1; i <= n.nrSegments; i++ {
  1336  		if current := (evictableRangeGapIterator{n, i}).Range().Length(); current > max {
  1337  			max = current
  1338  		}
  1339  	}
  1340  	return max
  1341  }
  1342  
  1343  // calculateMaxGapInternal iterates children's maxGap within an internal node n
  1344  // and calculate the max.
  1345  //
  1346  // Preconditions: n must be a non-leaf node.
  1347  func (n *evictableRangenode) calculateMaxGapInternal() uint64 {
  1348  	max := n.children[0].maxGap.Get()
  1349  	for i := 1; i <= n.nrSegments; i++ {
  1350  		if current := n.children[i].maxGap.Get(); current > max {
  1351  			max = current
  1352  		}
  1353  	}
  1354  	return max
  1355  }
  1356  
  1357  // searchFirstLargeEnoughGap returns the first gap having at least minSize length
  1358  // in the subtree rooted by n. If not found, return a terminal gap iterator.
  1359  func (n *evictableRangenode) searchFirstLargeEnoughGap(minSize uint64) evictableRangeGapIterator {
  1360  	if n.maxGap.Get() < minSize {
  1361  		return evictableRangeGapIterator{}
  1362  	}
  1363  	if n.hasChildren {
  1364  		for i := 0; i <= n.nrSegments; i++ {
  1365  			if largeEnoughGap := n.children[i].searchFirstLargeEnoughGap(minSize); largeEnoughGap.Ok() {
  1366  				return largeEnoughGap
  1367  			}
  1368  		}
  1369  	} else {
  1370  		for i := 0; i <= n.nrSegments; i++ {
  1371  			currentGap := evictableRangeGapIterator{n, i}
  1372  			if currentGap.Range().Length() >= minSize {
  1373  				return currentGap
  1374  			}
  1375  		}
  1376  	}
  1377  	panic(fmt.Sprintf("invalid maxGap in %v", n))
  1378  }
  1379  
  1380  // searchLastLargeEnoughGap returns the last gap having at least minSize length
  1381  // in the subtree rooted by n. If not found, return a terminal gap iterator.
  1382  func (n *evictableRangenode) searchLastLargeEnoughGap(minSize uint64) evictableRangeGapIterator {
  1383  	if n.maxGap.Get() < minSize {
  1384  		return evictableRangeGapIterator{}
  1385  	}
  1386  	if n.hasChildren {
  1387  		for i := n.nrSegments; i >= 0; i-- {
  1388  			if largeEnoughGap := n.children[i].searchLastLargeEnoughGap(minSize); largeEnoughGap.Ok() {
  1389  				return largeEnoughGap
  1390  			}
  1391  		}
  1392  	} else {
  1393  		for i := n.nrSegments; i >= 0; i-- {
  1394  			currentGap := evictableRangeGapIterator{n, i}
  1395  			if currentGap.Range().Length() >= minSize {
  1396  				return currentGap
  1397  			}
  1398  		}
  1399  	}
  1400  	panic(fmt.Sprintf("invalid maxGap in %v", n))
  1401  }
  1402  
  1403  // A Iterator is conceptually one of:
  1404  //
  1405  //   - A pointer to a segment in a set; or
  1406  //
  1407  //   - A terminal iterator, which is a sentinel indicating that the end of
  1408  //     iteration has been reached.
  1409  //
  1410  // Iterators are copyable values and are meaningfully equality-comparable. The
  1411  // zero value of Iterator is a terminal iterator.
  1412  //
  1413  // Unless otherwise specified, any mutation of a set invalidates all existing
  1414  // iterators into the set.
  1415  type evictableRangeIterator struct {
  1416  	// node is the node containing the iterated segment. If the iterator is
  1417  	// terminal, node is nil.
  1418  	node *evictableRangenode
  1419  
  1420  	// index is the index of the segment in node.keys/values.
  1421  	index int
  1422  }
  1423  
  1424  // Ok returns true if the iterator is not terminal. All other methods are only
  1425  // valid for non-terminal iterators.
  1426  func (seg evictableRangeIterator) Ok() bool {
  1427  	return seg.node != nil
  1428  }
  1429  
  1430  // Range returns the iterated segment's range key.
  1431  func (seg evictableRangeIterator) Range() EvictableRange {
  1432  	return seg.node.keys[seg.index]
  1433  }
  1434  
  1435  // Start is equivalent to Range().Start, but should be preferred if only the
  1436  // start of the range is needed.
  1437  func (seg evictableRangeIterator) Start() uint64 {
  1438  	return seg.node.keys[seg.index].Start
  1439  }
  1440  
  1441  // End is equivalent to Range().End, but should be preferred if only the end of
  1442  // the range is needed.
  1443  func (seg evictableRangeIterator) End() uint64 {
  1444  	return seg.node.keys[seg.index].End
  1445  }
  1446  
  1447  // SetRangeUnchecked mutates the iterated segment's range key. This operation
  1448  // does not invalidate any iterators.
  1449  //
  1450  // Preconditions:
  1451  // - r.Length() > 0.
  1452  // - The new range must not overlap an existing one:
  1453  //   - If seg.NextSegment().Ok(), then r.end <= seg.NextSegment().Start().
  1454  //   - If seg.PrevSegment().Ok(), then r.start >= seg.PrevSegment().End().
  1455  func (seg evictableRangeIterator) SetRangeUnchecked(r EvictableRange) {
  1456  	seg.node.keys[seg.index] = r
  1457  }
  1458  
  1459  // SetRange mutates the iterated segment's range key. If the new range would
  1460  // cause the iterated segment to overlap another segment, or if the new range
  1461  // is invalid, SetRange panics. This operation does not invalidate any
  1462  // iterators.
  1463  func (seg evictableRangeIterator) SetRange(r EvictableRange) {
  1464  	if r.Length() <= 0 {
  1465  		panic(fmt.Sprintf("invalid segment range %v", r))
  1466  	}
  1467  	if prev := seg.PrevSegment(); prev.Ok() && r.Start < prev.End() {
  1468  		panic(fmt.Sprintf("new segment range %v overlaps segment range %v", r, prev.Range()))
  1469  	}
  1470  	if next := seg.NextSegment(); next.Ok() && r.End > next.Start() {
  1471  		panic(fmt.Sprintf("new segment range %v overlaps segment range %v", r, next.Range()))
  1472  	}
  1473  	seg.SetRangeUnchecked(r)
  1474  }
  1475  
  1476  // SetStartUnchecked mutates the iterated segment's start. This operation does
  1477  // not invalidate any iterators.
  1478  //
  1479  // Preconditions: The new start must be valid:
  1480  //   - start < seg.End()
  1481  //   - If seg.PrevSegment().Ok(), then start >= seg.PrevSegment().End().
  1482  func (seg evictableRangeIterator) SetStartUnchecked(start uint64) {
  1483  	seg.node.keys[seg.index].Start = start
  1484  }
  1485  
  1486  // SetStart mutates the iterated segment's start. If the new start value would
  1487  // cause the iterated segment to overlap another segment, or would result in an
  1488  // invalid range, SetStart panics. This operation does not invalidate any
  1489  // iterators.
  1490  func (seg evictableRangeIterator) SetStart(start uint64) {
  1491  	if start >= seg.End() {
  1492  		panic(fmt.Sprintf("new start %v would invalidate segment range %v", start, seg.Range()))
  1493  	}
  1494  	if prev := seg.PrevSegment(); prev.Ok() && start < prev.End() {
  1495  		panic(fmt.Sprintf("new start %v would cause segment range %v to overlap segment range %v", start, seg.Range(), prev.Range()))
  1496  	}
  1497  	seg.SetStartUnchecked(start)
  1498  }
  1499  
  1500  // SetEndUnchecked mutates the iterated segment's end. This operation does not
  1501  // invalidate any iterators.
  1502  //
  1503  // Preconditions: The new end must be valid:
  1504  //   - end > seg.Start().
  1505  //   - If seg.NextSegment().Ok(), then end <= seg.NextSegment().Start().
  1506  func (seg evictableRangeIterator) SetEndUnchecked(end uint64) {
  1507  	seg.node.keys[seg.index].End = end
  1508  }
  1509  
  1510  // SetEnd mutates the iterated segment's end. If the new end value would cause
  1511  // the iterated segment to overlap another segment, or would result in an
  1512  // invalid range, SetEnd panics. This operation does not invalidate any
  1513  // iterators.
  1514  func (seg evictableRangeIterator) SetEnd(end uint64) {
  1515  	if end <= seg.Start() {
  1516  		panic(fmt.Sprintf("new end %v would invalidate segment range %v", end, seg.Range()))
  1517  	}
  1518  	if next := seg.NextSegment(); next.Ok() && end > next.Start() {
  1519  		panic(fmt.Sprintf("new end %v would cause segment range %v to overlap segment range %v", end, seg.Range(), next.Range()))
  1520  	}
  1521  	seg.SetEndUnchecked(end)
  1522  }
  1523  
  1524  // Value returns a copy of the iterated segment's value.
  1525  func (seg evictableRangeIterator) Value() evictableRangeSetValue {
  1526  	return seg.node.values[seg.index]
  1527  }
  1528  
  1529  // ValuePtr returns a pointer to the iterated segment's value. The pointer is
  1530  // invalidated if the iterator is invalidated. This operation does not
  1531  // invalidate any iterators.
  1532  func (seg evictableRangeIterator) ValuePtr() *evictableRangeSetValue {
  1533  	return &seg.node.values[seg.index]
  1534  }
  1535  
  1536  // SetValue mutates the iterated segment's value. This operation does not
  1537  // invalidate any iterators.
  1538  func (seg evictableRangeIterator) SetValue(val evictableRangeSetValue) {
  1539  	seg.node.values[seg.index] = val
  1540  }
  1541  
  1542  // PrevSegment returns the iterated segment's predecessor. If there is no
  1543  // preceding segment, PrevSegment returns a terminal iterator.
  1544  func (seg evictableRangeIterator) PrevSegment() evictableRangeIterator {
  1545  	if seg.node.hasChildren {
  1546  		return seg.node.children[seg.index].lastSegment()
  1547  	}
  1548  	if seg.index > 0 {
  1549  		return evictableRangeIterator{seg.node, seg.index - 1}
  1550  	}
  1551  	if seg.node.parent == nil {
  1552  		return evictableRangeIterator{}
  1553  	}
  1554  	return evictableRangesegmentBeforePosition(seg.node.parent, seg.node.parentIndex)
  1555  }
  1556  
  1557  // NextSegment returns the iterated segment's successor. If there is no
  1558  // succeeding segment, NextSegment returns a terminal iterator.
  1559  func (seg evictableRangeIterator) NextSegment() evictableRangeIterator {
  1560  	if seg.node.hasChildren {
  1561  		return seg.node.children[seg.index+1].firstSegment()
  1562  	}
  1563  	if seg.index < seg.node.nrSegments-1 {
  1564  		return evictableRangeIterator{seg.node, seg.index + 1}
  1565  	}
  1566  	if seg.node.parent == nil {
  1567  		return evictableRangeIterator{}
  1568  	}
  1569  	return evictableRangesegmentAfterPosition(seg.node.parent, seg.node.parentIndex)
  1570  }
  1571  
  1572  // PrevGap returns the gap immediately before the iterated segment.
  1573  func (seg evictableRangeIterator) PrevGap() evictableRangeGapIterator {
  1574  	if seg.node.hasChildren {
  1575  
  1576  		return seg.node.children[seg.index].lastSegment().NextGap()
  1577  	}
  1578  	return evictableRangeGapIterator{seg.node, seg.index}
  1579  }
  1580  
  1581  // NextGap returns the gap immediately after the iterated segment.
  1582  func (seg evictableRangeIterator) NextGap() evictableRangeGapIterator {
  1583  	if seg.node.hasChildren {
  1584  		return seg.node.children[seg.index+1].firstSegment().PrevGap()
  1585  	}
  1586  	return evictableRangeGapIterator{seg.node, seg.index + 1}
  1587  }
  1588  
  1589  // PrevNonEmpty returns the iterated segment's predecessor if it is adjacent,
  1590  // or the gap before the iterated segment otherwise. If seg.Start() ==
  1591  // Functions.MinKey(), PrevNonEmpty will return two terminal iterators.
  1592  // Otherwise, exactly one of the iterators returned by PrevNonEmpty will be
  1593  // non-terminal.
  1594  func (seg evictableRangeIterator) PrevNonEmpty() (evictableRangeIterator, evictableRangeGapIterator) {
  1595  	if prev := seg.PrevSegment(); prev.Ok() && prev.End() == seg.Start() {
  1596  		return prev, evictableRangeGapIterator{}
  1597  	}
  1598  	return evictableRangeIterator{}, seg.PrevGap()
  1599  }
  1600  
  1601  // NextNonEmpty returns the iterated segment's successor if it is adjacent, or
  1602  // the gap after the iterated segment otherwise. If seg.End() ==
  1603  // Functions.MaxKey(), NextNonEmpty will return two terminal iterators.
  1604  // Otherwise, exactly one of the iterators returned by NextNonEmpty will be
  1605  // non-terminal.
  1606  func (seg evictableRangeIterator) NextNonEmpty() (evictableRangeIterator, evictableRangeGapIterator) {
  1607  	if next := seg.NextSegment(); next.Ok() && next.Start() == seg.End() {
  1608  		return next, evictableRangeGapIterator{}
  1609  	}
  1610  	return evictableRangeIterator{}, seg.NextGap()
  1611  }
  1612  
  1613  // A GapIterator is conceptually one of:
  1614  //
  1615  //   - A pointer to a position between two segments, before the first segment, or
  1616  //     after the last segment in a set, called a *gap*; or
  1617  //
  1618  //   - A terminal iterator, which is a sentinel indicating that the end of
  1619  //     iteration has been reached.
  1620  //
  1621  // Note that the gap between two adjacent segments exists (iterators to it are
  1622  // non-terminal), but has a length of zero. GapIterator.IsEmpty returns true
  1623  // for such gaps. An empty set contains a single gap, spanning the entire range
  1624  // of the set's keys.
  1625  //
  1626  // GapIterators are copyable values and are meaningfully equality-comparable.
  1627  // The zero value of GapIterator is a terminal iterator.
  1628  //
  1629  // Unless otherwise specified, any mutation of a set invalidates all existing
  1630  // iterators into the set.
  1631  type evictableRangeGapIterator struct {
  1632  	// The representation of a GapIterator is identical to that of an Iterator,
  1633  	// except that index corresponds to positions between segments in the same
  1634  	// way as for node.children (see comment for node.nrSegments).
  1635  	node  *evictableRangenode
  1636  	index int
  1637  }
  1638  
  1639  // Ok returns true if the iterator is not terminal. All other methods are only
  1640  // valid for non-terminal iterators.
  1641  func (gap evictableRangeGapIterator) Ok() bool {
  1642  	return gap.node != nil
  1643  }
  1644  
  1645  // Range returns the range spanned by the iterated gap.
  1646  func (gap evictableRangeGapIterator) Range() EvictableRange {
  1647  	return EvictableRange{gap.Start(), gap.End()}
  1648  }
  1649  
  1650  // Start is equivalent to Range().Start, but should be preferred if only the
  1651  // start of the range is needed.
  1652  func (gap evictableRangeGapIterator) Start() uint64 {
  1653  	if ps := gap.PrevSegment(); ps.Ok() {
  1654  		return ps.End()
  1655  	}
  1656  	return evictableRangeSetFunctions{}.MinKey()
  1657  }
  1658  
  1659  // End is equivalent to Range().End, but should be preferred if only the end of
  1660  // the range is needed.
  1661  func (gap evictableRangeGapIterator) End() uint64 {
  1662  	if ns := gap.NextSegment(); ns.Ok() {
  1663  		return ns.Start()
  1664  	}
  1665  	return evictableRangeSetFunctions{}.MaxKey()
  1666  }
  1667  
  1668  // IsEmpty returns true if the iterated gap is empty (that is, the "gap" is
  1669  // between two adjacent segments.)
  1670  func (gap evictableRangeGapIterator) IsEmpty() bool {
  1671  	return gap.Range().Length() == 0
  1672  }
  1673  
  1674  // PrevSegment returns the segment immediately before the iterated gap. If no
  1675  // such segment exists, PrevSegment returns a terminal iterator.
  1676  func (gap evictableRangeGapIterator) PrevSegment() evictableRangeIterator {
  1677  	return evictableRangesegmentBeforePosition(gap.node, gap.index)
  1678  }
  1679  
  1680  // NextSegment returns the segment immediately after the iterated gap. If no
  1681  // such segment exists, NextSegment returns a terminal iterator.
  1682  func (gap evictableRangeGapIterator) NextSegment() evictableRangeIterator {
  1683  	return evictableRangesegmentAfterPosition(gap.node, gap.index)
  1684  }
  1685  
  1686  // PrevGap returns the iterated gap's predecessor. If no such gap exists,
  1687  // PrevGap returns a terminal iterator.
  1688  func (gap evictableRangeGapIterator) PrevGap() evictableRangeGapIterator {
  1689  	seg := gap.PrevSegment()
  1690  	if !seg.Ok() {
  1691  		return evictableRangeGapIterator{}
  1692  	}
  1693  	return seg.PrevGap()
  1694  }
  1695  
  1696  // NextGap returns the iterated gap's successor. If no such gap exists, NextGap
  1697  // returns a terminal iterator.
  1698  func (gap evictableRangeGapIterator) NextGap() evictableRangeGapIterator {
  1699  	seg := gap.NextSegment()
  1700  	if !seg.Ok() {
  1701  		return evictableRangeGapIterator{}
  1702  	}
  1703  	return seg.NextGap()
  1704  }
  1705  
  1706  // NextLargeEnoughGap returns the iterated gap's first next gap with larger
  1707  // length than minSize.  If not found, return a terminal gap iterator (does NOT
  1708  // include this gap itself).
  1709  //
  1710  // Precondition: trackGaps must be 1.
  1711  func (gap evictableRangeGapIterator) NextLargeEnoughGap(minSize uint64) evictableRangeGapIterator {
  1712  	if evictableRangetrackGaps != 1 {
  1713  		panic("set is not tracking gaps")
  1714  	}
  1715  	if gap.node != nil && gap.node.hasChildren && gap.index == gap.node.nrSegments {
  1716  
  1717  		gap.node = gap.NextSegment().node
  1718  		gap.index = 0
  1719  		return gap.nextLargeEnoughGapHelper(minSize)
  1720  	}
  1721  	return gap.nextLargeEnoughGapHelper(minSize)
  1722  }
  1723  
  1724  // nextLargeEnoughGapHelper is the helper function used by NextLargeEnoughGap
  1725  // to do the real recursions.
  1726  //
  1727  // Preconditions: gap is NOT the trailing gap of a non-leaf node.
  1728  func (gap evictableRangeGapIterator) nextLargeEnoughGapHelper(minSize uint64) evictableRangeGapIterator {
  1729  	for {
  1730  
  1731  		for gap.node != nil &&
  1732  			(gap.node.maxGap.Get() < minSize || (!gap.node.hasChildren && gap.index == gap.node.nrSegments)) {
  1733  			gap.node, gap.index = gap.node.parent, gap.node.parentIndex
  1734  		}
  1735  
  1736  		if gap.node == nil {
  1737  			return evictableRangeGapIterator{}
  1738  		}
  1739  
  1740  		gap.index++
  1741  		for gap.index <= gap.node.nrSegments {
  1742  			if gap.node.hasChildren {
  1743  				if largeEnoughGap := gap.node.children[gap.index].searchFirstLargeEnoughGap(minSize); largeEnoughGap.Ok() {
  1744  					return largeEnoughGap
  1745  				}
  1746  			} else {
  1747  				if gap.Range().Length() >= minSize {
  1748  					return gap
  1749  				}
  1750  			}
  1751  			gap.index++
  1752  		}
  1753  		gap.node, gap.index = gap.node.parent, gap.node.parentIndex
  1754  		if gap.node != nil && gap.index == gap.node.nrSegments {
  1755  
  1756  			gap.node, gap.index = gap.node.parent, gap.node.parentIndex
  1757  		}
  1758  	}
  1759  }
  1760  
  1761  // PrevLargeEnoughGap returns the iterated gap's first prev gap with larger or
  1762  // equal length than minSize.  If not found, return a terminal gap iterator
  1763  // (does NOT include this gap itself).
  1764  //
  1765  // Precondition: trackGaps must be 1.
  1766  func (gap evictableRangeGapIterator) PrevLargeEnoughGap(minSize uint64) evictableRangeGapIterator {
  1767  	if evictableRangetrackGaps != 1 {
  1768  		panic("set is not tracking gaps")
  1769  	}
  1770  	if gap.node != nil && gap.node.hasChildren && gap.index == 0 {
  1771  
  1772  		gap.node = gap.PrevSegment().node
  1773  		gap.index = gap.node.nrSegments
  1774  		return gap.prevLargeEnoughGapHelper(minSize)
  1775  	}
  1776  	return gap.prevLargeEnoughGapHelper(minSize)
  1777  }
  1778  
  1779  // prevLargeEnoughGapHelper is the helper function used by PrevLargeEnoughGap
  1780  // to do the real recursions.
  1781  //
  1782  // Preconditions: gap is NOT the first gap of a non-leaf node.
  1783  func (gap evictableRangeGapIterator) prevLargeEnoughGapHelper(minSize uint64) evictableRangeGapIterator {
  1784  	for {
  1785  
  1786  		for gap.node != nil &&
  1787  			(gap.node.maxGap.Get() < minSize || (!gap.node.hasChildren && gap.index == 0)) {
  1788  			gap.node, gap.index = gap.node.parent, gap.node.parentIndex
  1789  		}
  1790  
  1791  		if gap.node == nil {
  1792  			return evictableRangeGapIterator{}
  1793  		}
  1794  
  1795  		gap.index--
  1796  		for gap.index >= 0 {
  1797  			if gap.node.hasChildren {
  1798  				if largeEnoughGap := gap.node.children[gap.index].searchLastLargeEnoughGap(minSize); largeEnoughGap.Ok() {
  1799  					return largeEnoughGap
  1800  				}
  1801  			} else {
  1802  				if gap.Range().Length() >= minSize {
  1803  					return gap
  1804  				}
  1805  			}
  1806  			gap.index--
  1807  		}
  1808  		gap.node, gap.index = gap.node.parent, gap.node.parentIndex
  1809  		if gap.node != nil && gap.index == 0 {
  1810  
  1811  			gap.node, gap.index = gap.node.parent, gap.node.parentIndex
  1812  		}
  1813  	}
  1814  }
  1815  
  1816  // segmentBeforePosition returns the predecessor segment of the position given
  1817  // by n.children[i], which may or may not contain a child. If no such segment
  1818  // exists, segmentBeforePosition returns a terminal iterator.
  1819  func evictableRangesegmentBeforePosition(n *evictableRangenode, i int) evictableRangeIterator {
  1820  	for i == 0 {
  1821  		if n.parent == nil {
  1822  			return evictableRangeIterator{}
  1823  		}
  1824  		n, i = n.parent, n.parentIndex
  1825  	}
  1826  	return evictableRangeIterator{n, i - 1}
  1827  }
  1828  
  1829  // segmentAfterPosition returns the successor segment of the position given by
  1830  // n.children[i], which may or may not contain a child. If no such segment
  1831  // exists, segmentAfterPosition returns a terminal iterator.
  1832  func evictableRangesegmentAfterPosition(n *evictableRangenode, i int) evictableRangeIterator {
  1833  	for i == n.nrSegments {
  1834  		if n.parent == nil {
  1835  			return evictableRangeIterator{}
  1836  		}
  1837  		n, i = n.parent, n.parentIndex
  1838  	}
  1839  	return evictableRangeIterator{n, i}
  1840  }
  1841  
  1842  func evictableRangezeroValueSlice(slice []evictableRangeSetValue) {
  1843  
  1844  	for i := range slice {
  1845  		evictableRangeSetFunctions{}.ClearValue(&slice[i])
  1846  	}
  1847  }
  1848  
  1849  func evictableRangezeroNodeSlice(slice []*evictableRangenode) {
  1850  	for i := range slice {
  1851  		slice[i] = nil
  1852  	}
  1853  }
  1854  
  1855  // String stringifies a Set for debugging.
  1856  func (s *evictableRangeSet) String() string {
  1857  	return s.root.String()
  1858  }
  1859  
  1860  // String stringifies a node (and all of its children) for debugging.
  1861  func (n *evictableRangenode) String() string {
  1862  	var buf bytes.Buffer
  1863  	n.writeDebugString(&buf, "")
  1864  	return buf.String()
  1865  }
  1866  
  1867  func (n *evictableRangenode) writeDebugString(buf *bytes.Buffer, prefix string) {
  1868  	if n.hasChildren != (n.nrSegments > 0 && n.children[0] != nil) {
  1869  		buf.WriteString(prefix)
  1870  		buf.WriteString(fmt.Sprintf("WARNING: inconsistent value of hasChildren: got %v, want %v\n", n.hasChildren, !n.hasChildren))
  1871  	}
  1872  	for i := 0; i < n.nrSegments; i++ {
  1873  		if child := n.children[i]; child != nil {
  1874  			cprefix := fmt.Sprintf("%s- % 3d ", prefix, i)
  1875  			if child.parent != n || child.parentIndex != i {
  1876  				buf.WriteString(cprefix)
  1877  				buf.WriteString(fmt.Sprintf("WARNING: inconsistent linkage to parent: got (%p, %d), want (%p, %d)\n", child.parent, child.parentIndex, n, i))
  1878  			}
  1879  			child.writeDebugString(buf, fmt.Sprintf("%s- % 3d ", prefix, i))
  1880  		}
  1881  		buf.WriteString(prefix)
  1882  		if n.hasChildren {
  1883  			if evictableRangetrackGaps != 0 {
  1884  				buf.WriteString(fmt.Sprintf("- % 3d: %v => %v, maxGap: %d\n", i, n.keys[i], n.values[i], n.maxGap.Get()))
  1885  			} else {
  1886  				buf.WriteString(fmt.Sprintf("- % 3d: %v => %v\n", i, n.keys[i], n.values[i]))
  1887  			}
  1888  		} else {
  1889  			buf.WriteString(fmt.Sprintf("- % 3d: %v => %v\n", i, n.keys[i], n.values[i]))
  1890  		}
  1891  	}
  1892  	if child := n.children[n.nrSegments]; child != nil {
  1893  		child.writeDebugString(buf, fmt.Sprintf("%s- % 3d ", prefix, n.nrSegments))
  1894  	}
  1895  }
  1896  
  1897  // FlatSegment represents a segment as a single object. FlatSegment is used as
  1898  // an intermediate representation for save/restore and tests.
  1899  //
  1900  // +stateify savable
  1901  type evictableRangeFlatSegment struct {
  1902  	Start uint64
  1903  	End   uint64
  1904  	Value evictableRangeSetValue
  1905  }
  1906  
  1907  // ExportSlice returns a copy of all segments in the given set, in ascending
  1908  // key order.
  1909  func (s *evictableRangeSet) ExportSlice() []evictableRangeFlatSegment {
  1910  	var fs []evictableRangeFlatSegment
  1911  	for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
  1912  		fs = append(fs, evictableRangeFlatSegment{
  1913  			Start: seg.Start(),
  1914  			End:   seg.End(),
  1915  			Value: seg.Value(),
  1916  		})
  1917  	}
  1918  	return fs
  1919  }
  1920  
  1921  // ImportSlice initializes the given set from the given slice.
  1922  //
  1923  // Preconditions:
  1924  //   - s must be empty.
  1925  //   - fs must represent a valid set (the segments in fs must have valid
  1926  //     lengths that do not overlap).
  1927  //   - The segments in fs must be sorted in ascending key order.
  1928  func (s *evictableRangeSet) ImportSlice(fs []evictableRangeFlatSegment) error {
  1929  	if !s.IsEmpty() {
  1930  		return fmt.Errorf("cannot import into non-empty set %v", s)
  1931  	}
  1932  	gap := s.FirstGap()
  1933  	for i := range fs {
  1934  		f := &fs[i]
  1935  		r := EvictableRange{f.Start, f.End}
  1936  		if !gap.Range().IsSupersetOf(r) {
  1937  			return fmt.Errorf("segment overlaps a preceding segment or is incorrectly sorted: %v => %v", r, f.Value)
  1938  		}
  1939  		gap = s.InsertWithoutMerging(gap, r, f.Value).NextGap()
  1940  	}
  1941  	return nil
  1942  }
  1943  
  1944  // segmentTestCheck returns an error if s is incorrectly sorted, does not
  1945  // contain exactly expectedSegments segments, or contains a segment which
  1946  // fails the passed check.
  1947  //
  1948  // This should be used only for testing, and has been added to this package for
  1949  // templating convenience.
  1950  func (s *evictableRangeSet) segmentTestCheck(expectedSegments int, segFunc func(int, EvictableRange, evictableRangeSetValue) error) error {
  1951  	havePrev := false
  1952  	prev := uint64(0)
  1953  	nrSegments := 0
  1954  	for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
  1955  		next := seg.Start()
  1956  		if havePrev && prev >= next {
  1957  			return fmt.Errorf("incorrect order: key %d (segment %d) >= key %d (segment %d)", prev, nrSegments-1, next, nrSegments)
  1958  		}
  1959  		if segFunc != nil {
  1960  			if err := segFunc(nrSegments, seg.Range(), seg.Value()); err != nil {
  1961  				return err
  1962  			}
  1963  		}
  1964  		prev = next
  1965  		havePrev = true
  1966  		nrSegments++
  1967  	}
  1968  	if nrSegments != expectedSegments {
  1969  		return fmt.Errorf("incorrect number of segments: got %d, wanted %d", nrSegments, expectedSegments)
  1970  	}
  1971  	return nil
  1972  }
  1973  
  1974  // countSegments counts the number of segments in the set.
  1975  //
  1976  // Similar to Check, this should only be used for testing.
  1977  func (s *evictableRangeSet) countSegments() (segments int) {
  1978  	for seg := s.FirstSegment(); seg.Ok(); seg = seg.NextSegment() {
  1979  		segments++
  1980  	}
  1981  	return segments
  1982  }
  1983  func (s *evictableRangeSet) saveRoot() []evictableRangeFlatSegment {
  1984  	fs := s.ExportSlice()
  1985  
  1986  	fs = fs[:len(fs):len(fs)]
  1987  	return fs
  1988  }
  1989  
  1990  func (s *evictableRangeSet) loadRoot(_ context.Context, fs []evictableRangeFlatSegment) {
  1991  	if err := s.ImportSlice(fs); err != nil {
  1992  		panic(err)
  1993  	}
  1994  }