Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change variant to dynamic #5302

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions runtime/vam/expr/function/bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (b *Base64) Call(args ...vector.Any) vector.Any {
out.Append(base64.StdEncoding.EncodeToString(bytes))
}
err := vector.NewStringError(b.zctx, "base64: illegal null argument", errcnt)
return vector.NewVariant(tags, []vector.Any{out, err})
return vector.NewDynamic(tags, []vector.Any{out, err})
case zed.IDString:
errvals := vector.NewStringEmpty(0, nil)
tags := make([]uint32, val.Len())
Expand All @@ -49,7 +49,7 @@ func (b *Base64) Call(args ...vector.Any) vector.Any {
out.Append(bytes)
}
err := vector.NewWrappedError(b.zctx, "base64: string argument is not base64", errvals)
return vector.NewVariant(tags, []vector.Any{out, err})
return vector.NewDynamic(tags, []vector.Any{out, err})
default:
return vector.NewWrappedError(b.zctx, "base64: argument must a bytes or string type", val)
}
Expand Down Expand Up @@ -77,7 +77,7 @@ func (h *Hex) Call(args ...vector.Any) vector.Any {
out.Append(hex.EncodeToString(bytes))
}
err := vector.NewStringError(h.zctx, "hex: illegal null argument", errcnt)
return vector.NewVariant(tags, []vector.Any{out, err})
return vector.NewDynamic(tags, []vector.Any{out, err})
case zed.IDString:
errvals := vector.NewStringEmpty(0, nil)
tags := make([]uint32, val.Len())
Expand All @@ -96,7 +96,7 @@ func (h *Hex) Call(args ...vector.Any) vector.Any {
out.Append(bytes)
}
err := vector.NewWrappedError(h.zctx, "hex: string argument is not hexidecimal", errvals)
return vector.NewVariant(tags, []vector.Any{out, err})
return vector.NewDynamic(tags, []vector.Any{out, err})
default:
return vector.NewWrappedError(h.zctx, "hex: argument must a bytes or string type", val)
}
Expand Down
2 changes: 1 addition & 1 deletion runtime/vam/expr/function/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (r *Replace) Call(args ...vector.Any) vector.Any {
out.Append(strings.ReplaceAll(s, old, new))
}
errval := vector.NewStringError(r.zctx, "replace: an input arg is null", errcnt)
return vector.NewVariant(tags, []vector.Any{out, errval})
return vector.NewDynamic(tags, []vector.Any{out, errval})
}

// https://github.com/brimdata/zed/blob/main/docs/language/functions.md#run_len
Expand Down
2 changes: 1 addition & 1 deletion runtime/vam/expr/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ func indexRecord(zctx *zed.Context, record *vector.Record, index vector.Any) vec
for i, field := range record.Fields {
out[i] = vector.NewView(viewIndexes[i], field)
}
return vector.NewVariant(tags, out)
return vector.NewDynamic(tags, out)
}
10 changes: 5 additions & 5 deletions runtime/vam/expr/logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func NewLogicalOr(zctx *zed.Context, lhs, rhs Evaluator) *Or {
}

func (a *And) Eval(val vector.Any) vector.Any {
//XXX change this logic to handle variant instead of simple ok decision,
//XXX change this logic to handle dynamic instead of simple ok decision,
// if there are any valid bools then we need to and them together
lhs, ok := EvalBool(a.zctx, val, a.lhs)
if !ok {
Expand Down Expand Up @@ -102,15 +102,15 @@ func (o *Or) Eval(val vector.Any) vector.Any {
// slot and they are returned as an error. If all of the value slots are errors,
// then the return value is nil.
func EvalBool(zctx *zed.Context, val vector.Any, e Evaluator) (vector.Any, bool) {
//XXX Eval could return a variant of errors and bools and we should
//XXX Eval could return a dynamic vector of errors and bools and we should
// handle this correctly so the logic above is really the fast path
// and a slower path will handle picking apart the variant.
// maybe we could have a generic way to traverse variants for
// and a slower path will handle picking apart the dynamic vector.
// maybe we could have a generic way to traverse dynamics for
// appliers doing their thing along the slow path
if val, ok := vector.Under(e.Eval(val)).(*vector.Bool); ok {
return val, true
}
//XXX need to implement a sparse variant (vector.Collection?)
//XXX need to implement a sparse dynamic (vector.Collection?)
// and check for that here.
// for now, if the vector is not uniformly boolean, we return error.
// XXX example is a field ref a union of structs where the type of
Expand Down
8 changes: 4 additions & 4 deletions runtime/vam/materialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ func (m *Materializer) Pull(done bool) (zbuf.Batch, error) {
if vec == nil || err != nil {
return nil, err
}
variant, _ := vec.(*vector.Variant)
d, _ := vec.(*vector.Dynamic)
var typ zed.Type
if variant == nil {
if d == nil {
typ = vec.Type()
}
builder := zcode.NewBuilder()
var vals []zed.Value
n := vec.Len()
for slot := uint32(0); slot < n; slot++ {
vec.Serialize(builder, slot)
if variant != nil {
typ = variant.TypeOf(slot)
if d != nil {
typ = d.TypeOf(slot)
}
val := zed.NewValue(typ, bytes.Clone(builder.Bytes().Body()))
vals = append(vals, val)
Expand Down
4 changes: 2 additions & 2 deletions runtime/vam/op/agg.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (c *CountByString) Pull(done bool) (vector.Any, error) {
}

func (c *CountByString) update(val vector.Any) {
if val, ok := val.(*vector.Variant); ok {
if val, ok := val.(*vector.Dynamic); ok {
for _, val := range val.Values {
c.update(val)
}
Expand Down Expand Up @@ -183,7 +183,7 @@ func (c *Sum) Pull(done bool) (vector.Any, error) {
}

func (c *Sum) update(vec vector.Any) {
if vec, ok := vec.(*vector.Variant); ok {
if vec, ok := vec.(*vector.Dynamic); ok {
for _, vec := range vec.Values {
c.update(vec)
}
Expand Down
4 changes: 2 additions & 2 deletions runtime/vam/op/yield.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func filterQuiet(val vector.Any) vector.Any {
return val
}

// XXX should work for input variants
// XXX should work for vector.Dynamic
func interleave(vals []vector.Any) vector.Any {
if len(vals) < 2 {
panic("interleave requires two or more vals")
Expand All @@ -61,5 +61,5 @@ func interleave(vals []vector.Any) vector.Any {
tags[k] = k % nvals

}
return vector.NewVariant(tags, vals)
return vector.NewDynamic(tags, vals)
}
2 changes: 1 addition & 1 deletion runtime/vam/op/ztests/arith.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Test that arithmetic works on union and variant vectors.
# Test that arithmetic works on union and dynamic vectors.

script: |
zq -o t.vng -f vng -
Expand Down
2 changes: 1 addition & 1 deletion runtime/vam/op/ztests/compare.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Test that comparison works on union and variant vectors.
# Test that comparison works on union and dynamic vectors.

script: |
zq -o t.vng -f vng -
Expand Down
6 changes: 3 additions & 3 deletions runtime/vcache/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (l *loader) load(paths Path, s shadow) (vector.Any, error) {

func (l *loader) loadVector(g *errgroup.Group, paths Path, s shadow) {
switch s := s.(type) {
case *variant:
case *dynamic:
//XXX we need an ordered option to load tags only when needed
l.loadUint32(g, &s.mu, &s.tags, s.loc)
for _, m := range s.vals {
Expand Down Expand Up @@ -476,7 +476,7 @@ func (l *loader) loadOffsets(g *errgroup.Group, mu *sync.Mutex, slice *[]uint32,

func (l *loader) fetchNulls(g *errgroup.Group, paths Path, s shadow) {
switch s := s.(type) {
case *variant:
case *dynamic:
for _, m := range s.vals {
l.fetchNulls(g, paths, m)
}
Expand Down Expand Up @@ -533,7 +533,7 @@ func (l *loader) fetchNulls(g *errgroup.Group, paths Path, s shadow) {

func flattenNulls(paths Path, s shadow, parent *vector.Bool) {
switch s := s.(type) {
case *variant:
case *dynamic:
for _, m := range s.vals {
flattenNulls(paths, m, nil)
}
Expand Down
8 changes: 4 additions & 4 deletions runtime/vcache/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (

func project(zctx *zed.Context, paths Path, s shadow) vector.Any {
switch s := s.(type) {
case *variant:
return projectVariant(zctx, paths, s)
case *dynamic:
return projectDynamic(zctx, paths, s)
case *record:
return projectRecord(zctx, paths, s)
case *array:
Expand Down Expand Up @@ -54,12 +54,12 @@ func project(zctx *zed.Context, paths Path, s shadow) vector.Any {
}
}

func projectVariant(zctx *zed.Context, paths Path, s *variant) vector.Any {
func projectDynamic(zctx *zed.Context, paths Path, s *dynamic) vector.Any {
vals := make([]vector.Any, 0, len(s.vals))
for _, m := range s.vals {
vals = append(vals, project(zctx, paths, m))
}
return vector.NewVariant(s.tags, vals)
return vector.NewDynamic(s.tags, vals)
}

func projectRecord(zctx *zed.Context, paths Path, s *record) vector.Any {
Expand Down
12 changes: 6 additions & 6 deletions runtime/vcache/shadow.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ type shadow interface {
length() uint32
}

type variant struct {
type dynamic struct {
mu sync.Mutex
len uint32
tags []uint32 // need not be loaded for unordered variants
tags []uint32 // need not be loaded for unordered dynamics
loc vng.Segment
vals []shadow
}

func (v *variant) length() uint32 {
return v.len
func (d *dynamic) length() uint32 {
return d.len
}

type record struct {
Expand Down Expand Up @@ -133,12 +133,12 @@ func (c count) length() uint32 {
// by the runtime.
func newShadow(m vng.Metadata, n *vng.Nulls, nullsCnt uint32) shadow {
switch m := m.(type) {
case *vng.Variant:
case *vng.Dynamic:
vals := make([]shadow, 0, len(m.Values))
for _, val := range m.Values {
vals = append(vals, newShadow(val, nil, 0))
}
return &variant{
return &dynamic{
vals: vals,
len: m.Len(),
loc: m.Tags,
Expand Down
8 changes: 4 additions & 4 deletions vector/any.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ type Builder func(*zcode.Builder) bool
func Combine(vec Any, index []uint32, add Any) Any {
var vecs []Any
tags := make([]uint32, int(vec.Len())+len(index))
if variant, ok := vec.(*Variant); ok {
vecs = variant.Values
varTags := variant.Tags
if d, ok := vec.(*Dynamic); ok {
vecs = d.Values
varTags := d.Tags
n := uint32(len(vecs))
for i := uint32(0); i < uint32(len(tags)); i++ {
if len(index) > 0 && i == index[0] {
Expand All @@ -44,5 +44,5 @@ func Combine(vec Any, index []uint32, add Any) Any {
tags[k] = 1
}
}
return NewVariant(tags, append(vecs, add))
return NewDynamic(tags, append(vecs, add))
}
28 changes: 14 additions & 14 deletions vector/apply.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
package vector

// Apply applies eval to vecs. If any element of vecs is a Variant, Apply rips
// Apply applies eval to vecs. If any element of vecs is a Dynamic, Apply rips
// vecs accordingly, applies eval to the ripped vectors, and stitches the
// results together into a Variant. If ripUnions is true, Apply also rips
// results together into a Dynamic. If ripUnions is true, Apply also rips
// Unions.
func Apply(ripUnions bool, eval func(...Any) Any, vecs ...Any) Any {
if ripUnions {
for k, vec := range vecs {
if union, ok := Under(vec).(*Union); ok {
vecs[k] = union.Variant
vecs[k] = union.Dynamic
}
}
}
variant, ok := findVariant(vecs)
d, ok := findDynamic(vecs)
if !ok {
return eval(vecs...)
}
var results []Any
for _, ripped := range rip(vecs, variant) {
for _, ripped := range rip(vecs, d) {
results = append(results, Apply(ripUnions, eval, ripped...))
}
// Stitch results together by creating a Variant.
return NewVariant(variant.Tags, results)
// Stitch results together in a new Dynamic.
return NewDynamic(d.Tags, results)
}

func findVariant(vecs []Any) (*Variant, bool) {
func findDynamic(vecs []Any) (*Dynamic, bool) {
for _, vec := range vecs {
if variant, ok := vec.(*Variant); ok {
return variant, true
if d, ok := vec.(*Dynamic); ok {
return d, true
}
}
return nil, false
}

func rip(vecs []Any, variant *Variant) [][]Any {
func rip(vecs []Any, d *Dynamic) [][]Any {
var ripped [][]Any
for j, rev := range variant.TagMap.Reverse {
for j, rev := range d.TagMap.Reverse {
var newVecs []Any
for _, vec := range vecs {
if vec == variant {
newVecs = append(newVecs, variant.Values[j])
if vec == d {
newVecs = append(newVecs, d.Values[j])
} else {
newVecs = append(newVecs, NewView(rev, vec))
}
Expand Down
2 changes: 1 addition & 1 deletion vector/bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func BoolValue(vec Any, slot uint32) bool {
return vec.Value().Ptr().AsBool()
case *Dict:
return BoolValue(vec.Any, uint32(vec.Index[slot]))
case *Variant:
case *Dynamic:
tag := vec.Tags[slot]
return BoolValue(vec.Values[tag], vec.TagMap.Forward[slot])
case *View:
Expand Down
47 changes: 47 additions & 0 deletions vector/dynamic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package vector

import (
"github.com/brimdata/zed"
"github.com/brimdata/zed/zcode"
)

// Dynamic is an ordered sequence of values taken from one or more
// hetereogenously-typed vectors.
type Dynamic struct {
Tags []uint32
Values []Any
TagMap *TagMap
}

var _ Any = (*Dynamic)(nil)

func NewDynamic(tags []uint32, values []Any) *Dynamic {
return &Dynamic{Tags: tags, Values: values, TagMap: NewTagMap(tags, values)}
}

func (*Dynamic) Type() zed.Type {
panic("can't call Type() on a vector.Dynamic")
}

func (d *Dynamic) TypeOf(slot uint32) zed.Type {
vals := d.Values[d.Tags[slot]]
if v2, ok := vals.(*Dynamic); ok {
return v2.TypeOf(d.TagMap.Forward[slot])
}
return vals.Type()
}

func (d *Dynamic) Len() uint32 {
if d.Tags != nil {
return uint32(len(d.Tags))
}
var length uint32
for _, val := range d.Values {
length += val.Len()
}
return length
}

func (d *Dynamic) Serialize(b *zcode.Builder, slot uint32) {
d.Values[d.Tags[slot]].Serialize(b, d.TagMap.Forward[slot])
}
2 changes: 1 addition & 1 deletion vector/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func IntValue(vec Any, slot uint32) (int64, bool) {
return vec.Value().Ptr().AsInt(), vec.Nulls.Value(slot)
case *Dict:
return IntValue(vec.Any, uint32(vec.Index[slot]))
case *Variant:
case *Dynamic:
tag := vec.Tags[slot]
return IntValue(vec.Values[tag], vec.TagMap.Forward[slot])
case *View:
Expand Down
2 changes: 1 addition & 1 deletion vector/tagmap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package vector

// TagMap is used by variants and unions to map slots between parent and child in
// TagMap is used by dynamics and unions to map slots between parent and child in
// both the forward and reverse directions. We need this because vectors are stored
// in a dense format where different types hold only the values needed for that type.
// If we stored vectors in a sparse format, the amount of overhead would increase
Expand Down
Loading