v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/time2/timeutil/intersection.go (about) 1 package timeutil 2 3 import ( 4 "errors" 5 "sort" 6 ) 7 8 type iTuple struct { 9 Offset uint64 10 Type uint8 11 } 12 13 type iSlice []iTuple 14 15 func (s iSlice) Len() int { 16 return len(s) 17 } 18 19 func (s iSlice) Less(i, j int) bool { 20 return s[i].Offset < s[j].Offset 21 } 22 23 func (s iSlice) Swap(i, j int) { 24 s[i], s[j] = s[j], s[i] 25 } 26 27 func (s iSlice) Sort() { 28 sort.Sort(s) 29 } 30 31 var ErrInvalidInterval = errors.New("invalid interval") 32 33 func intersection(s iSlice) (lower, upper uint64, ok bool) { 34 var M uint64 = uint64(s.Len()) / 3 35 var F uint64 36 37 for F < M/2 { 38 var End, Mid uint64 39 40 for i := range s { 41 End = End - uint64(s[i].Type) 42 if End >= M-F { 43 lower = s[i].Offset 44 break 45 } 46 47 if s[i].Type == 0 { 48 Mid = Mid + 1 49 } 50 } 51 52 End = 0 53 54 for i := len(s) - 1; i >= 0; i-- { 55 End = End + uint64(s[i].Type) 56 if End >= M-F { 57 upper = s[i].Offset 58 break 59 } 60 61 if s[i].Type == 0 { 62 Mid = Mid + 1 63 } 64 } 65 66 if lower <= upper && Mid <= F { 67 return lower, upper, true 68 } 69 70 F = F + 1 71 if F >= M/2 { 72 break 73 } 74 } 75 76 ok = false 77 return 78 }