github.com/tobgu/qframe@v0.4.0/internal/fcolumn/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 fcolumn
     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 []float64
    22  }
    23  
    24  func New(d []float64) Column {
    25  	return Column{data: d}
    26  }
    27  
    28  func NewConst(val float64, count int) Column {
    29  	var nullVal float64
    30  	data := make([]float64, 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(float64) 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(float64) 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(float64) 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(float64) *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(float64, float64) float64)
    86  	if !ok {
    87  		return Column{}, qerrors.New("Apply2", "invalid function type: %#v", fn)
    88  	}
    89  
    90  	result := make([]float64, 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([]float64, 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([]float64) float64
   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([]float64) float64:
   148  		actualFn = t
   149  	default:
   150  		return nil, qerrors.New(c.fnName("Aggregate"), "invalid aggregation function type: %v", t)
   151  	}
   152  
   153  	data := make([]float64, 0, len(indices))
   154  	var buf []float64
   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 *[]float64) Column {
   164  	if cap(*buf) < len(index) {
   165  		*buf = make([]float64, 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           []float64
   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  []float64
   196  	index index.Int
   197  }
   198  
   199  // ItemAt returns the value at position i.
   200  func (v View) ItemAt(i int) float64 {
   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() []float64 {
   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([]float64, v.Len())
   215  	for i, j := range v.index {
   216  		result[i] = v.data[j]
   217  	}
   218  	return result
   219  }