forked from parquet-go/parquet-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
allocator.go
64 lines (54 loc) · 1.49 KB
/
allocator.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
package parquet
import (
"unsafe"
"github.com/parquet-go/parquet-go/internal/unsafecast"
)
type allocator struct{ buffer []byte }
func (a *allocator) makeBytes(n int) []byte {
if free := cap(a.buffer) - len(a.buffer); free < n {
newCap := 2 * cap(a.buffer)
if newCap == 0 {
newCap = 4096
}
for newCap < n {
newCap *= 2
}
a.buffer = make([]byte, 0, newCap)
}
i := len(a.buffer)
j := len(a.buffer) + n
a.buffer = a.buffer[:j]
return a.buffer[i:j:j]
}
func (a *allocator) copyBytes(v []byte) []byte {
b := a.makeBytes(len(v))
copy(b, v)
return b
}
func (a *allocator) copyString(v string) string {
b := a.makeBytes(len(v))
copy(b, v)
return unsafecast.String(b)
}
func (a *allocator) reset() {
a.buffer = a.buffer[:0]
}
// rowAllocator is a memory allocator used to make a copy of rows referencing
// memory buffers that parquet-go does not have ownership of.
//
// This type is used in the implementation of various readers and writers that
// need to capture rows passed to the ReadRows/WriteRows methods. Copies to a
// local buffer is necessary in those cases to repect the reader/writer
// contracts that do not allow the implementations to retain the rows they
// are passed as arguments.
//
// See: RowBuffer, DedupeRowReader, DedupeRowWriter
type rowAllocator struct{ allocator }
func (a *rowAllocator) capture(row Row) {
for i, v := range row {
switch v.Kind() {
case ByteArray, FixedLenByteArray:
row[i].ptr = unsafe.SliceData(a.copyBytes(v.byteArray()))
}
}
}