C · Inputs and Outputs

Inputs and Outputs

#include <usearch/arrow.h>#include <usearch/dense_index.h>#include <usearch/geospatial_index.h>#include <usearch/sequence_index.h>#include <usearch/shapes_index.h>#include <usearch/types.h> 3.0.0-rc.1 · 4c3e5023

§ Arenas

Every output whose length scales with the call lands in an arena: the matches of a search, every vector stored under one key, every pair a sparse product scored, a monolith, a cursor’s batch. An arena is memory the library allocates and the caller passes to call after call, each of which rewinds it and writes views into it, growing only when the new outputs outsize everything it held. An executor makes it where it computes, and a NULL executor makes host pages for calls on the calling thread; an arena of host pages may outlive the executor that made it. Nothing is allocated until a call writes into it, and it keeps its high-water mark, so a steady loop allocates once. Only fixed-size reports, such as stats, descriptions and written counts, stay fields the caller points at. Arenas keep the interface at one verb per operation, never a twin per output style.

usearch_arena_t arena = NULL;
usearch_arena_init(&(usearch_arena_init_t) {.arena = &arena, .executor = executor, .outcome = &outcome});
for (size_t i = 0; i != 2; ++i) {
    usearch_rows_view_t rows = {0};
    size_t rows_count = 0;
    usearch_dense_get(&(usearch_dense_get_t) {.index = index,
                                              .executor = executor,
                                              .outcome = &outcome,
                                              .key = keys[i],
                                              .vectors = &rows,
                                              .written = &rows_count,
                                              .arena = arena,
                                              .outputs_scalar = usearch_scalar_f32_k});
    if (outcome.status != usearch_status_success_k) break;
    // `rows.data` holds `rows_count` vectors `rows.stride` bytes apart,
    // valid until the next call given `arena`
}
usearch_arena_free(arena);

Any verb may reuse any arena of its residency, so a search and a get can share one, as long as the first call’s views are not read after the second starts. To keep one call’s outputs alive past the next, pass the next call another arena. An arena serves one call at a time: a call holds it until just before its final status, and a second call naming it meanwhile finishes usearch_status_contended_k. A NULL arena, or inputs pointing into the arena a call is about to rewind, refuse with usearch_status_invalid_argument_k, and a call that fails leaves its outputs NULL. A GPU arena grows, fills and frees on the first stream of the executor that made it, so it serves only calls on that executor, and any other executor, NULL included, is refused with usearch_status_device_k. Free a GPU arena before the executor that made it.

§ Rows & Scalars

A batch of rows is a usearch_rows_view_t: a base pointer, a byte stride, the values per row, and the scalar kind they hold, converted on the way in where it differs from storage. A zero stride repeats the first row, as in BLAS, and the call’s count alone is the batch axis. Vectors are quantized on insertion into the index’s quantization, from f64 down to i8, u8, the four 8- and 6-bit floats e5m2, e4m3, e3m2 and e2m3, and packed 4- and 1-bit integers. The library compiles the first USEARCH_DENSE_DTYPES storage types of bf16, u1x8, i8, e4m3, f16, u8, e5m2, i4x2, u4x2, e3m2 and e2m3, and refuses the rest with usearch_status_unsupported_k. The precompiled binaries carry all eleven, while a CMake build takes the first four unless configured with -D USEARCH_DENSE_DTYPES=11.

USearch comes pre-packaged with NumKong, bringing SIMD-accelerated distance kernels for x86, Arm, RISC-V and GPUs. The dense metric kinds are:

  • usearch_dense_metric_inner_k - Inner Product distance, 1−∑iaibi1 - \sum_i a_i b_i, unnormalized and scale-sensitive.
  • usearch_dense_metric_angular_k - Cosine distance, 1−∑iaibi∑iai2∑ibi21 - \frac{\sum_i a_i b_i}{\sqrt{\sum_i a_i^2} \sqrt{\sum_i b_i^2}}, in [0,2][0, 2] and blind to magnitude.
  • usearch_dense_metric_euclidean_k - Euclidean distance, ∑i(ai−bi)2\sqrt{\sum_i (a_i - b_i)^2}, zero only for identical vectors.
  • usearch_dense_metric_hamming_k - Hamming distance, ∑iai⊕bi\sum_i a_i \oplus b_i, over usearch_scalar_u1x8_k bit sets.
  • usearch_dense_metric_jaccard_k - Jaccard distance, ∑iai⊕bi∑iai∨bi\frac{\sum_i a_i \oplus b_i}{\sum_i a_i \lor b_i}, in [0,1][0, 1], over usearch_scalar_u1x8_k bit sets.

usearch_scalar_name, usearch_dense_metric_name and their _from_name inverses spell these sets the way every binding parses them.

A search writes a usearch_matches_view_t into its arena: columns packed columns for each of its count queries, query i holding counts[i] matches from keys[i * columns] and scores[i * columns] on, nearest first. wanted bounds the columns, the “k” in “kANN”. The graph’s connectivity is frozen when the index is created, while the expansion_factor, the breadth of the candidates a walk explores, is chosen per call. Higher expansion values buy recall at the cost of latency; zero derives a default from the connectivity.

usearch_traversal_stats_t stats = {0};
usearch_dense_search(&(usearch_dense_search_t) {.index = index,
                                                .executor = executor,
                                                .outcome = &outcome,
                                                .count = 1,
                                                .queries = {query, 0, 128, usearch_scalar_f32_k},
                                                .matches = &matches,
                                                .arena = arena,
                                                .wanted = 10,
                                                .expansion_factor = 128,
                                                .stats = &stats});

.traversal = usearch_traversal_scan_k scores every published entry instead of walking, the exact ground truth a walk approximates, on RAM, NVMe and NVIDIA VRAM. AMD and Apple VRAM handles refuse scans with usearch_status_unsupported_k. Every verb that walks the graph fills the optional stats with the members it visited, the distances it computed, and its restarts, a connectivity health signal rather than a cost.

API

Types

usearch_byte_tOne byte of raw storage, read or written without interpretation: a key's identity, a borrowed run's contents, the buffers callers hand in.
types.h:137 ↗
typedef uint8_t usearch_byte_t;
usearch_scalar_tScalar types the indexes store and exchange, named by width and encoding.
types.h:288 ↗
enum usearch_scalar_t

Sub-byte types pack several dimensions per byte, as their xN suffixes spell.

Values

usearch_scalar_unknown_k0No scalar named - an unset field, or a custom metric owning its own storage.
usearch_scalar_f64_k1IEEE-754 binary64: ±1.80e308, epsilon 2.22e-16, subnormals to 4.94e-324, with infinities and NaNs.
usearch_scalar_f32_k2IEEE-754 binary32: ±3.40e38, epsilon 1.19e-7, subnormals to 1.40e-45, with infinities and NaNs.
usearch_scalar_bf16_k3Truncated f32 - 8-bit exponent, 7-bit mantissa: f32's range at ±3.39e38 and epsilon 7.81e-3, with infinities and NaNs.
usearch_scalar_f16_k4IEEE-754 binary16: ±65504, epsilon 9.77e-4, subnormals to 5.96e-8, with infinities and NaNs.
usearch_scalar_e5m2_k5FP8 with a 5-bit exponent: ±57344, epsilon 0.25, with infinities and NaNs - f16's dynamic range carried on two mantissa bits.
usearch_scalar_e4m3_k6FP8 with a 4-bit exponent: ±448, epsilon 0.125, no infinities, and two NaN codes at 0x7F and 0xFF.
usearch_scalar_e3m2_k7FP6 with a 3-bit exponent, byte-aligned with two padding bits: ±28, no infinities or NaNs, so every one of its 64 codes is a number.
usearch_scalar_e2m3_k8FP6 with a 2-bit exponent, byte-aligned with two padding bits: ±7.5, no infinities or NaNs, and 72% of its codes outside [-1, 1].
usearch_scalar_i8_k108-bit signed integer spanning -128 to 127, every code a number.
usearch_scalar_i4x2_k11Two signed nibbles per byte spanning -8 to 7, even dimensions in the low nibble and odd ones in the high.
usearch_scalar_i32_k1232-bit signed integer spanning ±2.15e9, every code a number.
usearch_scalar_u8_k208-bit unsigned integer spanning 0 to 255, every code a number.
usearch_scalar_u4x2_k21Two unsigned nibbles per byte spanning 0 to 15, even dimensions in the low nibble and odd ones in the high.
usearch_scalar_u1x8_k22Eight single-bit dimensions per byte - the form the Hamming & Jaccard metrics score, where only the set-bit count of a XOR or AND carries meaning.

Spellings

char const * usearch_scalar_name(usearch_scalar_t scalar);
usearch_scalar_t usearch_scalar_from_name(usearch_bytes_view_t name);
usearch_rows_view_tA run of rows along a call's batch axis - the currency of every verb whose rows share one width, borrowed from the caller as an input and written packed into an arena as an output.
types.h:360 ↗
struct usearch_rows_view_t

An input's row count is the call's count, and the call checks columns against the frozen geometry. A zero stride repeats the first row. An output's rows are packed: the call writes one row's bytes as stride, and columns and scalar as it wrote them, so neither a repeat nor a geometry check applies.

Fields

datavoid const *Base pointer of the first row.
stridesize_tBytes between the starts of consecutive rows; zero repeats the first row.
columnssize_tValues per row; an input's must match the frozen geometry, and sub-byte rows of either kind must fill whole bytes, or they are refused.
scalarusearch_scalar_tThe scalar type the rows hold, converted on the way in where it differs.
usearch_matrix_view_tA borrowed strided matrix off the batch axis - an operand whose rows and columns are its own, like the value rows attention gathers from.
types.h:383 ↗
struct usearch_matrix_view_t

rows and columns are counts and stride alone is in bytes. A zero stride repeats the first row.

Fields

datavoid const *Base pointer of the first row.
rowssize_tRows the matrix carries.
columnssize_tLogical scalars per row, as the caller counts them.
stridesize_tBytes between the starts of consecutive rows; zero repeats the first row.
scalarusearch_scalar_tThe scalar type the rows hold.
usearch_tape_layout_tHow wide a tape's offsets are, naming the member of its offsets union to read.
types.h:402 ↗
enum usearch_tape_layout_t

Values

usearch_tape_u32_k0Apache Arrow Binary or List, with 32-bit offsets.
usearch_tape_u64_k1Apache Arrow LargeBinary or LargeList, the same with 64-bit offsets.
usearch_tape_view_tA ragged batch as Apache Arrow lays one out: elements end to end, and one more offset than entries around them, borrowed as an input or written into an arena as an output.
types.h:420 ↗
struct usearch_tape_view_t

Entry i spans elements offsets[i] up to offsets[i+1], so the last offset closes the final entry. What an element is belongs to the modality: a byte of a sequence, a point of a shape or of a geospatial set. As an output the call writes 32-bit offsets while its elements fit them, and 64-bit beyond.

Fields

datavoid const *First element of the tape, which every offset counts from.
layoutusearch_tape_layout_tWhich member of offsets the tape spells them in.
offsetsunion usearch_tape_view_t::@255032373266025347346062347373025110336350121000
scalarusearch_scalar_tThe scalar type the elements hold: u8 for sequences, f64 degrees for geospatial inputs, and any kind for shape points, converted on the way in where it differs from storage.
usearch_matches_view_tA ranked run a call wrote into its arena - count rows of columns packed columns, where count is the call's own.
types.h:457 ↗
struct usearch_matches_view_t

Carries no query count of its own: the call already fixed it, and a second copy is a second thing to disagree. Query i holds counts[i] matches from keys[i · columns] and scores[i · columns] on, and the columns past them are unwritten.

What scores hold is each verb's own: a search writes distances nearest-first, whichever kind the index froze - the inner kind as 1 - dot - while the linear-algebra verbs write similarities, as their own docs state.

Fields

keysusearch_key_t const *First row of the keys, columns per row.
scoresusearch_distance_t const *First row of the scores, positionally paired with keys.
countssize_t const *Matches written per query, one entry per query.
columnssize_tColumns per row the call wrote, at most its wanted - the "k" in "kANN".
usearch_matches_tape_view_tA ragged run of matches a call wrote into its arena, for verbs whose queries hold as many matches as their walks found: keys and scores end to end, and one more offset than queries.
types.h:479 ↗
struct usearch_matches_tape_view_t

Query i spans offsets[i] up to offsets[i+1] in both arrays, so the last offset is the total. Scores follow the same per-verb meaning as in usearch_matches_view_t.

Fields

keysusearch_key_t const *Every query's keys, end to end.
scoresusearch_distance_t const *Every query's scores, positionally paired with keys.
offsetssize_t const *The call's count + 1 non-decreasing offsets into keys and scores.
usearch_traversal_tHow a search reaches the indexed entries it scores.
types.h:691 ↗
enum usearch_traversal_t

Values

usearch_traversal_unknown_k0No traversal named, which derives the walk.
usearch_traversal_walk_k1Walk the graph, scoring the entries the expansion reaches - approximate, the default.
usearch_traversal_scan_k2Score every entry published when the query's scan starts - exact, the ground truth a walk approximates.

Spellings

char const * usearch_traversal_name(usearch_traversal_t traversal);
usearch_traversal_t usearch_traversal_from_name(
    usearch_bytes_view_t name);
usearch_traversal_stats_tTraversal telemetry, shared by every verb that walks a graph in every modality - a pure output, fully overwritten by the call it is passed to.
types.h:706 ↗
struct usearch_traversal_stats_t

Passing NULL skips reporting.

Fields

visited_memberssize_tGraph members visited while resolving the batch.
computed_distancessize_tDistances computed while resolving the batch, diversity re-selections included.
restartssize_tStarvation restarts - re-seedings after the frontier drained prematurely, and a graph-connectivity health signal rather than a cost counter.
missing_hintssize_tHint keys no shard held an entry under; zero unless a search was handed hints.
usearch_arena_tMemory the library writes every output whose length scales with a call into, reused across calls.
types.h:1328 ↗
typedef struct usearch_arena_handle_t * usearch_arena_t;

Memory

Made by usearch_arena_init where its executor computes: host pages on its memory domains, or the memory of its GPU, and a GPU that runs out reports usearch_status_out_of_memory_k rather than falling back to the host. Each call given the arena rewinds it, which invalidates every output of the previous call, and refills it, growing only when the new outputs outsize everything it held, so a steady loop allocates once. To keep one call's outputs alive past the next call, pass the next call another arena.

  • A NULL arena is refused with usearch_status_invalid_argument_k.
  • A call whose inputs point into the arena it is about to rewind reports usearch_status_invalid_argument_k.
  • An arena serves one call at a time; a second call naming it finishes usearch_status_contended_k, and a deferred one does so at submission.
  • A call on another residency or device than the arena's, or a call naming a GPU arena with another executor than the one that made it, NULL included, reports usearch_status_device_k.
  • A blocking call borrows the arena until it returns, and a deferred one holds it until final.
  • A call that fails, is cancelled, or has nothing to report leaves its outputs NULL.

Notes

A GPU arena grows, fills and frees on the first stream of the executor that made it, so it serves only calls on that executor, and must be freed before that executor is.

Functions

usearch_keys_view_from_arrowViews the 16-byte keys of one Arrow fixed_size_binary(16) column in place, tagged arrow.uuid or not.
arrow.h:241 ↗
usearch_status_t usearch_keys_view_from_arrow(
    struct ArrowSchema const *schema,
    struct ArrowArray const *array,
    usearch_keys_view_t *keys,
    size_t *count);

A null_count of -1 with a validity buffer may hold a null, and is refused as one.

Parameters

schemainThe column's schema.
arrayinThe column, whose offset is applied; only its lengths and pointers are read, never its buffers, so the array of an ArrowDeviceArray converts as well.
keysoutThe keys, one every 16 bytes.
countoutThe number of keys.

Returns

usearch_status_invalid_argument_k for a missing or released input or one holding a null, usearch_status_unsupported_layout_k for another format, a dictionary or a view, usearch_status_malformed_k for a negative length or offset or a missing buffer, and usearch_status_overflow_k for a length past what size_t counts.

usearch_rows_view_from_arrowViews the rows of one Arrow fixed_size_list column, or of a fixed_size_binary one tagged numkong.u1x8, in place, the offsets of the column and its child applied.
arrow.h:255 ↗
usearch_status_t usearch_rows_view_from_arrow(
    struct ArrowSchema const *schema,
    struct ArrowArray const *array,
    usearch_rows_view_t *rows,
    size_t *count);

Parameters

schemainThe column's schema.
arrayinThe column, whose offset is applied.
rowsoutThe rows, packed, with their columns and scalar.
countoutThe number of rows.

Returns

The statuses of usearch_keys_view_from_arrow, with a list of bool refused as an unsupported layout.

usearch_tape_view_from_arrowViews one Arrow column of sequences or shapes in place: binary, utf8 or a list of 3-element lists as a tape of 32-bit offsets, and large_binary, large_utf8 or a large_list of them as one of 64-bit offsets, starting at the column's offset.
arrow.h:269 ↗
usearch_status_t usearch_tape_view_from_arrow(
    struct ArrowSchema const *schema,
    struct ArrowArray const *array,
    usearch_tape_view_t *tape,
    size_t *count);

Parameters

schemainThe column's schema.
arrayinThe column, whose offset is applied.
tapeoutThe tape, its scalar u8 for bytes and the points' otherwise.
countoutThe number of entries.

Returns

usearch_keys_view_to_arrowExports count keys a call wrote into arena as one Arrow fixed_size_binary(16) column tagged as arrow.uuid, in place.
arrow.h:294 ↗
usearch_status_t usearch_keys_view_to_arrow(
    usearch_keys_view_t keys,
    size_t count,
    usearch_arena_t arena,
    struct ArrowSchema *schema,
    struct ArrowDeviceArray *array);

The array pins arena until its release: meanwhile a call naming the arena is refused with usearch_status_contended_k, and usearch_arena_free leaves the arena to the last release. Arenas on host pages export as ARROW_DEVICE_CPU, and those of a VRAM executor as ARROW_DEVICE_CUDA, ARROW_DEVICE_ROCM or ARROW_DEVICE_METAL with the vendor's ordinal of their device and no sync_event, as the call that filled one drained its uploads. The schema's name is empty, for the caller to point at its own. Schema and array release apart, and a consumer may move their children out before either release.

Statuses

Notes

A device arena's last release must come before the free of the executor that made it, which usearch_arena_t asks of the free it stands in for.

usearch_rows_view_to_arrowExports count packed rows a call wrote into arena as one Arrow fixed_size_list column of their scalar, or a fixed_size_binary one for u1x8, in place.
arrow.h:304 ↗
usearch_status_t usearch_rows_view_to_arrow(
    usearch_rows_view_t rows,
    size_t count,
    usearch_arena_t arena,
    struct ArrowSchema *schema,
    struct ArrowDeviceArray *array);

Returns

The statuses of usearch_keys_view_to_arrow, with a scalar Arrow carries no layout for, or columns filling no whole element, refused as an unsupported layout.

usearch_tape_view_to_arrowExports a tape of count entries a call wrote into arena as one Arrow column in place, its offsets as they are: binary or large_binary for u8 elements, which a sequence's are, and a list or large_list of 3-element lists for any other scalar.
arrow.h:319 ↗
usearch_status_t usearch_tape_view_to_arrow(
    usearch_tape_view_t tape,
    size_t count,
    usearch_arena_t arena,
    struct ArrowSchema *schema,
    struct ArrowDeviceArray *array);

A list length comes from the tape's last offset, which crosses from a device arena through its driver. Shape points asked for in u8 read as binary, whose offsets are bytes, so ask a shapes get for another scalar before exporting it.

Returns

The statuses of usearch_keys_view_to_arrow, with an unknown layout refused as an unsupported one, and usearch_status_device_k for a device's last offset no driver reads.

usearch_keys_tape_view_to_arrowExports a ragged run of count entries' keys a call wrote into arena as one Arrow large_list of arrow.uuid keys, in place.
arrow.h:328 ↗
usearch_status_t usearch_keys_tape_view_to_arrow(
    usearch_keys_tape_view_t keys,
    size_t count,
    usearch_arena_t arena,
    struct ArrowSchema *schema,
    struct ArrowDeviceArray *array);

Returns

usearch_matches_view_to_arrowExports the padded matches of count queries a call wrote into arena as one Arrow large_list_view of struct{key, distance} over their columns.
arrow.h:343 ↗
usearch_status_t usearch_matches_view_to_arrow(
    usearch_matches_view_t matches,
    size_t count,
    usearch_arena_t arena,
    struct ArrowSchema *schema,
    struct ArrowDeviceArray *array);

Keys, scores and sizes stay in place. The view's offsets are written behind the call's outputs in arena under the arena's hold, so no other call or carving export runs on arena meanwhile, and a device arena's reach its device on the first stream of the executor that made the arena.

Returns

usearch_matches_tape_view_to_arrowExports a ragged run of count queries' matches a call wrote into arena as one Arrow large_list of struct{key, distance}, in place.
arrow.h:352 ↗
usearch_status_t usearch_matches_tape_view_to_arrow(
    usearch_matches_tape_view_t matches,
    size_t count,
    usearch_arena_t arena,
    struct ArrowSchema *schema,
    struct ArrowDeviceArray *array);

Returns

usearch_dense_insertAdds a run of vectors under their keys - the native batch operation; a single vector is a count of one.
dense_index.h:800 ↗
void usearch_dense_insert(usearch_dense_insert_t *arguments);

Overlaps safely with concurrent searches on the same handle. Concurrency & Thread Safety

An insertion is all-or-nothing per call, with or without a handler, and its entries become visible at once on RAM and VRAM handles alike, so a concurrent search sees every entry of the call or none of them. Every entry is claimed before the handler's first report, and a claimed entry cannot be withdrawn, so the handler reports progress but cannot cancel: a returned usearch_cancel_k is ignored.

On a RAM handle every fallible step runs before the first entry identity is claimed, so a failed call leaves the index untouched. A VRAM call that fails after its first launch publishes none of its entries and leaves the handle refusing every later mutation with that failure, while searches continue.

usearch_outcome_t outcome = {0};
usearch_dense_insert(&(usearch_dense_insert_t){
    .index = index, .executor = executor, .outcome = &outcome,
    .count = 256, .keys = {keys, sizeof(usearch_key_t)},
    .vectors = {rows_base, 128 * sizeof(float), 128, usearch_scalar_f32_k}});
if (outcome.status != usearch_status_success_k) report(outcome.message);

Parameters

indexusearch_dense_index_tThe handle to be populated.
executorusearch_executor_tThe executor driving the batch; its kind must match the handle's residency.
outcomeusearch_outcome_t *Output for the outcome, final once its status leaves usearch_status_deferred_k.
completionusearch_completion_tBlocking, the default, or deferred.
countsize_tEntries to admit - the batch axis of keys and vectors.
keysusearch_keys_view_tThe identities to admit the entries under, one per entry.
vectorsusearch_rows_view_tThe vectors to admit, converted on ingest to the stored type.
expansion_factorsize_tThe optional breadth of the candidates the build walk explores; zero derives.
progressusearch_progress_tThe optional handler, called with entries admitted, which reports and cannot cancel.
statsusearch_traversal_stats_t *The optional traversal telemetry; NULL skips reporting.

Statuses

usearch_geospatial_insertAdds observations under their keys - the native batch operation; a single observation is a batch of one.
geospatial_index.h:753 ↗
void usearch_geospatial_insert(usearch_geospatial_insert_t *arguments);

An observation without an altitude is placed on the handle's terrain when it has one, and on the ellipsoid otherwise.

An insertion is all-or-nothing per call. Every fallible step runs before the first entry identity is claimed, so a rejected call publishes nothing - a cancelled one included, which reports usearch_status_cancelled_k - and on a RAM handle the entries of an accepted one become visible at once, their keys right after.

A key already holding values_per_key entries rejects the whole call, since a smaller retry cannot help.

Parameters

indexusearch_geospatial_index_tThe handle to be populated.
executorusearch_executor_tThe executor to fan out over; its kind must match the residency.
outcomeusearch_outcome_t *Output for the outcome, final once its status leaves usearch_status_deferred_k.
completionusearch_completion_tBlocking, the default, or deferred.
countsize_tObservations to admit - the batch axis of keys and observations.
keysusearch_keys_view_tThe identities to admit the observations under, one per entry and not necessarily unique.
observationsusearch_geospatial_observation_t const *The observations, count of them.
expansion_factorsize_tThe optional breadth of the candidates the build walk explores - the ef of the literature; zero derives.
progressusearch_progress_tThe optional handler, called with entries admitted and the batch length.
statsusearch_traversal_stats_t *The optional traversal telemetry; NULL skips reporting.

Statuses

usearch_geospatial_withinReports every entry within the radius of each query observation that the relation admits - the containment counterpart of the ranked search, unbounded in result count.
geospatial_index.h:1015 ↗
void usearch_geospatial_within(usearch_geospatial_within_t *arguments);

Complete on the converged graph: the walk widens its candidates by the cone graph's spanner bound before trusting it, so every candidate inside the tolerance is enumerated, at about thirty times the cost of the ball it reports. Containment sizes its own candidates from that bound, so it takes no breadth a caller could make the report incomplete with. Only the walks learn how large the report is, so the keys, scores and Apache Arrow offsets are written in arena as one ragged output, as usearch_dense_multiply writes its pairs. A predicate narrows the report without stopping the walk from crossing the entries it rejects.

A cancelled call reports usearch_status_cancelled_k and leaves the outputs NULL.

Parameters

indexusearch_geospatial_index_tThe handle to be queried.
executorusearch_executor_tThe executor to fan out over; its kind must match the residency.
outcomeusearch_outcome_t *Output for the outcome, final once its status leaves usearch_status_deferred_k.
completionusearch_completion_tBlocking, the default, or deferred.
countsize_tQueries to resolve, one walk apiece.
queriesusearch_geospatial_observation_t const *The count query observations.
relationusearch_geospatial_relation_tWhich entries count as matches.
toleranceusearch_geospatial_tolerance_tThe radius and time slack; metres must be positive.
matchesusearch_matches_tape_view_t *Output for the report inside arena, query i spanning entries matches->offsets[i] up to matches->offsets[i+1].
writtensize_t *The optional output for the entries written across every query.
arenausearch_arena_tMemory for matches, rewound by the call.
traversalusearch_traversal_tHow entries are reached: a complete walk, the default, or an exact scan of every entry, on RAM and NVMe.
predicateusearch_predicate_tThe optional predicate, asked about a batch of candidates at a time.
progressusearch_progress_tThe optional handler, called with queries resolved and their count.
statsusearch_traversal_stats_t *The optional traversal telemetry; NULL skips reporting.

Statuses

usearch_sequence_insertAdds a tape of sequences under their keys - the native batch operation; a single sequence is a tape of one.
sequence_index.h:728 ↗
void usearch_sequence_insert(usearch_sequence_insert_t *arguments);

An insertion is all-or-nothing per call. Every fallible step runs before the first entry identity is claimed, so a rejected call publishes nothing - a cancelled one included, which reports usearch_status_cancelled_k - and the entries of an accepted one become visible at once, their keys right after.

A key already holding values_per_key entries rejects the whole call, since a smaller retry cannot help.

Parameters

indexusearch_sequence_index_tThe handle to be populated.
executorusearch_executor_tThe executor to fan out over; its kind must match the residency.
outcomeusearch_outcome_t *Output for the outcome, final once its status leaves usearch_status_deferred_k.
completionusearch_completion_tBlocking, the default, or deferred.
countsize_tSequences to admit - the batch axis of keys and sequences.
keysusearch_keys_view_tThe identities to admit the sequences under, one per sequence.
sequencesusearch_tape_view_tThe sequences, as bytes end to end around count + 1 offsets.
expansion_factorsize_tThe optional breadth of the candidates the build walk explores - the ef of the literature; zero derives.
progressusearch_progress_tThe optional handler, called with entries admitted and the batch length.
statsusearch_traversal_stats_t *The optional traversal telemetry; NULL skips reporting.

Statuses

usearch_shapes_insertAdds a tape of shapes under their keys - the native batch operation; a single shape is a tape of one.
shapes_index.h:714 ↗
void usearch_shapes_insert(usearch_shapes_insert_t *arguments);

Point counts may differ freely between entries. Overlaps safely with concurrent searches on the same handle. Concurrency & Thread Safety

An insertion is all-or-nothing per call. Every fallible step runs before the first entry identity is claimed, so a rejected call publishes nothing - a cancelled one included, which reports usearch_status_cancelled_k - and on a RAM handle the entries of an accepted one become visible at once.

A key already holding values_per_key entries rejects the whole call, since a smaller retry cannot help.

Parameters

indexusearch_shapes_index_tThe handle to be populated.
executorusearch_executor_tThe executor to fan out over; its kind must match the residency.
outcomeusearch_outcome_t *Output for the outcome, final once its status leaves usearch_status_deferred_k.
completionusearch_completion_tBlocking, the default, or deferred.
countsize_tShapes to admit - the batch axis of keys and shapes.
keysusearch_keys_view_tThe identities to admit the shapes under, one per entry and not necessarily unique.
shapesusearch_tape_view_tThe shapes, points end to end around count + 1 point offsets.
expansion_factorsize_tThe optional breadth of the candidates the build walk explores; zero derives.
progressusearch_progress_tThe optional handler, called with entries admitted and the batch length.
statsusearch_traversal_stats_t *The optional traversal telemetry; NULL skips reporting.

Statuses

usearch_arena_initCreates an empty arena where executor computes, so its placement is decided once and GPU code keeps its outputs on the device without asking.
types.h:1352 ↗
void usearch_arena_init(usearch_arena_init_t *arguments);

Nothing is allocated until a call writes into it. An arena of host pages may outlive the executor that made it, keeping its own memory until it is freed; a GPU arena keeps the rule usearch_arena_t notes.

Parameters

arenausearch_arena_t *Output for the new arena.
executorusearch_executor_tThe executor whose calls the arena serves, which decides where it lives; NULL serves calls on the calling thread from host pages.
outcomeusearch_outcome_t *Output for the outcome, final once its status leaves usearch_status_deferred_k.
usearch_arena_freeFrees the arena and every output in it; NULL is safe, and it cannot fail, so takes no outcome.
types.h:1364 ↗
void usearch_arena_free(usearch_arena_t arena);

Waits until every deferred call naming the handle is final, and leaves the arena to the last release of the Arrow exports still pinning it. Free a GPU arena once the caller's own device work on its outputs has finished, keeping the rule usearch_arena_t notes.

Parameters

arenainoutThe arena to be freed; invalid afterwards.