| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- package segments
- import (
- "sort"
- g "github.com/anacrolix/generics"
- )
- func NewIndex(segments LengthIter) (ret Index) {
- var start Length
- for l, ok := segments(); ok; l, ok = segments() {
- ret.segments = append(ret.segments, Extent{start, l})
- start += l
- }
- return
- }
- type Index struct {
- segments []Extent
- }
- func NewIndexFromSegments(segments []Extent) Index {
- return Index{segments}
- }
- func (me Index) iterSegments() func() (Extent, bool) {
- var lastEnd g.Option[Int]
- return func() (ret Extent, ok bool) {
- if len(me.segments) == 0 {
- return
- }
- cur := me.segments[0]
- me.segments = me.segments[1:]
- ret.Start = cur.Start - lastEnd.UnwrapOr(cur.Start)
- ret.Length = cur.Length
- lastEnd.Set(cur.End())
- ok = true
- return
- }
- }
- // Returns true if the callback returns false early, or extents are found in the index for all parts
- // of the given extent.
- func (me Index) Locate(e Extent, output Callback) bool {
- first := sort.Search(len(me.segments), func(i int) bool {
- _e := me.segments[i]
- return _e.End() > e.Start
- })
- if first == len(me.segments) {
- return e.Length == 0
- }
- e.Start -= me.segments[first].Start
- // The extent is before the first segment.
- if e.Start < 0 {
- e.Length += e.Start
- e.Start = 0
- }
- me.segments = me.segments[first:]
- return ScanConsecutive(me.iterSegments(), e, func(i int, e Extent) bool {
- return output(i+first, e)
- })
- }
|