-
Notifications
You must be signed in to change notification settings - Fork 77
Expand file tree
/
Copy pathrecordbuilder.go
More file actions
74 lines (66 loc) · 1.56 KB
/
recordbuilder.go
File metadata and controls
74 lines (66 loc) · 1.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package vector
import (
"slices"
"github.com/brimdata/super"
"github.com/brimdata/super/pkg/field"
)
type RecordBuilder struct {
sctx *super.Context
base *rec
}
func NewRecordBuilder(sctx *super.Context, fields field.List) (*RecordBuilder, error) {
base := &rec{}
for _, path := range fields {
if err := addPath(base, path); err != nil {
return nil, err
}
}
return &RecordBuilder{sctx: sctx, base: base}, nil
}
func (r *RecordBuilder) New(vecs []Any) *Record {
rec, _ := r.base.build(r.sctx, vecs)
return rec
}
type rec struct {
paths []string
recs []*rec
}
func addPath(r *rec, path field.Path) error {
for k, name := range path {
idx := slices.Index(r.paths, name)
if k == len(path)-1 {
if idx > -1 {
return &super.DuplicateFieldError{Name: path.String()}
}
r.paths = append(r.paths, path[k])
r.recs = append(r.recs, nil)
return nil
}
if idx == -1 {
idx = len(r.paths)
r.paths = append(r.paths, name)
r.recs = append(r.recs, &rec{})
}
if r.recs[idx] == nil {
return &super.DuplicateFieldError{Name: path[:k+1].String()}
}
r = r.recs[idx]
}
return nil
}
func (r *rec) build(sctx *super.Context, leafs []Any) (*Record, []Any) {
var fields []super.Field
var out []Any
for i, name := range r.paths {
var vec Any
if r.recs[i] != nil {
vec, leafs = r.recs[i].build(sctx, leafs)
} else {
vec, leafs = leafs[0], leafs[1:]
}
fields = append(fields, super.NewField(name, vec.Type()))
out = append(out, vec)
}
typ := sctx.MustLookupTypeRecord(fields)
return NewRecord(typ, out, out[0].Len()), leafs
}