]> Sergey Matveev's repositories - btrtrc.git/blob - segments/segments.go
Drop support for go 1.20
[btrtrc.git] / segments / segments.go
1 package segments
2
3 type Int = int64
4
5 type Length = Int
6
7 func min(i Int, rest ...Int) Int {
8         ret := i
9         for _, i := range rest {
10                 if i < ret {
11                         ret = i
12                 }
13         }
14         return ret
15 }
16
17 type Extent struct {
18         Start, Length Int
19 }
20
21 func (e Extent) End() Int {
22         return e.Start + e.Length
23 }
24
25 type (
26         Callback   = func(int, Extent) bool
27         LengthIter = func() (Length, bool)
28 )
29
30 func Scan(haystack LengthIter, needle Extent, callback Callback) bool {
31         i := 0
32         for needle.Length != 0 {
33                 l, ok := haystack()
34                 if !ok {
35                         return false
36                 }
37                 if needle.Start < l || needle.Start == l && l == 0 {
38                         e1 := Extent{
39                                 Start:  needle.Start,
40                                 Length: min(l, needle.End()) - needle.Start,
41                         }
42                         if e1.Length >= 0 {
43                                 if !callback(i, e1) {
44                                         return true
45                                 }
46                                 needle.Start = 0
47                                 needle.Length -= e1.Length
48                         }
49                 } else {
50                         needle.Start -= l
51                 }
52                 i++
53         }
54         return true
55 }
56
57 func LocaterFromLengthIter(li LengthIter) Locater {
58         return func(e Extent, c Callback) bool {
59                 return Scan(li, e, c)
60         }
61 }
62
63 type Locater func(Extent, Callback) bool