Var-length Attributes

Writing variable-length attribute values to an array involves passing two buffers to TileDB, one for the variable-length cell values and one for the starting offset of each value in the first buffer. We illustrate this in the code block below with a sparse write, but it is also applicable to dense writes.

C
C++
Python
R
Java
Go
C
#include <tiledb/tiledb.h>
// Create TileDB context
tiledb_ctx_t* ctx;
tiledb_ctx_alloc(NULL, &ctx);
// Open array for writing
tiledb_array_t* array;
tiledb_array_alloc(ctx, array_name, &array);
tiledb_array_open(ctx, array, TILEDB_WRITE);
// Prepare some data for the array
long long coords[] = {1, 2, 2, 1, 3, 3, 4, 4};
unsigned long long coords_size = sizeof(coords);
int data[] = {1, 1, 2, 3, 3, 3, 4};
unsigned long long data_size = sizeof(data);
unsigned long long data_off[] = {0, 8, 12, 24};
unsigned long long data_off_size = sizeof(data_off);
// Create the query
tiledb_query_t* query;
tiledb_query_alloc(ctx, array, TILEDB_WRITE, &query);
tiledb_query_set_layout(ctx, query, TILEDB_UNORDERED);
tiledb_query_set_buffer(ctx, query, TILEDB_COORDS, coords, &coords_size);
tiledb_query_set_buffer_var(ctx, query, "a", data_off, data_off_size, data, &data_size);
// Submit query
tiledb_query_submit(ctx, query);
// Close array
tiledb_array_close(ctx, array);
// Clean up
tiledb_array_free(&array);
tiledb_query_free(&query);
tiledb_ctx_free(&ctx);
C++
#include <tiledb/tiledb>
// Creatre context
Context ctx;
// Prepare some data for the array
std::vector<int64_t> d1 = {1, 2, 3, 4};
std::vector<int64_t> d2 = {2, 1, 3, 4};
std::vector<int32_t> data = {1, 1, 2, 3, 3, 3, 4};
std::vector<uint64_t> data_off = {0, 8, 12, 24};
// Open array for writing
Array array(ctx, array_name, TILEDB_WRITE);
// Create the query
Query query(ctx, array);
query.set_layout(TILEDB_UNORDERED)
.set_buffer("d1", d1)
.set_buffer("d2", d2)
.set_buffer("a", data_off, data);
// Submit query
query.submit();
// Close the array
array.close();
Python
import tiledb
import numpy as np
# note: the Attribute must be created with `var=True`
# att = tiledb.Attr(dtype=dtype, var=True, ctx=ctx)
c1 = np.array([1,2,3,4])
c2 = np.array([2,1,3,2])
data = np.array([
np.array([1,1], dtype=np.int32),
np.array([2], dtype=np.int32),
np.array([3,3,3], dtype=np.int32),
np.array([4], dtype=np.int32)
], dtype='O')
with tiledb.SparseArray(array_name, 'w') as A:
A[c1, c2] = data
R
## Define the array
d1 <- tiledb_dim("d1", domain = c(1L, 10L))
d2 <- tiledb_dim("d2", domain = c(1L, 10L))
dom <- tiledb_domain(c(d1, d2))
attr <- tiledb_attr("a", type = "INT32")
## set to two values per cell
tiledb:::libtiledb_attribute_set_cell_val_num(attr@ptr, NA)
sch <- tiledb_array_schema(dom, attr, sparse=TRUE)
res <- tiledb_array_create(tmp, sch)
arrptr <- tiledb:::libtiledb_array_open(ctx@ptr, tmp, "WRITE")
d1 <- c(1L, 2L, 3L, 4L)
d2 <- c(2L, 1L, 3L, 4L)
data <- c(1L, 1L, 2L, 3L, 3L, 3L, 4L)
data_off <- c(0, 8, 12, 24)
qryptr <- tiledb:::libtiledb_query(ctx@ptr, arrptr, "WRITE")
qryptr <- tiledb:::libtiledb_query_set_layout(qryptr, "UNORDERED")
vecptr <- tiledb:::libtiledb_query_buffer_var_vec_create(data_off, data)
qryptr <- tiledb:::libtiledb_query_set_buffer_var_vec(qryptr, "a", vecptr)
qryptr <- tiledb:::libtiledb_query_set_buffer(qryptr, "d1", d1)
qryptr <- tiledb:::libtiledb_query_set_buffer(qryptr, "d2", d2)
qryptr <- tiledb:::libtiledb_query_submit(qryptr)
res <- tiledb:::libtiledb_array_close(arrptr)
#TODO Higher-level R support
Java
// Create context, array and query
try(Context ctx = new Context(),
Array array = new Array(ctx, array_name, TILEDB_WRITE),
Query query = new Query(ctx, array);) {
// Prepare some data for the array
NativeArray coords = new NativeArray(ctx, new long[] {1l, 2l, 2l, 1l, 3l, 3l, 4l, 4l}, Long.class);
NativeArray data_off =
new NativeArray(ctx, new long[] {0l, 8l, 12l, 24l}, Long.class);
NativeArray data = new NativeArray(ctx, new int[] {1, 1, 2, 3, 3, 3, 4}, Integer.class);
// Create the query
query.setLayout(TILEDB_ROW_MAJOR)
.setCoords(coords)
.setBuffer("a", data_off, data);
// Submit query
query.submit();
}
Go
import "github.com/TileDB-Inc/TileDB-Go"
// Create context
ctx, _ := tiledb.NewContext(nil)
// Prepare some data for the array
buffD1 := []int32{1, 2, 3, 4}
buffD2 := []int32{2, 1, 3, 4}
data := []int32{1, 1, 2, 3, 3, 3, 4}
data_off := []uint64{0, 8, 12, 24}
// Open array for writing
array, _ := tiledb.NewArray(ctx, array_name)
array.Open(tiledb.TILEDB_WRITE)
// Create the query
query, _ := tiledb.NewQuery(ctx, array)
query.SetLayout(tiledb.TILEDB_ROW_MAJOR)
_, err = query.SetBuffer("d1", buffD1)
_, err = query.SetBuffer("d2", buffD2)
query.SetBufferVar("a", data_off, data)
// Submit query
query.Submit();
// Close the array
array.Close();