-
Notifications
You must be signed in to change notification settings - Fork 53
/
hybrid_encoder.go
109 lines (87 loc) · 1.85 KB
/
hybrid_encoder.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
107
108
109
package goparquet
import (
"bytes"
"encoding/binary"
"io"
)
type hybridEncoder struct {
w io.Writer
left []int32
original io.Writer
bitWidth int
unpackerFn pack8int32Func
data *packedArray
}
func newHybridEncoder(bitWidth int) *hybridEncoder {
p := &packedArray{}
return &hybridEncoder{
bitWidth: bitWidth,
unpackerFn: pack8Int32FuncByWidth[bitWidth],
data: p,
}
}
func (he *hybridEncoder) init(w io.Writer) error {
he.w = w
he.left = nil
he.original = nil
he.data.reset(he.bitWidth)
return nil
}
func (he *hybridEncoder) initSize(w io.Writer) error {
_ = he.init(&bytes.Buffer{})
he.original = w
return nil
}
func (he *hybridEncoder) write(items ...[]byte) error {
for i := range items {
if err := writeFull(he.w, items[i]); err != nil {
return err
}
}
return nil
}
func (he *hybridEncoder) bpEncode() error {
// If the bit width is zero, no need to write any
if he.bitWidth == 0 {
return nil
}
l := he.data.count
if x := l % 8; x != 0 {
l += 8 - x
}
header := ((l / 8) << 1) | 1
buf := make([]byte, 4) // big enough for int
cnt := binary.PutUvarint(buf, uint64(header))
return he.write(buf[:cnt], he.data.data)
}
func (he *hybridEncoder) encode(data []int32) error {
for i := range data {
he.data.appendSingle(data[i])
}
return nil
}
func (he *hybridEncoder) encodePacked(data *packedArray) error {
he.data.appendArray(data)
return nil
}
func (he *hybridEncoder) flush() error {
he.data.flush()
return he.bpEncode()
}
func (he *hybridEncoder) Close() error {
if he.bitWidth == 0 {
return nil
}
if err := he.flush(); err != nil {
return err
}
if he.original != nil {
data := he.w.(*bytes.Buffer).Bytes()
var size = uint32(len(data))
if err := binary.Write(he.original, binary.LittleEndian, size); err != nil {
return err
}
return writeFull(he.original, data)
}
return nil
}