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

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