github.com/tobgu/qframe@v0.4.0/internal/bcolumn/column_gen.go (about) 1 // Code generated by genny. DO NOT EDIT. 2 // This file was automatically generated by genny. 3 // Any changes will be lost if this file is regenerated. 4 // see https://github.com/mauricelam/genny 5 6 package bcolumn 7 8 // Code generated from template/column.go DO NOT EDIT 9 10 import ( 11 "fmt" 12 13 "github.com/tobgu/qframe/config/rolling" 14 15 "github.com/tobgu/qframe/internal/column" 16 "github.com/tobgu/qframe/internal/index" 17 "github.com/tobgu/qframe/qerrors" 18 ) 19 20 type Column struct { 21 data []bool 22 } 23 24 func New(d []bool) Column { 25 return Column{data: d} 26 } 27 28 func NewConst(val bool, count int) Column { 29 var nullVal bool 30 data := make([]bool, count) 31 if val != nullVal { 32 for i := range data { 33 data[i] = val 34 } 35 } 36 37 return Column{data: data} 38 } 39 40 func (c Column) fnName(name string) string { 41 return fmt.Sprintf("%s.%s", c.DataType(), name) 42 } 43 44 // Apply single argument function. The result may be a column 45 // of a different type than the current column. 46 func (c Column) Apply1(fn interface{}, ix index.Int) (interface{}, error) { 47 switch t := fn.(type) { 48 case func(bool) int: 49 result := make([]int, len(c.data)) 50 for _, i := range ix { 51 result[i] = t(c.data[i]) 52 } 53 return result, nil 54 case func(bool) float64: 55 result := make([]float64, len(c.data)) 56 for _, i := range ix { 57 result[i] = t(c.data[i]) 58 } 59 return result, nil 60 case func(bool) bool: 61 result := make([]bool, len(c.data)) 62 for _, i := range ix { 63 result[i] = t(c.data[i]) 64 } 65 return result, nil 66 case func(bool) *string: 67 result := make([]*string, len(c.data)) 68 for _, i := range ix { 69 result[i] = t(c.data[i]) 70 } 71 return result, nil 72 default: 73 return nil, qerrors.New(c.fnName("Apply1"), "cannot apply type %#v to column", fn) 74 } 75 } 76 77 // Apply double argument function to two columns. Both columns must have the 78 // same type. The resulting column will have the same type as this column. 79 func (c Column) Apply2(fn interface{}, s2 column.Column, ix index.Int) (column.Column, error) { 80 ss2, ok := s2.(Column) 81 if !ok { 82 return Column{}, qerrors.New(c.fnName("Apply2"), "invalid column type: %s", s2.DataType()) 83 } 84 85 t, ok := fn.(func(bool, bool) bool) 86 if !ok { 87 return Column{}, qerrors.New("Apply2", "invalid function type: %#v", fn) 88 } 89 90 result := make([]bool, len(c.data)) 91 for _, i := range ix { 92 result[i] = t(c.data[i], ss2.data[i]) 93 } 94 95 return New(result), nil 96 } 97 98 func (c Column) subset(index index.Int) Column { 99 data := make([]bool, len(index)) 100 for i, ix := range index { 101 data[i] = c.data[ix] 102 } 103 104 return Column{data: data} 105 } 106 107 func (c Column) Subset(index index.Int) column.Column { 108 return c.subset(index) 109 } 110 111 func (c Column) Comparable(reverse, equalNull, nullLast bool) column.Comparable { 112 result := Comparable{data: c.data, ltValue: column.LessThan, gtValue: column.GreaterThan, nullLtValue: column.LessThan, nullGtValue: column.GreaterThan, equalNullValue: column.NotEqual} 113 if reverse { 114 result.ltValue, result.nullLtValue, result.gtValue, result.nullGtValue = 115 result.gtValue, result.nullGtValue, result.ltValue, result.nullLtValue 116 } 117 118 if nullLast { 119 result.nullLtValue, result.nullGtValue = result.nullGtValue, result.nullLtValue 120 } 121 122 if equalNull { 123 result.equalNullValue = column.Equal 124 } 125 126 return result 127 } 128 129 func (c Column) String() string { 130 return fmt.Sprintf("%v", c.data) 131 } 132 133 func (c Column) Len() int { 134 return len(c.data) 135 } 136 137 func (c Column) Aggregate(indices []index.Int, fn interface{}) (column.Column, error) { 138 var actualFn func([]bool) bool 139 var ok bool 140 141 switch t := fn.(type) { 142 case string: 143 actualFn, ok = aggregations[t] 144 if !ok { 145 return nil, qerrors.New(c.fnName("Aggregate"), "aggregation function %c is not defined for column", fn) 146 } 147 case func([]bool) bool: 148 actualFn = t 149 default: 150 return nil, qerrors.New(c.fnName("Aggregate"), "invalid aggregation function type: %v", t) 151 } 152 153 data := make([]bool, 0, len(indices)) 154 var buf []bool 155 for _, ix := range indices { 156 subS := c.subsetWithBuf(ix, &buf) 157 data = append(data, actualFn(subS.data)) 158 } 159 160 return Column{data: data}, nil 161 } 162 163 func (c Column) subsetWithBuf(index index.Int, buf *[]bool) Column { 164 if cap(*buf) < len(index) { 165 *buf = make([]bool, 0, len(index)) 166 } 167 168 data := (*buf)[:0] 169 for _, ix := range index { 170 data = append(data, c.data[ix]) 171 } 172 173 return Column{data: data} 174 } 175 176 func (c Column) View(ix index.Int) View { 177 return View{data: c.data, index: ix} 178 } 179 180 func (c Column) Rolling(fn interface{}, ix index.Int, config rolling.Config) (column.Column, error) { 181 return c, nil 182 } 183 184 type Comparable struct { 185 data []bool 186 ltValue column.CompareResult 187 nullLtValue column.CompareResult 188 gtValue column.CompareResult 189 nullGtValue column.CompareResult 190 equalNullValue column.CompareResult 191 } 192 193 // View is a view into a column that allows access to individual elements by index. 194 type View struct { 195 data []bool 196 index index.Int 197 } 198 199 // ItemAt returns the value at position i. 200 func (v View) ItemAt(i int) bool { 201 return v.data[v.index[i]] 202 } 203 204 // Len returns the column length. 205 func (v View) Len() int { 206 return len(v.index) 207 } 208 209 // Slice returns a slice containing a copy of the column data. 210 func (v View) Slice() []bool { 211 // TODO: This forces an alloc, as an alternative a slice could be taken 212 // as input that can be (re)used by the client. Are there use cases 213 // where this would actually make sense? 214 result := make([]bool, v.Len()) 215 for i, j := range v.index { 216 result[i] = v.data[j] 217 } 218 return result 219 }