github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/lookup/rangeslice.go (about) 1 // Copyright 2020 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lookup 16 17 import "sort" 18 19 // rangeSlice is a sortable slice of ranges. 20 type rangeSlice struct { 21 ranges []Range 22 err error 23 } 24 25 func (r *rangeSlice) Len() int { return len(r.ranges) } 26 func (r *rangeSlice) Swap(i, j int) { r.ranges[i], r.ranges[j] = r.ranges[j], r.ranges[i] } 27 func (r *rangeSlice) Less(i, j int) bool { 28 lc, err := r.ranges[i].LowerBound.Compare(r.ranges[j].LowerBound) 29 if err != nil { 30 r.err = err 31 return false 32 } 33 if lc < 0 { 34 return true 35 } else if lc > 0 { 36 return false 37 } 38 uc, err := r.ranges[i].UpperBound.Compare(r.ranges[j].UpperBound) 39 if err != nil { 40 r.err = err 41 return false 42 } 43 return uc < 0 44 } 45 46 // SimplifyRanges combines all ranges that are connected and returns a new slice. 47 func SimplifyRanges(rs []Range) ([]Range, error) { 48 if len(rs) == 0 { 49 return []Range{EmptyRange()}, nil 50 } 51 sorted := make([]Range, len(rs)) 52 copy(sorted, rs) 53 rSlice := &rangeSlice{ranges: sorted} 54 sort.Sort(rSlice) 55 if rSlice.err != nil { 56 return nil, rSlice.err 57 } 58 var res []Range 59 cur := EmptyRange() 60 for _, r := range sorted { 61 merged, ok, err := cur.TryUnion(r) 62 if err != nil { 63 return nil, err 64 } 65 if ok { 66 cur = merged 67 } else if !cur.IsEmpty() { 68 res = append(res, cur) 69 cur = r 70 } 71 } 72 if !cur.IsEmpty() { 73 res = append(res, cur) 74 } 75 return res, nil 76 }