# Executors

> USearch for Java

An executor owns the host threads or device streams a fanned-out verb runs on; an index owns entries.
Keeping them apart is what lets one pool serve several indexes, and what makes the cost of spawning visible at the line that spawns.
Its residency must match the residency of every handle it drives.
The index itself runs a call on the calling thread instead: single-threaded on RAM, on the handle's device and default stream on VRAM.

There is one factory per C constructor, and each takes every argument its C twin takes.

```java
Executor.forRam(new int[] {0, 1}, null, 16);                        // two NUMA nodes, sixteen workers
Executor.forRam(new int[0], CPUClass.INTEL_HASWELL, 0);             // waiters and atomics of one class
Executor.onPool(forkUnionPool, new int[0], null);                   // a thread pool the caller already runs
Executor.forVram(new int[] {0, 1, 2, 3}, null, new MemorySegment[0], 0); // four devices, own streams
Executor.forNvme(new String[] {"/mnt/a", "/mnt/b"}, null, 8);       // two drives, eight submission rings
```

`forVram` takes no thread count: one host thread keeps every device fed, so the width of that pool is the device list itself.
It borrows one CUDA stream per device when given them, and caps scratch bytes per device at a non-zero `scratchLimit`.
Naming no hardware derives it: an empty domain list spreads over every memory domain the process may allocate on, an empty device list opens one free device, and an empty path list leaves every shard where its manifest already points.

```java
try (Executor pool = Executor.forRam(new int[0], null, 16)) {
    DenseIndex.On receiver = index.on(pool);
    receiver.insert(keys, vectors);
    Matches matches = receiver.search(queries, 10, arena);
    receiver.save("index.safegraphs");
    pool.drain(Mood.PARKED);
}
```

One call holds an executor at a time, and handles themselves stay freely concurrent.
`drain` waits until no call holds the executor, then sets what it does once idle: `Mood.PARKED` lets its threads sleep, `Mood.SPINNING` keeps them hot for the next call's latency.

### Concurrency

A handle may be shared across threads.
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.

Every call leases the index it names through the FFM scope its handle lives in, so closing an index while another thread's blocking call still runs on it raises `IllegalStateException` rather than freeing the handle under that call; deferred calls are waited for by the close itself.
A pull leases its cursor or stream in place of the index, and a call leases one scope only, so an executor, or the index under a pull, is closed once no other thread still calls through it.
An index, executor, arena or deferred call the program drops without closing is released once it is unreachable, and never while a call naming it is unfinished.

### Receivers & Deferred Calls

The receiver chooses how a call completes, and the verb stays the same.
`DenseIndex` runs a verb on the caller's thread, `index.on(executor)` answers an `On` whose verbs block on that executor, and `index.deferred(executor)` answers a `DeferredOn` whose verbs submit there and answer a `Deferred`.
A `Deferred` owns its outcome, its argument structure and its inputs until the call is final; `status` polls without blocking, and `join` blocks, then answers or raises.
It borrows the index, executor and arena it names exactly as a blocking call does, and `join` answers the same view a blocking call would, over that arena.

```java
try (Arena arena = new Arena(pool);
        Deferred<Matches> call = index.deferred(pool).search(queries, 10, arena)) {
    if (call.status() == Status.DEFERRED) {
        // other work
}
    Matches matches = call.join();    // valid until the next call given `arena`
}
```

The first `join` frees the outcome and keeps what it answered or raised, so a later `status` or `join` repeats it; only a closed `Deferred` raises `IllegalStateException`.
Closing an unfinished `Deferred` waits for the call before freeing what it lent, so a native slab lent to one must stay open until then.
Dropping one never blocks the collector: what it lent stays reachable until the call is final, and only then is it freed.
One call holds an executor at a time, so a second call finding it held finishes with `Status.CONTENDED`, and nothing queues.
A deferred call on a caller-exclusive pool runs on the pool's thread 0, so polling `status` alone finishes it, and its progress handler and predicate run on the pool's threads; a single thread or a VRAM executor runs it at submission.
Calls depending on each other are ordered by joining the first before submitting the second, since no call carries an ordering field.

`import cloud.unum.usearch.*;`

## Mood

What an executor does with its threads or streams once it goes idle.

```java
enum Mood
```

- `PARKED` ``: Idle threads sleep; the next call pays a wake-up.
- `SPINNING` ``: Idle threads stay hot, trading power for the next call's latency.

## Executor

The workers every fanned-out verb runs on, shared across indexes: an executor owns host threads or device streams and their scratch, an index owns entries.

```java
class Executor
```

One factory per C constructor, each taking every argument its own kind takes: memory domains and a thread count for RAM, a borrowed ForkUnion pool, device ordinals and optional streams for VRAM, where a single host thread drives one stream per device, and device paths and a thread count for NVMe. Naming no hardware derives it, a zero deferred limit takes the default size of the deferred-call table, and the kind must match the residency of every handle it drives.

A receiver names the executor its verbs run on, and the index alone runs them on the caller's thread. Calls on one executor run in submission order; handles stay freely concurrent.

```
try (Executor pool = Executor.forRam(new int[] {0, 1}, null, 16, 0);
        DenseIndex index = DenseIndex.initRam(new DenseOptions().dimensions(256), new int[0])) {
    index.on(pool).insert(keys, vectors);
    pool.drain(Mood.PARKED);
}
```

## Deferred

A submitted call, which owns its outcome, argument structure and inputs, and borrows its handles and arena, until the call is final.

```java
template <Result>
class Deferred
```

`status()` polls without blocking and `join()` blocks until the call is final, then answers what it produced or raises what it reported; the first join frees the outcome and every later one repeats its answer. Closing an unfinished one waits for the call before freeing what it lent, and a dropped one keeps what it lent until the call is final, when the collector frees it without ever waiting. It starts no thread: waiting off the caller's thread is the caller's own, as withContext(Dispatchers.IO) { call.join() } in a Kotlin coroutine or a virtual thread in Java.

Binding-only; joining and closing call usearch_outcome_wait.

## On

The blocking verbs of a dense index, written once for the two receivers that block: the `[DenseIndex](https://www.unum.cloud/docs/usearch/java/metrics.md#DenseIndex)` itself, which runs every call on the caller's thread, and the `[DenseIndex.On](https://www.unum.cloud/docs/usearch/java/metrics.md#On)` that `DenseIndex#on` makes, which runs it on an executor.

```java
class On
```

The `[DenseIndex.DeferredOn](https://www.unum.cloud/docs/usearch/java/metrics.md#DeferredOn)` that `DenseIndex#deferred` makes offers the same verbs, each answering a `[Types.Deferred](#Deferred)`.

Every verb that takes knobs beyond its inputs has a bare form and one taking its Dense*Config, named after the C structure it fills. Every verb whose output scales with the call takes an `[Arena](https://www.unum.cloud/docs/usearch/java/inputs-and-outputs.md#Arena)` last, borrows it until it returns, and answers a view over it that the arena's next call invalidates.

Binding-only; every verb names the C symbol it calls.

## reserve

Claims capacity for a number of incoming vectors ahead of insertion, a hint, since insertions grow the index on demand.

```java
void reserve(long capacity);
```

The capacity is the desired total, including the current size. Calls usearch_dense_reserve.

- `capacity`: the desired total number of entries, including the current size.

## clear

Erases all entries, keeping the reserved capacity and the frozen geometry.

```java
void clear();
```

No other call may overlap it. Calls usearch_dense_clear.

## describe

Reports the frozen metadata and the current counters in one call.

```java
DenseIndexDescription describe();
```

Calls usearch_dense_describe.

## count

How many entries are stored under a key; zero means the index holds none.

```java
long count(Key key);
```

Calls usearch_dense_count.

- `key`: the key to look up.

## contains

Whether the index holds at least one entry under a key.

```java
boolean contains(Key key);
```

Binding-only sugar over `[count](#count)`.

- `key`: the key to look up.

## get

Retrieves every vector stored under a key into arena, one row per entry sharing it, in insertion order, packed at the natural width of the kind asked for - one call, however many there turn out to be.

```java
DenseVectors get(Key key, Scalar outputsScalar, Arena arena);
```

Calls usearch_dense_get.

- `key`: the key to look up.
- `outputsScalar`: the scalar kind the rows are converted into.
- `arena`: the arena the output lands in, borrowed until the call returns.

## insert

Inserts a matrix of vectors under their keys, with every knob derived.

```java
void insert(Key[] keys, RowsView vectors);
```

```java
void insert(Key[] keys, RowsView vectors, DenseInsertConfig config);
```

Inserts a matrix of vectors under their keys - the native batch operation, where a single vector is a one-row matrix.

Overlaps safely with concurrent searches on the same handle.

The input scalar type is independent of the stored quantization; the library converts on ingest. A batch is all-or-nothing: a returning call published every entry, a failing one published none. An accelerator fault severe enough to poison the device context is the sole exception, reporting DEVICE and latching the index unusable rather than partially applied. Calls usearch_dense_insert.

- `keys`: one key per vector row.
- `vectors`: the rows to insert, of any scalar kind the engine converts.
- `config`: the insertion knobs.

## refine

Re-selects the neighbors of every stored entry, with every knob derived.

```java
RefineReport refine();
```

```java
RefineReport refine(DenseRefineConfig config);
```

Re-selects the neighbors of every stored entry against the finished graph, improving neighbors chosen when the graph around them was still incomplete.

Searches may run throughout on a RAM handle, since re-selection publishes one node at a time and never removes one; insertions may not. Re-selecting a settled node changes nothing, so a caller loops until the report's changed falls below whatever rate it considers settled. Calls usearch_dense_refine.

- `config`: the refinement knobs.

## health

Audits how much of the graph a search reaches: forward reachability from as many landmarks as one search draws, swept level by level.

```java
DenseReachability health();
```

Read-only, so concurrent insertions merely leave fresh entries unaudited. Calls usearch_dense_health.

## search

Resolves a matrix of queries into up to wanted nearest matches apiece, with every other knob derived.

```java
Matches search(RowsView queries, long wanted, Arena arena);
```

```java
Matches search(RowsView queries, DenseSearchConfig config, Arena arena);
```

Resolves a matrix of queries into arena - the native batch operation, parallelized internally.

Never writes to the graph, so any number of these may overlap with concurrent insertions. Calls usearch_dense_search.

- `queries`: the query rows, as wide as the frozen geometry.
- `wanted`: the most matches kept per query.
- `arena`: the arena the output lands in, borrowed until the call returns.
- `config`: the wanted count and the other search knobs.

## maxsim

Late-interaction scoring keeping up to wanted keys per query, zero keeping every key a query scored, with every other knob derived.

```java
DenseProducts maxsim(
    RowsView queries,
    long rowsPerQuery,
    long wanted,
    Arena arena);
```

```java
DenseProducts maxsim(
    RowsView queries,
    long rowsPerQuery,
    DenseMaxsimConfig config,
    Arena arena);
```

Late-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.

A document is one key holding its token rows, so the wanted count is the "k" over keys rather than over rows.

Every query carries the same number of rows, so a padded token batch applies as is, and the query count is the row count divided by that. Approximate in the same way a search is: a key can score below its exact value but never above it. Runs on the inner-product kinds alone. Each query's keys land in arena largest score first, as one ragged output like `[multiply](#multiply)`'s. Calls usearch_dense_maxsim.

- `queries`: the query rows, as wide as the frozen geometry.
- `rowsPerQuery`: the token rows every query carries.
- `wanted`: the most keys kept per query, zero keeping every key it scored.
- `arena`: the arena the output lands in, borrowed until the call returns.
- `config`: the wanted count and the other scoring knobs.

## multiply

Approximate sparse product keeping every pair, with every other knob derived.

```java
DenseProducts multiply(RowsView left, Arena arena);
```

```java
DenseProducts multiply(
    RowsView left,
    DenseMultiplyConfig config,
    Arena arena);
```

Approximate sparse product of a matrix against the indexed vectors - the linear-algebra sibling of `[search](#search)`, reporting every pair the traversal scored rather than only the nearest.

Pairs arrive in traversal order, and the pairs the walk never reaches are the low and negative products. Runs on the inner-product kinds alone.

Only the call knows how many pairs it scores, so the keys, the products and their offsets land in arena as one ragged output. Calls usearch_dense_multiply.

- `left`: the rows multiplied against the indexed vectors.
- `arena`: the arena the output lands in, borrowed until the call returns.
- `config`: the product knobs.

## attend

Softmax attention with every knob derived.

```java
DenseVectors attend(
    RowsView queries,
    ValueLookup valueLookup,
    Arena arena);
```

```java
DenseVectors attend(
    RowsView queries,
    ValueLookup valueLookup,
    DenseAttendConfig config,
    Arena arena);
```

Softmax attention of every query row over every indexed key its walk scores, folded as Flash Attention folds key tiles, with no top-k cut, writing one row per query into arena already divided by the partition.

Runs on the inner-product kinds alone, since a softmax needs logits.

The index holds one layer's keys for one key-value head and no values, so the lookup resolves every scored key to its value row. Calls usearch_dense_attend.

- `queries`: the query rows, as wide as the frozen geometry.
- `valueLookup`: resolves every scored key to its value row.
- `arena`: the arena the output lands in, borrowed until the call returns.
- `config`: the attention knobs.

## absorb

Absorbs every donor into this index, one after another, keeping their graphs rather than re-inserting their vectors and linking each in across the appended part.

```java
RefineReport absorb(DenseIndex... donors);
```

Every donor refuses every verb until the call is final; then each one absorbed stays closed, and one it did not absorb is a live index again, which the caller still owns, though its entries may already have moved here. Calls usearch_dense_absorb.

- `donors`: the indexes absorbed, of this index's residency, scalar, metric and geometry.

## split

Splits this index into the empty receivers, the inverse of `[absorb](#absorb)`: the entries are partitioned along the graph, each part lands in one receiver with its edges kept, and a closing refinement re-links every receiver, leaving this index empty and live.

```java
RefineReport split(DenseSplitConfig config, DenseIndex... receivers);
```

Calls usearch_dense_split.

- `config`: the partitioning knobs.
- `receivers`: at least two empty indexes matching this one, which take the parts.

## sample

Draws keys around the focus, or across the whole index, each hanging from a shown or earlier draw and placed in three dimensions beside the shown ones - so a view grows one connected sample as it zooms.

```java
Sample sample(long wanted, Arena arena, DenseSampleConfig config);
```

Writes up to wanted draws, and a larger count under the same seed draws a superset; only a RAM index samples yet. Calls usearch_dense_sample.

- `wanted`: the most draws written.
- `arena`: the arena the output lands in, borrowed until the call returns.
- `config`: the focus, seed and other sampling knobs.

## save

Writes the index under a path, in the layout its extension picks - one .safegraphs monolith, or a .safegraphs.json manifest beside its shards.

```java
void save(String path);
```

Demands a mutation-free window; concurrent readers keep searching throughout. Calls usearch_dense_save.

- `path`: the destination; its extension picks the layout.

## saveBuffer

Writes the index as one monolith - every shard, entries in placement order - the same bytes `[save](#save)` writes to a .safegraphs path, into arena.

```java
Monolith saveBuffer(Arena arena);
```

Calls usearch_dense_save_buffer.

- `arena`: the arena the output lands in, borrowed until the call returns.

## cursor

Opens a walk over the current contents, pulled on this receiver's executor.

```java
DenseCursor cursor(Key... starts);
```

Each shard's publication watermark is read as the walk enters it, so an entry once passed is never revisited. Without starts it yields every entry as stored; with them, the start keys' own entries first in order, then the entries those link to breadth-first, each once. Calls usearch_dense_cursor_init.

- `starts`: the keys whose entries the walk starts from, or none to yield every entry.

## searchStream

Opens a resumable search for one query row, with the breadth of the candidates derived.

```java
DenseSearchStream searchStream(RowsView query);
```

```java
DenseSearchStream searchStream(RowsView query, long expansionFactor);
```

Opens a resumable search for one query row, pulled on this receiver's executor: best-first traversal is naturally pausable, so callers that post-filter aggressively pull until satisfied instead of guessing the wanted count upfront.

Calls usearch_dense_search_stream_init.

- `query`: exactly one query row.
- `expansionFactor`: the breadth of the candidates, zero to derive it.

