pub const Distance = f64 API
Types
DistanceDistance or similarity score between two entries, in the metric of the index that produced it.
DenseOptionsThe geometry and metric an empty index freezes - what DenseIndex.initRam and initVram read beside their placement.
pub const DenseOptions = struct Binding-only.
Stored vectors round up to whole steps of the distance kit the build picked, so the memory is slightly larger than the logical vectors, and that is not a knob.
Fields
metric | DenseMetric | The metric kind used for distance calculations between vectors. |
|---|---|---|
quantization | Scalar | The scalar type vectors are stored and quantized into. |
dimensions | usize | Dimensions of the indexed vectors. |
connectivity | usize | The optional connections-per-node bound; zero derives. |
values_per_key | usize | Upper bound on entries sharing one key; zero is unbounded. |
EnumDenseMetricThe dense metric kinds shipped out of the box, all derived from one inner-product kernel with pre-computed magnitudes.2
pub const DenseMetric = enum(c_int) The bit-level pair reads its rows as Scalar.u1x8 and refuses any
other quantization; the first three refuse that one. Mirrors usearch_dense_metric_t.
Non-exhaustive, so a kind a newer engine reports arrives intact rather than coerced.
Values
unknown | 0 | No kind named - an unset field, refused by every constructor. |
|---|---|---|
inner | 1 | Sum of elementwise products, unnormalized - the only kind the linear-algebra verbs accept. |
angular | 2 | Cosine distance in [0, 2], blind to magnitude. |
euclidean | 3 | L2 distance, zero only for identical vectors. |
hamming | 4 | Count of differing bits, so its range is the dimensionality. |
jaccard | 5 | Differing bits over union bits in [0, 1], ignoring the zeros both vectors share. |
nameThe canonical spelling, as .inner spells "inner".
fromNameReads a spelling back, or null when no kind spells it.
pub fn fromName(text: []const u8) ?DenseMetric Calls usearch_dense_metric_from_name.
StructDenseIndexVector Search Index over equidimensional dense representations.36
pub const DenseIndex = extern struct A handle is shareable across threads: searches never write to the graph, and insertions
synchronize through per-node locks and publish in order. It is the Executor that orders,
never the index.
const usearch = @import("usearch");
var index = try usearch.DenseIndex.initRam(.{ .dimensions = 4, .metric = .angular, .quantization = .i8 }, &.{});
defer index.deinit();
try index.reserve(1_000);
const keys = [_]usearch.Key{ .fromInteger(0), .fromInteger(1) };
const slab = [_]f32{ 0.2, 0.1, 0.2, 0.1, 0.1, 0.2, 0.1, 0.2 };
try index.insert(&keys, try .of(f32, &slab, 4), .{});
const query = [_]f32{ 0.2, 0.1, 0.2, 0.1 };
var arena = try usearch.Arena.init(null);
defer arena.deinit();
const matches = try index.search(try .ofRow(f32, &query), 10, &arena, .{});
const nearest = (try matches.query(0)).keys[0];
Fields
handle | ?*anyopaque | The opaque usearch_dense_index_t the ABI hands back. |
|---|
OnEvery verb of the index, blocking on an executor after every call submitted there before it.
pub const On = Receiver(.blocking, void) DeferredOnEvery verb of the index, submitted to an executor into a Deferred(Call) the caller holds, borrowing the arena a verb lands in as a blocking call does; only the verb Call describes compiles.
pub fn DeferredOn(comptime Call: type) type onRuns every verb on executor, whose kind must match the index's residency.
deferredSubmits a verb to executor, holding it in call - a *Deferred(Call) the caller places anywhere, which stays put until its deinit.
pub fn deferred(
self: DenseIndex,
executor: Executor,
call: anytype,
) DeferredOn(@FieldType(@TypeOf(call.*), "call")) Binding-only.
diagnosedRuns every verb on the calling thread, copying each call's final outcome into outcome.
initRamCreates an empty, mutable index in host memory, one shard per memory domain; empty derives every node the process may allocate on.
pub fn initRam(
options: DenseOptions,
memory_domains: []const i32,
) Error!DenseIndex Calls usearch_dense_init_ram.
initVramCreates an empty, mutable index in device memory, one shard per device and never a replica; empty derives one free device.
pub fn initVram(
options: DenseOptions,
devices: []const i32,
) Error!DenseIndex Calls usearch_dense_init_vram.
loadRamCopies a checkpoint into a new, mutable index in host memory, shard by shard.
pub fn loadRam(
path: []const u8,
config: DenseLoadRamConfig,
) Error!DenseIndex Point path at the .safegraphs.json manifest, never at one of the parts it enumerates.
The geometry and metric come from the checkpoint's own headers. Calls usearch_dense_load_ram.
loadVramCopies a checkpoint into a new, mutable index in device memory, with the placement rules of loadRam.
pub fn loadVram(
path: []const u8,
config: DenseLoadVramConfig,
) Error!DenseIndex Calls usearch_dense_load_vram.
loadRamBufferCopies a monolith from a memory buffer into a new index in host memory, as loadRam does a path.
pub fn loadRamBuffer(
buffer: []const u8,
config: DenseLoadRamBufferConfig,
) Error!DenseIndex Calls usearch_dense_load_ram_buffer.
loadVramBufferCopies a monolith from a host or device buffer into a new index in device memory.
pub fn loadVramBuffer(
buffer: []const u8,
config: DenseLoadVramBufferConfig,
) Error!DenseIndex Calls usearch_dense_load_vram_buffer.
viewRamServes a checkpoint in place through a memory mapping, as a read-only index whose mutating verbs report Error.ReadOnly; the files must stay unmodified while it lives.
viewNvmeServes a checkpoint in place from NVMe drives, read-only and sized past RAM; until NVMe checkpoints carry keys it answers Error.Unsupported.
pub fn viewNvme(
path: []const u8,
config: DenseViewNvmeConfig,
) Error!DenseIndex Calls usearch_dense_view_nvme.
metadataReadReads a checkpoint's geometry and metric, without loading it.
pub fn metadataRead(
path: []const u8,
config: DenseMetadataReadConfig,
) Error!DenseMetadata Calls usearch_dense_metadata_read.
metadataReadBufferReads geometry and metric out of a serialized monolith buffer, without loading it.
pub fn metadataReadBuffer(
buffer: []const u8,
config: DenseMetadataReadBufferConfig,
) Error!DenseMetadata Calls usearch_dense_metadata_read_buffer.
deinitFrees the resources associated with the index, waiting for every deferred call naming it; the handle is invalid afterwards.
reserveReserves room for a total number of entries, the current size included.
pub fn reserve(self: DenseIndex, capacity: usize) Error!void Calls usearch_dense_reserve.
clearErases all entries, keeping the reserved capacity and frozen geometry.
pub fn clear(self: DenseIndex) Error!void Never runs
concurrently with any other verb on the same handle. Calls usearch_dense_clear.
describeReports the frozen metadata and the current counters in one call.
pub fn describe(self: DenseIndex) Error!DenseIndexDescription Calls usearch_dense_describe.
countThe entries stored under key; zero means the index holds none.
containsWhether the index holds at least one entry under key.
pub fn contains(self: DenseIndex, key: Key) Error!bool Binding-only; calls usearch_dense_count.
getEvery vector stored under key as scalar, one packed row per entry in insertion order, written in arena; an absent key yields no rows.
pub fn get(
self: DenseIndex,
key: Key,
scalar: Scalar,
arena: *Arena,
) Error!DenseVectors Calls usearch_dense_get.
insertAdds a run of vectors under their keys - the native batch operation, one key per row.
pub fn insert(
self: DenseIndex,
keys: []const Key,
vectors: RowsView,
config: DenseInsertConfig,
) Error!void The batch is all-or-nothing: every fallible step runs before the first entry identity is
claimed, so a handler reports progress but cannot stop it. Overlaps safely with concurrent
searches on the same handle, and the input scalar type is independent of the stored
quantization. Calls usearch_dense_insert.
refineRe-selects the neighbors of every stored entry against the finished graph, reporting the entries re-selected and changed and the islands healed; zero changed means settled.
pub fn refine(
self: DenseIndex,
config: DenseRefineConfig,
) Error!DenseRefineReport A build step rather than a repair: a cheap insertion pass followed by one refinement
reaches a better graph, in less total time, than one expensive insertion pass - so a wide
expansion factor belongs here rather than in insert. A stopped sweep leaves the graph
correct and merely less improved, and reports no Error.Cancelled. Calls usearch_dense_refine.
healthAudits how much of the graph a search reaches from its landmarks; the entries it misses stay unfound until a refine re-links them.
pub fn health(self: DenseIndex) Error!DenseReachability Calls usearch_dense_health.
searchResolves a run of queries into up to wanted matches apiece, written in arena - the native batch operation.
pub fn search(
self: DenseIndex,
queries: RowsView,
wanted: usize,
arena: *Arena,
config: DenseSearchConfig,
) Error!Matches Never writes to the graph, so any number of these may overlap with concurrent insertions.
A zero wanted walks nothing and lands only the counts, every one zero.
Calls usearch_dense_search.
absorbAbsorbs every donor into the index, one after another, keeping their graphs rather than re-inserting their vectors: each donor's entries append shard by shard, then a refinement links them across the appended part.
pub fn absorb(
self: DenseIndex,
donors: []DenseIndex,
config: DenseAbsorbConfig,
) Error!DenseRefineReport Donors must share the index's residency, scalar, metric and
geometry, or the call answers Error.ConfigMismatch.
Each donor it absorbs is consumed and nulled in place, so deinit on every donor afterwards
frees only those a stop between donors or a failure left live. Readers of a RAM index keep
searching throughout; a VRAM one admits no overlapping search. Calls usearch_dense_absorb.
splitSplits the index into receivers, the inverse of absorb: graph-local parts keeping their edges, one per receiver, leaving this index empty but live.
pub fn split(
self: DenseIndex,
receivers: []const DenseIndex,
config: DenseSplitConfig,
) Error!DenseRefineReport Receivers must be empty and
share the index's residency, scalar, class, metric, geometry and shard count, or the call
answers Error.ConfigMismatch, and a refusal moves nothing. Calls usearch_dense_split.
sampleDraws up to wanted keys around config.focus, or across the whole index, each hanging from a shown or earlier draw and placed in three dimensions beside the shown ones, written in arena; a larger wanted draws a superset.
pub fn sample(
self: DenseIndex,
wanted: usize,
arena: *Arena,
config: DenseSampleConfig,
) Error!DenseDraws Only RAM samples yet. Calls usearch_dense_sample.
cursorNextCopies up to wanted more entries out of cursor into arena - their keys, and the keys each links to when links asks - answering an empty batch once the walk is exhausted.
pub fn cursorNext(
self: DenseIndex,
cursor: DenseCursor,
wanted: usize,
links: bool,
arena: *Arena,
) Error!DenseCursorBatch The
vectors themselves come from get. Calls usearch_dense_cursor_next.
searchStreamNextPulls up to wanted more matches out of stream into arena, as one query's matches, answering an empty query once the walk is drained.
pub fn searchStreamNext(
self: DenseIndex,
stream: DenseSearchStream,
wanted: usize,
arena: *Arena,
) Error!Matches Ordering beyond the configured expansion horizon is best-effort nearest rather than
globally exact, so pulling far past that breadth degrades the ranking rather than ending
the stream. Calls usearch_dense_search_stream_next.
saveSaves the index under path in the layout its extension picks - a .safegraphs monolith, or a .safegraphs.json manifest beside its shards.
pub fn save(
self: DenseIndex,
path: []const u8,
config: DenseSaveConfig,
) Error!void Demands a mutation-free window; concurrent readers keep searching throughout. A failed
save leaves a file without its header, which every reader rejects, and that leftover is
the caller's to remove. Calls usearch_dense_save.
saveBufferSaves the index as one monolith - the same bytes save writes to a .safegraphs path - written in arena.
pub fn saveBuffer(
self: DenseIndex,
arena: *Arena,
config: DenseSaveBufferConfig,
) Error!Monolith Calls usearch_dense_save_buffer.
multiplyApproximate sparse product of the left-hand rows against the indexed vectors, reporting every pair the traversal scored instead of only the nearest, as a ragged output written in arena with Apache Arrow offsets.
pub fn multiply(
self: DenseIndex,
left: RowsView,
arena: *Arena,
config: DenseMultiplyConfig,
) Error!DenseProducts Pairs arrive in traversal order rather than sorted, and carry no duplicates. Cost is
roughly rows × expansion × connectivity × dimensions, sublinear in the indexed entries.
Runs on the inner-product kind only, refusing others with Error.ConfigMismatch.
Calls usearch_dense_multiply.
attendSoftmax attention of a run of query heads over every indexed key their graph walks score, folded as Flash Attention folds key tiles - no top-k cut, so the long tail the walk scores brings the result toward exact dense attention.
pub fn attend(
self: DenseIndex,
queries: RowsView,
value_lookup: ValueLookup,
arena: *Arena,
config: DenseAttendConfig,
) Error!DenseVectors One walk per token serves its config.head_count heads, rows t · head_count + h. The
index stores no values: value_lookup resolves the keys of every scored batch to their
rows, a host function on RAM and a device one on VRAM. The attended rows land in arena as wide as the keys and divided by the partition,
and carry is worth asking for only to fold this branch into another over the same
queries. Runs on the inner-product kind only. Calls usearch_dense_attend.
maxsimLate-interaction scoring of multi-row queries against multi-vector documents: every query row takes its best match within a key, and those maxima sum to that key's score.
pub fn maxsim(
self: DenseIndex,
queries: RowsView,
rows_per_query: usize,
wanted: usize,
arena: *Arena,
config: DenseMaxsimConfig,
) Error!DenseProducts queries carries the queries laid end to end, rows_per_query rows apiece and uniform, so
ColBERT's padding applies as is, and each query's keys land in arena largest first, up to
wanted of them, or every key it scored when wanted is zero. Approximate downward only,
and runs on the inner-product kind only. Calls usearch_dense_maxsim.