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  }