Skip to content

Commit 47f62f7

Browse files
authored
Fixed numeric merging options (#74)
This PR fixes merging options on numerical columns, the argument was not passed properly. Also added a few tests and removed mandatory merge function on record column, to make the API more consistent.
1 parent a761108 commit 47f62f7

File tree

12 files changed

+106
-31
lines changed

12 files changed

+106
-31
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
go: ["1.18"]
12+
go: ["1.19"]
1313
steps:
1414
- name: Set up Go ${{ matrix.go }}
1515
uses: actions/setup-go@v3

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ Now that we have a record implementation, we can create a column for this struct
371371
```go
372372
players.CreateColumn("location", ForRecord(func() *Location {
373373
return new(Location)
374-
}, nil)) // no merging
374+
}))
375375
```
376376

377377
In order to manipulate the record, we can use the appropriate `Record()`, `SetRecord()` methods of the `Row`, similarly to other column types.

codegen/numbers.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func make{{.Name}}s(opts ...func(*option[{{.Type}}])) Column {
2929
fill.Remove(offset)
3030
}
3131
}
32-
},
32+
}, opts,
3333
)
3434
}
3535

collection_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ func BenchmarkRecord(b *testing.B) {
193193
col := NewCollection()
194194
col.CreateColumn("ts", ForRecord(func() *time.Time {
195195
return new(time.Time)
196-
}, nil))
196+
}))
197197

198198
for i := 0; i < amount; i++ {
199199
col.Insert(func(r Row) error {
@@ -247,7 +247,6 @@ func BenchmarkRecord(b *testing.B) {
247247
})
248248
}
249249
})
250-
251250
}
252251

253252
func TestCollection(t *testing.T) {
@@ -802,7 +801,7 @@ func newEmpty(capacity int) *Collection {
802801
out.CreateColumn("guild", ForEnum())
803802
out.CreateColumn("location", ForRecord(func() *fixtures.Location {
804803
return new(fixtures.Location)
805-
}, nil))
804+
}))
806805

807806
// index on humans
808807
out.CreateIndex("human", "race", func(r Reader) bool {

column.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func ForKind(kind reflect.Kind) (Column, error) {
116116

117117
// --------------------------- Generic Options ----------------------------
118118

119-
// optInt represents options for variouos columns.
119+
// option represents options for variouos columns.
120120
type option[T any] struct {
121121
Merge func(value, delta T) T
122122
}

column_numbers.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func makeInts(opts ...func(*option[int])) Column {
2929
fill.Remove(offset)
3030
}
3131
}
32-
},
32+
}, opts,
3333
)
3434
}
3535

@@ -78,7 +78,7 @@ func makeInt16s(opts ...func(*option[int16])) Column {
7878
fill.Remove(offset)
7979
}
8080
}
81-
},
81+
}, opts,
8282
)
8383
}
8484

@@ -127,7 +127,7 @@ func makeInt32s(opts ...func(*option[int32])) Column {
127127
fill.Remove(offset)
128128
}
129129
}
130-
},
130+
}, opts,
131131
)
132132
}
133133

@@ -176,7 +176,7 @@ func makeInt64s(opts ...func(*option[int64])) Column {
176176
fill.Remove(offset)
177177
}
178178
}
179-
},
179+
}, opts,
180180
)
181181
}
182182

@@ -225,7 +225,7 @@ func makeUints(opts ...func(*option[uint])) Column {
225225
fill.Remove(offset)
226226
}
227227
}
228-
},
228+
}, opts,
229229
)
230230
}
231231

@@ -274,7 +274,7 @@ func makeUint16s(opts ...func(*option[uint16])) Column {
274274
fill.Remove(offset)
275275
}
276276
}
277-
},
277+
}, opts,
278278
)
279279
}
280280

@@ -323,7 +323,7 @@ func makeUint32s(opts ...func(*option[uint32])) Column {
323323
fill.Remove(offset)
324324
}
325325
}
326-
},
326+
}, opts,
327327
)
328328
}
329329

@@ -372,7 +372,7 @@ func makeUint64s(opts ...func(*option[uint64])) Column {
372372
fill.Remove(offset)
373373
}
374374
}
375-
},
375+
}, opts,
376376
)
377377
}
378378

@@ -421,7 +421,7 @@ func makeFloat32s(opts ...func(*option[float32])) Column {
421421
fill.Remove(offset)
422422
}
423423
}
424-
},
424+
}, opts,
425425
)
426426
}
427427

@@ -470,7 +470,7 @@ func makeFloat64s(opts ...func(*option[float64])) Column {
470470
fill.Remove(offset)
471471
}
472472
}
473-
},
473+
}, opts,
474474
)
475475
}
476476

column_numeric.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type numericColumn[T simd.Number] struct {
3737
func makeNumeric[T simd.Number](
3838
write func(*commit.Buffer, uint32, T),
3939
apply func(*commit.Reader, bitmap.Bitmap, []T, option[T]),
40-
opts ...func(*option[T]),
40+
opts []func(*option[T]),
4141
) *numericColumn[T] {
4242
return &numericColumn[T]{
4343
chunks: make(chunks[T], 0, 4),

column_record.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ type columnRecord struct {
2828
// ForRecord creates a new column that contains a type marshaled into/from binary. It requires
2929
// a constructor for the type as well as optional merge function. If merge function is
3030
// set to nil, "overwrite" strategy will be used.
31-
func ForRecord[T recordType](new func() T, merge func(value, delta T) T) Column {
32-
if merge == nil {
33-
merge = func(value, delta T) T { return delta }
34-
}
31+
func ForRecord[T recordType](new func() T, opts ...func(*option[T])) Column {
32+
mergeFunc := configure(opts, option[T]{
33+
Merge: func(value, delta T) T { return delta },
34+
}).Merge
3535

3636
pool := &sync.Pool{
3737
New: func() any { return new() },
@@ -52,10 +52,8 @@ func ForRecord[T recordType](new func() T, merge func(value, delta T) T) Column
5252
return v
5353
}
5454

55-
// Apply the user-defined merging strategy
56-
merged := merge(value, delta)
57-
58-
// Marshal the value back
55+
// Apply the user-defined merging strategy and marshal it back
56+
merged := mergeFunc(value, delta)
5957
if encoded, err := merged.MarshalBinary(); err == nil {
6058
return b2s(&encoded)
6159
}

column_test.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ func TestRecord(t *testing.T) {
579579
col := NewCollection()
580580
col.CreateColumn("ts", ForRecord(func() *time.Time {
581581
return new(time.Time)
582-
}, nil))
582+
}))
583583

584584
// Insert the time, it implements binary marshaler
585585
idx, _ := col.Insert(func(r Row) error {
@@ -609,7 +609,7 @@ func TestRecord_Errors(t *testing.T) {
609609
col.CreateColumn("id", ForInt64())
610610
col.CreateColumn("ts", ForRecord(func() *time.Time {
611611
return new(time.Time)
612-
}, nil))
612+
}))
613613

614614
// Column "xxx" does not exist
615615
assert.Panics(t, func() {
@@ -643,7 +643,7 @@ func TestRecordMerge_ErrDecode(t *testing.T) {
643643
return mockRecord{
644644
errDecode: true,
645645
}
646-
}, nil))
646+
}))
647647

648648
// Insert the time, it implements binary marshaler
649649
idx, _ := col.Insert(func(r Row) error {
@@ -664,7 +664,7 @@ func TestRecordMerge_ErrEncode(t *testing.T) {
664664
return mockRecord{
665665
errEncode: true,
666666
}
667-
}, nil))
667+
}))
668668

669669
// Insert the time, it implements binary marshaler
670670
idx, _ := col.Insert(func(r Row) error {
@@ -679,6 +679,33 @@ func TestRecordMerge_ErrEncode(t *testing.T) {
679679
})
680680
}
681681

682+
func TestNumberMerge(t *testing.T) {
683+
col := NewCollection()
684+
col.CreateColumn("age", ForInt32(WithMerge(func(v, d int32) int32 {
685+
v -= d
686+
return v
687+
})))
688+
689+
// Insert the time, it implements binary marshaler
690+
idx, _ := col.Insert(func(r Row) error {
691+
r.SetInt32("age", 10)
692+
return nil
693+
})
694+
695+
for i := 0; i < 10; i++ {
696+
col.QueryAt(idx, func(r Row) error {
697+
r.MergeInt32("age", 1)
698+
return nil
699+
})
700+
}
701+
702+
col.QueryAt(idx, func(r Row) error {
703+
age, _ := r.Int32("age")
704+
assert.Equal(t, int32(0), age)
705+
return nil
706+
})
707+
}
708+
682709
func invoke(any interface{}, name string, args ...interface{}) []reflect.Value {
683710
inputs := make([]reflect.Value, len(args))
684711
for i := range args {

commit/buffer_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,17 @@ func TestBufferReadFromFailures(t *testing.T) {
306306
assert.Error(t, err)
307307
}
308308
}
309+
310+
func FuzzBufferString(f *testing.F) {
311+
f.Add(uint32(1), "test")
312+
313+
f.Fuzz(func(t *testing.T, i uint32, v string) {
314+
buf := NewBuffer(0)
315+
buf.PutString(Put, i, v)
316+
317+
r := NewReader()
318+
r.Seek(buf)
319+
assert.True(t, r.Next())
320+
assert.Equal(t, v, r.String())
321+
})
322+
}

0 commit comments

Comments
 (0)