

HnswGraph
- Namespace
- Rowles.LeanLucene.Codecs.Hnsw
- Assembly
- Rowles.LeanLucene.dll
In-memory hierarchical navigable small world graph. Vectors are expected to be L2-normalised so that dot product equals cosine similarity; the graph itself works in distance space (lower is better) with distance defined as negative dot product.
internal sealed class HnswGraph
Remarks
The graph supports two lifecycle states. While mutable (the default after construction) only single-threaded use is permitted: Insert(int) mutates internal adjacency lists without locks. Once Freeze() has been called, search becomes thread-safe and lock-free; mutation is no longer permitted.
Pruning uses the diversity-preserving heuristic from the original HNSW paper rather than the simple top-M variant, which gives materially better recall on clustered embedding spaces typical of real-world workloads.
Constructors
Properties
EfConstruction
Candidate set size used during graph construction.
IsReadOnly
True once Freeze() has been called; mutation is prohibited and search is thread-safe.
LevelCount
Number of layers including layer zero.
M
Maximum neighbours per node on layers above zero.
M0
Maximum neighbours per node on layer zero (typically
2 * M).
Seed
Seed used by the random number generator. Persisted to the .hnsw file for reproducibility.
Methods
ContainsNode(int)
True if a node with the given id is already present at layer 0.
Freeze()
Marks the graph as immutable. Required before search can be called concurrently.
FromFrozen(IVectorSource, HnswBuildConfig, long, List<Dictionary<int, int[]>>, int, int, int)
Builds an HnswGraph from pre-loaded adjacency. Used by the reader to materialise a graph from a .hnsw file. The graph is created in the read-only state immediately.
GetNeighbours(int, int)
Returns the neighbours of a node at a given layer. Used by the writer.
GetNodesAtLevel(int)
Enumerates every document identifier present at a given layer. Used by the writer.
Insert(int)
Inserts a node into the graph. The node's vector must already be present in the source.
Search(ReadOnlySpan<float>, HnswSearchOptions)
Searches the graph for the closest documents to a query vector. Safe for concurrent callers once Freeze() has been called.
Search(ReadOnlySpan<float>, HnswSearchOptions, out HnswSearchStats)
Searches the graph and returns per-call statistics for diagnostics and metrics.
Thaw()
Reverses Freeze(): copies frozen adjacency back into the mutable structure so further Insert(int) calls are permitted. Used by incremental merge to seed a new graph from the largest input segment's existing graph.