github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/common/intervals.go (about) 1 // Copyright 2021 Matrix Origin 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 common 16 17 import ( 18 "encoding/binary" 19 "io" 20 "sort" 21 22 "github.com/matrixorigin/matrixone/pkg/logutil" 23 ) 24 25 // "errors" 26 // "fmt" 27 // "sync/atomic" 28 29 type ClosedIntervals struct { 30 Intervals []*ClosedInterval 31 } 32 33 func (intervals *ClosedIntervals) GetMax() uint64 { 34 if intervals == nil || len(intervals.Intervals) == 0 { 35 return 0 36 } 37 return intervals.Intervals[len(intervals.Intervals)-1].End 38 } 39 func (intervals *ClosedIntervals) GetMin() uint64 { 40 if intervals == nil || len(intervals.Intervals) == 0 { 41 return 0 42 } 43 return intervals.Intervals[0].Start 44 } 45 func (intervals *ClosedIntervals) TryMerge(o ClosedIntervals) { 46 intervals.Intervals = append(intervals.Intervals, o.Intervals...) 47 sort.Slice(intervals.Intervals, func(i, j int) bool { 48 return intervals.Intervals[i].Start < intervals.Intervals[j].Start 49 }) 50 newIntervals := make([]*ClosedInterval, 0) 51 if len(intervals.Intervals) == 0 { 52 intervals.Intervals = newIntervals 53 return 54 } 55 start := intervals.Intervals[0].Start 56 end := intervals.Intervals[0].End 57 for _, interval := range intervals.Intervals { 58 if interval.Start <= end+1 { 59 if interval.End > end { 60 end = interval.End 61 } 62 } else { 63 newIntervals = append(newIntervals, &ClosedInterval{ 64 Start: start, 65 End: end, 66 }) 67 start = interval.Start 68 end = interval.End 69 } 70 } 71 newIntervals = append(newIntervals, &ClosedInterval{ 72 Start: start, 73 End: end, 74 }) 75 intervals.Intervals = newIntervals 76 } 77 78 func (intervals *ClosedIntervals) Contains(o ClosedIntervals) bool { 79 // sort.Slice(intervals.Intervals, func(i, j int) bool { 80 // return intervals.Intervals[i].Start < intervals.Intervals[j].Start 81 // }) 82 // sort.Slice(o.Intervals, func(i, j int) bool { 83 // return o.Intervals[i].Start < o.Intervals[j].Start 84 // }) 85 ilen := len(intervals.Intervals) 86 i := 0 87 for _, oIntervals := range o.Intervals { 88 contains := false 89 for _, iIntervals := range intervals.Intervals[i:] { 90 if iIntervals.Start > oIntervals.End { 91 return false 92 } 93 if iIntervals.Contains(*oIntervals) { 94 contains = true 95 break 96 } 97 i++ 98 if i == ilen { 99 return false 100 } 101 } 102 if !contains { 103 return false 104 } 105 } 106 return true 107 } 108 func (intervals *ClosedIntervals) ContainsInt(n uint64) bool { 109 for _, interval := range intervals.Intervals { 110 if interval.Start > interval.End { 111 return false 112 } 113 if interval.End >= n { 114 return true 115 } 116 } 117 return false 118 } 119 func (intervals *ClosedIntervals) ContainsInterval(oIntervals ClosedInterval) bool { 120 // sort.Slice(intervals.Intervals, func(i, j int) bool { 121 // return intervals.Intervals[i].Start < intervals.Intervals[j].Start 122 // }) 123 // sort.Slice(o.Intervals, func(i, j int) bool { 124 // return o.Intervals[i].Start < o.Intervals[j].Start 125 // }) 126 ilen := len(intervals.Intervals) 127 i := 0 128 contains := false 129 for _, iIntervals := range intervals.Intervals[i:] { 130 if iIntervals.Start > oIntervals.End { 131 return false 132 } 133 if iIntervals.Contains(oIntervals) { 134 contains = true 135 break 136 } 137 i++ 138 if i == ilen { 139 return false 140 } 141 } 142 return contains 143 } 144 145 func (intervals *ClosedIntervals) IsCoveredByInt(i uint64) bool { 146 if intervals.Intervals == nil || len(intervals.Intervals) == 0 { 147 return true 148 } 149 return i >= intervals.Intervals[len(intervals.Intervals)-1].End 150 } 151 152 func (intervals *ClosedIntervals) GetCardinality() int { 153 cardinality := 0 154 for _, interval := range intervals.Intervals { 155 cardinality += (int(interval.End) - int(interval.Start) + 1) 156 } 157 return cardinality 158 } 159 func (intervals *ClosedIntervals) WriteTo(w io.Writer) (n int64, err error) { 160 if intervals == nil { 161 if err = binary.Write(w, binary.BigEndian, uint64(0)); err != nil { 162 return 163 } 164 n += 8 165 return n, nil 166 } 167 if err = binary.Write(w, binary.BigEndian, uint64(len(intervals.Intervals))); err != nil { 168 return 169 } 170 n += 8 171 for _, interval := range intervals.Intervals { 172 if err = binary.Write(w, binary.BigEndian, interval.Start); err != nil { 173 return 174 } 175 n += 8 176 if err = binary.Write(w, binary.BigEndian, interval.End); err != nil { 177 return 178 } 179 n += 8 180 } 181 return 182 } 183 func (intervals *ClosedIntervals) ReadFrom(r io.Reader) (n int64, err error) { 184 length := uint64(0) 185 if err = binary.Read(r, binary.BigEndian, &length); err != nil { 186 return 187 } 188 n += 8 189 intervals.Intervals = make([]*ClosedInterval, length) 190 for i := 0; i < int(length); i++ { 191 intervals.Intervals[i] = &ClosedInterval{} 192 if err = binary.Read(r, binary.BigEndian, &intervals.Intervals[i].Start); err != nil { 193 return 194 } 195 n += 8 196 if err = binary.Read(r, binary.BigEndian, &intervals.Intervals[i].End); err != nil { 197 return 198 } 199 n += 8 200 } 201 return 202 } 203 204 // Equal is for test 205 func (intervals *ClosedIntervals) Equal(o *ClosedIntervals) bool { 206 if len(intervals.Intervals) != len(o.Intervals) { 207 logutil.Infof("%v\n%v", intervals.Intervals, o.Intervals) 208 return false 209 } 210 for i, interval := range intervals.Intervals { 211 if interval.Start != o.Intervals[i].Start || interval.End != o.Intervals[i].End { 212 logutil.Infof("%v\n%v", intervals.Intervals, o.Intervals) 213 return false 214 } 215 } 216 return true 217 } 218 219 func NewClosedIntervals() *ClosedIntervals { 220 return &ClosedIntervals{ 221 Intervals: make([]*ClosedInterval, 0), 222 } 223 } 224 func NewClosedIntervalsBySlice(array []uint64) *ClosedIntervals { 225 ranges := &ClosedIntervals{ 226 Intervals: make([]*ClosedInterval, 0), 227 } 228 if len(array) == 0 { 229 return ranges 230 } 231 sort.Slice(array, func(i, j int) bool { 232 return array[i] < array[j] 233 }) 234 interval := &ClosedInterval{Start: array[0]} 235 pre := array[0] 236 array = array[1:] 237 for _, idx := range array { 238 if idx <= pre+1 { 239 pre = idx 240 continue 241 } else { 242 interval.End = pre 243 ranges.Intervals = append(ranges.Intervals, interval) 244 interval = &ClosedInterval{Start: idx} 245 pre = idx 246 } 247 } 248 interval.End = pre 249 ranges.Intervals = append(ranges.Intervals, interval) 250 return ranges 251 } 252 func NewClosedIntervalsByInt(i uint64) *ClosedIntervals { 253 return &ClosedIntervals{ 254 Intervals: []*ClosedInterval{{ 255 Start: i, 256 End: i, 257 }}, 258 } 259 } 260 261 func NewClosedIntervalsByInterval(i *ClosedInterval) *ClosedIntervals { 262 return &ClosedIntervals{ 263 Intervals: []*ClosedInterval{{ 264 Start: i.Start, 265 End: i.End, 266 }}, 267 } 268 } 269 270 func NewClosedIntervalsByIntervals(i *ClosedIntervals) *ClosedIntervals { 271 intervals := &ClosedIntervals{ 272 Intervals: make([]*ClosedInterval, len(i.Intervals)), 273 } 274 for i, interval := range i.Intervals { 275 intervals.Intervals[i] = &ClosedInterval{ 276 Start: interval.Start, 277 End: interval.End, 278 } 279 } 280 return intervals 281 }