Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions gigamap/jvector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>4.2.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,30 +123,6 @@ void testBuilderRequiresNonNegativePqSubspaces()
);
}

@Test
void testBuilderRequiresNonNegativePersistenceIntervalMs()
{
// 0 is valid (means disabled)
final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(64)
.persistenceIntervalMs(0)
.build();
assertEquals(0L, config.persistenceIntervalMs());
assertFalse(config.backgroundPersistence());

assertThrows(IllegalArgumentException.class, () ->
VectorIndexConfiguration.builder().dimension(64).persistenceIntervalMs(-1).build()
);
}

@Test
void testBuilderRequiresNonNegativeMinChangesBetweenPersists()
{
assertThrows(IllegalArgumentException.class, () ->
VectorIndexConfiguration.builder().dimension(64).minChangesBetweenPersists(-1).build()
);
}

@Test
void testBuilderRequiresNonNegativeOptimizationIntervalMs()
{
Expand Down Expand Up @@ -192,19 +168,6 @@ void testOnDiskRequiresIndexDirectory()
);
}

@Test
void testOnDiskWithIndexDirectorySucceeds(@TempDir final Path tempDir)
{
final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(64)
.onDisk(true)
.indexDirectory(tempDir)
.build();

assertTrue(config.onDisk());
assertEquals(tempDir, config.indexDirectory());
}

@Test
void testCompressionRequiresOnDisk()
{
Expand Down Expand Up @@ -1014,4 +977,169 @@ void testFactoryMethodsDefaultEventualIndexingFalse(@TempDir final Path tempDir)
assertFalse(VectorIndexConfiguration.forLargeDataset(64, tempDir).eventualIndexing());
assertFalse(VectorIndexConfiguration.forHighPrecision(64).eventualIndexing());
}

/**
* Test on-disk configuration builder.
*/
@Test
void testOnDiskConfigurationBuilder(@TempDir final Path tempDir)
{

final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(128)
.similarityFunction(VectorSimilarityFunction.COSINE)
.onDisk(true)
.indexDirectory(tempDir)
.build();

assertTrue(config.onDisk());
assertEquals(tempDir, config.indexDirectory());
assertFalse(config.enablePqCompression());
assertEquals(0, config.pqSubspaces());
}

/**
* Test on-disk configuration with compression.
* FusedPQ requires maxDegree=32, so it should be auto-set.
*/
@Test
void testOnDiskConfigurationWithCompression(@TempDir final Path tempDir)
{

final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(128)
.similarityFunction(VectorSimilarityFunction.COSINE)
.maxDegree(16) // Will be overridden to 32 for FusedPQ
.onDisk(true)
.indexDirectory(tempDir)
.enablePqCompression(true)
.pqSubspaces(32)
.build();

assertTrue(config.onDisk());
assertTrue(config.enablePqCompression());
assertEquals(32, config.pqSubspaces());
assertEquals(32, config.maxDegree(), "FusedPQ requires maxDegree=32");
}

/**
* Test that maxDegree is auto-set to 32 when compression is enabled.
*/
@Test
void testFusedPQRequiresMaxDegree32(@TempDir final Path tempDir)
{
// Try to set maxDegree to 64 with compression enabled
final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(128)
.maxDegree(64)
.onDisk(true)
.indexDirectory(tempDir)
.enablePqCompression(true)
.build();

// Should be overridden to 32
assertEquals(32, config.maxDegree(), "FusedPQ should enforce maxDegree=32");
}

/**
* Test background persistence configuration builder.
*/
@Test
void testBackgroundPersistenceConfigurationBuilder(@TempDir final Path tempDir)
{
final Path indexDir = tempDir.resolve("index");

final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(128)
.similarityFunction(VectorSimilarityFunction.COSINE)
.onDisk(true)
.indexDirectory(indexDir)
.persistenceIntervalMs(60_000)
.persistOnShutdown(true)
.minChangesBetweenPersists(50)
.build();

assertTrue(config.onDisk());
assertTrue(config.backgroundPersistence());
assertEquals(60_000, config.persistenceIntervalMs());
assertTrue(config.persistOnShutdown());
assertEquals(50, config.minChangesBetweenPersists());
}

/**
* Test validation: persistenceIntervalMs must be non-negative.
*/
@Test
void testPersistenceIntervalMsMustBeNonNegative(@TempDir final Path tempDir)
{
// 0 is valid (means disabled)
final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(128)
.onDisk(true)
.indexDirectory(tempDir)
.persistenceIntervalMs(0)
.build();
assertEquals(0, config.persistenceIntervalMs());
assertFalse(config.backgroundPersistence());

assertThrows(IllegalArgumentException.class, () ->
VectorIndexConfiguration.builder()
.dimension(128)
.onDisk(true)
.indexDirectory(tempDir)
.persistenceIntervalMs(-1000)
.build()
);
}

/**
* Test validation: minChangesBetweenPersists must be non-negative.
*/
@Test
void testMinChangesBetweenPersistsMustBeNonNegative(@TempDir final Path tempDir)
{
assertThrows(IllegalArgumentException.class, () ->
VectorIndexConfiguration.builder()
.dimension(128)
.onDisk(true)
.indexDirectory(tempDir)
.minChangesBetweenPersists(-1)
.build()
);

// Zero should be allowed (persist on every interval)
final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(128)
.onDisk(true)
.indexDirectory(tempDir)
.minChangesBetweenPersists(0)
.build();
assertEquals(0, config.minChangesBetweenPersists());
}

/**
* Test background optimization configuration builder.
*/
@Test
void testBackgroundOptimizationConfigurationBuilder(@TempDir final Path tempDir)
{
final Path indexDir = tempDir.resolve("index");

final VectorIndexConfiguration config = VectorIndexConfiguration.builder()
.dimension(128)
.similarityFunction(VectorSimilarityFunction.COSINE)
.onDisk(true)
.indexDirectory(indexDir)
.optimizationIntervalMs(120_000)
.minChangesBetweenOptimizations(500)
.optimizeOnShutdown(true)
.build();

assertTrue(config.onDisk());
assertTrue(config.backgroundOptimization());
assertEquals(120_000, config.optimizationIntervalMs());
assertEquals(500, config.minChangesBetweenOptimizations());
assertTrue(config.optimizeOnShutdown());
}

}
Loading