Insert inserts the given segment into the given gap. If the new segment can be merged with adjacent segments, Insert will do so. Insert returns an iterator to the segment containing the inserted value (which may have been merged with other values). All existing iterators (including gap, but not incl
(gap GapIterator, r Range, val Value)
| 369 | // Insert since Insert must retrieve and inspect gap's predecessor and |
| 370 | // successor segments regardless. |
| 371 | func (s *Set) Insert(gap GapIterator, r Range, val Value) Iterator { |
| 372 | if r.Length() <= 0 { |
| 373 | panic(fmt.Sprintf("invalid segment range %v", r)) |
| 374 | } |
| 375 | prev, next := gap.PrevSegment(), gap.NextSegment() |
| 376 | if prev.Ok() && prev.End() > r.Start { |
| 377 | panic(fmt.Sprintf("new segment %v overlaps predecessor %v", r, prev.Range())) |
| 378 | } |
| 379 | if next.Ok() && next.Start() < r.End { |
| 380 | panic(fmt.Sprintf("new segment %v overlaps successor %v", r, next.Range())) |
| 381 | } |
| 382 | if prev.Ok() && prev.End() == r.Start { |
| 383 | if mval, ok := (Functions{}).Merge(prev.Range(), prev.Value(), r, val); ok { |
| 384 | shrinkMaxGap := trackGaps != 0 && gap.Range().Length() == gap.node.maxGap.Get() |
| 385 | prev.SetEndUnchecked(r.End) |
| 386 | prev.SetValue(mval) |
| 387 | if shrinkMaxGap { |
| 388 | gap.node.updateMaxGapLeaf() |
| 389 | } |
| 390 | if next.Ok() && next.Start() == r.End { |
| 391 | val = mval |
| 392 | if mval, ok := (Functions{}).Merge(prev.Range(), val, next.Range(), next.Value()); ok { |
| 393 | prev.SetEndUnchecked(next.End()) |
| 394 | prev.SetValue(mval) |
| 395 | return s.Remove(next).PrevSegment() |
| 396 | } |
| 397 | } |
| 398 | return prev |
| 399 | } |
| 400 | } |
| 401 | if next.Ok() && next.Start() == r.End { |
| 402 | if mval, ok := (Functions{}).Merge(r, val, next.Range(), next.Value()); ok { |
| 403 | shrinkMaxGap := trackGaps != 0 && gap.Range().Length() == gap.node.maxGap.Get() |
| 404 | next.SetStartUnchecked(r.Start) |
| 405 | next.SetValue(mval) |
| 406 | if shrinkMaxGap { |
| 407 | gap.node.updateMaxGapLeaf() |
| 408 | } |
| 409 | return next |
| 410 | } |
| 411 | } |
| 412 | // InsertWithoutMergingUnchecked will maintain maxGap if necessary. |
| 413 | return s.InsertWithoutMergingUnchecked(gap, r, val) |
| 414 | } |
| 415 | |
| 416 | // InsertWithoutMerging inserts the given segment into the given gap and |
| 417 | // returns an iterator to the inserted segment. All existing iterators |