Remove removes the given segment and returns an iterator to the vacated gap. All existing iterators (including seg, but not including the returned iterator) are invalidated.
(seg Iterator)
| 555 | // All existing iterators (including seg, but not including the returned |
| 556 | // iterator) are invalidated. |
| 557 | func (s *Set) Remove(seg Iterator) GapIterator { |
| 558 | // We only want to remove directly from a leaf node. |
| 559 | if seg.node.hasChildren { |
| 560 | // Since seg.node has children, the removed segment must have a |
| 561 | // predecessor (at the end of the rightmost leaf of its left child |
| 562 | // subtree). Move the contents of that predecessor into the removed |
| 563 | // segment's position, and remove that predecessor instead. (We choose |
| 564 | // to steal the predecessor rather than the successor because removing |
| 565 | // from the end of a leaf node doesn't involve any copying unless |
| 566 | // merging is required.) |
| 567 | victim := seg.PrevSegment() |
| 568 | // This must be unchecked since until victim is removed, seg and victim |
| 569 | // overlap. |
| 570 | seg.SetRangeUnchecked(victim.Range()) |
| 571 | seg.SetValue(victim.Value()) |
| 572 | // Need to update the nextAdjacentNode's maxGap because the gap in between |
| 573 | // must have been modified by updating seg.Range() to victim.Range(). |
| 574 | // seg.NextSegment() must exist since the last segment can't be in a |
| 575 | // non-leaf node. |
| 576 | nextAdjacentNode := seg.NextSegment().node |
| 577 | if trackGaps != 0 { |
| 578 | nextAdjacentNode.updateMaxGapLeaf() |
| 579 | } |
| 580 | return s.Remove(victim).NextGap() |
| 581 | } |
| 582 | copy(seg.node.keys[seg.index:], seg.node.keys[seg.index+1:seg.node.nrSegments]) |
| 583 | copy(seg.node.values[seg.index:], seg.node.values[seg.index+1:seg.node.nrSegments]) |
| 584 | Functions{}.ClearValue(&seg.node.values[seg.node.nrSegments-1]) |
| 585 | seg.node.nrSegments-- |
| 586 | if trackGaps != 0 { |
| 587 | seg.node.updateMaxGapLeaf() |
| 588 | } |
| 589 | return seg.node.rebalanceAfterRemove(GapIterator(seg)) |
| 590 | } |
| 591 | |
| 592 | // RemoveAll removes all segments from the set. All existing iterators are |
| 593 | // invalidated. |