Two fixes for recently-added HnswGraphBuilder.connectComponents: (#13642)

1. properly set frozen flag to avoid re-duplicative work
2. don't try to join a node to itself
This commit is contained in:
Michael Sokolov 2024-08-10 16:59:38 -04:00 committed by GitHub
parent 5aa1aa98ea
commit f0558ae263
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 8 additions and 3 deletions

View File

@ -180,7 +180,6 @@ public class HnswGraphBuilder implements HnswBuilder {
public OnHeapHnswGraph getCompletedGraph() throws IOException { public OnHeapHnswGraph getCompletedGraph() throws IOException {
if (!frozen) { if (!frozen) {
finish(); finish();
frozen = true;
} }
return getGraph(); return getGraph();
} }
@ -414,6 +413,7 @@ public class HnswGraphBuilder implements HnswBuilder {
void finish() throws IOException { void finish() throws IOException {
connectComponents(); connectComponents();
frozen = true;
} }
private void connectComponents() throws IOException { private void connectComponents() throws IOException {
@ -438,6 +438,7 @@ public class HnswGraphBuilder implements HnswBuilder {
maxConn *= 2; maxConn *= 2;
} }
List<Component> components = HnswUtil.components(hnsw, level, notFullyConnected, maxConn); List<Component> components = HnswUtil.components(hnsw, level, notFullyConnected, maxConn);
// System.out.println("HnswGraphBuilder.connectComponents " + components);
boolean result = true; boolean result = true;
if (components.size() > 1) { if (components.size() > 1) {
// connect other components to the largest one // connect other components to the largest one
@ -448,7 +449,7 @@ public class HnswGraphBuilder implements HnswBuilder {
} }
// try for more connections? We only do one since otherwise they may become full // try for more connections? We only do one since otherwise they may become full
// while linking // while linking
GraphBuilderKnnCollector beam = new GraphBuilderKnnCollector(1); GraphBuilderKnnCollector beam = new GraphBuilderKnnCollector(2);
int[] eps = new int[1]; int[] eps = new int[1];
for (Component c : components) { for (Component c : components) {
if (c != c0) { if (c != c0) {
@ -460,10 +461,14 @@ public class HnswGraphBuilder implements HnswBuilder {
graphSearcher.searchLevel(beam, scorer, 0, eps, hnsw, notFullyConnected); graphSearcher.searchLevel(beam, scorer, 0, eps, hnsw, notFullyConnected);
boolean linked = false; boolean linked = false;
while (beam.size() > 0) { while (beam.size() > 0) {
float score = beam.minimumScore();
int c0node = beam.popNode(); int c0node = beam.popNode();
if (c0node == c.start() || notFullyConnected.get(c0node) == false) {
continue;
}
float score = beam.minimumScore();
assert notFullyConnected.get(c0node); assert notFullyConnected.get(c0node);
// link the nodes // link the nodes
// System.out.println("link " + c0 + "." + c0node + " to " + c + "." + c.start());
link(level, c0node, c.start(), score, notFullyConnected); link(level, c0node, c.start(), score, notFullyConnected);
linked = true; linked = true;
} }