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  }