Skip to content

fix(vector): preserve HNSW connectivity when replacing vectors - #375

Open
jarmen423 wants to merge 1 commit into
GrafeoDB:mainfrom
jarmen423:codex/fix-hnsw-vector-replacement
Open

fix(vector): preserve HNSW connectivity when replacing vectors#375
jarmen423 wants to merge 1 commit into
GrafeoDB:mainfrom
jarmen423:codex/fix-hnsw-vector-replacement

Conversation

@jarmen423

@jarmen423 jarmen423 commented Jun 13, 2026

Copy link
Copy Markdown

Summary

  • treat insertion of an existing NodeId as vector replacement
  • remove the old topology entry and stale reciprocal links
  • reconnect the replaced node's former neighborhoods before reinsertion
  • add regression coverage for repeated identical updates and moved vectors

Fixes #374.

Problem

GrafeoDB::set_node_property() auto-syncs vector indexes by calling insert() even when the node is already indexed. HnswIndex::insert() previously overwrote that node's topology entry with fresh empty neighbor lists while other nodes retained reciprocal links to the old entry. Depending on the randomized HNSW level, this could make unrelated nodes unreachable.

A simple remove() followed by insert() prevents stale links but can still disconnect the removed node's former neighborhoods when it was a bridge. This patch reconnects those former neighbors at each shared layer, prunes them to the configured degree, and then performs normal insertion for the replacement vector.

Verification

cargo fmt --all --check
cargo test -p grafeo-engine --test vector_incremental --features vector-index
cargo test -p grafeo-core index::vector::hnsw::tests::test_hnsw_remove --features vector-index

The vector incremental suite passes 10/10 tests, including 60 fresh-database repeated-update iterations and a changed-vector replacement case.


Summary by cubic

Preserves HNSW connectivity when updating vectors via set_node_property(), preventing stale links and unreachable nodes. Adds neighbor reconnection and pruning during replacement, plus regression tests to ensure full reachability.

  • Bug Fixes
    • Treat inserting an existing NodeId as a replacement: remove the old topology and drop stale reciprocal links.
    • Reconnect the removed node’s former neighbors at each shared level, then prune to configured m/m_max; reinsert the new vector and update the entry point if needed.
    • Add tests for repeated identical updates and for moved vectors to verify all nodes remain reachable.

Written for commit 23102d7. Summary will update on new commits.

Review in cubic

@jarmen423
jarmen423 requested a review from StevenBtw as a code owner June 13, 2026 01:21

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vector index auto-sync can corrupt HNSW topology when updating an existing node vector

1 participant