github.com/grailbio/bigslice@v0.0.0-20230519005545-30c4c12152ad/accum_test.go (about)

     1  // Copyright 2018 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package bigslice
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  
    11  	fuzz "github.com/google/gofuzz"
    12  	"github.com/grailbio/bigslice/frame"
    13  	"github.com/grailbio/bigslice/slicefunc"
    14  	"github.com/grailbio/bigslice/sliceio"
    15  )
    16  
    17  var typeOfInt64 = reflect.TypeOf(int64(0))
    18  
    19  var accumulableTypes = []reflect.Type{typeOfString, typeOfInt, typeOfInt64}
    20  
    21  func TestAccumulator(t *testing.T) {
    22  	fz := fuzz.New()
    23  outer:
    24  	for _, typ := range accumulableTypes {
    25  		if !canMakeAccumulatorForKey(typ) {
    26  			t.Errorf("expected to be able to make accumulator for %s", typ)
    27  			continue
    28  		}
    29  		step, ok := slicefunc.Of(func(a, e int) int { return a + e })
    30  		if !ok {
    31  			t.Fatal("unexpected bad func")
    32  		}
    33  		accum := makeAccumulator(typ, typeOfInt, step)
    34  		const N = 100
    35  		for i := 0; i < N; i++ {
    36  			keysPtr := reflect.New(reflect.SliceOf(typ))
    37  			fz.Fuzz(keysPtr.Interface())
    38  			keys := keysPtr.Elem()
    39  			counts := make([]int, keys.Len())
    40  			for i := range counts {
    41  				counts[i] = 1
    42  			}
    43  			f := frame.Values([]reflect.Value{keys, reflect.ValueOf(counts)})
    44  			accum.Accumulate(f, keys.Len())
    45  			accum.Accumulate(f, keys.Len())
    46  		}
    47  		keys := reflect.MakeSlice(reflect.SliceOf(typ), N, N)
    48  		vals := reflect.MakeSlice(reflect.SliceOf(typeOfInt), N, N)
    49  		for {
    50  			n, err := accum.Read(keys, vals)
    51  			for i := 0; i < n; i++ {
    52  				if vals.Index(i).Int()%2 != 0 {
    53  					t.Errorf("odd count for key %v", keys.Index(i))
    54  				}
    55  			}
    56  			if err == sliceio.EOF {
    57  				break
    58  			} else if err != nil {
    59  				t.Errorf("unexpected error %v", err)
    60  				continue outer
    61  			}
    62  		}
    63  	}
    64  }