struct DenseSampleConfig Left alone, it draws across the whole index with nothing shown.
get lands every vector stored under a key in its arena, one row per entry sharing the key, converted to the scalar kind as: names.
let vectors = try index.get(key: 42, as: Float.self, arena: arena)
print(vectors.count, vectors.columns, vectors.stride, Array(vectors[0]))cursor() opens a walk over the contents in batches, which is what export and migration want.
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 starts’ own entries first, then the entries those link to breadth-first, each once.
Every pull lands up to wanted keys in its arena, and nextLinks lands the keys each links to beside them; the vectors themselves come from get.
let cursor = try index.on(executor).cursor()
while true {
let batch = try cursor.nextLinks(wanted: 1024, arena: arena)
guard !batch.keys.isEmpty else { break }
print(Array(batch.keys), batch.links[0])
}searchStream opens a resumable nearest-neighbor stream over one query row, so a caller that post-filters aggressively pulls until satisfied rather than guessing a wanted count upfront.
The stream keeps walk state rather than a thread, every pull is an ordinary call on its receiver’s executor, and a failed pull throws.
Ordering beyond the expansion horizon is best-effort nearest rather than globally exact.
The engine declares the stream before implementing it, so opening one reports unsupported for now.
let stream = try index.on(executor).searchStream(query)
while true {
let pulled = try stream.next(wanted: 64, arena: arena)[0] // nearest first, empty once drained
let close = pulled.prefix { $0.distance < 0.25 }
for match in close { print(match.key) }
guard !close.isEmpty, close.count == pulled.count else { break }
}Cursors and streams keep their index alive until they go.
sample draws keys around focus, or across the whole index, each hanging from a shown or earlier draw and placed in three dimensions beside the shown keys already on screen, so a view grows one connected sample as it zooms.
Equal seeds, shown keys and focus draw equally, and a larger wanted draws a superset.
let draws = try index.on(executor).sample(wanted: 256, arena: arena, config: DenseSampleConfig(
shown: shown, shownCoordinates: places, focus: near, seed: 42))
for draw in 0 ..< draws.count {
let (key, entryOrdinal, parent, point) = (draws.keys[draw], draws.entryOrdinal(draw), draws.parents[draw], draws.coordinates[draw])
}DenseSampleConfigThe knobs of sample.9struct DenseSampleConfig Left alone, it draws across the whole index with nothing shown.
shownThe keys already shown: never drawn again, and the paths reach toward them.var shown: [Key] shownCoordinatesWhere each shown key sits, three values apiece, end to end.var shownCoordinates: [Float] focusThe keys to look around; empty looks around the whole index.var focus: [Key] seedEqual seeds, shown keys and focus over an unchanged index draw equally.var seed: UInt64 expansionFactorThe breadth of the candidates of the walks behind the draws; zero derives.var expansionFactor: Int progressCalled with draws made; a stop answers cancelled.var progress: Progress? progressStepsReports the call makes at most, the last at completion; zero derives to ten.var progressSteps: Int statsThe traversal telemetry to write.var stats: DenseTraversalStats? initinit(shown: [Key] = [], shownCoordinates: [Float] = [], focus: [Key] = [], seed: UInt64 = 0, expansionFactor: Int = 0, progress: Progress? = nil, progressSteps: Int = 0, stats: DenseTraversalStats? = nil) DenseSearchStreamInitConfigThe knobs of searchStream.2struct DenseSearchStreamInitConfig expansionFactorThe breadth of the candidates the walk explores; zero derives it from the geometry.var expansionFactor: Int initinit(expansionFactor: Int = 0) DenseVectorsThe rows get or attend wrote into an arena, one per entry sharing the key or per query, read in place as Value.5struct DenseVectors<Value> where Value : ScalarValue RandomAccessCollection, BidirectionalCollection, Collection, SequenceendIndexOne past the last row the call wrote.let endIndex: Int startIndexThe first row's position, which a collection walk starts from.var startIndex: Int { get } strideThe bytes between consecutive rows, as the library reported them.var stride: Int { get } columnsThe logical values in each row, as the library reported them.var columns: Int { get } subscriptOne row's stored values, packed at their natural width.subscript(row: Int) -> Row { get } DenseVectors.RowOne row of the arena's values, read in place.3struct Row RandomAccessCollection, BidirectionalCollection, Collection, SequenceendIndexOne past the last value in the row.let endIndex: Int startIndexThe first value's position, which a collection walk starts from.var startIndex: Int { get } subscriptThe value at a position.subscript(position: Int) -> Value { get } DenseKeysThe keys a cursor pull wrote into an arena, in walk order.3struct DenseKeys RandomAccessCollection, BidirectionalCollection, Collection, SequenceendIndexOne past the last key the call wrote.let endIndex: Int startIndexThe first key's position, which a collection walk starts from.var startIndex: Int { get } subscriptThe key at a position.subscript(position: Int) -> Key { get } DenseDrawsThe draws sample wrote into an arena, one per draw: its key, which of that key's entries it is, the shown or earlier draw it hangs from, and where it is placed, read in place.5struct DenseDraws keysThe drawn keys.let keys: DenseKeys parentsEach draw's parent and its distance, one column per draw, a root holding none.let parents: Matches coordinatesWhere each draw is placed, one row of three values apiece.let coordinates: DenseVectors<Float> countThe draws written; fewer than wanted only once the region is exhausted.var count: Int { get } entryOrdinalWhich of its key's entries one draw is, in the order get writes them.func entryOrdinal(_ draw: Int) -> Int DenseLinksThe keys each entry of a cursor pull links to, wrote into an arena as a ragged run and read in place.3struct DenseLinks RandomAccessCollection, BidirectionalCollection, Collection, SequenceendIndexOne past the last entry the pull wrote.let endIndex: Int startIndexThe first entry's position, which a collection walk starts from.var startIndex: Int { get } subscriptThe keys one entry links to, as the graph stored them when the pull ran.subscript(entry: Int) -> [Key] { get } DenseCursorA walk over an index's contents; see DenseIndex.cursor().2final class DenseCursor The walk is sequential, so it stays a batch operation - export, migration, and visualization all move whole batches. Every pull blocks on the executor of the receiver that opened it, and the cursor keeps its index alive.
nextCopies up to wanted next keys into arena, walking the key column alone; an empty batch means the walk is exhausted.func next(wanted: Int, arena: Arena) throws(USearchError) -> DenseKeys nextLinksCopies up to wanted next keys into arena, each with the keys it links to; an empty batch means the walk is exhausted.func nextLinks(
wanted: Int,
arena: Arena
) throws(USearchError) -> (keys: DenseKeys, links: DenseLinks) The vectors themselves come from get.
DenseSearchStreamA resumable nearest-neighbor stream over one query; see DenseIndex.searchStream.1final class DenseSearchStream Best-first traversal is naturally pausable, so the stream keeps a live frontier and visited set and yields matches lazily. Ordering beyond the expansion horizon is best-effort nearest rather than globally exact, so pulling far past that breadth degrades the ranking rather than ending the stream. Every pull blocks on the executor of the receiver that opened it.
nextPulls up to wanted more matches into arena, as the one query of a search, nearest first; an empty query means the traversal is drained.func next(wanted: Int, arena: Arena) throws(USearchError) -> Matches