github.com/tobgu/qframe@v0.4.0/internal/bcolumn/column.go (about) 1 package bcolumn 2 3 import ( 4 "github.com/tobgu/qframe/internal/column" 5 "github.com/tobgu/qframe/internal/hash" 6 "github.com/tobgu/qframe/internal/index" 7 "github.com/tobgu/qframe/qerrors" 8 "github.com/tobgu/qframe/types" 9 "reflect" 10 "strconv" 11 ) 12 13 func (c Comparable) Compare(i, j uint32) column.CompareResult { 14 x, y := c.data[i], c.data[j] 15 if x == y { 16 return column.Equal 17 } 18 19 if x { 20 return c.gtValue 21 } 22 23 return c.ltValue 24 } 25 26 func (c Comparable) Hash(i uint32, seed uint64) uint64 { 27 if c.data[i] { 28 b := [1]byte{1} 29 return hash.HashBytes(b[:], seed) 30 } 31 32 b := [1]byte{0} 33 return hash.HashBytes(b[:], seed) 34 } 35 36 func (c Column) DataType() types.DataType { 37 return types.Bool 38 } 39 40 func (c Column) StringAt(i uint32, _ string) string { 41 return strconv.FormatBool(c.data[i]) 42 } 43 44 func (c Column) AppendByteStringAt(buf []byte, i uint32) []byte { 45 return strconv.AppendBool(buf, c.data[i]) 46 } 47 48 func (c Column) ByteSize() int { 49 // Slice header + data 50 return 2*8 + cap(c.data) 51 } 52 53 func (c Column) Equals(index index.Int, other column.Column, otherIndex index.Int) bool { 54 otherI, ok := other.(Column) 55 if !ok { 56 return false 57 } 58 59 for ix, x := range index { 60 if c.data[x] != otherI.data[otherIndex[ix]] { 61 return false 62 } 63 } 64 65 return true 66 } 67 68 func (c Column) filterBuiltIn(index index.Int, comparator string, comparatee interface{}, bIndex index.Bool) error { 69 switch t := comparatee.(type) { 70 case bool: 71 compFunc, ok := filterFuncs[comparator] 72 if !ok { 73 return qerrors.New("filter bool", "invalid comparison operator for bool, %v", comparator) 74 } 75 compFunc(index, c.data, t, bIndex) 76 case Column: 77 compFunc, ok := filterFuncs2[comparator] 78 if !ok { 79 return qerrors.New("filter bool", "invalid comparison operator for bool, %v", comparator) 80 } 81 compFunc(index, c.data, t.data, bIndex) 82 default: 83 return qerrors.New("filter bool", "invalid comparison value type %v", reflect.TypeOf(comparatee)) 84 } 85 return nil 86 } 87 88 func (c Column) filterCustom1(index index.Int, fn func(bool) bool, bIndex index.Bool) { 89 for i, x := range bIndex { 90 if !x { 91 bIndex[i] = fn(c.data[index[i]]) 92 } 93 } 94 } 95 96 func (c Column) filterCustom2(index index.Int, fn func(bool, bool) bool, comparatee interface{}, bIndex index.Bool) error { 97 otherC, ok := comparatee.(Column) 98 if !ok { 99 return qerrors.New("filter bool", "expected comparatee to be bool column, was %v", reflect.TypeOf(comparatee)) 100 } 101 102 for i, x := range bIndex { 103 if !x { 104 bIndex[i] = fn(c.data[index[i]], otherC.data[index[i]]) 105 } 106 } 107 108 return nil 109 } 110 111 func (c Column) Filter(index index.Int, comparator interface{}, comparatee interface{}, bIndex index.Bool) error { 112 var err error 113 switch t := comparator.(type) { 114 case string: 115 err = c.filterBuiltIn(index, t, comparatee, bIndex) 116 case func(bool) bool: 117 c.filterCustom1(index, t, bIndex) 118 case func(bool, bool) bool: 119 err = c.filterCustom2(index, t, comparatee, bIndex) 120 default: 121 err = qerrors.New("filter bool", "invalid filter type %v", reflect.TypeOf(comparator)) 122 } 123 return err 124 } 125 126 func (c Column) FunctionType() types.FunctionType { 127 return types.FunctionTypeBool 128 } 129 130 func (c Column) Append(cols ...column.Column) (column.Column, error) { 131 // TODO Append 132 return nil, qerrors.New("Append", "Not implemented yet") 133 }