]> Sergey Matveev's repositories - btrtrc.git/blob - segments/index.go
Fix file storage segments for v2 torrents
[btrtrc.git] / segments / index.go
1 package segments
2
3 import (
4         "sort"
5 )
6
7 func NewIndex(segments LengthIter) (ret Index) {
8         var start Length
9         for l, ok := segments(); ok; l, ok = segments() {
10                 ret.segments = append(ret.segments, Extent{start, l})
11                 start += l
12         }
13         return
14 }
15
16 type Index struct {
17         segments []Extent
18 }
19
20 func NewIndexFromSegments(segments []Extent) Index {
21         return Index{segments}
22 }
23
24 func (me Index) iterSegments() func() (Length, bool) {
25         return func() (Length, bool) {
26                 if len(me.segments) == 0 {
27                         return 0, false
28                 } else {
29                         l := me.segments[0].Length
30                         me.segments = me.segments[1:]
31                         return l, true
32                 }
33         }
34 }
35
36 // Returns true if the callback returns false early, or extents are found in the index for all parts
37 // of the given extent.
38 func (me Index) Locate(e Extent, output Callback) bool {
39         first := sort.Search(len(me.segments), func(i int) bool {
40                 _e := me.segments[i]
41                 return _e.End() > e.Start
42         })
43         if first == len(me.segments) {
44                 return false
45         }
46         e.Start -= me.segments[first].Start
47         me.segments = me.segments[first:]
48         return Scan(me.iterSegments(), e, func(i int, e Extent) bool {
49                 return output(i+first, e)
50         })
51 }