Quickstart

This page contains a quick tutorial on how to use TileDB to create, write to, and read from a dense and a sparse array. You need to first install TileDB with your favorite API.

Dense Array

First, let’s create a simple 4x4 dense array, i.e., with two dimensions (called d1 and d2), each with domain [1,4]. This array has a single int32 attribute, i.e., it will store integer values in its cells.

C
C++
Python
R
Java
Go
#include <tiledb/tiledb.h>
// Name of array.
const char* array_name = "quickstart_dense_array";
void create_array() {
// Create context
tiledb_ctx_t* ctx;
tiledb_ctx_alloc(NULL, &ctx);
// Create dimensions
int dim_domain[] = {1, 4};
int tile_extent = 4;
tiledb_dimension_t *d1, *d2;
tiledb_dimension_alloc(ctx, "d1", TILEDB_INT32, &dim_domain[0], &tile_extent, &d1);
tiledb_dimension_alloc(ctx, "d2", TILEDB_INT32, &dim_domain[0], &tile_extent, &d2);
// Create domain
tiledb_domain_t* domain;
tiledb_domain_alloc(ctx, &domain);
tiledb_domain_add_dimension(ctx, domain, d1);
tiledb_domain_add_dimension(ctx, domain, d2);
// Create attribute
tiledb_attribute_t* a;
tiledb_attribute_alloc(ctx, "a", TILEDB_INT32, &a);
// Create array schema for a dense array.
// Also add domain and attribute and set tile and cell order to row-major
tiledb_array_schema_t* schema;
tiledb_array_schema_alloc(ctx, TILEDB_DENSE, &schema);
tiledb_array_schema_set_domain(ctx, schema, domain);
tiledb_array_schema_add_attribute(ctx, schema, a);
tiledb_array_schema_set_tile_order(ctx, schema, TILEDB_ROW_MAJOR);
tiledb_array_schema_set_cell_order(ctx, schema, TILEDB_ROW_MAJOR);
// Create the (empty) array on disk.
tiledb_array_create(ctx, array_name, schema);
// Clean up
tiledb_dimension_free(&d1);
tiledb_dimension_free(&d2);
tiledb_domain_free(&domain);
tiledb_attribute_free(&a);
tiledb_array_schema_free(&schema);
tiledb_ctx_free(&ctx);
}
#include <tiledb/tiledb>
// Name of array.
std::string array_name("quickstart_dense_array");
void create_array() {
// Create a TileDB context.
Context ctx;
// The array will be 4x4 with dimensions "d1" and "d2", with domain [1,4].
Domain domain(ctx);
domain.add_dimension(Dimension::create<int>(ctx, "d1", {{1, 4}}, 4))
.add_dimension(Dimension::create<int>(ctx, "d2", {{1, 4}}, 4));
// The array will be dense.
ArraySchema schema(ctx, TILEDB_DENSE);
schema.set_domain(domain)
.set_order({{TILEDB_ROW_MAJOR, TILEDB_ROW_MAJOR}});
// Add a single attribute "a" so each (i,j) cell can store an integer.
schema.add_attribute(Attribute::create<int>(ctx, "a"));
// Create the (empty) array on disk.
Array::create(array_name, schema);
}
import numpy as np
import sys
import tiledb
# Name of array.
array_name = "quickstart_dense"
def create_array():
# The array will be 4x4 with dimensions "d1" and "d2", with domain [1,4].
dom = tiledb.Domain(tiledb.Dim(name="d1", domain=(1, 4), tile=4, dtype=np.int32),
tiledb.Dim(name="d2", domain=(1, 4), tile=4, dtype=np.int32))
# The array will be dense with a single attribute "a" so each (i,j) cell can store an integer.
schema = tiledb.ArraySchema(domain=dom, sparse=False,
attrs=[tiledb.Attr(name="a", dtype=np.int32)])
# Create the (empty) array on disk.
tiledb.DenseArray.create(array_name, schema)
library(tiledb)
# Name of array.
array_name = "quickstart_dense"
create_array <- function() {
# Create a TileDB context
ctx <- tiledb_ctx()
# Check if the array already exists.
if (tiledb_object_type(array_name, ctx=ctx) == "ARRAY") {
stop("Array already exists.")
quit(0)
}
# The array will be 4x4 with dimensions "d1" and "d2", with domain [1,4].
dom <- tiledb_domain(
dims = c(tiledb_dim("d1", c(1L, 4L), 4L, "INT32", ctx=ctx),
tiledb_dim("d2", c(1L, 4L), 4L, "INT32", ctx=ctx)), ctx=ctx)
# The array will be dense with a single attribute "a" so each (i,j) cell can store an integer.
schema <- tiledb_array_schema(
dom, attrs = c(tiledb_attr("a", type = "INT32", ctx=ctx)), ctx=ctx)
# Create the (empty) array on disk.
tiledb_array_create(array_name, schema)
}
package io.tiledb.java.api;
String array_name = "quickstart_dense";
public void createArray() throws Exception {
// Create context
Context ctx = new Context();;
// Create dimensions
Dimension<Integer> d1 =
new Dimension<Integer>(ctx, "d1", Integer.class, new Pair<Integer, Integer>(1, 4), 4);
Dimension<Integer> d2 =
new Dimension<Integer>(ctx, "d2", Integer.class, new Pair<Integer, Integer>(1, 4), 4);
// Create domain
Domain domain = new Domain(ctx);
domain.addDimension(d1);
domain.addDimension(d2);
// Create attribute
Attribute a = new Attribute(ctx, "a", Integer.class);
// Create schema
ArraySchema schema = new ArraySchema(ctx, TILEDB_DENSE);
schema.setDomain(domain);
schema.addAttribute(a);
Array.create(array_name, schema);
}
import (
"fmt"
"os"
"github.com/TileDB-Inc/TileDB-Go"
)
// Name of array.
var array_name = "quickstart_dense"
func createArray() {
// Create a TileDB context.
ctx, _ := tiledb.NewContext(nil)
// The array will be 4x4 with dimensions "d1" and "d2", with domain [1,4].
domain, _ := tiledb.NewDomain(ctx)
d1, _ := tiledb.NewDimension(ctx, "rows", []int32{1, 4}, int32(4))
d2, _ := tiledb.NewDimension(ctx, "cols", []int32{1, 4}, int32(4))
domain.AddDimensions(d1, d2)
// The array will be dense.
schema, _ := tiledb.NewArraySchema(ctx, tiledb.TILEDB_DENSE)
schema.SetDomain(domain)
schema.SetCellOrder(tiledb.TILEDB_ROW_MAJOR)
schema.SetTileOrder(tiledb.TILEDB_ROW_MAJOR)
// Add a single attribute "a" so each (i,j) cell can store an integer.
a, _ := tiledb.NewAttribute(ctx, "a", tiledb.TILEDB_INT32)
schema.AddAttributes(a)
// Create the (empty) array on disk.
array, _ := tiledb.NewArray(ctx, array_name)
array.Create(schema)
}

Next, we populate the array by writing some values to its cells, specifically 1, 2, …, 16 in a row-major layout (i.e., the columns of the first row will be populated first, then those of the second row, etc.).

C
C++
Python
R
Java
Go
void write_array() {
// 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
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
uint64_t data_size = sizeof(data);
// Create the query
tiledb_query_t* query;
tiledb_query_alloc(ctx, array, TILEDB_WRITE, &query);
tiledb_query_set_layout(ctx, query, TILEDB_ROW_MAJOR);
tiledb_query_set_buffer(ctx, query, "a", 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);
}
void write_array() {
Context ctx;
// Prepare some data for the array
std::vector<int> data = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
// Open the array for writing and create the query.
Array array(ctx, array_name, TILEDB_WRITE);
Query query(ctx, array);
query.set_layout(TILEDB_ROW_MAJOR)
.set_buffer("a", data);
// Perform the write and close the array.
query.submit();
array.close();
}
def write_array():
# Open the array and write to it.
with tiledb.DenseArray(array_name, mode='w') as A:
data = np.array(([1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]))
A[:] = data
write_array <- function() {
data <- array(c(c(1L, 5L, 9L, 13L),
c(2L, 6L, 10L, 14L),
c(3L, 7L, 11L, 15L),
c(4L, 8L, 12L, 16L)), dim = c(4,4))
# Open the array and write to it.
ctx <- tiledb_ctx()
A <- tiledb_dense(uri = array_name, ctx=ctx)
A[] <- data
}
public void writeArray() throws Exception {
// Create context
Context ctx = new Context();;
Array array = new Array(ctx, array_name, TILEDB_WRITE);
// Prepare cell buffers
NativeArray a_data =
new NativeArray(
ctx,
new int[] {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15
},
Integer.class);
// Create query
try (Query query = new Query(array, TILEDB_WRITE)) {
query
.setLayout(TILEDB_ROW_MAJOR)
.setBuffer("a", a_data);
// Submit query
query.submit();
}
}
func writeArray() {
ctx, _ := tiledb.NewContext(nil)
// Prepare some data for the array
data := []int32{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
// Open the array for writing and create the query.
array, _ := tiledb.NewArray(ctx, array_name)
array.Open(tiledb.TILEDB_WRITE)
query, _ := tiledb.NewQuery(ctx, array)
query.SetLayout(tiledb.TILEDB_ROW_MAJOR)
query.SetBuffer("a", data)
// Perform the write and close the array.
query.Submit()
array.Close()
}

The resulting array is depicted in the figure below. Finally, we will read a portion of the array (called slicing or subarray query) and simply output the contents of the selected cells on the screen. Suppose we wish to read subarray [1,2], [2,4], i.e., focus on the cells in rows 1, 2 and columns 2, 3, 4.

A 4x4 dense array, highlighting subarray [1:2, 2:4]
C
C++
Python
R
Java
Go
void read_array() {
// Create TileDB context
tiledb_ctx_t* ctx;
tiledb_ctx_alloc(NULL, &ctx);
// Open array for reading
tiledb_array_t* array;
tiledb_array_alloc(ctx, array_name, &array);
tiledb_array_open(ctx, array, TILEDB_READ);
// Slice only rows 1, 2 and cols 2, 3, 4
int subarray[] = {1, 2, 2, 4};
// Prepare the vector that will hold the result (of size 6 elements)
int data[6];
uint64_t data_size = sizeof(data);
// Create query
tiledb_query_t* query;
tiledb_query_alloc(ctx, array, TILEDB_READ, &query);
tiledb_query_set_subarray(ctx, query, subarray);
tiledb_query_set_layout(ctx, query, TILEDB_ROW_MAJOR);
tiledb_query_set_buffer(ctx, query, "a", data, &data_size);
// Submit query
tiledb_query_submit(ctx, query);
// Close array
tiledb_array_close(ctx, array);
// Print out the results.
for (int i = 0; i < 6; ++i)
printf("%d ", data[i]);
printf("\n");
// Clean up
tiledb_array_free(&array);
tiledb_query_free(&query);
tiledb_ctx_free(&ctx);
}
void read_array() {
Context ctx;
// Prepare the array for reading
Array array(ctx, array_name, TILEDB_READ);
// Slice only rows 1, 2 and cols 2, 3, 4
const std::vector<int> subarray = {1, 2, 2, 4};
// Prepare the vector that will hold the result (of size 6 elements)
std::vector<int> data(6);
// Prepare the query
Query query(ctx, array);
query.set_subarray(subarray)
.set_layout(TILEDB_ROW_MAJOR)
.set_buffer("a", data);
// Submit the query and close the array.
query.submit();
array.close();
// Print out the results.
for (auto d : data)
std::cout << d << " ";
std::cout << "\n";
}
def read_array():
# Open the array and read from it.
with tiledb.DenseArray(array_name, mode='r') as A:
# Slice only rows 1, 2 and cols 2, 3, 4.
data = A[1:3, 2:5]
print(data["a"])
read_array <- function() {
ctx = tiledb_ctx()
# Open the array and read from it.
A <- tiledb_dense(uri = array_name, ctx=ctx)
data <- A[1:2, 2:4]
show(data)
}
public void readArray() throws Exception {
// Create context
Context ctx = new Context();
Array array = new Array(ctx, array_name);
// Slice only rows 1, 2 and cols 2, 3, 4
NativeArray subarray = new NativeArray(ctx, new int[] {1, 2, 2, 4}, Integer.class);
// Create query
Query query = new Query(array, TILEDB_READ);
query.setLayout(TILEDB_ROW_MAJOR);
query.setSubarray(subarray);
query.setBuffer("a", new NativeArray(ctx, 10, Integer.class));
// Submit query
query.submit();
// Print cell values
HashMap<String, Pair<Long, Long>> result_el = query.resultBufferElements();
int[] a_buff = (int[]) query.getBuffer("a");
for (int res : a_buff) {
System.out.println(res);
}
}
func readArray() {
ctx, _ := tiledb.NewContext(nil)
// Prepare the array for reading
array, _ := tiledb.NewArray(ctx, array_name)
array.Open(tiledb.TILEDB_READ)
// Slice only rows 1, 2 and cols 2, 3, 4
subarray := []int32{1, 2, 2, 4}
// Prepare the vector that will hold the result (of size 6 elements)
data := make([]int32, 6)
// Prepare the query
query, _ := tiledb.NewQuery(ctx, array)
query.SetSubArray(subarray)
query.SetLayout(tiledb.TILEDB_ROW_MAJOR)
query.SetBuffer("a", data)
// Submit the query and close the array.
query.Submit()
array.Close()
// Print out the results.
fmt.Println(data)
}

If you run the example, you should see as output 2 3 4 6 7 8, reading again in row-major order (i.e., first the three selected columns of row 1, then the three selected columns of row 2).

Sparse Array

First, let’s create a simple 4x4 sparse array, i.e., with two dimensions (called d1 and d2), each with domain [1,4]. This array has a single int32 attribute, i.e., it will store integer values in its cells.

C
C++
Python
R
Java
Go
#include <tiledb/tiledb.h>
// Name of array.
const char* array_name = "quickstart_sparse_array";
void create_array() {
// Create TileDB context
tiledb_ctx_t* ctx;
tiledb_ctx_alloc(NULL, &ctx);
// The array will be 4x4 with dimensions "d1" and "d2", with domain [1,4].
int dim_domain[] = {1, 4, 1, 4};
int tile_extents[] = {4, 4};
tiledb_dimension_t *d1, *d2;
tiledb_dimension_alloc(
ctx, "d1", TILEDB_INT32, &dim_domain[0], &tile_extents[0], &d1);
tiledb_dimension_alloc(
ctx, "d2", TILEDB_INT32, &dim_domain[2], &tile_extents[1], &d2);
// Create domain
tiledb_domain_t* domain;
tiledb_domain_alloc(ctx, &domain);
tiledb_domain_add_dimension(ctx, domain, d1);
tiledb_domain_add_dimension(ctx, domain, d2);
// Create a single attribute "a" so each (i,j) cell can store an integer
tiledb_attribute_t* a;
tiledb_attribute_alloc(ctx, "a", TILEDB_INT32, &a);
// Create array schema
tiledb_array_schema_t* array_schema;
tiledb_array_schema_alloc(ctx, TILEDB_SPARSE, &array_schema);
tiledb_array_schema_set_cell_order(ctx, array_schema, TILEDB_ROW_MAJOR);
tiledb_array_schema_set_tile_order(ctx, array_schema, TILEDB_ROW_MAJOR);
tiledb_array_schema_set_domain(ctx, array_schema, domain);
tiledb_array_schema_add_attribute(ctx, array_schema, a);
// Create array
tiledb_array_create(ctx, array_name, array_schema);
// Clean up
tiledb_attribute_free(&a);
tiledb_dimension_free(&d1);
tiledb_dimension_free(&d2);
tiledb_domain_free(&domain);
tiledb_array_schema_free(&array_schema);
tiledb_ctx_free(&ctx);
}
#include <tiledb/tiledb>
// Name of array.
std::string array_name("quickstart_sparse_array");
void create_array() {
// Create a TileDB context.
Context ctx;
// The array will be 4x4 with dimensions "d1" and "d2", with domain [1,4].
Domain domain(ctx);
domain.add_dimension(Dimension::create<int>(ctx, "d1", {{1, 4}}, 4))
.add_dimension(Dimension::create<int>(ctx, "d2", {{1, 4}}, 4));
// The array will be sparse.
ArraySchema schema(ctx, TILEDB_SPARSE);
schema.set_domain(domain).set_order({{TILEDB_ROW_MAJOR, TILEDB_ROW_MAJOR}});
// Add a single attribute "a" so each (i,j) cell can store an integer.
schema.add_attribute(Attribute::create<int>(ctx, "a"));
// Create the (empty) array on disk.
Array::create(array_name, schema);
}
import numpy as np
import sys
import tiledb
# Name of the array to create.
array_name = "quickstart_sparse"
def create_array():
# The array will be 4x4 with dimensions "d1" and "d2", with domain [1,4].
dom = tiledb.Domain(tiledb.Dim(name="d1", domain=(1, 4), tile=4, dtype=np.int32),
tiledb.Dim(name="d2", domain=(1, 4), tile=4, dtype=np.int32))
# The array will be sparse with a single attribute "a" so each (i,j) cell can store an integer.
schema = tiledb.ArraySchema(domain=dom, sparse=True,
attrs=[tiledb.Attr(name="a", dtype=np.int32)])
# Create the (empty) array on disk.
tiledb.SparseArray.create(array_name, schema)
library(tiledb)
# Name of the array to create.
array_name = "quickstart_sparse"
create_array <- function() {
# Create a TileDB context
ctx <- tiledb_ctx()
# Check if the array already exists.
if (tiledb_object_type(array_name, ctx=ctx) == "ARRAY") {
stop("Array already exists.")
quit(0)
}
# The array will be 4x4 with dimensions "d1" and "d2", with domain [1,4].
dom <- tiledb_domain(
dims = c(tiledb_dim("d1", c(1L, 4L), 4L, "INT32", ctx=ctx),
tiledb_dim("d2", c(1L, 4L), 4L, "INT32", ctx=ctx)), ctx=ctx)
# The array will be dense with a single attribute "a" so each (i,j) cell can store an integer.
schema = tiledb_array_schema(
dom, attrs=c(tiledb_attr("a", type = "INT32", ctx=ctx)),
sparse = TRUE, ctx=ctx)
# Create the (empty) array on disk.
tiledb_array_create(array_name, schema)
}
package io.tiledb.java.api;
String array_name = "quickstart_sparse";
public void createArray() throws Exception {
// Create context
Context ctx = new Context();
// Create dimensions
Dimension<Integer> d1 =
new Dimension<Integer>(ctx, "d1", Integer.class, new Pair<Integer, Integer>(1, 4), 4);
Dimension<Integer> d2 =
new Dimension<Integer>(ctx, "d2", Integer.class, new Pair<Integer, Integer>(1, 4), 4);
// Create domain
Domain domain = new Domain(ctx);
domain.addDimension(d1);
domain.addDimension(d2);
// Create attributes
Attribute a = new Attribute(ctx, "a", Integer.class);
// Create array schema
ArraySchema schema = new ArraySchema(ctx, TILEDB_SPARSE);
schema.setTileOrder(TILEDB_ROW_MAJOR);
schema.setCellOrder(TILEDB_ROW_MAJOR);
schema.setDomain(domain);
schema.addAttribute(a);
// Create array
Array.create(array_name, schema);
}
import (
"fmt"
tiledb "github.com/TileDB-Inc/TileDB-Go"
"os"
)
// Name of array.
var array_name = "quickstart_sparse"
func createArray() {
// Create a TileDB context.
ctx, _ := tiledb.NewContext(nil)
// The array will be 4x4 with dimensions "d1" and "d2" with domain [1,4].
domain, _ := tiledb.NewDomain(ctx)
d1, _ := tiledb.NewDimension(ctx, "d1", []int32{1, 4}, int32(4))
d2, _ := tiledb.NewDimension(ctx, "d2", []int32{1, 4}, int32(4))
domain.AddDimensions(d1, d2)
// The array will be sparse.
schema, _ := tiledb.NewArraySchema(ctx, tiledb.TILEDB_SPARSE)
schema.SetDomain(domain)
schema.SetCellOrder(tiledb.TILEDB_ROW_MAJOR)
schema.SetTileOrder(tiledb.TILEDB_ROW_MAJOR)
// Add a single attribute "a" so each (i,j) cell can store an integer.
a, _ := tiledb.NewAttribute(ctx, "a", tiledb.TILEDB_UINT32)
schema.AddAttributes(a)
// Create the (empty) array on disk.
array, _ := tiledb.NewArray(ctx, array_name)
array.Create(schema)
}

Next we populate the array by writing some values to its cells, specifically 1, 2, and 3 at cells (1,1), (2,4) and (2,3), respectively. Notice that, contrary to the dense case, here we specify the exact indices where the values will be written, i.e., we provide the cell coordinates. Do not worry about the “unordered” query layout for now, just know that it is important.

C
C++
Python
R
Java
Go
void write_array() {
// 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);
// Write some simple data to cells (1, 1), (2, 4) and (2, 3).
int coords[] = {1, 1, 2, 4, 2, 3};
uint64_t coords_size = sizeof(coords);
int data[] = {1, 2, 3};
uint64_t data_size = sizeof(data);
// 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, "a", data, &data_size);
tiledb_query_set_buffer(ctx, query, TILEDB_COORDS, coords, &coords_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);
}
void write_array() {
Context ctx;
// Write some simple data to cells (1, 1), (2, 4) and (2, 3).
std::vector<int> coords = {1, 1, 2, 4, 2, 3};
std::vector<int> data = {1, 2, 3};
// Open the array for writing and create the query.
Array array(ctx, array_name, TILEDB_WRITE);
Query query(ctx, array);
query.set_layout(TILEDB_UNORDERED)
.set_buffer("a", data)
.set_coordinates(coords);
// Perform the write and close the array.
query.submit();
array.close();
}
def write_array():
# Open the array and write to it.
with tiledb.SparseArray(array_name, mode='w') as A:
# Write some simple data to cells (1, 1), (2, 4) and (2, 3).
I, J = [1, 2, 2], [1, 4, 3]
data = np.array(([1, 2, 3]))
A[I, J] = data
write_array <- function() {
I <- c(1, 2, 2)
J <- c(1, 4, 3)
data <- c(1L, 2L, 3L)
# Open the array and write to it.
ctx <- tiledb_ctx()
A <- tiledb_sparse(uri = array_name, ctx=ctx)
A[I, J] <- data
}
public void writeArray() throws Exception {
// Create context
Context ctx = new Context();
// Prepare cell buffers
NativeArray a_data =
new NativeArray(ctx, new int[] {0, 1, 2, 3, 4, 5, 6, 7}, Integer.class);
NativeArray coords_data =
new NativeArray(ctx, new int[] {1, 1, 1, 2, 1, 4, 2, 3, 3, 1, 4, 2, 3, 3, 3, 4}, Integer.class);
// Create query
Array array = new Array(ctx, array_name, TILEDB_WRITE);
Query query = new Query(array);
query.setLayout(TILEDB_UNORDERED);
query.setBuffer("a", a_data);
query.setCoordinates(coords_data);
// Submit query
query.submit();
query.close();
}
func writeArray() {
ctx, _ := tiledb.NewContext(nil)
// Write some simple data to cells (1, 1), (2, 4) and (2, 3).
coords := []int32{1, 1, 2, 4, 2, 3}
data := []uint32{1, 2, 3}
// Open the array for writing and create the query.
array, _ := tiledb.NewArray(ctx, array_name)
array.Open(tiledb.TILEDB_WRITE)
query, _ := tiledb.NewQuery(ctx, array)
query.SetLayout(tiledb.TILEDB_UNORDERED)
query.SetBuffer("a", data)
query.SetCoordinates(coords)
// Perform the write and close the array.
query.Submit()
array.Close()
}

The resulting array is depicted in the figure below. Similar to the dense array example, we read subarray [1,2], [2,4], i.e., focus on the cells in rows 1, 2 and columns 2, 3, 4. The result values should be 3 for cell (2,3) and 2 for cell (2,4) reading again in row-major order.

A 4x4 sparse array, highlighting subarray [1:2,2:4]
C
C++
Python
R
Java
Go
void read_array() {
// Create TileDB context
tiledb_ctx_t* ctx;
tiledb_ctx_alloc(NULL, &ctx);
// Open array for reading
tiledb_array_t* array;
tiledb_array_alloc(ctx, array_name, &array);
tiledb_array_open(ctx, array, TILEDB_READ);
// Slice only rows 1, 2 and cols 2, 3, 4
int subarray[] = {1, 2, 2, 4};
// Make enough space for your buffers
uint64_t coords_size = 10 * sizeof(int);
uint64_t data_size = 10 * sizeof(int);
int* coords = (int*)malloc(coords_size);
int* data = (int*)malloc(data_size);
// Create query
tiledb_query_t* query;
tiledb_query_alloc(ctx, array, TILEDB_READ, &query);
tiledb_query_set_subarray(ctx, query, subarray);
tiledb_query_set_layout(ctx, query, TILEDB_ROW_MAJOR);
tiledb_query_set_buffer(ctx, query, "a", data, &data_size);
tiledb_query_set_buffer(ctx, query, TILEDB_COORDS, coords, &coords_size);
// Submit query
tiledb_query_submit(ctx, query);
// Close array
tiledb_array_close(ctx, array);
// Print out the results.
int result_num = (int)(data_size / sizeof(int));
for (int r = 0; r < result_num; r++) {
int i = coords[2 * r], j = coords[2 * r + 1];
int a = data[r];
printf("Cell (%d, %d) has data %d\n", i, j, a);
}
// Clean up
free((void*)coords);
free((void*)data);
tiledb_array_free(&array);
tiledb_query_free(&query);
tiledb_ctx_free(&ctx);
}
void read_array() {
Context ctx;
// Prepare the array for reading
Array array(ctx, array_name, TILEDB_READ);
// Slice only rows 1, 2 and cols 2, 3, 4
const std::vector<int> subarray = {1, 2, 2, 4};
// Make sure to allocated enough space for your buffers.
std::vector<int> data(10);
std::vector<int> coords(10);
// Prepare the query
Query query(ctx, array);
query.set_subarray(subarray)
.set_layout(TILEDB_ROW_MAJOR)
.set_buffer("a", data)
.set_coordinates(coords);
// Submit the query and close the array.
query.submit();
array.close();
// Print out the results.
auto result_num = (int) query.result_buffer_elements()["a"].second;
for (int r = 0; r < result_num; r++) {
int i = coords[2 * r], j = coords[2 * r + 1];
int a = data[r];
std::cout << "Cell (" << i << "," << j << ") has data " << a << "\n";
}
}
def read_array():
# Open the array and read from it.
with tiledb.SparseArray(array_name, mode='r') as A:
# Slice only rows 1, 2 and cols 2, 3, 4.
data = A[1:3, 2:5]
a_vals = data["a"]
for i, coord in enumerate(data["coords"]):
print("Cell (%d, %d) has data %d" % (coord[0], coord[1], a_vals[i]))
read_array <- function() {
ctx <- tiledb_ctx()
# Open the array and read from it.
A <- tiledb_sparse(uri = array_name, ctx=ctx)
data <- A[1:2, 2:4]
coords <- data[["coords"]]
a_vals <- data[["a"]]
for (idx in seq_along(a_vals)) {
i <- coords[((idx - 1) * 2) + 1]
j <- coords[((idx - 1) * 2) + 2]
cat(sprintf("Cell (%d,%d) has data %d\n", i, j, a_vals[idx]))
}
}
private void readArray() throws Exception {
// Create context
Context ctx = new Context();
Array array = new Array(ctx, array_name, TILEDB_READ);
// Slice only rows 1, 2 and cols 2, 3, 4
NativeArray subarray = new NativeArray(ctx, new int[] {1, 2, 2, 4}, Integer.class);
// Create query
Query query = new Query(array, TILEDB_READ);
query.setLayout(TILEDB_ROW_MAJOR);
query.setSubarray(subarray);
query.setBuffer("a", new NativeArray(ctx, 10, Integer.class));
query.setCoordinates(new NativeArray(ctx, 20, Integer.class));
// Submit query
query.submit();
// Print cell values
HashMap<String, Pair<Long, Long>> result_el = query.resultBufferElements();
int[] a_buff = (int[]) query.getBuffer("a");
int[] coords = (int[]) query.getBuffer(TILEDB_COORDS);
for (int r = 0; r < result_num; r++) {
int i = coords[2 * r], j = coords[2 * r + 1];
int a = data[r];
System.out.printf("Cell (%d, %d) has data %d\n", i, j, a);
}
}
func readArray() {
ctx, _ := tiledb.NewContext(nil)
// Prepare the array for reading
array, _ := tiledb.NewArray(ctx, array_name)
array.Open(tiledb.TILEDB_READ)
// Slice only rows 1, 2 and cols 2, 3, 4
subarray := []int32{1, 2, 2, 4}
// Create buffers for the results
data := make([]uint32, 10)
coords := make([]int32, 20)
// Prepare the query
query, _ := tiledb.NewQuery(ctx, array)
query.SetSubArray(subarray)
query.SetLayout(tiledb.TILEDB_ROW_MAJOR)
query.SetBuffer("a", data)
query.SetCoordinates(coords)
// Submit the query and close the array.
query.Submit()
// Print out the results.
elements, _ := query.ResultBufferElements()
resultNum := elements["a"][1]
for r := 0; r < int(resultNum); r++ {