You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by be...@apache.org on 2025/01/28 13:34:48 UTC
(lucene) branch main updated: Make knn graph conn writing more consistent (#14174)
This is an automated email from the ASF dual-hosted git repository.
benwtrent pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/main by this push:
new cab88cafb17 Make knn graph conn writing more consistent (#14174)
cab88cafb17 is described below
commit cab88cafb1715c8844b69e366b7c8558c3c5f7d0
Author: Benjamin Trent <be...@gmail.com>
AuthorDate: Tue Jan 28 08:34:41 2025 -0500
Make knn graph conn writing more consistent (#14174)
* Make graph writing more consistent
* correct concurrent connected components logic
---
.../codecs/lucene99/Lucene99HnswVectorsWriter.java | 29 ++++++++++++++--------
.../util/hnsw/HnswConcurrentMergeBuilder.java | 4 +--
2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99HnswVectorsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99HnswVectorsWriter.java
index 4983fdec6bf..e219157ab98 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99HnswVectorsWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99HnswVectorsWriter.java
@@ -243,13 +243,14 @@ public final class Lucene99HnswVectorsWriter extends KnnVectorsWriter {
nodesByLevel.add(null);
int maxOrd = graph.size();
+ int[] scratch = new int[graph.maxConn() * 2];
NodesIterator nodesOnLevel0 = graph.getNodesOnLevel(0);
levelNodeOffsets[0] = new int[nodesOnLevel0.size()];
while (nodesOnLevel0.hasNext()) {
int node = nodesOnLevel0.nextInt();
NeighborArray neighbors = graph.getNeighbors(0, newToOldMap[node]);
long offset = vectorIndex.getFilePointer();
- reconstructAndWriteNeighbours(neighbors, oldToNewMap, maxOrd);
+ reconstructAndWriteNeighbours(neighbors, oldToNewMap, scratch, maxOrd);
levelNodeOffsets[0][node] = Math.toIntExact(vectorIndex.getFilePointer() - offset);
}
@@ -266,7 +267,7 @@ public final class Lucene99HnswVectorsWriter extends KnnVectorsWriter {
for (int node : newNodes) {
NeighborArray neighbors = graph.getNeighbors(level, newToOldMap[node]);
long offset = vectorIndex.getFilePointer();
- reconstructAndWriteNeighbours(neighbors, oldToNewMap, maxOrd);
+ reconstructAndWriteNeighbours(neighbors, oldToNewMap, scratch, maxOrd);
levelNodeOffsets[level][nodeOffsetIndex++] =
Math.toIntExact(vectorIndex.getFilePointer() - offset);
}
@@ -313,25 +314,33 @@ public final class Lucene99HnswVectorsWriter extends KnnVectorsWriter {
};
}
- private void reconstructAndWriteNeighbours(NeighborArray neighbors, int[] oldToNewMap, int maxOrd)
- throws IOException {
+ private void reconstructAndWriteNeighbours(
+ NeighborArray neighbors, int[] oldToNewMap, int[] scratch, int maxOrd) throws IOException {
int size = neighbors.size();
- vectorIndex.writeVInt(size);
-
// Destructively modify; it's ok we are discarding it after this
int[] nnodes = neighbors.nodes();
for (int i = 0; i < size; i++) {
nnodes[i] = oldToNewMap[nnodes[i]];
}
Arrays.sort(nnodes, 0, size);
+ int actualSize = 0;
+ if (size > 0) {
+ scratch[0] = nnodes[0];
+ actualSize = 1;
+ }
// Now that we have sorted, do delta encoding to minimize the required bits to store the
// information
- for (int i = size - 1; i > 0; --i) {
+ for (int i = 1; i < size; i++) {
assert nnodes[i] < maxOrd : "node too large: " + nnodes[i] + ">=" + maxOrd;
- nnodes[i] -= nnodes[i - 1];
+ if (nnodes[i - 1] == nnodes[i]) {
+ continue;
+ }
+ scratch[actualSize++] = nnodes[i] - nnodes[i - 1];
}
- for (int i = 0; i < size; i++) {
- vectorIndex.writeVInt(nnodes[i]);
+ // Write the size after duplicates are removed
+ vectorIndex.writeVInt(actualSize);
+ for (int i = 0; i < actualSize; i++) {
+ vectorIndex.writeVInt(scratch[i]);
}
}
diff --git a/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswConcurrentMergeBuilder.java b/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswConcurrentMergeBuilder.java
index d2e81addc5d..d9d58c829d3 100644
--- a/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswConcurrentMergeBuilder.java
+++ b/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswConcurrentMergeBuilder.java
@@ -90,9 +90,7 @@ public class HnswConcurrentMergeBuilder implements HnswBuilder {
});
}
taskExecutor.invokeAll(futures);
- finish();
- frozen = true;
- return workers[0].getCompletedGraph();
+ return getCompletedGraph();
}
@Override