Zig · Refinement

Refinement

const usearch = @import("usearch"); 3.0.0-rc.1 · 4c3e5023

refine re-selects the neighbors of every stored entry against the finished graph and returns a DenseRefineReport: the entries re-selected and changed, the islands found and reconnected, and the closing audit. A cheap insertion pass followed by one refinement reaches a better graph in less total time than one expensive insertion pass. Zero changed means the graph has settled, and on a RAM index searches may run throughout.

while ((try index.on(executor).refine(.{ .expansion_factor = 128 })).changed != 0) {}

§ Absorbing

absorb moves donor handles into one index, one after another, keeping their graphs rather than re-inserting their vectors, then refines every shard that took one across the appended part. A donor 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 freeing every donor afterwards is safe, and a stop between donors, or a failure, leaves the rest live for their deinit to free.

var donors = [_]usearch.DenseIndex{ first, second };
_ = try index.on(executor).absorb(&donors, .{});
for (&donors) |*donor| donor.deinit(); // frees only the donors a stop or a failure left live

split is the inverse: it hands graph-local parts of the index to empty receivers of the same configuration, one part each, keeping their edges and leaving the index empty but live. It reports the receivers’ closing refines as refine does.

const report = try index.on(executor).split(&receivers, .{ .seed = 42 });

API

Types

DenseRefineReportWhat one refine, absorb or split did to the graph.
pub const DenseRefineReport = extern struct

Mirrors usearch_refine_report_t.

Fields

reselectedusizeEntries whose neighbors were selected again, the islands of every heal round included.
changedusizeOf those, the entries whose neighbor set gained a member it lacked.
islands_foundusizeEntries the first audit found not reached both ways.
islands_reconnectedusizeLinks written between an island and an entry the audit reached both ways.
reachabilityDenseReachabilityThe audit closing the heal, as a fresh health right after would take it.
DenseRefineConfigOptional settings of DenseIndex.refine.
pub const DenseRefineConfig = struct

Fields

expansion_factorusizeThe breadth of the candidates the re-selection walk explores; zero derives.
progressProgressCallbackCalled with nodes swept; a stop is a time budget rather than a failure.
progress_stepsusizeReports the call makes at most, the last at completion; zero derives to ten.
stats?*DenseTraversalStats
DenseAbsorbConfigOptional settings of DenseIndex.absorb.
pub const DenseAbsorbConfig = struct

Fields

progressProgressCallbackCalled with donors absorbed; a stop between donors keeps those already absorbed.
progress_stepsusizeReports the call makes at most, the last at completion; zero derives to ten.
DenseSplitConfigOptional settings of DenseIndex.split.
pub const DenseSplitConfig = struct

Fields

seedu64Picks the part roots: equal seeds over an unchanged index split equally.
expansion_factorusizeThe breadth of the candidates of the closing refines' walks; zero derives.
progressProgressCallbackCalled with nodes the closing refines re-selected; a stop never undoes a move.
progress_stepsusizeReports the call makes at most, the last at completion; zero derives to ten.
stats?*DenseTraversalStats
DenseRefineOne DenseIndex.refine, as a Deferred holds it.
pub const DenseRefine = struct

Fields

DenseAbsorbOne DenseIndex.absorb, as a Deferred holds it.
pub const DenseAbsorb = struct

Fields

DenseSplitOne DenseIndex.split, as a Deferred holds it.
pub const DenseSplit = struct

Fields

receivers[]const DenseIndex
configDenseSplitConfig
reportDenseRefineReport
outcomeOutcome