github.com/anacrolix/torrent@v1.61.0/segments/segments.go (about) 1 package segments 2 3 import ( 4 "iter" 5 ) 6 7 type Int = int64 8 9 type Length = Int 10 11 type Extent struct { 12 Start, Length Int 13 } 14 15 func (e Extent) End() Int { 16 return e.Start + e.Length 17 } 18 19 type ( 20 Callback = func(segmentIndex int, segmentBounds Extent) bool 21 LengthIter = iter.Seq[Length] 22 ConsecutiveExtentIter = iter.Seq[Extent] 23 ) 24 25 // TODO: Does this handle discontiguous extents? 26 func scanConsecutive(haystack ConsecutiveExtentIter, needle Extent) iter.Seq[Extent] { 27 return func(yield func(Extent) bool) { 28 // Extents have been found in the haystack, and we're waiting for the needle to end. This is 29 // kind of for backwards compatibility for some tests that expect to have zero-length extents. 30 startedNeedle := false 31 next, stop := iter.Pull(haystack) 32 defer stop() 33 for needle.Length != 0 { 34 l, ok := next() 35 if !ok { 36 return 37 } 38 39 e1 := Extent{ 40 Start: max(needle.Start-l.Start, 0), 41 } 42 e1.Length = max(min(l.Length, needle.End()-l.Start)-e1.Start, 0) 43 needle.Start = max(0, needle.Start-l.End()) 44 needle.Length -= e1.Length + l.Start 45 if e1.Length > 0 || (startedNeedle && needle.Length != 0) { 46 if !yield(e1) { 47 return 48 } 49 startedNeedle = true 50 } 51 } 52 } 53 } 54 55 type Locater func(Extent, Callback) bool