-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathfilter.go
140 lines (123 loc) · 4.7 KB
/
filter.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
package tiledb
/*
#include <tiledb/tiledb.h>
#include <stdlib.h>
*/
import "C"
import (
"errors"
"fmt"
"unsafe"
)
// Filter represents
type Filter struct {
tiledbFilter *C.tiledb_filter_t
context *Context
}
// NewFilter allocates a new filter.
func NewFilter(context *Context, filterType FilterType) (*Filter, error) {
filter := Filter{context: context}
ret := C.tiledb_filter_alloc(filter.context.tiledbContext, C.tiledb_filter_type_t(filterType), &filter.tiledbFilter)
if ret != C.TILEDB_OK {
return nil, fmt.Errorf("error creating tiledb filter: %w", filter.context.LastError())
}
freeOnGC(&filter)
return &filter, 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 (f *Filter) Free() {
if f.tiledbFilter != nil {
C.tiledb_filter_free(&f.tiledbFilter)
}
}
// Context exposes the internal TileDB context used to initialize the filter.
func (f *Filter) Context() *Context {
return f.context
}
// Type returns the filter type.
func (f *Filter) Type() (FilterType, error) {
var filterType C.tiledb_filter_type_t
ret := C.tiledb_filter_get_type(f.context.tiledbContext, f.tiledbFilter, &filterType)
if ret != C.TILEDB_OK {
return 0, fmt.Errorf("error getting tiledb filter type: %w", f.context.LastError())
}
return FilterType(filterType), nil
}
// SetOption sets an option on a filter. Options are filter dependent;
// this function returns an error if the given option is not valid for the
// given filter.
func (f *Filter) SetOption(filterOption FilterOption, valueInterface interface{}) error {
var cvalue unsafe.Pointer
switch filterOption {
case TILEDB_COMPRESSION_LEVEL:
value, ok := valueInterface.(int32)
if !ok {
return errors.New("error setting tiledb filter option TILEDB_COMPRESSION_LEVEL, passed data is not int32")
}
cvalue = unsafe.Pointer(&value)
ret := C.tiledb_filter_set_option(f.context.tiledbContext, f.tiledbFilter, C.tiledb_filter_option_t(filterOption), cvalue)
if ret != C.TILEDB_OK {
return fmt.Errorf("error setting tiledb filter option: %w", f.context.LastError())
}
case TILEDB_BIT_WIDTH_MAX_WINDOW:
value, ok := valueInterface.(uint32)
if !ok {
return errors.New("error setting tiledb filter option TILEDB_BIT_WIDTH_MAX_WINDOW, passed data is not uint32")
}
cvalue = unsafe.Pointer(&value)
ret := C.tiledb_filter_set_option(f.context.tiledbContext, f.tiledbFilter, C.tiledb_filter_option_t(filterOption), cvalue)
if ret != C.TILEDB_OK {
return fmt.Errorf("error setting tiledb filter option: %w", f.context.LastError())
}
case TILEDB_POSITIVE_DELTA_MAX_WINDOW:
value, ok := valueInterface.(uint32)
if !ok {
return errors.New("error setting tiledb filter option TILEDB_POSITIVE_DELTA_MAX_WINDOW, passed data is not uint32")
}
cvalue = unsafe.Pointer(&value)
ret := C.tiledb_filter_set_option(f.context.tiledbContext, f.tiledbFilter, C.tiledb_filter_option_t(filterOption), cvalue)
if ret != C.TILEDB_OK {
return fmt.Errorf("error setting tiledb filter option: %w", f.context.LastError())
}
}
return nil
}
// Option fetches the specified option set on a filter. Returns an interface{}
// dependent on the option being fetched
// var optionValue int32
// optionValueInterface, err := filter.Option(TILEDB_FILTER_GZIP)
// optionValue = optionValueInterface.(int32)
func (f *Filter) Option(filterOption FilterOption) (interface{}, error) {
var cvalue unsafe.Pointer
switch filterOption {
case TILEDB_COMPRESSION_LEVEL:
var val int32
cvalue = unsafe.Pointer(&val)
ret := C.tiledb_filter_get_option(f.context.tiledbContext, f.tiledbFilter, C.tiledb_filter_option_t(filterOption), cvalue)
if ret != C.TILEDB_OK {
return nil, fmt.Errorf("error getting tiledb filter option: %w", f.context.LastError())
}
return val, nil
case TILEDB_BIT_WIDTH_MAX_WINDOW:
var val uint32
cvalue = unsafe.Pointer(&val)
ret := C.tiledb_filter_get_option(f.context.tiledbContext, f.tiledbFilter, C.tiledb_filter_option_t(filterOption), cvalue)
if ret != C.TILEDB_OK {
return nil, fmt.Errorf("error getting tiledb filter option: %w", f.context.LastError())
}
return val, nil
case TILEDB_POSITIVE_DELTA_MAX_WINDOW:
var val uint32
cvalue = unsafe.Pointer(&val)
ret := C.tiledb_filter_get_option(f.context.tiledbContext, f.tiledbFilter, C.tiledb_filter_option_t(filterOption), cvalue)
if ret != C.TILEDB_OK {
return nil, fmt.Errorf("error getting tiledb filter option: %w", f.context.LastError())
}
return val, nil
}
return nil, nil
}