You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
1.6 KiB
Go
85 lines
1.6 KiB
Go
package mget
|
|
|
|
import "sort"
|
|
|
|
type Range struct {
|
|
Min uint64 `json:"min"`
|
|
Max uint64 `json:"max"`
|
|
}
|
|
type SortRange []Range
|
|
|
|
func (s SortRange) Len() int { return len(s) }
|
|
func (s SortRange) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
func (s SortRange) Less(i, j int) bool { return s[i].Min < s[j].Min }
|
|
|
|
func uniformRange(rg []Range) ([]Range, error) {
|
|
newRg := make([]Range, 0, len(rg))
|
|
sort.Sort(SortRange(rg))
|
|
var last *Range = nil
|
|
for _, v := range rg {
|
|
if last != nil && v.Min <= last.Max+1 {
|
|
if last.Max <= v.Max {
|
|
last.Max = v.Max
|
|
}
|
|
continue
|
|
}
|
|
newRg = append(newRg, v)
|
|
last = &newRg[len(newRg)-1]
|
|
}
|
|
return newRg, nil
|
|
}
|
|
|
|
func singleSubRange(origin []Range, v Range) []Range {
|
|
newRg := make([]Range, 0)
|
|
sort.Sort(SortRange(origin))
|
|
for i := 0; i < len(origin); i++ {
|
|
ori := origin[i]
|
|
res := make([]Range, 0)
|
|
shouldAdd := true
|
|
for j := 0; j < 1; j++ {
|
|
if v.Min <= ori.Min && v.Max >= ori.Max {
|
|
shouldAdd = false
|
|
break
|
|
}
|
|
if v.Max < ori.Min {
|
|
continue
|
|
}
|
|
if v.Min > ori.Max {
|
|
break
|
|
}
|
|
ur1 := Range{
|
|
Min: ori.Min,
|
|
Max: v.Min - 1,
|
|
}
|
|
if v.Min == 0 {
|
|
ur1.Min = 1
|
|
ur1.Max = 0
|
|
}
|
|
ur2 := Range{
|
|
Min: v.Max + 1,
|
|
Max: ori.Max,
|
|
}
|
|
if ur1.Max >= ur1.Min {
|
|
res = append(res, ur1)
|
|
}
|
|
if ur2.Max >= ur2.Min {
|
|
res = append(res, ur2)
|
|
}
|
|
}
|
|
if len(res) == 0 && shouldAdd {
|
|
res = append(res, ori)
|
|
}
|
|
newRg = append(newRg, res...)
|
|
}
|
|
return newRg
|
|
}
|
|
|
|
func subRange(origin, rg []Range) []Range {
|
|
sort.Sort(SortRange(rg))
|
|
sort.Sort(SortRange(origin))
|
|
for _, v := range rg {
|
|
origin = singleSubRange(origin, v)
|
|
}
|
|
return origin
|
|
}
|