|
52 | 52 | import org.junit.jupiter.api.Tag; |
53 | 53 | import org.junit.jupiter.api.Test; |
54 | 54 | import org.junit.jupiter.api.extension.AfterTestExecutionCallback; |
| 55 | +import org.junit.jupiter.api.extension.ExtendWith; |
55 | 56 | import org.junit.jupiter.api.extension.ExtensionContext; |
56 | 57 | import org.junit.jupiter.api.extension.RegisterExtension; |
| 58 | +import org.junit.jupiter.api.io.TempDir; |
57 | 59 | import org.junit.jupiter.api.parallel.Execution; |
58 | 60 | import org.junit.jupiter.api.parallel.ExecutionMode; |
59 | 61 | import org.junit.jupiter.params.ParameterInfo; |
|
67 | 69 | import javax.annotation.Nonnull; |
68 | 70 | import javax.annotation.Nullable; |
69 | 71 | import java.io.BufferedWriter; |
70 | | -import java.io.FileWriter; |
71 | 72 | import java.io.IOException; |
72 | 73 | import java.nio.channels.FileChannel; |
| 74 | +import java.nio.file.Files; |
73 | 75 | import java.nio.file.Path; |
74 | 76 | import java.nio.file.Paths; |
75 | 77 | import java.nio.file.StandardOpenOption; |
@@ -116,6 +118,9 @@ class HNSWTest { |
116 | 118 | @RegisterExtension |
117 | 119 | TestSubspaceExtension rtSecondarySubspace = new TestSubspaceExtension(dbExtension); |
118 | 120 |
|
| 121 | + @TempDir |
| 122 | + Path tempDir; |
| 123 | + |
119 | 124 | private Database db; |
120 | 125 |
|
121 | 126 | @BeforeEach |
@@ -316,7 +321,7 @@ void testBasicInsert(final long seed, final Config config) { |
316 | 321 | Assertions.assertThat(readIds.size()).isBetween(10, 50); |
317 | 322 | } |
318 | 323 |
|
319 | | - //@ExtendWith(HNSWTest.DumpLayersIfFailure.class) |
| 324 | + @ExtendWith(HNSWTest.DumpLayersIfFailure.class) |
320 | 325 | @ParameterizedTest |
321 | 326 | @MethodSource("randomSeedsWithConfig") |
322 | 327 | void testBasicInsertDelete(final long seed, final Config config) { |
@@ -404,11 +409,6 @@ void testBasicInsertDelete(final long seed, final Config config) { |
404 | 409 | onReadListener.getNodeCountByLayer(), onReadListener.getBytesReadByLayer(), |
405 | 410 | String.format(Locale.ROOT, "%.2f", recall * 100.0d)); |
406 | 411 |
|
407 | | - if (recall <= 0.9) { |
408 | | - db.run(tr -> |
409 | | - hnsw.kNearestNeighborsSearch(tr, k, 100, true, queryVector).join()); |
410 | | - } |
411 | | - |
412 | 412 | Assertions.assertThat(recall).isGreaterThan(0.9); |
413 | 413 |
|
414 | 414 | final long remainingNumNodes = countNodesOnLayer(config, 0); |
@@ -710,28 +710,37 @@ private void scanLayer(@Nonnull final Config config, |
710 | 710 |
|
711 | 711 | private boolean dumpLayer(@Nonnull final Config config, |
712 | 712 | @Nonnull final String prefix, final int layer) throws IOException { |
713 | | - final String verticesFileName = "/Users/nseemann/Downloads/vertices-" + prefix + "-" + layer + ".csv"; |
714 | | - final String edgesFileName = "/Users/nseemann/Downloads/edges-" + prefix + "-" + layer + ".csv"; |
| 713 | + final Path verticesFile = tempDir.resolve("vertices-" + prefix + "-" + layer + ".csv"); |
| 714 | + final Path edgesFile = tempDir.resolve("edges-" + prefix + "-" + layer + ".csv"); |
| 715 | + |
| 716 | + final StorageAdapter<? extends NodeReference> storageAdapter = |
| 717 | + HNSW.storageAdapterForLayer(config, rtSubspace.getSubspace(), |
| 718 | + OnWriteListener.NOOP, OnReadListener.NOOP, layer); |
715 | 719 |
|
716 | 720 | final AtomicLong numReadAtomic = new AtomicLong(0L); |
717 | | - try (final BufferedWriter verticesWriter = new BufferedWriter(new FileWriter(verticesFileName)); |
718 | | - final BufferedWriter edgesWriter = new BufferedWriter(new FileWriter(edgesFileName))) { |
| 721 | + try (final BufferedWriter verticesWriter = Files.newBufferedWriter(verticesFile); |
| 722 | + final BufferedWriter edgesWriter = Files.newBufferedWriter(edgesFile)) { |
719 | 723 | scanLayer(config, layer, 100, node -> { |
720 | | - final CompactNode compactNode = node.asCompactNode(); |
721 | | - final Transformed<RealVector> vector = compactNode.getVector(); |
| 724 | + @Nullable final Transformed<RealVector> vector = |
| 725 | + storageAdapter.isCompactStorageAdapter() |
| 726 | + ? node.asCompactNode().getVector() |
| 727 | + : null; |
722 | 728 | try { |
723 | | - verticesWriter.write(compactNode.getPrimaryKey().getLong(0) + ","); |
724 | | - final RealVector realVector = vector.getUnderlyingVector(); |
725 | | - for (int i = 0; i < realVector.getNumDimensions(); i++) { |
726 | | - if (i != 0) { |
727 | | - verticesWriter.write(","); |
| 729 | + verticesWriter.write(Long.toString(node.getPrimaryKey().getLong(0))); |
| 730 | + if (vector != null) { |
| 731 | + verticesWriter.write(","); |
| 732 | + final RealVector realVector = vector.getUnderlyingVector(); |
| 733 | + for (int i = 0; i < realVector.getNumDimensions(); i++) { |
| 734 | + if (i != 0) { |
| 735 | + verticesWriter.write(","); |
| 736 | + } |
| 737 | + verticesWriter.write(String.valueOf(realVector.getComponent(i))); |
728 | 738 | } |
729 | | - verticesWriter.write(String.valueOf(realVector.getComponent(i))); |
730 | 739 | } |
731 | 740 | verticesWriter.newLine(); |
732 | 741 |
|
733 | | - for (final var neighbor : compactNode.getNeighbors()) { |
734 | | - edgesWriter.write(compactNode.getPrimaryKey().getLong(0) + "," + |
| 742 | + for (final var neighbor : node.getNeighbors()) { |
| 743 | + edgesWriter.write(node.getPrimaryKey().getLong(0) + "," + |
735 | 744 | neighbor.getPrimaryKey().getLong(0)); |
736 | 745 | edgesWriter.newLine(); |
737 | 746 | } |
|
0 commit comments