github.com/ttpreport/gvisor-ligolo@v0.0.0-20240123134145-a858404967ba/pkg/sentry/pgalloc/reclaim_set.go (about)

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