github.com/matrixorigin/matrixone@v1.2.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  	"io"
    19  	"sort"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/container/types"
    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  		length := uint64(0)
   162  		if _, err = w.Write(types.EncodeUint64(&length)); err != nil {
   163  			return
   164  		}
   165  		n += 8
   166  		return n, nil
   167  	}
   168  	length := uint64(len(intervals.Intervals))
   169  	if _, err = w.Write(types.EncodeUint64(&length)); err != nil {
   170  		return
   171  	}
   172  	n += 8
   173  	for _, interval := range intervals.Intervals {
   174  		if _, err = w.Write(EncodeCloseInterval(interval)); err != nil {
   175  			return
   176  		}
   177  		n += CloseIntervalSize
   178  	}
   179  	return
   180  }
   181  func (intervals *ClosedIntervals) ReadFrom(r io.Reader) (n int64, err error) {
   182  	length := uint64(0)
   183  	if _, err = r.Read(types.EncodeUint64(&length)); err != nil {
   184  		return
   185  	}
   186  	n += 8
   187  	intervals.Intervals = make([]*ClosedInterval, length)
   188  	for i := 0; i < int(length); i++ {
   189  		intervals.Intervals[i] = &ClosedInterval{}
   190  		if _, err = r.Read(EncodeCloseInterval(intervals.Intervals[i])); err != nil {
   191  			return
   192  		}
   193  		n += CloseIntervalSize
   194  	}
   195  	return
   196  }
   197  
   198  // Equal is for test
   199  func (intervals *ClosedIntervals) Equal(o *ClosedIntervals) bool {
   200  	if len(intervals.Intervals) != len(o.Intervals) {
   201  		logutil.Debugf("%v\n%v", intervals.Intervals, o.Intervals)
   202  		return false
   203  	}
   204  	for i, interval := range intervals.Intervals {
   205  		if interval.Start != o.Intervals[i].Start || interval.End != o.Intervals[i].End {
   206  			logutil.Debugf("%v\n%v", intervals.Intervals, o.Intervals)
   207  			return false
   208  		}
   209  	}
   210  	return true
   211  }
   212  
   213  func NewClosedIntervals() *ClosedIntervals {
   214  	return &ClosedIntervals{
   215  		Intervals: make([]*ClosedInterval, 0),
   216  	}
   217  }
   218  func NewClosedIntervalsBySlice(array []uint64) *ClosedIntervals {
   219  	ranges := &ClosedIntervals{
   220  		Intervals: make([]*ClosedInterval, 0),
   221  	}
   222  	if len(array) == 0 {
   223  		return ranges
   224  	}
   225  	sort.Slice(array, func(i, j int) bool {
   226  		return array[i] < array[j]
   227  	})
   228  	interval := &ClosedInterval{Start: array[0]}
   229  	pre := array[0]
   230  	array = array[1:]
   231  	for _, idx := range array {
   232  		if idx <= pre+1 {
   233  			pre = idx
   234  			continue
   235  		} else {
   236  			interval.End = pre
   237  			ranges.Intervals = append(ranges.Intervals, interval)
   238  			interval = &ClosedInterval{Start: idx}
   239  			pre = idx
   240  		}
   241  	}
   242  	interval.End = pre
   243  	ranges.Intervals = append(ranges.Intervals, interval)
   244  	return ranges
   245  }
   246  func NewClosedIntervalsByInt(i uint64) *ClosedIntervals {
   247  	return &ClosedIntervals{
   248  		Intervals: []*ClosedInterval{{
   249  			Start: i,
   250  			End:   i,
   251  		}},
   252  	}
   253  }
   254  
   255  func NewClosedIntervalsByInterval(i *ClosedInterval) *ClosedIntervals {
   256  	return &ClosedIntervals{
   257  		Intervals: []*ClosedInterval{{
   258  			Start: i.Start,
   259  			End:   i.End,
   260  		}},
   261  	}
   262  }
   263  
   264  func NewClosedIntervalsByIntervals(i *ClosedIntervals) *ClosedIntervals {
   265  	intervals := &ClosedIntervals{
   266  		Intervals: make([]*ClosedInterval, len(i.Intervals)),
   267  	}
   268  	for i, interval := range i.Intervals {
   269  		intervals.Intervals[i] = &ClosedInterval{
   270  			Start: interval.Start,
   271  			End:   interval.End,
   272  		}
   273  	}
   274  	return intervals
   275  }