Every verb takes one argument struct, initialized by designator, so every field left out keeps its default.
Every struct opens in the same order: the handle, executor, outcome, then completion; inputs follow, then outputs and the arena they land in, then knobs, and last progress and stats.
Structs carry no size or version field, so they grow source-compatibly only, and the major version changes whenever one does.
#include <stdio.h> // For printing.
#include <usearch/usearch.h> // For the win 🚀
int main(void) {
usearch_outcome_t outcome = {0};
usearch_executor_t executor = NULL;
usearch_arena_t arena = NULL;
usearch_dense_index_t index = NULL;
usearch_key_t keys[2] = {{.bytes[15] = 1}, {.bytes[15] = 2}};
float vectors[2][128] = {{0}};
usearch_matches_view_t matches = {0};
// Threads live in the executor, the data lives in the index, and outputs land in the arena.
usearch_executor_for_ram(&(usearch_executor_for_ram_t) {.executor = &executor, .outcome = &outcome});
if (outcome.status != usearch_status_success_k) goto cleanup;
usearch_arena_init(&(usearch_arena_init_t) {.arena = &arena, .executor = executor, .outcome = &outcome});
if (outcome.status != usearch_status_success_k) goto cleanup;
usearch_dense_init_ram(&(usearch_dense_init_ram_t) {.index = &index,
.outcome = &outcome,
.metric = usearch_dense_metric_angular_k,
.quantization = usearch_scalar_bf16_k,
.dimensions = 128});
if (outcome.status != usearch_status_success_k) goto cleanup;
// Populate:
usearch_dense_insert(
&(usearch_dense_insert_t) {.index = index,
.executor = executor,
.outcome = &outcome,
.count = 2,
.keys = {keys, sizeof(usearch_key_t)},
.vectors = {vectors, sizeof(vectors[0]), 128, usearch_scalar_f32_k}});
if (outcome.status != usearch_status_success_k) goto cleanup;
// Search one query; a zero stride would repeat it across a larger `count`.
usearch_dense_search(&(usearch_dense_search_t) {.index = index,
.executor = executor,
.outcome = &outcome,
.count = 1,
.queries = {vectors[0], 0, 128, usearch_scalar_f32_k},
.matches = &matches,
.arena = arena,
.wanted = 10});
if (outcome.status != usearch_status_success_k) goto cleanup;
printf("Found %zu matches\n", matches.counts[0]);
cleanup:
if (outcome.message) fprintf(stderr, "%s: %s\n", usearch_status_name(outcome.status), outcome.message);
usearch_dense_free(index);
usearch_arena_free(arena);
usearch_executor_free(executor);
return outcome.status == usearch_status_success_k ? 0 : 1;
}Every call here blocks, so its outcome is final by the time it returns.