Skip to content

Commit

Permalink
Merge pull request #1243 from TileDB-Inc/ttd/1235
Browse files Browse the repository at this point in the history
Add tiledb_buffer_t buffer get/set C API functions.
  • Loading branch information
tdenniston authored May 3, 2019
2 parents 193f604 + 3f6ebf0 commit ea8fbd6
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 19 deletions.
2 changes: 1 addition & 1 deletion HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* Added functions `tiledb_subarray_{get_est_result_size, get_est_result_size_var}`.
* Added object `tiledb_subarray_t` and functions `tiledb_subarray_{alloc, free, get_layout, get_type, get_ndim, get_domain, add_range, get_range_num, get_range}`.
* Added function `tiledb_query_get_layout`
* Added datatype `tiledb_buffer_t` and functions `tiledb_buffer_{alloc,free,get_type,set_type,get_size}`.
* Added datatype `tiledb_buffer_t` and functions `tiledb_buffer_{alloc,free,get_type,set_type,get_data,set_data}`.

### C++ API

Expand Down
4 changes: 3 additions & 1 deletion doc/source/c-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,9 @@ Buffer
:project: TileDB-C
.. doxygenfunction:: tiledb_buffer_set_type
:project: TileDB-C
.. doxygenfunction:: tiledb_buffer_get_size
.. doxygenfunction:: tiledb_buffer_get_data
:project: TileDB-C
.. doxygenfunction:: tiledb_buffer_set_data
:project: TileDB-C

Object Management
Expand Down
59 changes: 49 additions & 10 deletions test/src/unit-capi-buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,55 @@ TEST_CASE("C API: Test buffer", "[capi], [buffer]") {
tiledb_buffer_t* buffer;
REQUIRE(tiledb_buffer_alloc(ctx, &buffer) == TILEDB_OK);

uint64_t size = 123;
REQUIRE(tiledb_buffer_get_size(ctx, buffer, &size) == TILEDB_OK);
REQUIRE(size == 0);

tiledb_datatype_t type;
REQUIRE(tiledb_buffer_get_type(ctx, buffer, &type) == TILEDB_OK);
REQUIRE(type == TILEDB_UINT8);
REQUIRE(tiledb_buffer_set_type(ctx, buffer, TILEDB_INT32) == TILEDB_OK);
REQUIRE(tiledb_buffer_get_type(ctx, buffer, &type) == TILEDB_OK);
REQUIRE(type == TILEDB_INT32);
SECTION("- Check size and data pointer") {
void* data;
uint64_t size = 123;
REQUIRE(tiledb_buffer_get_data(ctx, buffer, &data, &size) == TILEDB_OK);
REQUIRE(data == nullptr);
REQUIRE(size == 0);
}

SECTION("- Check get/set datatype") {
tiledb_datatype_t type;
REQUIRE(tiledb_buffer_get_type(ctx, buffer, &type) == TILEDB_OK);
REQUIRE(type == TILEDB_UINT8);
REQUIRE(tiledb_buffer_set_type(ctx, buffer, TILEDB_INT32) == TILEDB_OK);
REQUIRE(tiledb_buffer_get_type(ctx, buffer, &type) == TILEDB_OK);
REQUIRE(type == TILEDB_INT32);
}

SECTION("- Check get/set buffer") {
const unsigned alloc_size = 123;
void* alloc = std::malloc(alloc_size);
REQUIRE(
tiledb_buffer_set_data(ctx, buffer, alloc, alloc_size) == TILEDB_OK);

// Check size/data
void* data;
uint64_t size = 123;
REQUIRE(tiledb_buffer_get_data(ctx, buffer, &data, &size) == TILEDB_OK);
REQUIRE(data == alloc);
REQUIRE(size == alloc_size);

// Check it works to set again
REQUIRE(
tiledb_buffer_set_data(ctx, buffer, alloc, alloc_size) == TILEDB_OK);

// Buffers can alias
tiledb_buffer_t* buffer2;
REQUIRE(tiledb_buffer_alloc(ctx, &buffer2) == TILEDB_OK);
REQUIRE(
tiledb_buffer_set_data(ctx, buffer2, alloc, alloc_size) == TILEDB_OK);
tiledb_buffer_free(&buffer2);

// Check setting to nullptr works
REQUIRE(tiledb_buffer_set_data(ctx, buffer, nullptr, 0) == TILEDB_OK);
REQUIRE(tiledb_buffer_get_data(ctx, buffer, &data, &size) == TILEDB_OK);
REQUIRE(size == 0);
REQUIRE(data == nullptr);

std::free(alloc);
}

tiledb_buffer_free(&buffer);
tiledb_ctx_free(&ctx);
Expand Down
27 changes: 25 additions & 2 deletions tiledb/sm/c_api/tiledb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -567,17 +567,40 @@ int32_t tiledb_buffer_get_type(
return TILEDB_OK;
}

int32_t tiledb_buffer_get_size(
tiledb_ctx_t* ctx, const tiledb_buffer_t* buffer, uint64_t* num_bytes) {
int32_t tiledb_buffer_get_data(
tiledb_ctx_t* ctx,
const tiledb_buffer_t* buffer,
void** data,
uint64_t* num_bytes) {
if (sanity_check(ctx) == TILEDB_ERR ||
sanity_check(ctx, buffer) == TILEDB_ERR)
return TILEDB_ERR;

*data = buffer->buffer_->data();
*num_bytes = buffer->buffer_->size();

return TILEDB_OK;
}

int32_t tiledb_buffer_set_data(
tiledb_ctx_t* ctx, tiledb_buffer_t* buffer, void* data, uint64_t size) {
if (sanity_check(ctx) == TILEDB_ERR ||
sanity_check(ctx, buffer) == TILEDB_ERR)
return TILEDB_ERR;

// Create a temporary Buffer object as a wrapper.
tiledb::sm::Buffer tmp_buffer(data, size, false);

// Swap with the given buffer.
if (SAVE_ERROR_CATCH(ctx, buffer->buffer_->swap(tmp_buffer)))
return TILEDB_ERR;

// 'tmp_buffer' now destructs, freeing the old allocation (if any) of the
// given buffer.

return TILEDB_OK;
}

/* ****************************** */
/* CONFIG */
/* ****************************** */
Expand Down
51 changes: 46 additions & 5 deletions tiledb/sm/c_api/tiledb.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,8 @@ TILEDB_EXPORT int32_t tiledb_buffer_get_type(
tiledb_datatype_t* datatype);

/**
* Gets the current number of bytes in the specified buffer object.
* Gets a pointer to the current allocation and the current number of bytes in
* the specified buffer object.
*
* @note For string buffers allocated by TileDB, the number of bytes includes
* the terminating NULL byte.
Expand All @@ -413,9 +414,10 @@ TILEDB_EXPORT int32_t tiledb_buffer_get_type(
* @code{.c}
* tiledb_buffer_t* buffer;
* tiledb_buffer_alloc(ctx, &buffer);
* void* data;
* uint64_t num_bytes;
* tiledb_buffer_get_size(ctx, buffer, &num_bytes);
* // num_bytes == 0 because the buffer is currently empty.
* tiledb_buffer_get_data(ctx, buffer, &data, num_bytes);
* // data == NULL and num_bytes == 0 because the buffer is currently empty.
* tiledb_buffer_free(&buffer);
* @endcode
*
Expand All @@ -424,8 +426,47 @@ TILEDB_EXPORT int32_t tiledb_buffer_get_type(
* @param num_bytes Set to the number of bytes in the buffer.
* @return `TILEDB_OK` for success or `TILEDB_ERR` for error.
*/
TILEDB_EXPORT int32_t tiledb_buffer_get_size(
tiledb_ctx_t* ctx, const tiledb_buffer_t* buffer, uint64_t* num_bytes);
TILEDB_EXPORT int32_t tiledb_buffer_get_data(
tiledb_ctx_t* ctx,
const tiledb_buffer_t* buffer,
void** data,
uint64_t* num_bytes);

/**
* Sets (wraps) a pre-allocated region of memory with the given buffer object.
* This does not perform a copy.
*
* @note The TileDB buffer object does not take ownership of the allocation
* set with this function. That means the call to `tiledb_buffer_free` will not
* free a user allocation set via `tiledb_buffer_set_buffer`.
*
* **Example:**
*
* @code{.c}
* tiledb_buffer_t* buffer;
* tiledb_buffer_alloc(ctx, &buffer);
*
* void* my_data = malloc(100);
* tiledb_buffer_set_data(ctx, buffer, my_data, 100);
*
* void* data;
* uint64_t num_bytes;
* tiledb_buffer_get_data(ctx, buffer, &data, num_bytes);
* assert(data == my_data);
* assert(num_bytes == 100);
*
* tiledb_buffer_free(&buffer);
* free(my_data);
* @endcode
*
* @param ctx TileDB context
* @param buffer TileDB buffer instance
* @param data Pre-allocated region of memory to wrap with this buffer.
* @param size Size (in bytes) of the region pointed to by data.
* @return `TILEDB_OK` for success or `TILEDB_ERR` for error.
*/
TILEDB_EXPORT int32_t tiledb_buffer_set_data(
tiledb_ctx_t* ctx, tiledb_buffer_t* buffer, void* data, uint64_t size);

/* ********************************* */
/* CONFIG */
Expand Down

0 comments on commit ea8fbd6

Please sign in to comment.