-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathbuffer_list.go
146 lines (117 loc) · 4.31 KB
/
buffer_list.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package tiledb
/*
#include <tiledb/tiledb.h>
#include <stdlib.h>
*/
import "C"
import (
"fmt"
"io"
"runtime"
"unsafe"
)
type bufferListHandle struct{ *capiHandle }
func freeCapiBufferList(c unsafe.Pointer) {
C.tiledb_buffer_list_free((**C.tiledb_buffer_list_t)(unsafe.Pointer(&c)))
}
func newBufferListHandle(ptr *C.tiledb_buffer_list_t) bufferListHandle {
return bufferListHandle{newCapiHandle(unsafe.Pointer(ptr), freeCapiBufferList)}
}
func (x bufferListHandle) Get() *C.tiledb_buffer_list_t {
return (*C.tiledb_buffer_list_t)(x.capiHandle.Get())
}
// BufferList A list of TileDB BufferList objects
type BufferList struct {
tiledbBufferList bufferListHandle
context *Context
}
func newBufferListFromHandle(context *Context, handle bufferListHandle) *BufferList {
return &BufferList{tiledbBufferList: handle, context: context}
}
// NewBufferList Allocs a new buffer list
func NewBufferList(context *Context) (*BufferList, error) {
var bufferListPtr *C.tiledb_buffer_list_t
ret := C.tiledb_buffer_list_alloc(context.tiledbContext.Get(), &bufferListPtr)
runtime.KeepAlive(context)
if ret != C.TILEDB_OK {
return nil, fmt.Errorf("error creating tiledb buffer list: %w", context.LastError())
}
return newBufferListFromHandle(context, newBufferListHandle(bufferListPtr)), nil
}
// Free releases the internal TileDB core data that was allocated on the C heap.
// It is automatically called when this object is garbage collected, but can be
// called earlier to manually release memory if needed. Free is idempotent and
// can safely be called many times on the same object; if it has already
// been freed, it will not be freed again.
func (b *BufferList) Free() {
b.tiledbBufferList.Free()
}
// Context exposes the internal TileDB context used to initialize the buffer list.
func (b *BufferList) Context() *Context {
return b.context
}
// WriteTo writes the contents of a BufferList to an io.Writer.
func (b *BufferList) WriteTo(w io.Writer) (int64, error) {
nbuffs, err := b.NumBuffers()
if err != nil {
return 0, err
}
written := int64(0)
for i := uint(0); i < uint(nbuffs); i++ {
buff, err := b.GetBuffer(i)
if err != nil {
return 0, err
}
n, err := buff.WriteTo(w)
written += n
buff.Free()
if err != nil {
return written, err
}
}
return written, nil
}
// Static assert that BufferList implements io.WriterTo.
var _ io.WriterTo = (*BufferList)(nil)
// NumBuffers returns number of buffers in the list.
func (b *BufferList) NumBuffers() (uint64, error) {
var numBuffers C.uint64_t
ret := C.tiledb_buffer_list_get_num_buffers(b.context.tiledbContext.Get(), b.tiledbBufferList.Get(), &numBuffers)
runtime.KeepAlive(b)
if ret != C.TILEDB_OK {
return 0, fmt.Errorf("error getting tiledb bufferList num buffers: %w", b.context.LastError())
}
return uint64(numBuffers), nil
}
// GetBuffer returns a Buffer at the given index in the list.
func (b *BufferList) GetBuffer(bufferIndex uint) (*Buffer, error) {
var bufferPtr *C.tiledb_buffer_t
ret := C.tiledb_buffer_list_get_buffer(b.context.tiledbContext.Get(), b.tiledbBufferList.Get(), C.uint64_t(bufferIndex), &bufferPtr)
runtime.KeepAlive(b)
if ret != C.TILEDB_OK {
return nil, fmt.Errorf("error getting tiledb buffer index %d from buffer list: %w", bufferIndex, b.context.LastError())
}
return newBufferFromHandle(b.context, newBufferHandle(bufferPtr)), nil
}
// TotalSize returns the total number of bytes in the buffers in the list.
func (b *BufferList) TotalSize() (uint64, error) {
var totalSize C.uint64_t
ret := C.tiledb_buffer_list_get_total_size(b.context.tiledbContext.Get(), b.tiledbBufferList.Get(), &totalSize)
runtime.KeepAlive(b)
if ret != C.TILEDB_OK {
return 0, fmt.Errorf("error getting tiledb bufferList num buffers: %w", b.context.LastError())
}
return uint64(totalSize), nil
}
// Flatten copies and concatenates all buffers in the list into a new buffer.
//
// Deprecated: Use WriteTo instead for increased performance.
func (b *BufferList) Flatten() (*Buffer, error) {
var bufferPtr *C.tiledb_buffer_t
ret := C.tiledb_buffer_list_flatten(b.context.tiledbContext.Get(), b.tiledbBufferList.Get(), &bufferPtr)
runtime.KeepAlive(b)
if ret != C.TILEDB_OK {
return nil, fmt.Errorf("error getting tiledb bufferList num buffers: %w", b.context.LastError())
}
return newBufferFromHandle(b.context, newBufferHandle(bufferPtr)), nil
}