github.com/coyove/sdss@v0.0.0-20231129015646-c2ec58cca6a2/contrib/simple/uint64.go (about)

     1  package simple
     2  
     3  import (
     4  	"reflect"
     5  	"sort"
     6  )
     7  
     8  var Uint64 struct {
     9  	Dedup       func([]uint64) []uint64
    10  	Contains    func([]uint64, uint64) bool
    11  	ContainsAny func([]uint64, []uint64) bool
    12  	Equal       func([]uint64, []uint64) bool
    13  	Of          func(interface{}) []uint64
    14  }
    15  
    16  func init() {
    17  	Uint64.Dedup = func(v []uint64) []uint64 {
    18  		if len(v) <= 1 {
    19  			return v
    20  		}
    21  		if len(v) == 2 {
    22  			if v[0] == v[1] {
    23  				return v[:1]
    24  			}
    25  			return v
    26  		}
    27  		s := uint64Sort{v}
    28  		sort.Sort(s)
    29  		for i := len(v) - 1; i > 0; i-- {
    30  			if v[i] == v[i-1] {
    31  				v = append(v[:i], v[i+1:]...)
    32  			}
    33  		}
    34  		return v
    35  	}
    36  
    37  	Uint64.ContainsAny = func(a []uint64, b []uint64) bool {
    38  		if len(a)+len(b) < 10 {
    39  			for _, v := range a {
    40  				for _, v2 := range b {
    41  					if v == v2 {
    42  						return true
    43  					}
    44  				}
    45  			}
    46  			return false
    47  		}
    48  		sa := uint64Sort{a}
    49  		sb := uint64Sort{b}
    50  		if !sort.IsSorted(sa) {
    51  			sort.Sort(sa)
    52  		}
    53  		if !sort.IsSorted(sb) {
    54  			sort.Sort(sb)
    55  		}
    56  
    57  		for _, b := range b {
    58  			idx := sort.Search(len(a), func(i int) bool { return a[i] >= b })
    59  			if idx < len(a) {
    60  				if a[idx] == b {
    61  					return true
    62  				}
    63  				if idx > 0 {
    64  					a = a[idx-1:]
    65  				}
    66  			} else {
    67  				break
    68  			}
    69  		}
    70  		return false
    71  	}
    72  
    73  	Uint64.Contains = func(a []uint64, b uint64) bool {
    74  		if len(a) < 10 {
    75  			for _, v := range a {
    76  				if v == b {
    77  					return true
    78  				}
    79  			}
    80  			return false
    81  		}
    82  		s := uint64Sort{a}
    83  		if !sort.IsSorted(s) {
    84  			sort.Sort(s)
    85  		}
    86  		idx := sort.Search(len(a), func(i int) bool { return a[i] >= b })
    87  		return idx < len(a) && a[idx] == b
    88  	}
    89  
    90  	Uint64.Equal = func(a, b []uint64) bool {
    91  		if len(a) != len(b) {
    92  			return false
    93  		}
    94  		sort.Sort(uint64Sort{a})
    95  		sort.Sort(uint64Sort{b})
    96  		for i := range a {
    97  			if a[i] != b[i] {
    98  				return false
    99  			}
   100  		}
   101  		return true
   102  	}
   103  
   104  	Uint64.Of = func(in interface{}) (res []uint64) {
   105  		rv := reflect.ValueOf(in)
   106  		res = make([]uint64, rv.Len())
   107  		for i := range res {
   108  			switch el := rv.Index(i); el.Kind() {
   109  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   110  				res[i] = uint64(el.Int())
   111  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   112  				res[i] = el.Uint()
   113  			case reflect.Float32, reflect.Float64:
   114  				res[i] = uint64(el.Float())
   115  			}
   116  		}
   117  		return res
   118  	}
   119  }
   120  
   121  type uint64Sort struct{ data []uint64 }
   122  
   123  func (h uint64Sort) Len() int { return len(h.data) }
   124  
   125  func (h uint64Sort) Less(i, j int) bool { return h.data[i] < h.data[j] }
   126  
   127  func (h uint64Sort) Swap(i, j int) { h.data[i], h.data[j] = h.data[j], h.data[i] }