Java · Metrics

Metrics

import cloud.unum.usearch.*; 3.0.0-rc.1 · 4c3e5023

§ Dense Indexes

DenseIndex carries the modality’s options, metric, telemetry and per-call settings as nested types.

API

ClassDenseIndexA Vector Search Index over equidimensional dense representations, with the modality's own options, metric, telemetry and per-call settings as nested types.39
DenseIndex.java:83 ↗
class DenseIndex

Every verb is a batch over strided matrices, so a memory-mapped dataset reaches the index with no reshape and no copy, and a single vector is a one-row matrix. The breadth of the candidates rides each call rather than the handle, which lets a recall sweep run against one immutable index with no mutation between points.

A handle may be shared across threads, so no method here takes a lock. On a RAM handle, insertions and searches overlap freely: searches read only entries published behind the visibility watermark and never write to the graph, while insertions synchronize through per-node locks and publish in order. Serialization is the one exception, demanding a mutation-free window, though concurrent readers keep searching throughout.

The receiver chooses how a call runs, and the verb stays the same: the index runs every verb on the caller's thread, the On that on makes blocks on an executor, and the DeferredOn that deferred makes submits there and answers a Deferred. The filtered search and the progress handlers of the C interface stay unbound: they run on engine threads, where every candidate would pay an upcall and a throwing handler could not unwind. Filter the results of search instead, or narrow the index.

Every method here reports failure as an unchecked USearchException carrying the Status the engine named, so the per-method tags below list only the statuses that method distinctly produces. An IllegalStateException on a handle that was closed applies to all of them and is not repeated.


DenseOptions options = new DenseOptions().dimensions(2);
try (Executor pool = Executor.forRam(new int[0], null, 0, 0);
        Arena arena = new Arena(pool);
        DenseIndex index = DenseIndex.initRam(options, new int[0])) {
    index.reserve(2);
    index.insert(new Key[] {Key.of(1), Key.of(2)}, RowsView.of(new float[] {0, 1, 1, 0}, 2));
    Matches matches = index.on(pool).search(RowsView.of(new float[] {0, 1}, 2), 1, arena);
    System.out.println(matches.key(0, 0));
}
DenseMetadataThe geometry and metric a checkpoint froze - everything a reader learns without opening it, and nothing a reader must choose for itself.
DenseIndex.java:282 ↗
record DenseMetadata(
    long dimensions,
    DenseMetric metric,
    Scalar quantization,
    long connectivity);

A checkpoint records neither the placement nor the bound on entries sharing one key: the first says where it was written rather than where a reader must keep it, and the second bounds a live handle's mutable state rather than the serialized form. Both stay the caller's to choose in the lifecycle verb a handle is loaded with.

Mirrors usearch_dense_metadata_t.

Parameters

dimensionsthe scalars per stored vector.
metricthe distance kind the checkpoint scores with.
quantizationthe scalar type its vectors are stored and quantized into.
connectivitythe connections-per-node bound the graph was built with.
DenseIndexDescriptionA live index's state.
DenseIndex.java:310 ↗
record DenseIndexDescription(
    DenseMetadata metadata,
    long size,
    long capacity,
    long memoryUsage,
    String cpuClass,
    String gpuClass,
    long shardsCount);

Each counter is read once, so under concurrent insertions they may come from slightly different moments.

Mirrors usearch_dense_index_description_t.

Parameters

metadatathe frozen metric, quantization, dimensions and connectivity.
sizethe stored entries.
capacitythe entries hosted without growing again.
memoryUsagethe bytes the handle holds; traversal scratch is the executor's.
cpuClassthe CPU class dispatch picked on this machine, as usearch_cpu_class_name spells it.
gpuClassthe GPU class dispatch picked on the index's devices; "unknown" for a host index.
shardsCountthe live shards.
DenseReachabilityOne reachability audit: the population it judged, and how much of it a search reaches.
DenseIndex.java:349 ↗
record DenseReachability(
    long audited,
    long reachable,
    long sweeps,
    long backSweeps);

Mirrors usearch_reachability_t.

Parameters

auditedthe entries published when the audit started; compare reachable against this, never a later size.
reachablethe entries a search reaches; the rest no search finds until a refinement re-links them.
sweepsthe levels the sweep took to converge.
backSweepsthe levels the sweep back toward the entry point took, where an audit sweeps both ways.
RefineReportWhat one refine-family call did to the graph: DenseVerbs#refine(DenseRefineConfig), DenseVerbs#absorb and DenseVerbs#split(DenseSplitConfig, DenseIndex...) land it.
DenseIndex.java:374 ↗
record RefineReport(
    long reselected,
    long changed,
    long islandsFound,
    long islandsReconnected,
    DenseReachability reachability);

Mirrors usearch_refine_report_t.

Parameters

reselectedthe entries whose neighbors were selected again, the islands of every heal round included.
changedof those, the entries whose neighbor set gained a member it lacked; zero means the graph has settled.
islandsFoundthe entries the first audit found not reached both ways.
islandsReconnectedthe links written between an island and an entry reached both ways.
reachabilitythe audit closing the heal, as a fresh DenseVerbs#health() right after would take it.
DenseSoftmaxStateThe online-softmax carry of one query row - Flash Attention's running maximum and partition, which is what lets one attention call's output fold into another's over the same queries.
DenseIndex.java:400 ↗
record DenseSoftmaxState(float maximumScore, float partition);

Mirrors usearch_dense_softmax_state_t.

Parameters

maximumScorethe largest logit seen so far - the recurrence's m.
partitionthe sum of exponentials taken against that maximum - the recurrence's l.
onThe receiver whose verbs block on executor, after the calls submitted there before them.
DenseIndex.java:1594 ↗
On on(Executor executor);

Binding-only.

deferredThe receiver whose verbs submit to executor, each answering a Deferred.
DenseIndex.java:1599 ↗
DeferredOn deferred(Executor executor);

Binding-only.

closeReleases the index, after every deferred call naming it is final.
DenseIndex.java:1858 ↗
void close();

It is idempotent, and a freed handle must not be used again; one the program drops without closing is released once it is unreachable. Calls usearch_dense_free.

toStringRenders the index as the handle it wraps.
DenseIndex.java:1864 ↗
String toString();
initRamCreates an empty, mutable index in host memory, one shard per NUMA node named.
DenseIndex.java:1610 ↗
DenseIndex initRam(DenseOptions options, int[] memoryDomains);

Calls usearch_dense_init_ram.

Parameters

memoryDomainsNUMA node ids to place shards on; an empty list derives every node.
initVramCreates an empty, mutable index in device memory, one shard per device named.
DenseIndex.java:1626 ↗
DenseIndex initVram(DenseOptions options, int[] devices);

Calls usearch_dense_init_vram.

Parameters

devicesCUDA device ordinals to place shards on; an empty list derives one free device.
loadRamCopies a checkpoint into a new index in host memory on the caller's thread, over every memory domain, with no bound on entries per key.
DenseIndex.java:1640 ↗
DenseIndex loadRam(String path);
DenseIndex loadRam(
    String path,
    @Nullable Executor executor,
    int[] memoryDomains,
    @Nullable CPUClass cpuClass,
    long valuesPerKey);

Copies a checkpoint into a new, mutable index in host memory, shard by shard.

The geometry and metric come from the checkpoint's own headers, and part p lands whole on shard p modulo the shard count. Calls usearch_dense_load_ram.

Parameters

executorthe executor the read fans out over, or null for the caller's thread.
memoryDomainsNUMA node ids to place the parts on; an empty list derives every node.
cpuClassthe class the index dispatches as, or null for the CPU's own.
valuesPerKeythe upper bound on entries sharing one key, which no checkpoint records; zero is unbounded.
loadVramUploads a checkpoint into a new index in device memory on the default stream of one free device, with no bound on entries per key.
DenseIndex.java:1677 ↗
DenseIndex loadVram(String path);
DenseIndex loadVram(
    String path,
    @Nullable Executor executor,
    int[] devices,
    @Nullable GPUClass gpuClass,
    long valuesPerKey);

Copies a checkpoint into a new, mutable index in device memory, with the placement rules of loadRam(String, Executor, int[], CPUClass, long).

Calls usearch_dense_load_vram.

Parameters

executorthe executor the upload runs on, or null for each device's default stream.
devicesCUDA device ordinals to place the parts on; an empty list derives one free device.
gpuClassthe class the index dispatches as, or null for the devices' own.
valuesPerKeythe upper bound on entries sharing one key; zero is unbounded.
loadRamBufferCopies a monolith from a buffer into a new index in host memory on the caller's thread, with no bound on entries per key.
DenseIndex.java:1709 ↗
DenseIndex loadRamBuffer(MemorySegment buffer);
DenseIndex loadRamBuffer(
    MemorySegment buffer,
    @Nullable Executor executor,
    int[] memoryDomains,
    @Nullable CPUClass cpuClass,
    long valuesPerKey);

Copies a monolith from a buffer into a new, mutable index in host memory, as loadRam(String, Executor, int[], CPUClass, long) reads a path; the monolith lands whole on the first shard.

A native buffer is read in place, a heap one is copied first. Calls usearch_dense_load_ram_buffer.

loadVramBufferUploads a monolith from a buffer into a new index in device memory on the default stream of one free device, with no bound on entries per key.
DenseIndex.java:1742 ↗
DenseIndex loadVramBuffer(MemorySegment buffer);
DenseIndex loadVramBuffer(
    MemorySegment buffer,
    @Nullable Executor executor,
    int[] devices,
    @Nullable GPUClass gpuClass,
    long valuesPerKey);

Copies a monolith from a buffer into a new, mutable index in device memory, as loadRamBuffer(MemorySegment, Executor, int[], CPUClass, long) does in host memory.

Calls usearch_dense_load_vram_buffer.

viewRamServes a checkpoint in place through a memory mapping, as a read-only index whose mutating verbs report READ_ONLY.
DenseIndex.java:1776 ↗
DenseIndex viewRam(String path);

Nothing is copied, and the files must stay unmodified until the index is closed. Calls usearch_dense_view_ram.

viewNvmeServes a checkpoint in place from NVMe drives on the caller's thread, each part where its manifest points.
DenseIndex.java:1786 ↗
DenseIndex viewNvme(String path);
DenseIndex viewNvme(
    String path,
    @Nullable Executor executor,
    String[] paths,
    @Nullable CPUClass cpuClass);

Serves a checkpoint in place from NVMe drives, read through the executor's submission rings, as a read-only index.

Calls usearch_dense_view_nvme.

Parameters

executorthe NVMe executor whose rings read the headers, or null for the caller's thread.
pathsdevices or directories to serve the parts from; an empty list serves each where its manifest points.
cpuClassthe class the view dispatches as, or null for the CPU's own.
metadataReadReads a checkpoint's geometry and metric on the caller's thread without loading it.
DenseIndex.java:1815 ↗
DenseMetadata metadataRead(String path);
DenseMetadata metadataRead(String path, @Nullable Executor executor);

Reads a checkpoint's geometry and metric without loading it - from the manifest's summary when the path names one, so no shard is opened.

Calls usearch_dense_metadata_read.

metadataReadBufferReads geometry and metric metadata from a serialized monolith on the caller's thread.
DenseIndex.java:1835 ↗
DenseMetadata metadataReadBuffer(MemorySegment buffer);
DenseMetadata metadataReadBuffer(
    MemorySegment buffer,
    @Nullable Executor executor);

Reads geometry and metric metadata from a serialized monolith buffer.

Calls usearch_dense_metadata_read_buffer.

DenseMetricA distance kind supported out of the box, with SIMD kernels dispatched by the machine's capabilities.
DenseIndex.java:92 ↗
enum DenseMetric

All of them derive from a single inner-product kernel with pre-computed magnitudes; Hamming and Jaccard are bit-level, over the packed sub-byte kinds. The C layer's custom-callback escape hatch stays unexposed, since a caller-supplied metric would be scored from engine threads that are not attached to this JVM.

Fields

UNKNOWNA metric the library could not name.
INNERThe inner product.
ANGULARThe cosine distance.
EUCLIDEANThe euclidean distance.
HAMMINGThe count of differing bits.
JACCARDThe bit-level Jaccard distance.
DenseOptionsThe geometry and metric an empty index freezes - the fields usearch_dense_init_ram_t and usearch_dense_init_vram_t share.
DenseIndex.java:151 ↗
class DenseOptions

Every setter returns this instance, so an index is configured in one expression and created by the lifecycle verb that takes it:


try (DenseIndex index = DenseIndex.initRam(
        new DenseOptions().dimensions(768).metric(DenseMetric.ANGULAR).quantization(Scalar.I8),
        new int[0])) {
    index.reserve(1_000_000);
}
DenseTraversalStatsThe traversal telemetry one call reports, fully overwritten by every call it is passed to, so one reading always belongs to one call and a sweep over many batches sums them itself.
DenseIndex.java:415 ↗
class DenseTraversalStats

Mirrors usearch_traversal_stats_t.

ValueLookupResolves the keys a walk scores to their value rows, which the index does not store: each key names one row of values, as row answers it, and a row outside the matrix, a thrown exception, or a matrix of another scalar or width than the call states leaves the key without one, which refuses the call.
DenseIndex.java:472 ↗
class ValueLookup

The function runs on the executor's threads together.

The values are borrowed once, here, and so is the upcall every call hands across: a native slab is read in place and must stay open while the lookup is used, and a heap one is copied once.

Mirrors usearch_value_lookup_t, whose scalar and columns are checked against the matrix. It is a host function, so it serves RAM handles alone: a VRAM walk resolves rows through a device function, which this binding does not build, so an attention into a VRAM arena refuses it with DEVICE.

DenseInsertConfigThe knobs of an insertion; see DenseVerbs#insert(Key[], RowsView, DenseInsertConfig).
DenseIndex.java:564 ↗
class DenseInsertConfig

Mirrors usearch_dense_insert_t.

DenseRefineConfigThe knobs of a refinement; see DenseVerbs#refine(DenseRefineConfig).
DenseIndex.java:595 ↗
class DenseRefineConfig

Mirrors usearch_dense_refine_t.

DenseSplitConfigThe knobs of a split's closing refinements; see DenseVerbs#split(DenseSplitConfig, DenseIndex...).
DenseIndex.java:626 ↗
class DenseSplitConfig

Mirrors usearch_dense_split_t.

DenseSampleConfigThe view a sample grows and how it draws, by default across the whole index with nothing shown yet; see DenseVerbs#sample(long, Arena, DenseSampleConfig).
DenseIndex.java:665 ↗
class DenseSampleConfig

Mirrors usearch_dense_sample_t.

DenseSearchConfigHow many matches a search keeps and the knobs of its walk; see DenseVerbs#search(RowsView, DenseSearchConfig, Arena).
DenseIndex.java:724 ↗
class DenseSearchConfig

Mirrors usearch_dense_search_t.

DenseMaxsimConfigHow many documents a late-interaction search keeps and the knobs of its walk; see DenseVerbs#maxsim(RowsView, long, DenseMaxsimConfig, Arena).
DenseIndex.java:772 ↗
class DenseMaxsimConfig

Mirrors usearch_dense_maxsim_t.

DenseMultiplyConfigHow many pairs a sparse product keeps and the knobs of its walk; see DenseVerbs#multiply(RowsView, DenseMultiplyConfig, Arena).
DenseIndex.java:811 ↗
class DenseMultiplyConfig

Mirrors usearch_dense_multiply_t.

DenseAttendConfigThe knobs of an attention; see DenseVerbs#attend(RowsView, ValueLookup, DenseAttendConfig, Arena).
DenseIndex.java:853 ↗
class DenseAttendConfig

Mirrors usearch_dense_attend_t.

DenseVectorsRows a call wrote into its arena - the entries DenseVerbs#get found under a key, the outputs of DenseVerbs#attend, or the vectors of a DenseBatch - at the width, pitch and scalar the library reported.
DenseIndex.java:919 ↗
class DenseVectors

Valid until the arena's next call or its close.

DenseProductsThe ragged sparse product DenseVerbs#multiply wrote into its arena: per left row, every pair its walk scored, in traversal order; or the keys DenseVerbs#maxsim kept per query, largest score first.
DenseIndex.java:986 ↗
class DenseProducts

Valid until the arena's next call or its close.

SampleThe draws of one DenseVerbs#sample(long, Arena, DenseSampleConfig), written into its arena: the keys drawn, which of its key's entries each is, the shown or earlier draw each hangs from, and where each is placed.
DenseIndex.java:1084 ↗
class Sample

Valid until the arena's next call or its close.

DenseBatchOne pull of a DenseCursor, written into its arena: the keys of the entries passed, and the keys each links to when asked for.
DenseIndex.java:1184 ↗
class DenseBatch

Valid until the arena's next call or its close.

DenseCursorA sequential walk over the index contents, pulled blocking on the executor of the receiver that opened it - export, migration, and visualization feed off it.
DenseIndex.java:1270 ↗
class DenseCursor

It serves one thread at a time, and an overlapping pull reports CONTENDED.

DenseSearchStreamA resumable search over one query, pulled blocking on the executor of the receiver that opened it: the stream keeps the walk's frontier and visited set between pulls and yields matches lazily, holding state rather than a thread.
DenseIndex.java:1354 ↗
class DenseSearchStream
OnThe receiver whose verbs block on an executor, after the calls submitted there before them.
DenseIndex.java:1398 ↗
class On
DeferredOnThe receiver whose verbs submit their calls to an executor, each answering a Deferred that owns what the call reads until final, and whose join answers the view the blocking verb would, over the same borrowed arena.
DenseIndex.java:1425 ↗
class DeferredOn

Its verbs are those of DenseVerbs, which each documents, less the scans that pull one batch at a time.