Skip to content

Commit 323773e

Browse files
committed
Add default graph build progress logging
1 parent bc720f7 commit 323773e

1 file changed

Lines changed: 33 additions & 10 deletions

File tree

engine/src/main/java/com/arcadedb/index/vector/LSMVectorIndex.java

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,29 @@ private void buildGraphFromScratch(final GraphBuildCallback graphCallback) {
784784
* @param graphCallback Optional callback for graph build progress
785785
*/
786786
private void buildGraphFromScratchWithRetry(final GraphBuildCallback graphCallback) {
787+
// Always have a progress reporter: if caller didn't provide one, log throttled progress every ~2s
788+
final GraphBuildCallback effectiveGraphCallback;
789+
if (graphCallback != null) {
790+
effectiveGraphCallback = graphCallback;
791+
} else {
792+
final long[] lastLogTimeMs = {System.currentTimeMillis()};
793+
final int[] lastLoggedProcessed = {-1};
794+
effectiveGraphCallback = (phase, processedNodes, totalNodes, vectorAccesses) -> {
795+
if (totalNodes <= 0)
796+
return;
797+
798+
final long now = System.currentTimeMillis();
799+
final boolean shouldLog = processedNodes == totalNodes
800+
|| (now - lastLogTimeMs[0] >= 2000 && processedNodes != lastLoggedProcessed[0]);
801+
802+
if (shouldLog) {
803+
LogManager.instance().log(this, Level.INFO,
804+
"Graph build %s: %d/%d (vector accesses=%d)", phase, processedNodes, totalNodes, vectorAccesses);
805+
lastLogTimeMs[0] = now;
806+
lastLoggedProcessed[0] = processedNodes;
807+
}
808+
};
809+
}
787810
// CRITICAL FIX: Collect vectors DIRECTLY from pages instead of from vectorIndex.
788811
// This avoids race conditions where concurrent replication adds entries to vectorIndex
789812
// that don't yet exist on disk pages. We iterate pages and read what's actually persisted.
@@ -966,14 +989,14 @@ private void buildGraphFromScratchWithRetry(final GraphBuildCallback graphCallba
966989

967990
// Report validation progress
968991
validatedCount++;
969-
if (graphCallback != null && validatedCount % VALIDATION_PROGRESS_INTERVAL == 0) {
970-
graphCallback.onGraphBuildProgress("validating", validatedCount, totalVectorsToValidate, 0);
992+
if (effectiveGraphCallback != null && validatedCount % VALIDATION_PROGRESS_INTERVAL == 0) {
993+
effectiveGraphCallback.onGraphBuildProgress("validating", validatedCount, totalVectorsToValidate, 0);
971994
}
972995
}
973996

974997
// Final validation progress report
975-
if (graphCallback != null && validatedCount > 0) {
976-
graphCallback.onGraphBuildProgress("validating", validatedCount, totalVectorsToValidate, 0);
998+
if (effectiveGraphCallback != null && validatedCount > 0) {
999+
effectiveGraphCallback.onGraphBuildProgress("validating", validatedCount, totalVectorsToValidate, 0);
9771000
}
9781001

9791002
if (skippedDeletedDocs > 0) {
@@ -1034,7 +1057,7 @@ private void buildGraphFromScratchWithRetry(final GraphBuildCallback graphCallba
10341057
// Start progress monitoring thread if callback provided
10351058
final Thread progressMonitor;
10361059
final AtomicBoolean buildComplete = new AtomicBoolean(false);
1037-
if (graphCallback != null) {
1060+
if (effectiveGraphCallback != null) {
10381061
final int totalNodes = vectors.size();
10391062
progressMonitor = new Thread(() -> {
10401063
try {
@@ -1044,7 +1067,7 @@ private void buildGraphFromScratchWithRetry(final GraphBuildCallback graphCallba
10441067
final int insertsInProgress = builder.insertsInProgress();
10451068

10461069
// Report progress
1047-
graphCallback.onGraphBuildProgress("building", nodesAdded, totalNodes, nodesAdded + insertsInProgress);
1070+
effectiveGraphCallback.onGraphBuildProgress("building", nodesAdded, totalNodes, nodesAdded + insertsInProgress);
10481071

10491072
// Sleep briefly before next poll
10501073
Thread.sleep(100); // Poll every 100ms
@@ -1102,8 +1125,8 @@ private void buildGraphFromScratchWithRetry(final GraphBuildCallback graphCallba
11021125
LogManager.instance().log(this, Level.FINE, "Writing vector graph to disk for index: %s (nodes=%d)", indexName, totalNodes);
11031126

11041127
// Report persistence phase start
1105-
if (graphCallback != null)
1106-
graphCallback.onGraphBuildProgress("persisting", 0, totalNodes, 0);
1128+
if (effectiveGraphCallback != null)
1129+
effectiveGraphCallback.onGraphBuildProgress("persisting", 0, totalNodes, 0);
11071130

11081131
// Start a dedicated transaction for graph persistence with chunked commits
11091132
long chunkSizeMB = getTxChunkSize();
@@ -1132,8 +1155,8 @@ private void buildGraphFromScratchWithRetry(final GraphBuildCallback graphCallba
11321155
graphFile.writeGraph(graphIndex, vectors, chunkSizeMB, chunkCallback);
11331156

11341157
// Report persistence completion
1135-
if (graphCallback != null) {
1136-
graphCallback.onGraphBuildProgress("persisting", totalNodes, totalNodes, 0);
1158+
if (effectiveGraphCallback != null) {
1159+
effectiveGraphCallback.onGraphBuildProgress("persisting", totalNodes, totalNodes, 0);
11371160
}
11381161

11391162
// Commit the transaction to persist graph pages

0 commit comments

Comments
 (0)