-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for dimension labels #259
Conversation
This pull request has been linked to: |
48ae1fd
to
0d661fe
Compare
0d661fe
to
3f6857f
Compare
1849736
to
ce55d2d
Compare
+ Add binding for SetDimensionLabelTileExtent
ce55d2d
to
0885fde
Compare
Rebased to latest master to get TileDB 2.17 and the Subarray APIs |
// AttributeName returns the name of the attribute the label data is stored under. | ||
func (d *DimensionLabel) AttributeName() (string, error) { | ||
var labelAttrName *C.char | ||
ret := C.tiledb_dimension_label_get_label_attr_name(d.context.tiledbContext, d.tiledbDimensionLabel, &labelAttrName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who owns the memory pointed to by labelAttrName after this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Memory is owned by core but GoString at return makes a safe copy in the go space
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment saying this? Just so that future readers know why this is safe. (Similarly in other cases where we get a reference to C-owned memory that we copy out of.)
dimension_label.go
Outdated
func (a *ArraySchema) DimensionLabelsNum() (uint64, error) { | ||
var labelNum uint64 | ||
|
||
ret := C.tiledb_array_schema_get_dimension_label_num(a.context.tiledbContext, a.tiledbArraySchema, (*C.uint64_t)(unsafe.Pointer(&labelNum))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here would recommend doing the same thing as you've done in other places with
var labelNum C.uint64_t
// ...
return uint64(labelNum)
which I believe should avoid the need for an unsafe.Pointer
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
dimension_label.go
Outdated
switch dimType { | ||
case TILEDB_INT8: | ||
tmpExtent := extent.(int8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few things going on here which will be annoying to deal with:
- Since Go is garbage-collected, memory becomes eligible for freeing (and thus should be considered as already freed) after the last time they are referred to.
unsafe.Pointer
intentionally is opaque to the GC, so something referred to by anunsafe.Pointer
does not count as actually there.
This means that in this case:
tmpExtent
gets space allocated (on the stack, in this case), and the value ofextent
is copied into it.- We create an
unsafe.Pointer
totmpExtent
. tmpExtent
is no longer referred to, thus making it eligible for collection.- We pass that pointer out to TileDB.
(This might be something we do elsewhere in this package; if so we need to fix it there too.)
In this case we need to ensure tmpExtent
stays around. So I think we need to do something like:
var extentPtr any
defer runtime.KeepAlive(extentPtr)
// Here we can also reduce the amount of repetition by using a type-switch.
switch extent := extent.(type) {
case int8:
// This ensures that `extent` stays alive.
extentPtr = &extent
// and since cExtent is a pointer to the same thing as extentPtr, it's OK.
cExtent := unsafe.Pointer(&extent)
// ...
}
(This is annoying and fiddly.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks! Similar pattern was also in dimension.go, I made this change there too.
dimension_label.go
Outdated
return nil | ||
} | ||
|
||
// getDimensionLabelDataType Retrieve a dimension label Datatype from the schema using experimental APIs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*retrieves a dimension label
enums.go
Outdated
} | ||
|
||
// FromString Converts from a string to the equivalent DataOrder enum | ||
func (d *DataOrder) FromString(name string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like an odd API:
var myDO DataOrder
myDO.FromString("someStr")
I would expect something like:
order, err := tiledb.DataOrderFromString(someStr)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. Made it a package method
// AttributeName returns the name of the attribute the label data is stored under. | ||
func (d *DimensionLabel) AttributeName() (string, error) { | ||
var labelAttrName *C.char | ||
ret := C.tiledb_dimension_label_get_label_attr_name(d.context.tiledbContext, d.tiledbDimensionLabel, &labelAttrName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment saying this? Just so that future readers know why this is safe. (Similarly in other cases where we get a reference to C-owned memory that we copy out of.)
@@ -11,6 +11,11 @@ func checkError(err error) { | |||
} | |||
} | |||
|
|||
func checkedValue[T any](v T, err error) T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you add a docstring here? a one-liner should suffice.
case int8: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case int16: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case int32: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case int64: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case uint8: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case uint16: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case uint32: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case uint64: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case float32: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case float64: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) | ||
case bool: | ||
extentPtr = &tmpExtent | ||
cExtent = unsafe.Pointer(&tmpExtent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i love go
This adds support for dimension labels. I needed this support to continue working on SC-25205 (See blocking SC-28383 for more detail).
I'm generally new to Go, so please point out any weirdness and I will address asap. Specifically looking for help or advice on this PR in the following areas: