v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/time2/timeutil/intersection.go (about)

     1  package timeutil
     2  
     3  import (
     4  	"errors"
     5  	"sort"
     6  )
     7  
     8  type iTuple struct {
     9  	Offset uint64
    10  	Type   uint8
    11  }
    12  
    13  type iSlice []iTuple
    14  
    15  func (s iSlice) Len() int {
    16  	return len(s)
    17  }
    18  
    19  func (s iSlice) Less(i, j int) bool {
    20  	return s[i].Offset < s[j].Offset
    21  }
    22  
    23  func (s iSlice) Swap(i, j int) {
    24  	s[i], s[j] = s[j], s[i]
    25  }
    26  
    27  func (s iSlice) Sort() {
    28  	sort.Sort(s)
    29  }
    30  
    31  var ErrInvalidInterval = errors.New("invalid interval")
    32  
    33  func intersection(s iSlice) (lower, upper uint64, ok bool) {
    34  	var M uint64 = uint64(s.Len()) / 3
    35  	var F uint64
    36  
    37  	for F < M/2 {
    38  		var End, Mid uint64
    39  
    40  		for i := range s {
    41  			End = End - uint64(s[i].Type)
    42  			if End >= M-F {
    43  				lower = s[i].Offset
    44  				break
    45  			}
    46  
    47  			if s[i].Type == 0 {
    48  				Mid = Mid + 1
    49  			}
    50  		}
    51  
    52  		End = 0
    53  
    54  		for i := len(s) - 1; i >= 0; i-- {
    55  			End = End + uint64(s[i].Type)
    56  			if End >= M-F {
    57  				upper = s[i].Offset
    58  				break
    59  			}
    60  
    61  			if s[i].Type == 0 {
    62  				Mid = Mid + 1
    63  			}
    64  		}
    65  
    66  		if lower <= upper && Mid <= F {
    67  			return lower, upper, true
    68  		}
    69  
    70  		F = F + 1
    71  		if F >= M/2 {
    72  			break
    73  		}
    74  	}
    75  
    76  	ok = false
    77  	return
    78  }