Skip to content

Commit 88d35cd

Browse files
nixprimegvisor-bot
authored andcommittedNov 17, 2023
segment.Set API improvements.
- Replace Add with TryInsertRange; for symmetry with RemoveRange, to establish the convention that *Range methods perform an implicit search in the set, and so that we can fork InsertRange which has Insert-like semantics (panics on conflict), which the majority of callers want. - Rename MergeRange and MergeAdjacent to MergeInsideRange and MergeOutsideRange respectively; for the same convention, and to more clearly describe the difference between these functions. - Add MergePrev and MergeNext. These solve the longstanding problem of requiring a separate call to Merge{Inside,Outside}Range (which will perform additional searches) after mutating a set in a relatively simple manner. - Add SplitBefore and SplitAfter, which are halves of Isolate. These are slightly preferable to Isolate in many use cases for the latter (when iterating segments within a range, only the first segment can include a key before the start, so this saves some useless comparisons in almost every iteration of such loops), and are useful in some more complex algorithms. Also add LowerBoundSegmentSplitBefore and UpperBoundSegmentSplitAfter as ergonomic aids for the former use case. - Add {Visit,Mutate}[Full]Range, which are convenience wrappers around the iterator API (including new functions) for simple use cases (and hence also serve to demonstrate how the new iterator functions are used). MutateFullRange in particular replaces ApplyContiguous and adds merging during iteration. - Add RemoveFullRange, which (analogous to {Visit,Mutate}FullRange) is a variant of RemoveRange that checks that the range is fully covered by segments. - Add Unisolate, which combines MergePrev and MergeNext in the same way that Isolate combines SplitBefore and SplitAfter. This is useful for merging after mutation of a single segment. - Add {First,Last,LowerBound,UpperBound}LargeEnoughGap, which are convenient loop starters when using gap tracking. - Replace SegmentDataSlices with FlatSegment, which is easier to use when specifying "set literals" (as in tests). - Make {prev,next}LargeEnoughGapHelper iterative rather than tail-recursive. - Slightly optimize Iterator.{Prev,Next}NonEmpty: GapIterator.{Start,End} needs to find the corresponding Iterator, so call Iterator.{Prev,Next}Segment directly rather than doing so twice. PiperOrigin-RevId: 583506148
1 parent 2ef56fe commit 88d35cd

File tree

16 files changed

+768
-490
lines changed

16 files changed

+768
-490
lines changed
 

‎pkg/segment/set.go

Lines changed: 507 additions & 161 deletions
Large diffs are not rendered by default.

‎pkg/segment/set_state.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414

1515
package segment
1616

17-
func (s *Set) saveRoot() *SegmentDataSlices {
18-
return s.ExportSortedSlices()
17+
func (s *Set) saveRoot() []FlatSegment {
18+
fs := s.ExportSlice()
19+
// The state package saves data in slice capacity beyond slice length; save
20+
// it some time by cutting ours off.
21+
fs = fs[:len(fs):len(fs)]
22+
return fs
1923
}
2024

21-
func (s *Set) loadRoot(sds *SegmentDataSlices) {
22-
if err := s.ImportSortedSlices(sds); err != nil {
25+
func (s *Set) loadRoot(fs []FlatSegment) {
26+
if err := s.ImportSlice(fs); err != nil {
2327
panic(err)
2428
}
2529
}

0 commit comments

Comments
 (0)