diff --git a/server/compose/automation/expr_types.go b/server/compose/automation/expr_types.go index b6c4d5fc4..0b97de568 100644 --- a/server/compose/automation/expr_types.go +++ b/server/compose/automation/expr_types.go @@ -349,7 +349,7 @@ func composeRecordValuesTypedValueSelector(res *types.Record, k string) (expr.Ty // // We'll be using types.Record for the base (and not types.RecordValueSet) func assignToComposeRecordValues(res *types.Record, p expr.Pather, val interface{}) (err error) { - if !p.More() { + if p == nil || !p.More() { switch val := expr.UntypedValue(val).(type) { case types.RecordValueSet: res.Values = val diff --git a/server/compose/automation/expr_types_test.go b/server/compose/automation/expr_types_test.go index eb7e188a6..55115f3c2 100644 --- a/server/compose/automation/expr_types_test.go +++ b/server/compose/automation/expr_types_test.go @@ -273,10 +273,10 @@ func TestAssignToComposeRecordValues(t *testing.T) { target = &types.Record{Values: types.RecordValueSet{}} ) - req.NoError(assignToComposeRecordValues(target, []string{"a"}, "b")) + req.NoError(assignToComposeRecordValues(target, initPather(req, expr.Path("a")), "b")) req.Len(target.Values, 1) req.True(target.Values.Has("a", 0)) - req.NoError(assignToComposeRecordValues(target, []string{"a", "1"}, "b")) + req.NoError(assignToComposeRecordValues(target, initPather(req, expr.Path("a[1]")), "b")) req.Len(target.Values, 2) req.True(target.Values.Has("a", 0)) req.True(target.Values.Has("a", 1)) @@ -320,13 +320,13 @@ func TestAssignToComposeRecordValues(t *testing.T) { target = &types.Record{Values: types.RecordValueSet{}} ) - req.Error(assignToComposeRecordValues(target, []string{"a", "2"}, expr.Must(expr.NewAny([]interface{}{"1", "2"})))) + req.Error(assignToComposeRecordValues(target, initPather(req, expr.Path("a[2]")), expr.Must(expr.NewAny([]interface{}{"1", "2"})))) req.Len(target.Values, 0) - req.NoError(assignToComposeRecordValues(target, []string{"a"}, expr.Must(expr.NewAny([]interface{}{"1", "2"})))) + req.NoError(assignToComposeRecordValues(target, initPather(req, expr.Path("a")), expr.Must(expr.NewAny([]interface{}{"1", "2"})))) req.Len(target.Values, 2) - req.NoError(assignToComposeRecordValues(target, []string{"a"}, expr.Must(expr.NewAny([]string{"1", "2"})))) + req.NoError(assignToComposeRecordValues(target, initPather(req, expr.Path("a")), expr.Must(expr.NewAny([]string{"1", "2"})))) req.Len(target.Values, 2) }) @@ -669,3 +669,59 @@ func TestRecordValues_Omit(t *testing.T) { req.NoError(err) req.Equal(expected, out.Get()) } + +// goos: darwin +// goarch: arm64 +// pkg: github.com/cortezaproject/corteza/server/compose/automation +// BenchmarkAssignToComposeRecordValues-12 22131764 53.22 ns/op 96 B/op 1 allocs/op +// PASS +func BenchmarkAssignToComposeRecordValues(b *testing.B) { + var ( + req = require.New(b) + target = &types.Record{Values: types.RecordValueSet{}} + p = initPather(req, expr.Path("a")) + ) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + assignToComposeRecordValues(target, p, "b") + } +} + +// goos: darwin +// goarch: arm64 +// pkg: github.com/cortezaproject/corteza/server/compose/automation +// BenchmarkRecordFieldValuesAccess-12 1947148 593.6 ns/op 544 B/op 19 allocs/op +// PASS +func BenchmarkRecordFieldValuesAccess(b *testing.B) { + var ( + mod = &types.Module{Fields: types.ModuleFieldSet{ + &types.ModuleField{Name: "s1", Multi: true, Kind: "String"}, + }} + + rawValues = types.RecordValueSet{ + &types.RecordValue{Name: "s1", Value: "sVal1.0", Place: 0}, + &types.RecordValue{Name: "s1", Value: "sVal1.1", Place: 1}, + &types.RecordValue{Name: "s1", Value: "sVal1.2", Place: 2}, + } + raw = &types.Record{Values: rawValues} + + scope, _ = expr.NewVars(map[string]interface{}{ + "rec": &ComposeRecord{value: raw}, + }) + ) + + // @todo see note above regarding back-ref to record + raw.SetModule(mod) + b.ResetTimer() + for n := 0; n < b.N; n++ { + expr.Select(scope, "rec.values.s1[1]") + } +} + +func initPather(req *require.Assertions, p expr.Pather) (out expr.Pather) { + err := p.Next() + req.NoError(err) + + return p +}