Skip to content

Commit 3ca3ce1

Browse files
authored
Multidirectory (#634)
* monitor both test and cache directories * resource management
1 parent 8bb9316 commit 3ca3ce1

4 files changed

Lines changed: 319 additions & 90 deletions

File tree

jvector-examples/src/main/java/io/github/jbellis/jvector/example/Grid.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
2929
import io.github.jbellis.jvector.example.benchmarks.diagnostics.BenchmarkDiagnostics;
3030
import io.github.jbellis.jvector.example.benchmarks.diagnostics.DiagnosticLevel;
3131
import io.github.jbellis.jvector.example.benchmarks.datasets.DataSet;
32+
import io.github.jbellis.jvector.example.benchmarks.diagnostics.DiskUsageMonitor;
3233
import io.github.jbellis.jvector.example.reporting.*;
3334
import io.github.jbellis.jvector.example.reporting.RunArtifacts;
3435
import io.github.jbellis.jvector.example.util.CompressorParameters;
3536
import io.github.jbellis.jvector.example.util.FilteredForkJoinPool;
3637
import io.github.jbellis.jvector.example.util.OnDiskGraphIndexCache;
37-
import io.github.jbellis.jvector.example.yaml.BenchmarkSelection;
3838
import io.github.jbellis.jvector.example.yaml.MetricSelection;
3939
import io.github.jbellis.jvector.graph.ImmutableGraphIndex;
4040
import io.github.jbellis.jvector.graph.GraphIndexBuilder;
@@ -233,7 +233,8 @@ static void runOneGraph(OnDiskGraphIndexCache cache,
233233
// TODO this does not capture disk usage for cached indexes. Need to update
234234
// Capture initial memory and disk state
235235
try (var diagnostics = new BenchmarkDiagnostics(getDiagnosticLevel())) {
236-
diagnostics.setMonitoredDirectory(workDirectory);
236+
diagnostics.startMonitoring("testDirectory", workDirectory);
237+
diagnostics.startMonitoring("indexCache", Paths.get(indexCacheDir));
237238
diagnostics.capturePrePhaseSnapshot("Graph Build");
238239

239240
// Resolve build compressor (and label quant type) so we can record compute time
@@ -822,7 +823,8 @@ public static List<BenchResult> runAllAndCollectResults(
822823
Path testDirectory = Files.createTempDirectory("bench");
823824
try (var diagnostics = new BenchmarkDiagnostics(getDiagnosticLevel())) {
824825
// Capture initial state
825-
diagnostics.setMonitoredDirectory(testDirectory);
826+
diagnostics.startMonitoring("testDirectory", testDirectory);
827+
diagnostics.startMonitoring("indexCache", Paths.get(indexCacheDir));
826828
diagnostics.capturePrePhaseSnapshot("Build");
827829
Map<Set<FeatureId>, ImmutableGraphIndex> indexes = new HashMap<>();
828830

@@ -873,7 +875,7 @@ public static List<BenchResult> runAllAndCollectResults(
873875
diagnostics.capturePostPhaseSnapshot("Build");
874876
diagnostics.printDiskStatistics("Graph Index Build");
875877
var buildSnapshot = diagnostics.getLatestSystemSnapshot();
876-
var buildDiskSnapshot = diagnostics.getLatestDiskSnapshot();
878+
DiskUsageMonitor.MultiDirectorySnapshot buildDiskSnapshot = diagnostics.getLatestDiskSnapshot();
877879

878880
try (ConfiguredSystem cs = new ConfiguredSystem(ds, index, cvArg, features)) {
879881
int queryRuns = 2;
@@ -927,8 +929,8 @@ public static List<BenchResult> runAllAndCollectResults(
927929

928930
// Add disk metrics if available
929931
if (buildDiskSnapshot != null) {
930-
allMetrics.put("Disk Usage (MB)", buildDiskSnapshot.totalBytes / 1024.0 / 1024.0);
931-
allMetrics.put("File Count", buildDiskSnapshot.fileCount);
932+
allMetrics.put("Disk Usage (MB)", buildDiskSnapshot.getTotalBytes() / 1024.0 / 1024.0);
933+
allMetrics.put("File Count", buildDiskSnapshot.getTotalFileCount());
932934
}
933935

934936
results.add(new BenchResult(ds.getName(), params, allMetrics));

jvector-examples/src/main/java/io/github/jbellis/jvector/example/benchmarks/QueryTester.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ public List<Metric> run(
114114
if (diskSnapshot != null) {
115115
// Number of index files created
116116
results.add(Metric.of("search.disk.file_count", "File count", ".0f",
117-
diskSnapshot.fileCount));
117+
diskSnapshot.getTotalFileCount()));
118118

119119
// Total size of index files created
120120
results.add(Metric.of("search.disk.total_file_size_mb", "Total file size (MB)", ".1f",
121-
diskSnapshot.totalBytes / (1024.0 * 1024.0)));
121+
diskSnapshot.getTotalBytes() / (1024.0 * 1024.0)));
122122
}
123123

124124
} catch (IOException e) {

jvector-examples/src/main/java/io/github/jbellis/jvector/example/benchmarks/diagnostics/BenchmarkDiagnostics.java

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ public class BenchmarkDiagnostics implements AutoCloseable {
3636
private final DiskUsageMonitor diskUsageMonitor;
3737
private final PerformanceAnalyzer performanceAnalyzer;
3838
private final List<SystemMonitor.SystemSnapshot> snapshots;
39-
private final List<DiskUsageMonitor.DiskUsageSnapshot> diskSnapshots;
39+
private final List<DiskUsageMonitor.MultiDirectorySnapshot> diskSnapshots;
4040
private final List<PerformanceAnalyzer.TimingAnalysis> timingAnalyses;
41-
private Path monitoredDirectory;
4241
private boolean diskMonitorStarted = false;
4342

4443
public BenchmarkDiagnostics(DiagnosticLevel level) {
@@ -49,7 +48,6 @@ public BenchmarkDiagnostics(DiagnosticLevel level) {
4948
this.snapshots = new ArrayList<>();
5049
this.diskSnapshots = new ArrayList<>();
5150
this.timingAnalyses = new ArrayList<>();
52-
this.monitoredDirectory = null;
5351
}
5452

5553
/**
@@ -79,12 +77,27 @@ public static BenchmarkDiagnostics createVerbose() {
7977
*
8078
* @param directory the directory to monitor
8179
* @throws IOException if unable to start monitoring
80+
* @deprecated Use {@link #startMonitoring(String, Path)} instead
8281
*/
82+
@Deprecated
8383
public void setMonitoredDirectory(Path directory) throws IOException {
84-
this.monitoredDirectory = directory;
85-
if (directory != null && !diskMonitorStarted) {
86-
diskUsageMonitor.start(directory);
84+
startMonitoring("default", directory);
85+
}
86+
87+
/**
88+
* Starts monitoring a labeled directory for disk usage.
89+
* This should be called before capturing any snapshots for optimal performance.
90+
*
91+
* @param label a label to identify this directory in reports
92+
* @param directory the directory to monitor
93+
* @throws IOException if unable to start monitoring
94+
*/
95+
public void startMonitoring(String label, Path directory) throws IOException {
96+
if (!diskMonitorStarted) {
97+
diskUsageMonitor.startMonitoring(label, directory);
8798
diskMonitorStarted = true;
99+
} else {
100+
diskUsageMonitor.addDirectory(label, directory);
88101
}
89102
}
90103

@@ -95,12 +108,12 @@ public void capturePrePhaseSnapshot(String phase) {
95108
SystemMonitor.SystemSnapshot snapshot = systemMonitor.captureSnapshot();
96109
snapshots.add(snapshot);
97110

98-
// Capture disk usage if directory is set
99-
if (monitoredDirectory != null) {
111+
// Capture disk usage if monitoring is started
112+
if (diskMonitorStarted) {
100113
try {
101-
DiskUsageMonitor.DiskUsageSnapshot diskSnapshot = diskUsageMonitor.captureSnapshot(monitoredDirectory);
114+
DiskUsageMonitor.MultiDirectorySnapshot diskSnapshot = diskUsageMonitor.captureSnapshot();
102115
diskSnapshots.add(diskSnapshot);
103-
} catch (IOException e) {
116+
} catch (Exception e) {
104117
if (level != DiagnosticLevel.NONE) {
105118
System.err.printf("[%s] Failed to capture disk usage: %s%n", phase, e.getMessage());
106119
}
@@ -127,15 +140,15 @@ public void capturePostPhaseSnapshot(String phase) {
127140
snapshots.add(postSnapshot);
128141

129142
// Capture and log disk usage changes
130-
if (monitoredDirectory != null) {
143+
if (diskMonitorStarted) {
131144
try {
132-
DiskUsageMonitor.DiskUsageSnapshot postDiskSnapshot = diskUsageMonitor.captureSnapshot(monitoredDirectory);
145+
DiskUsageMonitor.MultiDirectorySnapshot postDiskSnapshot = diskUsageMonitor.captureSnapshot();
133146
if (!diskSnapshots.isEmpty() && level != DiagnosticLevel.NONE) {
134-
DiskUsageMonitor.DiskUsageSnapshot preDiskSnapshot = diskSnapshots.get(diskSnapshots.size() - 1);
147+
DiskUsageMonitor.MultiDirectorySnapshot preDiskSnapshot = diskSnapshots.get(diskSnapshots.size() - 1);
135148
diskUsageMonitor.logDifference(phase, preDiskSnapshot, postDiskSnapshot);
136149
}
137150
diskSnapshots.add(postDiskSnapshot);
138-
} catch (IOException e) {
151+
} catch (Exception e) {
139152
if (level != DiagnosticLevel.NONE) {
140153
System.err.printf("[%s] Failed to capture disk usage: %s%n", phase, e.getMessage());
141154
}
@@ -223,7 +236,7 @@ public SystemMonitor.SystemSnapshot getLatestSystemSnapshot() {
223236
/**
224237
* Gets the latest disk usage snapshot, or null if none captured
225238
*/
226-
public DiskUsageMonitor.DiskUsageSnapshot getLatestDiskSnapshot() {
239+
public DiskUsageMonitor.MultiDirectorySnapshot getLatestDiskSnapshot() {
227240
return diskSnapshots.isEmpty() ? null : diskSnapshots.get(diskSnapshots.size() - 1);
228241
}
229242

@@ -298,17 +311,33 @@ public void logSummary() {
298311
public void printDiskStatistics(String label) {
299312
// Disk usage summary
300313
if (!diskSnapshots.isEmpty()) {
301-
DiskUsageMonitor.DiskUsageSnapshot firstDisk = diskSnapshots.get(0);
302-
DiskUsageMonitor.DiskUsageSnapshot lastDisk = diskSnapshots.get(diskSnapshots.size() - 1);
303-
DiskUsageMonitor.DiskUsageSnapshot totalDisk = lastDisk.subtract(firstDisk);
314+
DiskUsageMonitor.MultiDirectorySnapshot firstDisk = diskSnapshots.get(0);
315+
DiskUsageMonitor.MultiDirectorySnapshot lastDisk = diskSnapshots.get(diskSnapshots.size() - 1);
316+
DiskUsageMonitor.MultiDirectorySnapshot totalDisk = lastDisk.subtract(firstDisk);
304317

305318
System.out.printf("\nDisk Usage Summary %s:%n", label);
306-
System.out.printf(" Total Disk Used: %s%n", DiskUsageMonitor.formatBytes(lastDisk.totalBytes));
307-
System.out.printf(" Total Files: %d%n", lastDisk.fileCount);
308-
System.out.printf(" Net Change: %s, %+d files%n",
309-
DiskUsageMonitor.formatBytes(totalDisk.totalBytes), totalDisk.fileCount);
319+
320+
// Print statistics for each monitored directory
321+
for (String dirLabel : lastDisk.snapshots.keySet()) {
322+
DiskUsageMonitor.DiskUsageSnapshot lastSnap = lastDisk.get(dirLabel);
323+
DiskUsageMonitor.DiskUsageSnapshot totalSnap = totalDisk.get(dirLabel);
324+
325+
System.out.printf(" [%s]:%n", dirLabel);
326+
System.out.printf(" Total Disk Used: %s%n", DiskUsageMonitor.formatBytes(lastSnap.totalBytes));
327+
System.out.printf(" Total Files: %d%n", lastSnap.fileCount);
328+
if (totalSnap != null) {
329+
System.out.printf(" Net Change: %s, %+d files%n",
330+
DiskUsageMonitor.formatBytes(totalSnap.totalBytes), totalSnap.fileCount);
331+
}
332+
}
333+
334+
// Print overall totals
335+
System.out.printf(" [Overall Total]:%n");
336+
System.out.printf(" Total Disk Used: %s%n", DiskUsageMonitor.formatBytes(lastDisk.getTotalBytes()));
337+
System.out.printf(" Total Files: %d%n", lastDisk.getTotalFileCount());
338+
System.out.printf(" Net Change: %s, %+d files%n",
339+
DiskUsageMonitor.formatBytes(totalDisk.getTotalBytes()), totalDisk.getTotalFileCount());
310340
}
311-
312341
}
313342

314343
/**

0 commit comments

Comments
 (0)