Skip to content

Commit a5deed1

Browse files
committed
groot/rtree: implement rleafElem
1 parent d39f1c0 commit a5deed1

File tree

7 files changed

+748
-484
lines changed

7 files changed

+748
-484
lines changed

groot/gen.rtree.go

+48-33
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ func genRLeaves() {
617617
Kind Kind
618618
Func string
619619
Decay string
620+
Count bool
620621

621622
WithStreamerElement bool // for TLeaf{F16,D32}
622623
}{
@@ -627,52 +628,60 @@ func genRLeaves() {
627628
Size: int(reflect.TypeOf(true).Size()),
628629
},
629630
{
630-
Name: "I8",
631-
Base: "LeafB",
632-
Type: "int8",
633-
Size: int(reflect.TypeOf(int8(0)).Size()),
631+
Name: "I8",
632+
Base: "LeafB",
633+
Type: "int8",
634+
Size: int(reflect.TypeOf(int8(0)).Size()),
635+
Count: true,
634636
},
635637
{
636-
Name: "I16",
637-
Base: "LeafS",
638-
Type: "int16",
639-
Size: int(reflect.TypeOf(int16(0)).Size()),
638+
Name: "I16",
639+
Base: "LeafS",
640+
Type: "int16",
641+
Size: int(reflect.TypeOf(int16(0)).Size()),
642+
Count: true,
640643
},
641644
{
642-
Name: "I32",
643-
Base: "LeafI",
644-
Type: "int32",
645-
Size: int(reflect.TypeOf(int32(0)).Size()),
645+
Name: "I32",
646+
Base: "LeafI",
647+
Type: "int32",
648+
Size: int(reflect.TypeOf(int32(0)).Size()),
649+
Count: true,
646650
},
647651
{
648-
Name: "I64",
649-
Base: "LeafL",
650-
Type: "int64",
651-
Size: int(reflect.TypeOf(int64(0)).Size()),
652+
Name: "I64",
653+
Base: "LeafL",
654+
Type: "int64",
655+
Size: int(reflect.TypeOf(int64(0)).Size()),
656+
Count: true,
652657
},
653658
{
654-
Name: "U8",
655-
Base: "LeafB",
656-
Type: "uint8",
657-
Size: int(reflect.TypeOf(uint8(0)).Size()),
659+
Name: "U8",
660+
Base: "LeafB",
661+
Type: "uint8",
662+
Size: int(reflect.TypeOf(uint8(0)).Size()),
663+
Count: true,
658664
},
659665
{
660-
Name: "U16",
661-
Base: "LeafS",
662-
Type: "uint16",
663-
Size: int(reflect.TypeOf(uint16(0)).Size()),
666+
Name: "U16",
667+
Base: "LeafS",
668+
Type: "uint16",
669+
Size: int(reflect.TypeOf(uint16(0)).Size()),
670+
Count: true,
664671
},
665672
{
666-
Name: "U32",
667-
Base: "LeafI",
668-
Type: "uint32",
669-
Size: int(reflect.TypeOf(uint32(0)).Size()),
673+
Name: "U32",
674+
Base: "LeafI",
675+
Type: "uint32",
676+
Size: int(reflect.TypeOf(uint32(0)).Size()),
677+
Count: true,
670678
},
671679
{
672-
Name: "U64",
673-
Base: "LeafL",
674-
Type: "uint64",
675-
Size: int(reflect.TypeOf(uint64(0)).Size()),
680+
Name: "U64",
681+
Base: "LeafL",
682+
Type: "uint64",
683+
Size: int(reflect.TypeOf(uint64(0)).Size()),
684+
Count: true,
676685
},
677686
{
678687
Name: "F32",
@@ -769,7 +778,7 @@ func newRLeaf{{.Name}}(leaf *{{.Base}}, rvar ReadVar, rctx rleafCtx) rleaf {
769778
}
770779
return &rleafSli{{.Name}}{
771780
base: leaf,
772-
n: rctx.rcount(leaf.count.Name()),
781+
n: rctx.rcountFunc(leaf.count.Name()),
773782
v: slice,
774783
}
775784
@@ -794,6 +803,12 @@ func (leaf *rleaf{{.Kind}}{{.Name}}) Offset() int64 {
794803
return int64(leaf.base.Offset())
795804
}
796805
806+
{{if eq .Kind "Val"}}
807+
{{if .Count}}
808+
func (leaf *rleaf{{.Kind}}{{.Name}}) ivalue() int { return int(*leaf.v) }
809+
{{- end}}
810+
{{- end}}
811+
797812
{{if eq .Kind "Arr"}}
798813
func unsafeDecayArray{{.Name}}(ptr interface{}) interface{} {
799814
rv := reflect.ValueOf(ptr).Elem()

groot/rtree/reader.go

+36-154
Original file line numberDiff line numberDiff line change
@@ -7,127 +7,8 @@ package rtree
77
import (
88
"fmt"
99
"io"
10-
"reflect"
11-
"regexp"
12-
"strings"
1310
)
1411

15-
// ReadVar describes a variable to be read out of a tree.
16-
type ReadVar struct {
17-
Name string // name of the branch to read
18-
Leaf string // name of the leaf to read
19-
Value interface{} // pointer to the value to fill
20-
count string // name of the leaf-count, if any
21-
}
22-
23-
// NewReadVars returns the complete set of ReadVars to read all the data
24-
// contained in the provided Tree.
25-
func NewReadVars(t Tree) []ReadVar {
26-
var vars []ReadVar
27-
for _, b := range t.Branches() {
28-
for _, leaf := range b.Leaves() {
29-
ptr := newValue(leaf)
30-
cnt := ""
31-
if leaf.LeafCount() != nil {
32-
cnt = leaf.LeafCount().Name()
33-
}
34-
vars = append(vars, ReadVar{Name: b.Name(), Leaf: leaf.Name(), Value: ptr, count: cnt})
35-
}
36-
}
37-
38-
return vars
39-
}
40-
41-
// ReadVarsFromStruct returns a list of ReadVars bound to the exported fields
42-
// of the provided pointer to a struct value.
43-
//
44-
// ReadVarsFromStruct panicks if the provided value is not a pointer to
45-
// a struct value.
46-
func ReadVarsFromStruct(ptr interface{}) []ReadVar {
47-
rv := reflect.ValueOf(ptr)
48-
if rv.Kind() != reflect.Ptr {
49-
panic(fmt.Errorf("rtree: expect a pointer value, got %T", ptr))
50-
}
51-
52-
rv = rv.Elem()
53-
if rv.Kind() != reflect.Struct {
54-
panic(fmt.Errorf("rtree: expect a pointer to struct value, got %T", ptr))
55-
}
56-
57-
var (
58-
rt = rv.Type()
59-
rvars = make([]ReadVar, 0, rt.NumField())
60-
reDims = regexp.MustCompile(`\w*?\[(\w*)\]+?`)
61-
)
62-
63-
split := func(s string) (string, []string) {
64-
n := s
65-
if i := strings.Index(s, "["); i > 0 {
66-
n = s[:i]
67-
}
68-
69-
out := reDims.FindAllStringSubmatch(s, -1)
70-
if len(out) == 0 {
71-
return n, nil
72-
}
73-
74-
dims := make([]string, len(out))
75-
for i := range out {
76-
dims[i] = out[i][1]
77-
}
78-
return n, dims
79-
}
80-
81-
for i := 0; i < rt.NumField(); i++ {
82-
var (
83-
ft = rt.Field(i)
84-
fv = rv.Field(i)
85-
)
86-
if ft.Name != strings.Title(ft.Name) {
87-
// not exported. ignore.
88-
continue
89-
}
90-
rvar := ReadVar{
91-
Name: ft.Tag.Get("groot"),
92-
Value: fv.Addr().Interface(),
93-
}
94-
if rvar.Name == "" {
95-
rvar.Name = ft.Name
96-
}
97-
98-
if strings.Contains(rvar.Name, "[") {
99-
switch ft.Type.Kind() {
100-
case reflect.Slice:
101-
sli, dims := split(rvar.Name)
102-
if len(dims) > 1 {
103-
panic(fmt.Errorf("rtree: invalid number of slice-dimensions for field %q: %q", ft.Name, rvar.Name))
104-
}
105-
rvar.Name = sli
106-
rvar.count = dims[0]
107-
108-
case reflect.Array:
109-
arr, dims := split(rvar.Name)
110-
if len(dims) > 3 {
111-
panic(fmt.Errorf("rtree: invalid number of array-dimension for field %q: %q", ft.Name, rvar.Name))
112-
}
113-
rvar.Name = arr
114-
default:
115-
panic(fmt.Errorf("rtree: invalid field type for %q, or invalid struct-tag %q: %T", ft.Name, rvar.Name, fv.Interface()))
116-
}
117-
}
118-
switch ft.Type.Kind() {
119-
case reflect.Int, reflect.Uint, reflect.UnsafePointer, reflect.Uintptr, reflect.Chan, reflect.Interface:
120-
panic(fmt.Errorf("rtree: invalid field type for %q: %T", ft.Name, fv.Interface()))
121-
case reflect.Map:
122-
panic(fmt.Errorf("rtree: invalid field type for %q: %T (not yet supported)", ft.Name, fv.Interface()))
123-
}
124-
125-
rvar.Leaf = rvar.Name
126-
rvars = append(rvars, rvar)
127-
}
128-
return rvars
129-
}
130-
13112
// Reader reads data from a Tree.
13213
type Reader struct {
13314
r reader
@@ -329,6 +210,7 @@ func newReader(t Tree, rvars []ReadVar, n int, beg, end int64) reader {
329210
if err != nil {
330211
panic(err)
331212
}
213+
332214
switch t := t.(type) {
333215
case *ttree:
334216
return newRTree(t, rvars, n, beg, end)
@@ -374,19 +256,17 @@ func newRTree(t *ttree, rvars []ReadVar, n int, beg, end int64) *rtree {
374256
Name: leaf.Branch().Name(),
375257
Leaf: leaf.Name(),
376258
Value: ptr,
259+
leaf: leaf,
377260
})
378261
}
379262
}
380263
r.rvs = append(rcounts, r.rvs...)
264+
r.rvs = bindRVarsTo(t, r.rvs)
381265

382-
r.lvs = make([]rleaf, len(r.rvs))
383-
for i, rvar := range r.rvs {
384-
br := t.Branch(rvar.Name)
385-
if br == nil {
386-
continue
387-
}
388-
leaf := br.Leaf(rvar.Leaf)
389-
r.lvs[i] = rleafFrom(leaf, rvar, r)
266+
r.lvs = make([]rleaf, 0, len(r.rvs))
267+
for i := range r.rvs {
268+
rv := r.rvs[i]
269+
r.lvs = append(r.lvs, rleafFrom(rv.leaf, rv, r))
390270
}
391271

392272
// regroup leaves by holding branch
@@ -410,7 +290,6 @@ func newRTree(t *ttree, rvars []ReadVar, n int, beg, end int64) *rtree {
410290

411291
return r
412292
}
413-
414293
func (r *rtree) Close() error {
415294
for i := range r.brs {
416295
rb := &r.brs[i]
@@ -426,50 +305,53 @@ func (r *rtree) reset() {
426305
}
427306
}
428307

429-
func (r *rtree) rcount(name string) func() int {
308+
func (r *rtree) rcountFunc(name string) func() int {
430309
for _, leaf := range r.lvs {
431310
n := leaf.Leaf().Name()
432311
if n != name {
433312
continue
434313
}
435314
switch leaf := leaf.(type) {
436315
case *rleafValI8:
437-
return func() int {
438-
return int(*leaf.v)
439-
}
316+
return leaf.ivalue
440317
case *rleafValI16:
441-
return func() int {
442-
return int(*leaf.v)
443-
}
318+
return leaf.ivalue
444319
case *rleafValI32:
445-
return func() int {
446-
return int(*leaf.v)
447-
}
320+
return leaf.ivalue
448321
case *rleafValI64:
449-
return func() int {
450-
return int(*leaf.v)
451-
}
322+
return leaf.ivalue
452323
case *rleafValU8:
453-
return func() int {
454-
return int(*leaf.v)
455-
}
324+
return leaf.ivalue
456325
case *rleafValU16:
457-
return func() int {
458-
return int(*leaf.v)
459-
}
326+
return leaf.ivalue
460327
case *rleafValU32:
461-
return func() int {
462-
return int(*leaf.v)
463-
}
328+
return leaf.ivalue
464329
case *rleafValU64:
465-
return func() int {
466-
return int(*leaf.v)
467-
}
330+
return leaf.ivalue
331+
case *rleafElem:
332+
leaf.bindCount()
333+
return leaf.ivalue
334+
468335
default:
469336
panic(fmt.Errorf("rleaf %T not implemented", leaf))
470337
}
471338
}
472-
panic("impossible")
339+
panic(fmt.Errorf("impossible: no leaf for %s", name))
340+
}
341+
342+
func (r *rtree) rcountLeaf(name string) leafCount {
343+
for _, leaf := range r.lvs {
344+
n := leaf.Leaf().Name()
345+
if n != name {
346+
continue
347+
}
348+
return &rleafCount{
349+
Leaf: leaf.Leaf(),
350+
n: r.rcountFunc(name),
351+
leaf: leaf,
352+
}
353+
}
354+
panic(fmt.Errorf("impossible: no leaf for %s", name))
473355
}
474356

475357
func (r *rtree) run(off, beg, end int64, f func(RCtx) error) error {

0 commit comments

Comments
 (0)