/
map.go
106 lines (94 loc) · 1.94 KB
/
map.go
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package vng
import (
"io"
"github.com/brimdata/zed"
"github.com/brimdata/zed/zcode"
"golang.org/x/sync/errgroup"
)
type MapEncoder struct {
keys Encoder
values Encoder
lengths *Int64Encoder
count uint32
}
func NewMapEncoder(typ *zed.TypeMap) *MapEncoder {
return &MapEncoder{
keys: NewEncoder(typ.KeyType),
values: NewEncoder(typ.ValType),
lengths: NewInt64Encoder(),
}
}
func (m *MapEncoder) Write(body zcode.Bytes) {
m.count++
var len int
it := body.Iter()
for !it.Done() {
m.keys.Write(it.Next())
m.values.Write(it.Next())
len++
}
m.lengths.Write(int64(len))
}
func (m *MapEncoder) Emit(w io.Writer) error {
if err := m.lengths.Emit(w); err != nil {
return err
}
if err := m.keys.Emit(w); err != nil {
return err
}
return m.values.Emit(w)
}
func (m *MapEncoder) Metadata(off uint64) (uint64, Metadata) {
off, lens := m.lengths.Metadata(off)
off, keys := m.keys.Metadata(off)
off, vals := m.values.Metadata(off)
return off, &Map{
Lengths: lens.(*Primitive).Location,
Keys: keys,
Values: vals,
Length: m.count,
}
}
func (m *MapEncoder) Encode(group *errgroup.Group) {
m.lengths.Encode(group)
m.keys.Encode(group)
m.values.Encode(group)
}
type MapBuilder struct {
Keys Builder
Values Builder
Lengths *Int64Decoder
}
var _ Builder = (*MapBuilder)(nil)
func NewMapBuilder(m *Map, r io.ReaderAt) (*MapBuilder, error) {
keys, err := NewBuilder(m.Keys, r)
if err != nil {
return nil, err
}
values, err := NewBuilder(m.Values, r)
if err != nil {
return nil, err
}
return &MapBuilder{
Keys: keys,
Values: values,
Lengths: NewInt64Decoder(m.Lengths, r),
}, nil
}
func (m *MapBuilder) Build(b *zcode.Builder) error {
len, err := m.Lengths.Next()
if err != nil {
return err
}
b.BeginContainer()
for k := 0; k < int(len); k++ {
if err := m.Keys.Build(b); err != nil {
return err
}
if err := m.Values.Build(b); err != nil {
return err
}
}
b.EndContainer()
return nil
}