From 0b30b354d5584e36cd7d25428a454cb9261fdae7 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Sat, 4 Apr 2026 18:04:25 +0200 Subject: [PATCH 01/38] DEBUG: Add task to run without jar --- build.gradle | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/build.gradle b/build.gradle index cb4f0a0..9587cb0 100644 --- a/build.gradle +++ b/build.gradle @@ -239,6 +239,19 @@ task copyPolyphenyNewJdbcDriver(type: Copy) { compileJava.dependsOn(copyPolyphenyOldJdbcDriver) compileJava.dependsOn(copyPolyphenyNewJdbcDriver) + + +/* ------------ Local testing config ------------ */ +processResources { + dependsOn copyPolyphenyOldJdbcDriver, copyPolyphenyNewJdbcDriver + from('libs/polyphenyJdbcDrivers') { + rename { name -> name.replace('.jar', '.zip') } + into 'libs/polyphenyJdbcDrivers' + } + } +/* ---------------------------------------------- */ + + /** * IntelliJ */ From 7f7fa09b61552feaf4919057cc66c345bd2fea24 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Sat, 4 Apr 2026 18:09:38 +0200 Subject: [PATCH 02/38] DEBUG: Change KnnBench to work properly on run --- .../simpleclient/scenario/knnbench/KnnBench.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBench.java b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBench.java index 555d0dd..d507aa5 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBench.java @@ -61,19 +61,10 @@ public class KnnBench extends PolyphenyScenario { private final KnnBenchConfig config; - private final List measuredTimes; - private long executeRuntime; - private final Map queryTypes; - private final Map> measuredTimePerQueryType; - - public KnnBench( Executor.ExecutorFactory executorFactory, KnnBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); this.config = config; - measuredTimes = Collections.synchronizedList( new LinkedList<>() ); - queryTypes = new HashMap<>(); - measuredTimePerQueryType = new ConcurrentHashMap<>(); } @@ -96,10 +87,9 @@ public void createSchema( DatabaseInstance databaseInstance, boolean includingKe Executor executor = null; try { executor = executorFactory.createExecutorInstance(); - executor.executeQuery( (new CreateMetadata( findMatchingDataStoreName( config.dataStoreMetadata ) )).getNewQuery() ); - executor.executeQuery( (new CreateIntFeature( findMatchingDataStoreName( config.dataStoreFeature ), config.dimensionFeatureVectors )).getNewQuery() ); - executor.executeQuery( (new CreateRealFeature( findMatchingDataStoreName( config.dataStoreFeature ), config.dimensionFeatureVectors )).getNewQuery() ); - } catch ( ExecutorException e ) { + executor.executeQuery( (new CreateMetadata( config.dataStoreMetadata )).getNewQuery() ); + executor.executeQuery( (new CreateIntFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() ); + executor.executeQuery( (new CreateRealFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() );} catch ( ExecutorException e ) { throw new RuntimeException( "Exception while creating schema", e ); } finally { commitAndCloseExecutor( executor ); From 68cc0670ee3b61cb9c81268d1ae8fad58c9e2307 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Sun, 5 Apr 2026 13:22:29 +0200 Subject: [PATCH 03/38] DEBUG: Modify build.gradle to be runnable from cli --- build.gradle | 9 + .../simpleclient/cli/VectorCommand.java | 4 + .../main/VectorBenchScenario.java | 4 + .../scenario/vectorbench/DataGenerator.java | 120 +++++++++++ .../scenario/vectorbench/VectorBench.java | 198 ++++++++++++++++++ .../vectorbench/VectorBenchConfig.java | 151 +++++++++++++ .../queryBuilder/CreateIntFeature.java | 126 +++++++++++ .../queryBuilder/CreateMetadata.java | 122 +++++++++++ .../queryBuilder/CreateRealFeature.java | 126 +++++++++++ .../queryBuilder/InsertIntFeature.java | 170 +++++++++++++++ .../queryBuilder/InsertMetadata.java | 139 ++++++++++++ .../queryBuilder/InsertRealFeature.java | 170 +++++++++++++++ .../queryBuilder/MetadataKnnIntFeature.java | 141 +++++++++++++ .../queryBuilder/MetadataKnnRealFeature.java | 141 +++++++++++++ .../queryBuilder/SimpleKnnIdIntFeature.java | 188 +++++++++++++++++ .../queryBuilder/SimpleKnnIdRealFeature.java | 188 +++++++++++++++++ .../queryBuilder/SimpleKnnIntFeature.java | 183 ++++++++++++++++ .../queryBuilder/SimpleKnnRealFeature.java | 183 ++++++++++++++++ .../queryBuilder/SimpleMetadata.java | 117 +++++++++++ 19 files changed, 2480 insertions(+) create mode 100644 src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java create mode 100644 src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java diff --git a/build.gradle b/build.gradle index 9587cb0..4115557 100644 --- a/build.gradle +++ b/build.gradle @@ -41,8 +41,13 @@ apply plugin: "io.freefair.lombok" apply plugin: "com.github.johnrengelman.shadow" apply plugin: "app.cash.licensee" apply plugin: "com.jaredsburrows.license" +apply plugin: "application" +application { + mainClass = "org.polypheny.simpleclient.cli.Main" +} + tasks.withType(JavaCompile).configureEach { options.encoding = "UTF-8" } @@ -249,6 +254,10 @@ processResources { into 'libs/polyphenyJdbcDrivers' } } + +run { + dependsOn processResources +} /* ---------------------------------------------- */ diff --git a/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java b/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java new file mode 100644 index 0000000..ccae89f --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java @@ -0,0 +1,4 @@ +package org.polypheny.simpleclient.cli; + +public class VectorCommand { +} diff --git a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java new file mode 100644 index 0000000..f1d0b7a --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java @@ -0,0 +1,4 @@ +package org.polypheny.simpleclient.main; + +public class VectorBenchScenario { +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java new file mode 100644 index 0000000..44a32ff --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java @@ -0,0 +1,120 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench; + +import java.util.LinkedList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.executor.Executor; +import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.main.ProgressReporter; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.scenario.knnbench.queryBuilder.InsertIntFeature; +import org.polypheny.simpleclient.scenario.knnbench.queryBuilder.InsertMetadata; +import org.polypheny.simpleclient.scenario.knnbench.queryBuilder.InsertRealFeature; + + +@Slf4j +public class DataGenerator { + + private final Executor theExecutor; + private final KnnBenchConfig config; + private final ProgressReporter progressReporter; + + private final List batchList; + + private boolean aborted; + + + DataGenerator( Executor executor, KnnBenchConfig config, ProgressReporter progressReporter ) { + theExecutor = executor; + this.config = config; + this.progressReporter = progressReporter; + batchList = new LinkedList<>(); + + aborted = false; + } + + + void generateMetadata() throws ExecutorException { + InsertMetadata queryBuilder = new InsertMetadata(); + for ( int i = 0; i < config.numberOfEntries; i++ ) { + if ( aborted ) { + break; + } + + addToInsertList( queryBuilder.getNewQuery() ); + } + executeInsertList(); + } + + + void generateIntFeatures() throws ExecutorException { + InsertIntFeature queryBuilder = new InsertIntFeature( config.randomSeedInsert, config.dimensionFeatureVectors ); + for ( int i = 0; i < config.numberOfEntries; i++ ) { + if ( aborted ) { + break; + } + + addToInsertList( queryBuilder.getNewQuery() ); + } + executeInsertList(); + } + + + void generateRealFeatures() throws ExecutorException { + InsertRealFeature queryBuilder = new InsertRealFeature( config.randomSeedInsert, config.dimensionFeatureVectors ); + for ( int i = 0; i < config.numberOfEntries; i++ ) { + if ( aborted ) { + break; + } + + addToInsertList( queryBuilder.getNewQuery() ); + } + executeInsertList(); + } + + + private void addToInsertList( BatchableInsert query ) throws ExecutorException { + batchList.add( query ); + if ( batchList.size() >= config.batchSizeInserts ) { + executeInsertList(); + } + } + + + private void executeInsertList() throws ExecutorException { + theExecutor.executeInsertList( batchList, config ); + theExecutor.executeCommit(); + batchList.clear(); + } + + + public void abort() { + aborted = true; + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java new file mode 100644 index 0000000..7057157 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -0,0 +1,198 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench; + +import java.io.File; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.Vector; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.QueryMode; +import org.polypheny.simpleclient.executor.Executor; +import org.polypheny.simpleclient.executor.Executor.DatabaseInstance; +import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.main.CsvWriter; +import org.polypheny.simpleclient.main.ProgressReporter; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.polypheny.simpleclient.query.QueryListEntry; +import org.polypheny.simpleclient.scenario.PolyphenyScenario; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.CreateIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.CreateMetadata; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.CreateRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnIdRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleMetadata; + + +@Slf4j +public class KnnBench extends PolyphenyScenario { + + private final KnnBenchConfig config; + + public KnnBench(Executor.ExecutorFactory executorFactory, KnnBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { + super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); + this.config = config; + + } + + + @Override + public void createSchema( DatabaseInstance databaseInstance, boolean includingKeys ) { + if ( queryMode != QueryMode.TABLE ) { + throw new UnsupportedOperationException( "Unsupported query mode: " + queryMode.name() ); + } + + if ( config.newTablePlacementStrategy.equalsIgnoreCase( "Optimized" ) && config.dataStores.size() > 1 ) { + if ( config.dataStoreMetadata == null ) { + throw new RuntimeException( "Optimized placements is selected but 'dataStoreMetadata' is null!" ); + } + if ( config.dataStoreFeature == null ) { + throw new RuntimeException( "Optimized placements is selected but 'dataStoreFeature' is null!" ); + } + } + + log.info( "Creating schema..." ); + Executor executor = null; + try { + executor = executorFactory.createExecutorInstance(); + executor.executeQuery( (new CreateMetadata( config.dataStoreMetadata )).getNewQuery() ); + executor.executeQuery( (new CreateIntFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() ); + executor.executeQuery( (new CreateRealFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() );} catch (ExecutorException e ) { + throw new RuntimeException( "Exception while creating schema", e ); + } finally { + commitAndCloseExecutor( executor ); + } + } + + + @Override + public void generateData( DatabaseInstance databaseInstance, ProgressReporter progressReporter ) { + log.info( "Generating data..." ); + Executor executor1 = executorFactory.createExecutorInstance(); + DataGenerator dataGenerator = new DataGenerator( executor1, config, progressReporter ); + + try { + dataGenerator.generateMetadata(); + dataGenerator.generateIntFeatures(); + dataGenerator.generateRealFeatures(); + } catch ( ExecutorException e ) { + throw new RuntimeException( "Exception while generating data", e ); + } finally { + commitAndCloseExecutor( executor1 ); + } + } + + + @Override + public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, File outputDirectory, int numberOfThreads ) { + log.info( "Preparing query list for the benchmark..." ); + List queryList = new Vector<>(); + addNumberOfTimes( queryList, new SimpleKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIntFeatureQueries ); + addNumberOfTimes( queryList, new SimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnRealFeatureQueries ); + addNumberOfTimes( queryList, new SimpleMetadata( config.randomSeedQuery, config.numberOfEntries ), config.numberOfSimpleMetadataQueries ); +// addNumberOfTimes( queryList, new SimpleKnnIdIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIdIntFeatureQueries ); + addNumberOfTimes( queryList, new SimpleKnnIdRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIdRealFeatureQueries ); + addNumberOfTimes( queryList, new MetadataKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnIntFeatureQueries ); + addNumberOfTimes( queryList, new MetadataKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnRealFeatureQueries ); + + return commonExecute( queryList, progressReporter, outputDirectory, numberOfThreads, Query::getSql, () -> executorFactory.createExecutorInstance( csvWriter ), new Random() ); + } + + + @Override + public void warmUp( ProgressReporter progressReporter ) { + log.info( "Warm-up..." ); + + Executor executor = null; + SimpleKnnIntFeature simpleKnnIntFeatureBuilder = new SimpleKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + SimpleKnnRealFeature simpleKnnRealFeatureBuilder = new SimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + SimpleMetadata simpleMetadataBuilder = new SimpleMetadata( config.randomSeedQuery, config.numberOfEntries ); +// SimpleKnnIdIntFeature simpleKnnIdIntFeatureBuilder = new SimpleKnnIdIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + SimpleKnnIdRealFeature simpleKnnIdRealFeatureBuilder = new SimpleKnnIdRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + MetadataKnnIntFeature metadataKnnIntFeature = new MetadataKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + MetadataKnnRealFeature metadataKnnRealFeature = new MetadataKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + + for ( int i = 0; i < config.numberOfWarmUpIterations; i++ ) { + try { + executor = executorFactory.createExecutorInstance(); + if ( config.numberOfSimpleKnnIntFeatureQueries > 0 ) { + executor.executeQuery( simpleKnnIntFeatureBuilder.getNewQuery() ); + } + if ( config.numberOfSimpleKnnRealFeatureQueries > 0 ) { + executor.executeQuery( simpleKnnRealFeatureBuilder.getNewQuery() ); + } + + if ( config.numberOfSimpleMetadataQueries > 0 ) { + executor.executeQuery( simpleMetadataBuilder.getNewQuery() ); + } + +// if ( config.numberOfSimpleKnnIdIntFeatureQueries > 0 ) { +// executor.executeQuery( simpleKnnIdIntFeatureBuilder.getNewQuery() ); +// } + if ( config.numberOfSimpleKnnIdRealFeatureQueries > 0 ) { + executor.executeQuery( simpleKnnIdRealFeatureBuilder.getNewQuery() ); + } + if ( config.numberOfMetadataKnnIntFeatureQueries > 0 ) { + executor.executeQuery( metadataKnnIntFeature.getNewQuery() ); + } + if ( config.numberOfMetadataKnnRealFeatureQueries > 0 ) { + executor.executeQuery( metadataKnnRealFeature.getNewQuery() ); + } + } catch ( ExecutorException e ) { + throw new RuntimeException( "Error while executing warm-up queries", e ); + } finally { + commitAndCloseExecutor( executor ); + } + try { + Thread.sleep( 10000 ); + } catch ( InterruptedException e ) { + throw new RuntimeException( "Unexpected interrupt", e ); + } + } + } + + + @Override + public int getNumberOfInsertThreads() { + return 1; + } + + + private void addNumberOfTimes( List list, QueryBuilder queryBuilder, int numberOfTimes ) { + int id = queryTypes.size() + 1; + queryTypes.put( id, queryBuilder.getNewQuery().getSql() ); + measuredTimePerQueryType.put( id, Collections.synchronizedList( new LinkedList<>() ) ); + for ( int i = 0; i < numberOfTimes; i++ ) { + list.add( new QueryListEntry( queryBuilder.getNewQuery(), id ) ); + } + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java new file mode 100644 index 0000000..aa9b6b0 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -0,0 +1,151 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.vectorbench; + +import java.util.Map; +import java.util.Properties; +import java.util.Random; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.scenario.AbstractConfig; + + +@Slf4j +public class KnnBenchConfig extends AbstractConfig { + + public String dataStoreFeature; + public String dataStoreMetadata; + + public long randomSeedInsert; + public long randomSeedQuery; + + public int dimensionFeatureVectors; + public int batchSizeInserts; + public int batchSizeQueries; + + public int numberOfEntries; + public int numberOfSimpleKnnIntFeatureQueries; + public int numberOfSimpleKnnRealFeatureQueries; + public int numberOfSimpleMetadataQueries; + public int numberOfSimpleKnnIdIntFeatureQueries; + public int numberOfSimpleKnnIdRealFeatureQueries; + public int numberOfMetadataKnnIntFeatureQueries; + public int numberOfMetadataKnnRealFeatureQueries; +// public final int numberOfCombinedQueries; + + public int limitKnnQueries; + public String distanceNorm; + + + public KnnBenchConfig( Properties properties, int multiplier ) { + super( "knnBench", "polypheny-jdbc", properties ); + + dataStoreFeature = null; + dataStoreMetadata = null; + //dataStores.add( "cottontail" ); + + if ( getBooleanProperty( properties, "useRandomSeeds" ) ) { + Random tempRand = new Random(); + randomSeedInsert = tempRand.nextLong(); + randomSeedQuery = tempRand.nextLong(); + } else { + randomSeedInsert = getLongProperty( properties, "randomSeedInsert" ); + randomSeedQuery = getLongProperty( properties, "randomSeedQuery" ); + } + + dimensionFeatureVectors = getIntProperty( properties, "dimensionFeatureVectors" ); + batchSizeInserts = getIntProperty( properties, "batchSizeInserts" ); + numberOfEntries = getIntProperty( properties, "numberOfEntries" ) * multiplier; + + batchSizeQueries = getIntProperty( properties, "batchSizeQueries" ); + numberOfSimpleKnnIntFeatureQueries = getIntProperty( properties, "numberOfSimpleKnnIntFeatureQueries" ) * multiplier; + numberOfSimpleKnnRealFeatureQueries = getIntProperty( properties, "numberOfSimpleKnnRealFeatureQueries" ) * multiplier; + numberOfSimpleMetadataQueries = getIntProperty( properties, "numberOfSimpleMetadataQueries" ) * multiplier; + numberOfSimpleKnnIdIntFeatureQueries = getIntProperty( properties, "numberOfSimpleKnnIdIntFeatureQueries" ) * multiplier; + numberOfSimpleKnnIdRealFeatureQueries = getIntProperty( properties, "numberOfSimpleKnnIdRealFeatureQueries" ) * multiplier; + numberOfMetadataKnnIntFeatureQueries = getIntProperty( properties, "numberOfMetadataKnnIntFeatureQueries" ) * multiplier; + numberOfMetadataKnnRealFeatureQueries = getIntProperty( properties, "numberOfMetadataKnnRealFeatureQueries" ) * multiplier; + limitKnnQueries = getIntProperty( properties, "limitKnnQueries" ); + distanceNorm = getStringProperty( properties, "distanceNorm" ); + } + + + public KnnBenchConfig( Map cdl ) { + super( "gavel", cdl.get( "store" ), cdl ); + + dataStoreFeature = cdl.get( "dataStoreFeature" ); + dataStoreMetadata = cdl.get( "dataStoreMetadata" ); + if ( dataStoreFeature.equals( dataStoreMetadata ) ) { + dataStores.add( dataStoreFeature ); + } else { + dataStores.add( dataStoreFeature ); + dataStores.add( dataStoreMetadata ); + } + + if ( Boolean.parseBoolean( cdl.get( "useRandomSeeds" ) ) ) { + Random tempRand = new Random(); + randomSeedInsert = tempRand.nextLong(); + randomSeedQuery = tempRand.nextLong(); + } else { + randomSeedInsert = Long.parseLong( cdl.get( "randomSeedInsert" ) ); + randomSeedQuery = Long.parseLong( cdl.get( "randomSeedQuery" ) ); + } + + dimensionFeatureVectors = Integer.parseInt( cdl.get( "dimensionFeatureVectors" ) ); + batchSizeInserts = Integer.parseInt( cdl.get( "batchSizeInserts" ) ); + numberOfEntries = Integer.parseInt( cdl.get( "numberOfEntries" ) ); + + batchSizeQueries = Integer.parseInt( cdl.get( "batchSizeQueries" ) ); + numberOfSimpleKnnIntFeatureQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnIntFeatureQueries" ) ); + numberOfSimpleKnnRealFeatureQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnRealFeatureQueries" ) ); + numberOfSimpleMetadataQueries = Integer.parseInt( cdl.get( "numberOfSimpleMetadataQueries" ) ); + numberOfSimpleKnnIdIntFeatureQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnIdIntFeatureQueries" ) ); + numberOfSimpleKnnIdRealFeatureQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnIdRealFeatureQueries" ) ); + numberOfMetadataKnnIntFeatureQueries = Integer.parseInt( cdl.get( "numberOfMetadataKnnIntFeatureQueries" ) ); + numberOfMetadataKnnRealFeatureQueries = Integer.parseInt( cdl.get( "numberOfMetadataKnnRealFeatureQueries" ) ); +// numberOfCombinedQueries = getIntProperty( properties, "numberOfCombinedQueries" ) * multiplier; + limitKnnQueries = Integer.parseInt( cdl.get( "limitKnnQueries" ) ); + distanceNorm = cdl.get( "distanceNorm" ).trim(); + } + + + // For MultiBench + protected KnnBenchConfig( String scenario, String system, Map cdl ) { + super( scenario, system, cdl ); + } + + + // For MultiBench + protected KnnBenchConfig( String scenario, String system, Properties properties ) { + super( scenario, system, properties ); + } + + + @Override + public boolean usePreparedBatchForDataInsertion() { + return true; + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java new file mode 100644 index 0000000..1fde3be --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java @@ -0,0 +1,126 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc.ColumnDefinition; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.EntityDefinition; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Type; + + +public class CreateIntFeature extends QueryBuilder { + + private final String store; + private final int dimension; + + + public CreateIntFeature( String store, int dimension ) { + this.store = store; + this.dimension = dimension; + } + + + @Override + public Query getNewQuery() { + return new CreateIntFeatureQuery( store, dimension ); + } + + + private static class CreateIntFeatureQuery extends Query { + + private final String store; + private final int dimension; + + + CreateIntFeatureQuery( String store, int dimension ) { + super( false ); + this.store = store; + this.dimension = dimension; + } + + + @Override + public String getSql() { + String sql = "CREATE TABLE knn_intfeature (id INTEGER NOT NULL, feature INTEGER ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; + if ( this.store != null ) { + sql += "ON STORE \"" + this.store + "\""; + } + return sql; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + List columns = new ArrayList<>(); + columns.add( ColumnDefinition.newBuilder().setName( "id" ).setType( Type.INTEGER ).build() ); + columns.add( ColumnDefinition.newBuilder().setName( "feature" ).setType( Type.INT_VEC ).setLength( dimension ).build() ); + EntityDefinition entityDefinition = EntityDefinition.newBuilder() + .setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ) + .addAllColumns( columns ) + .build(); + return new CottontailQuery( + QueryType.ENTITY_CREATE, + entityDefinition + ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java new file mode 100644 index 0000000..544c8b1 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java @@ -0,0 +1,122 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc.ColumnDefinition; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.EntityDefinition; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Type; + + +public class CreateMetadata extends QueryBuilder { + + private final String store; + + + public CreateMetadata( String store ) { + this.store = store; + } + + + @Override + public Query getNewQuery() { + return new CreateMetadataQuery( this.store ); + } + + + private static class CreateMetadataQuery extends Query { + + private final String store; + + + CreateMetadataQuery( String store ) { + super( false ); + this.store = store; + } + + + @Override + public String getSql() { + String sql = "CREATE TABLE knn_metadata (id integer NOT NULL, textdata VARCHAR(100), PRIMARY KEY (id))"; + if ( this.store != null ) { + sql += "ON STORE \"" + this.store + "\""; + } + return sql; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + List columns = new ArrayList<>(); + columns.add( ColumnDefinition.newBuilder().setName( "id" ).setType( Type.INTEGER ).build() ); + columns.add( ColumnDefinition.newBuilder().setName( "textdata" ).setType( Type.STRING ).build() ); + EntityDefinition entityDefinition = EntityDefinition.newBuilder() + .setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_metadata" ).build() ) + .addAllColumns( columns ) + .build(); + return new CottontailQuery( + QueryType.ENTITY_CREATE, + entityDefinition + ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java new file mode 100644 index 0000000..319dfb1 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java @@ -0,0 +1,126 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc.ColumnDefinition; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.EntityDefinition; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Type; + + +public class CreateRealFeature extends QueryBuilder { + + private final String store; + private final int dimension; + + + public CreateRealFeature( String store, int dimension ) { + this.store = store; + this.dimension = dimension; + } + + + @Override + public Query getNewQuery() { + return new CreateRealFeatureQuery( store, dimension ); + } + + + private static class CreateRealFeatureQuery extends Query { + + private final String store; + private final int dimension; + + + CreateRealFeatureQuery( String store, int dimension ) { + super( false ); + this.store = store; + this.dimension = dimension; + } + + + @Override + public String getSql() { + String sql = "CREATE TABLE knn_realfeature (id INTEGER NOT NULL, feature REAL ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; + if ( this.store != null ) { + sql += "ON STORE \"" + this.store + "\""; + } + return sql; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + List columns = new ArrayList<>(); + columns.add( ColumnDefinition.newBuilder().setName( "id" ).setType( Type.INTEGER ).build() ); + columns.add( ColumnDefinition.newBuilder().setName( "feature" ).setType( Type.FLOAT_VEC ).setLength( dimension ).build() ); + EntityDefinition entityDefinition = EntityDefinition.newBuilder() + .setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_realfeature" ).build() ) + .addAllColumns( columns ) + .build(); + return new CottontailQuery( + QueryType.ENTITY_CREATE, + entityDefinition + ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java new file mode 100644 index 0000000..31fbbe6 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java @@ -0,0 +1,170 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import com.google.gson.JsonObject; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Data; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.From; +import org.vitrivr.cottontail.grpc.CottontailGrpc.InsertMessage; +import org.vitrivr.cottontail.grpc.CottontailGrpc.IntVector; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Tuple; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; + + +public class InsertIntFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = false; + + private static final AtomicInteger nextId = new AtomicInteger( 1 ); + private final long randomSeed; + private final int dimension; + + private final Random random; + + + public InsertIntFeature( long randomSeed, int dimension ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + + this.random = new Random( randomSeed ); + } + + + private Integer[] getRandomVector() { + Integer[] integers = new Integer[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + integers[i] = random.nextInt( 500 ); + } + + return integers; + } + + + @Override + public synchronized BatchableInsert getNewQuery() { + return new InsertIntFeatureQuery( + nextId.getAndIncrement(), + getRandomVector() + ); + } + + + private static class InsertIntFeatureQuery extends BatchableInsert { + + private static final String SQL = "INSERT INTO knn_intfeature (id, feature) VALUES "; + private final int id; + private final Integer[] feature; + + + private InsertIntFeatureQuery( int id, Integer[] feature ) { + super( EXPECT_RESULT ); + this.id = id; + this.feature = feature; + } + + + @Override + public String getSqlRowExpression() { + return "(" + id + ", ARRAY" + Arrays.toString( feature ) + ")"; + } + + + @Override + public String getParameterizedSqlQuery() { + return SQL + "(?, ?)"; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, id ) ); + map.put( 2, new ImmutablePair<>( DataTypes.ARRAY_INT, feature ) ); + return map; + } + + + @Override + public JsonObject getRestRowExpression() { + return null; + } + + + @Override + public String getEntity() { + return "public.knn_intfeature"; + } + + + @Override + public String getSql() { + return SQL + getSqlRowExpression(); + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + Map dataMap = new HashMap<>(); + dataMap.put( "id", Data.newBuilder().setIntData( id ).build() ); + dataMap.put( "feature", Data.newBuilder().setVectorData( + Vector.newBuilder().setIntVector( IntVector.newBuilder() + .addAllVector( Arrays.asList( feature ) ) + .build() ).build() ).build() ); + InsertMessage insertMessage = InsertMessage.newBuilder() + .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ).build() ) + .setTuple( Tuple.newBuilder().putAllData( dataMap ).build() ) + .build(); + return new CottontailQuery( QueryType.INSERT, insertMessage ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java new file mode 100644 index 0000000..d2b9c9e --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java @@ -0,0 +1,139 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import com.google.gson.JsonObject; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Data; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.From; +import org.vitrivr.cottontail.grpc.CottontailGrpc.InsertMessage; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Tuple; + + +public class InsertMetadata extends QueryBuilder { + + private static final boolean EXPECT_RESULT = false; + + private static final AtomicInteger nextId = new AtomicInteger( 1 ); + + + @Override + public BatchableInsert getNewQuery() { + return new InsertMetadataQuery( nextId.getAndIncrement() ); + } + + + private static class InsertMetadataQuery extends BatchableInsert { + + private static final String SQL = "INSERT INTO knn_metadata (id, textdata) VALUES "; + + private final int id; + private final String textdata; + + + private InsertMetadataQuery( int id ) { + super( EXPECT_RESULT ); + this.id = id; + this.textdata = "textdata_" + id + "_blubber"; + } + + + @Override + public String getSqlRowExpression() { + return "(" + id + ", '" + textdata + "')"; + } + + + @Override + public String getParameterizedSqlQuery() { + return SQL + "(?, ?)"; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, id ) ); + map.put( 2, new ImmutablePair<>( DataTypes.VARCHAR, textdata ) ); + return map; + } + + + @Override + public JsonObject getRestRowExpression() { + return null; + } + + + @Override + public String getEntity() { + return "public.knn_metadata"; + } + + + @Override + public String getSql() { + return SQL + getSqlRowExpression(); + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + Map dataMap = new HashMap<>(); + dataMap.put( "id", Data.newBuilder().setIntData( id ).build() ); + dataMap.put( "textdata", Data.newBuilder().setStringData( textdata ).build() ); + InsertMessage insertMessage = InsertMessage.newBuilder() + .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_metadata" ).build() ).build() ) + .setTuple( Tuple.newBuilder().putAllData( dataMap ).build() ) + .build(); + return new CottontailQuery( QueryType.INSERT, insertMessage ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java new file mode 100644 index 0000000..87760b6 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java @@ -0,0 +1,170 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import com.google.gson.JsonObject; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Data; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.FloatVector; +import org.vitrivr.cottontail.grpc.CottontailGrpc.From; +import org.vitrivr.cottontail.grpc.CottontailGrpc.InsertMessage; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Tuple; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; + + +public class InsertRealFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = false; + + private static final AtomicInteger nextId = new AtomicInteger( 1 ); + private final long randomSeed; + private final int dimension; + + private final Random random; + + + public InsertRealFeature( long randomSeed, int dimension ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + + this.random = new Random( randomSeed ); + } + + + private Float[] getRandomVector() { + Float[] floats = new Float[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + + return floats; + } + + + @Override + public synchronized BatchableInsert getNewQuery() { + return new InsertRealFeatureQuery( + nextId.getAndIncrement(), + getRandomVector() + ); + } + + + private static class InsertRealFeatureQuery extends BatchableInsert { + + private static final String SQL = "INSERT INTO knn_realfeature (id, feature) VALUES "; + private final int id; + private final Float[] feature; + + + private InsertRealFeatureQuery( int id, Float[] feature ) { + super( EXPECT_RESULT ); + this.id = id; + this.feature = feature; + } + + + @Override + public String getSqlRowExpression() { + return "(" + id + ", ARRAY" + Arrays.toString( feature ) + ")"; + } + + + @Override + public String getParameterizedSqlQuery() { + return SQL + "(?, ?)"; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, id ) ); + map.put( 2, new ImmutablePair<>( DataTypes.ARRAY_REAL, feature ) ); + return map; + } + + + @Override + public JsonObject getRestRowExpression() { + return null; + } + + + @Override + public String getEntity() { + return "public.knn_realfeature"; + } + + + @Override + public String getSql() { + return SQL + getSqlRowExpression(); + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + Map dataMap = new HashMap<>(); + dataMap.put( "id", Data.newBuilder().setIntData( id ).build() ); + dataMap.put( "feature", Data.newBuilder().setVectorData( + Vector.newBuilder().setFloatVector( FloatVector.newBuilder() + .addAllVector( Arrays.asList( feature ) ) + .build() ).build() ).build() ); + InsertMessage insertMessage = InsertMessage.newBuilder() + .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_realfeature" ).build() ).build() ) + .setTuple( Tuple.newBuilder().putAllData( dataMap ).build() ) + .build(); + return new CottontailQuery( QueryType.INSERT, insertMessage ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java new file mode 100644 index 0000000..09fe4f8 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java @@ -0,0 +1,141 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class MetadataKnnIntFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final long randomSeed; + private final int dimension; + private final int limit; + private final String norm; + + private final Random random; + + + public MetadataKnnIntFeature( long randomSeed, int dimension, int limit, String norm ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + this.limit = limit; + this.norm = norm; + + this.random = new Random( randomSeed ); + } + + + private Integer[] getRandomVector() { + Integer[] integers = new Integer[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + integers[i] = random.nextInt( 500 ); + } + + return integers; + } + + + @Override + public synchronized Query getNewQuery() { + return new MetadataKnnIntFeatureQuery( + getRandomVector(), + limit, + norm + ); + } + + + private static class MetadataKnnIntFeatureQuery extends Query { + + private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_4 = ") AS closest WHERE knn_metadata.id = closest.id ORDER BY closest.dist ASC"; + + private final Integer[] target; + private final int limit; + private final String norm; + + + private MetadataKnnIntFeatureQuery( Integer[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + + @Override + public String getSql() { + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + //return SQL_1 + "?" + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.ARRAY_INT, target ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + throw new RuntimeException( "This query is unsupported by cottontail." ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java new file mode 100644 index 0000000..f1d897e --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java @@ -0,0 +1,141 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class MetadataKnnRealFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final long randomSeed; + private final int dimension; + private final int limit; + private final String norm; + + private final Random random; + + + public MetadataKnnRealFeature( long randomSeed, int dimension, int limit, String norm ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + this.limit = limit; + this.norm = norm; + + this.random = new Random( randomSeed ); + } + + + private Float[] getRandomVector() { + Float[] floats = new Float[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + + return floats; + } + + + @Override + public synchronized Query getNewQuery() { + return new MetadataKnnRealFeatureQuery( + getRandomVector(), + limit, + norm + ); + } + + + private static class MetadataKnnRealFeatureQuery extends Query { + + private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_4 = ") AS closest WHERE knn_metadata.id = closest.id ORDER BY closest.dist ASC"; + + private final Float[] target; + private final int limit; + private final String norm; + + + private MetadataKnnRealFeatureQuery( Float[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + + @Override + public String getSql() { + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + //return SQL_1 + "?" + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.ARRAY_REAL, target ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + throw new RuntimeException( "This query is unsupported by cottontail." ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java new file mode 100644 index 0000000..b1de916 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java @@ -0,0 +1,188 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.From; +import org.vitrivr.cottontail.grpc.CottontailGrpc.IntVector; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn.Distance; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Projection; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; + + +public class SimpleKnnIdIntFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final long randomSeed; + private final int dimension; + private final int limit; + private final String norm; + + private final Random random; + + + public SimpleKnnIdIntFeature( long randomSeed, int dimension, int limit, String norm ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + + this.random = new Random( randomSeed ); + this.limit = limit; + this.norm = norm; + } + + + private Integer[] getRandomVector() { + Integer[] integers = new Integer[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + integers[i] = random.nextInt( 500 ); + } + + return integers; + } + + + @Override + public synchronized Query getNewQuery() { + return new SimpleKnnIdIntFeatureQuery( + getRandomVector(), + limit, + norm + ); + } + + + private static class SimpleKnnIdIntFeatureQuery extends Query { + + private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_4 = ") AS closest"; + + private final Integer[] target; + private final int limit; + private final String norm; + + + public SimpleKnnIdIntFeatureQuery( Integer[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + + @Override + public String getSql() { + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + //return SQL_1 + "?" + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.ARRAY_INT, target ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + Map projection = new HashMap<>(); + projection.put( "id", "id" ); + CottontailGrpc.Query query = CottontailGrpc.Query.newBuilder() + .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ) ) + .setLimit( limit ) + .setKnn( Knn.newBuilder() + .setAttribute( "feature" ) + .setK( limit ) + .addQuery( Vector.newBuilder().setIntVector( IntVector.newBuilder().addAllVector( Arrays.asList( target ) ).build() ).build() ) + .setDistance( getDistance( norm ) ) + .build() ) + .setProjection( Projection.newBuilder().putAllAttributes( projection ).build() ) + .build(); + return new CottontailQuery( + QueryType.QUERY, + query + ); + } + + + private static Distance getDistance( String norm ) { + if ( "L2".equalsIgnoreCase( norm ) ) { + return Distance.L2; + } + if ( "L1".equalsIgnoreCase( norm ) ) { + return Distance.L1; + } + if ( "L2SQUARED".equalsIgnoreCase( norm ) ) { + return Distance.L2SQUARED; + } + if ( "CHISQUARED".equalsIgnoreCase( norm ) ) { + return Distance.CHISQUARED; + } + if ( "COSINE".equalsIgnoreCase( norm ) ) { + return Distance.COSINE; + } + + throw new RuntimeException( "Unsupported norm: " + norm ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java new file mode 100644 index 0000000..8eb7d00 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java @@ -0,0 +1,188 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.FloatVector; +import org.vitrivr.cottontail.grpc.CottontailGrpc.From; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn.Distance; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Projection; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; + + +public class SimpleKnnIdRealFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final long randomSeed; + private final int dimension; + private final int limit; + private final String norm; + + private final Random random; + + + public SimpleKnnIdRealFeature( long randomSeed, int dimension, int limit, String norm ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + + this.random = new Random( randomSeed ); + this.limit = limit; + this.norm = norm; + } + + + private Float[] getRandomVector() { + Float[] integers = new Float[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + integers[i] = random.nextInt( 100 ) / 100.0f; + } + + return integers; + } + + + @Override + public synchronized Query getNewQuery() { + return new SimpleKnnIdRealFeatureQuery( + getRandomVector(), + limit, + norm + ); + } + + + private static class SimpleKnnIdRealFeatureQuery extends Query { + + private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_4 = ") AS closest"; + + private final Float[] target; + private final int limit; + private final String norm; + + + public SimpleKnnIdRealFeatureQuery( Float[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + + @Override + public String getSql() { + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + //return SQL_1 + "?" + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.ARRAY_REAL, target ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + Map projection = new HashMap<>(); + projection.put( "id", "id" ); + CottontailGrpc.Query query = CottontailGrpc.Query.newBuilder() + .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ) ) + .setLimit( limit ) + .setKnn( Knn.newBuilder() + .setAttribute( "feature" ) + .setK( limit ) + .addQuery( Vector.newBuilder().setFloatVector( FloatVector.newBuilder().addAllVector( Arrays.asList( target ) ).build() ).build() ) + .setDistance( getDistance( norm ) ) + .build() ) + .setProjection( Projection.newBuilder().putAllAttributes( projection ).build() ) + .build(); + return new CottontailQuery( + QueryType.QUERY, + query + ); + } + + + private static Distance getDistance( String norm ) { + if ( "L2".equalsIgnoreCase( norm ) ) { + return Distance.L2; + } + if ( "L1".equalsIgnoreCase( norm ) ) { + return Distance.L1; + } + if ( "L2SQUARED".equalsIgnoreCase( norm ) ) { + return Distance.L2SQUARED; + } + if ( "CHISQUARED".equalsIgnoreCase( norm ) ) { + return Distance.CHISQUARED; + } + if ( "COSINE".equalsIgnoreCase( norm ) ) { + return Distance.COSINE; + } + + throw new RuntimeException( "Unsupported norm: " + norm ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java new file mode 100644 index 0000000..bdde21e --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java @@ -0,0 +1,183 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.From; +import org.vitrivr.cottontail.grpc.CottontailGrpc.IntVector; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn.Distance; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; + + +public class SimpleKnnIntFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final long randomSeed; + private final int dimension; + private final int limit; + private final String norm; + + private final Random random; + + + public SimpleKnnIntFeature( long randomSeed, int dimension, int limit, String norm ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + + this.random = new Random( randomSeed ); + this.limit = limit; + this.norm = norm; + } + + + private Integer[] getRandomVector() { + Integer[] integers = new Integer[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + integers[i] = random.nextInt( 500 ); + } + + return integers; + } + + + @Override + public synchronized Query getNewQuery() { + return new SimpleKnnIntFeatureQuery( + getRandomVector(), + limit, + norm + ); + } + + + private static class SimpleKnnIntFeatureQuery extends Query { + + private static final String SQL_1 = "SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") as dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + + private final Integer[] target; + private final int limit; + private final String norm; + + + public SimpleKnnIntFeatureQuery( Integer[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + + @Override + public String getSql() { + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + //return SQL_1 + "?" + SQL_2 + "'" + norm + "'" + SQL_3 + limit; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.ARRAY_INT, target ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + CottontailGrpc.Query query = CottontailGrpc.Query.newBuilder() + .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ) ) + .setLimit( limit ) + .setKnn( Knn.newBuilder() + .setAttribute( "feature" ) + .setK( limit ) + .addQuery( Vector.newBuilder().setIntVector( IntVector.newBuilder().addAllVector( Arrays.asList( target ) ).build() ).build() ) + .setDistance( getDistance( norm ) ) + .build() ) + .build(); + return new CottontailQuery( + QueryType.QUERY, + query + ); + } + + + private static CottontailGrpc.Knn.Distance getDistance( String norm ) { + if ( "L2".equalsIgnoreCase( norm ) ) { + return Distance.L2; + } + if ( "L1".equalsIgnoreCase( norm ) ) { + return Distance.L1; + } + if ( "L2SQUARED".equalsIgnoreCase( norm ) ) { + return Distance.L2SQUARED; + } + if ( "CHISQUARED".equalsIgnoreCase( norm ) ) { + return Distance.CHISQUARED; + } + if ( "COSINE".equalsIgnoreCase( norm ) ) { + return Distance.COSINE; + } + + throw new RuntimeException( "Unsupported norm: " + norm ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java new file mode 100644 index 0000000..bd969a0 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java @@ -0,0 +1,183 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2021 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.CottontailQuery; +import org.polypheny.simpleclient.query.CottontailQuery.QueryType; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.vitrivr.cottontail.grpc.CottontailGrpc; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; +import org.vitrivr.cottontail.grpc.CottontailGrpc.FloatVector; +import org.vitrivr.cottontail.grpc.CottontailGrpc.From; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn.Distance; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; +import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; + + +public class SimpleKnnRealFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final long randomSeed; + private final int dimension; + private final int limit; + private final String norm; + + private final Random random; + + + public SimpleKnnRealFeature( long randomSeed, int dimension, int limit, String norm ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + + this.random = new Random( randomSeed ); + this.limit = limit; + this.norm = norm; + } + + + private Float[] getRandomVector() { + Float[] integers = new Float[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + integers[i] = random.nextInt( 100 ) / 100.0f; + } + + return integers; + } + + + @Override + public synchronized Query getNewQuery() { + return new SimpleKnnRealFeatureQuery( + getRandomVector(), + limit, + norm + ); + } + + + private static class SimpleKnnRealFeatureQuery extends Query { + + private static final String SQL_1 = "SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") as dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; + + private final Float[] target; + private final int limit; + private final String norm; + + + public SimpleKnnRealFeatureQuery( Float[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + + @Override + public String getSql() { + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + //return SQL_1 + "?" + SQL_2 + "'" + norm + "'" + SQL_3 + limit; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.ARRAY_REAL, target ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + + @Override + public CottontailQuery getCottontail() { + CottontailGrpc.Query query = CottontailGrpc.Query.newBuilder() + .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_realfeature" ).build() ) ) + .setLimit( limit ) + .setKnn( Knn.newBuilder() + .setAttribute( "feature" ) + .setK( limit ) + .addQuery( Vector.newBuilder().setFloatVector( FloatVector.newBuilder().addAllVector( Arrays.asList( target ) ).build() ).build() ) + .setDistance( getDistance( norm ) ) + .build() ) + .build(); + return new CottontailQuery( + QueryType.QUERY, + query + ); + } + + + private static CottontailGrpc.Knn.Distance getDistance( String norm ) { + if ( "L2".equalsIgnoreCase( norm ) ) { + return Distance.L2; + } + if ( "L1".equalsIgnoreCase( norm ) ) { + return Distance.L1; + } + if ( "L2SQUARED".equalsIgnoreCase( norm ) ) { + return Distance.L2SQUARED; + } + if ( "CHISQUARED".equalsIgnoreCase( norm ) ) { + return Distance.CHISQUARED; + } + if ( "COSINE".equalsIgnoreCase( norm ) ) { + return Distance.COSINE; + } + + throw new RuntimeException( "Unsupported norm: " + norm ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java new file mode 100644 index 0000000..a738ff5 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java @@ -0,0 +1,117 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2022 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class SimpleMetadata extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final long randomSeed; + private final int numOfEntries; + + private final Random random; + + + public SimpleMetadata( long randomSeed, int numOfEntries ) { + this.randomSeed = randomSeed; + this.numOfEntries = numOfEntries; + + this.random = new Random( randomSeed ); + } + + + private int getRandomId() { + return this.random.nextInt( this.numOfEntries ); + } + + + @Override + public Query getNewQuery() { + return new SimpleMetadataQuery( this.getRandomId() ); + } + + + private static class SimpleMetadataQuery extends Query { + + private static final String SQL = "SELECT id, textdata FROM knn_metadata WHERE id = "; + + private final int id; + + + private SimpleMetadataQuery( int id ) { + super( EXPECT_RESULT ); + this.id = id; + } + + + @Override + public String getSql() { + return SQL + id; + } + + + @Override + public String getParameterizedSqlQuery() { + return SQL + "?"; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, id ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + throw new UnsupportedOperationException( "kNN benchmarking is not supported for the REST interface." ); + } + + + @Override + public String getMongoQl() { + throw new UnsupportedOperationException( "kNN benchmarking is not supported for the MongoQl interface." ); + } + + + @Override + public String getCypher() { + throw new UnsupportedOperationException( "kNN benchmarking is not supported for the Cypher interface." ); + } + + } + +} From d971239fec87cfdfde87286a3c24fd97613547e2 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Tue, 7 Apr 2026 15:39:26 +0200 Subject: [PATCH 04/38] Add vectorbench scenario mirroring knnbench with adjustements --- .../org/polypheny/simpleclient/cli/Main.java | 1 + .../simpleclient/cli/VectorCommand.java | 106 +++++++++++++++++- .../main/VectorBenchScenario.java | 86 ++++++++++++++ .../scenario/vectorbench/DataGenerator.java | 12 +- .../scenario/vectorbench/VectorBench.java | 6 +- .../vectorbench/VectorBenchConfig.java | 21 ++-- .../queryBuilder/CreateIntFeature.java | 29 +---- .../queryBuilder/CreateMetadata.java | 31 +---- .../queryBuilder/CreateRealFeature.java | 30 +---- .../queryBuilder/InsertIntFeature.java | 31 +---- .../queryBuilder/InsertMetadata.java | 26 +---- .../queryBuilder/InsertRealFeature.java | 31 +---- .../queryBuilder/MetadataKnnIntFeature.java | 36 +++--- .../queryBuilder/MetadataKnnRealFeature.java | 33 ++++-- .../queryBuilder/SimpleKnnIdIntFeature.java | 83 ++++---------- .../queryBuilder/SimpleKnnIdRealFeature.java | 83 ++++---------- .../queryBuilder/SimpleKnnIntFeature.java | 79 ++++--------- .../queryBuilder/SimpleKnnRealFeature.java | 81 ++++--------- .../queryBuilder/SimpleMetadata.java | 10 +- .../scenario/vectorbench/vector.properties | 31 +++++ 20 files changed, 396 insertions(+), 450 deletions(-) create mode 100644 src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties diff --git a/src/main/java/org/polypheny/simpleclient/cli/Main.java b/src/main/java/org/polypheny/simpleclient/cli/Main.java index 988ac96..1a40051 100644 --- a/src/main/java/org/polypheny/simpleclient/cli/Main.java +++ b/src/main/java/org/polypheny/simpleclient/cli/Main.java @@ -42,6 +42,7 @@ public static void main( String[] args ) throws SQLException { builder.withCommands( ComsCommand.class ); builder.withCommands( GavelCommand.class ); builder.withCommands( KnnCommand.class ); + builder.withCommands( VectorCommand.class ); builder.withCommands( MultimediaCommand.class ); builder.withCommands( GraphCommand.class ); builder.withCommands( DocBenchCommand.class ); diff --git a/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java b/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java index ccae89f..71e85b2 100644 --- a/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java +++ b/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java @@ -1,4 +1,108 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package org.polypheny.simpleclient.cli; -public class VectorCommand { +import com.github.rvesse.airline.HelpOption; +import com.github.rvesse.airline.annotations.AirlineModule; +import com.github.rvesse.airline.annotations.Arguments; +import com.github.rvesse.airline.annotations.Command; +import com.github.rvesse.airline.annotations.Option; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.executor.Executor.ExecutorFactory; +import org.polypheny.simpleclient.executor.PolyphenyDbJdbcExecutor.PolyphenyDbJdbcExecutorFactory; +import org.polypheny.simpleclient.main.VectorBenchScenario; +import java.sql.SQLException; +import java.util.List; + +@Slf4j +@Command(name = "vector", description = "Mode for quick testing of Polypheny-DB using the vector benchmark.") +public class VectorCommand implements CliRunnable { + + @AirlineModule + private HelpOption help; + + @Arguments(description = "Task { schema | data | workload } and multiplier.") + private List args; + + + @Option(name = { "-pdb", "--polyphenydb" }, title = "IP or Hostname", arity = 1, description = "IP or Hostname of the Polypheny-DB server (default: 127.0.0.1).") + public static String polyphenyDbHost = "127.0.0.1"; + + + @Option(name = { "--writeCSV" }, arity = 0, description = "Write a CSV file containing execution times for all executed queries (default: false).") + public boolean writeCsv = false; + + + @Option(name = { "--queryList" }, arity = 0, description = "Dump all queries into a file (default: false).") + public boolean dumpQueryList = false; + + + @Override + public int run() throws SQLException { + + if ( args == null || args.size() < 1 ) { + System.err.println( "Missing task" ); + System.exit( 1 ); + } + + int multiplier = 1; + if ( args.size() > 1 ) { + multiplier = Integer.parseInt( args.get( 1 ) ); + if ( multiplier < 1 ) { + System.err.println( "Multiplier needs to be a integer > 0!" ); + System.exit( 1 ); + } + } + + ExecutorFactory executorFactory; + executorFactory = new PolyphenyDbJdbcExecutorFactory( polyphenyDbHost, false ); + + try { + if ( args.getFirst().equalsIgnoreCase( "data" ) ) { + VectorBenchScenario.data( executorFactory, multiplier, true ); + } else if ( args.getFirst().equalsIgnoreCase( "workload" ) ) { + VectorBenchScenario.workload( executorFactory, multiplier, true, writeCsv, dumpQueryList ); + } else if ( args.getFirst().equalsIgnoreCase( "schema" ) ) { + VectorBenchScenario.schema( executorFactory, true ); + } else if ( args.getFirst().equalsIgnoreCase( "warmup" ) ) { + VectorBenchScenario.warmup( executorFactory, multiplier, true, dumpQueryList ); + } else { + System.err.println( "Unknown task: " + args.getFirst() ); + } + } catch ( Throwable t ) { + log.error( "Exception while executing VectorBench!", t ); + System.exit( 1 ); + } + + try { + Thread.sleep( 2000 ); + } catch ( InterruptedException e ) { + throw new RuntimeException( "Unexpected interrupt", e ); + } + + return 0; + } + } diff --git a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java index f1d0b7a..16af8c4 100644 --- a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java +++ b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java @@ -1,4 +1,90 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-4/4/26, 11:01 PM The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package org.polypheny.simpleclient.main; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.executor.Executor.ExecutorFactory; +import org.polypheny.simpleclient.scenario.vectorbench.VectorBench; +import org.polypheny.simpleclient.scenario.vectorbench.VectorBenchConfig; +import java.io.File; +import java.io.IOException; +import java.util.Objects; +import java.util.Properties; + +@Slf4j public class VectorBenchScenario { + + public static void schema( ExecutorFactory executorFactory, boolean commitAfterEveryQuery ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), 1 ); + VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, false ); + vectorBench.createSchema( null, true ); + } + + + public static void data( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); + VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, false ); + + ProgressReporter progressReporter = new ProgressBar( config.numberOfThreads, config.progressReportBase ); + vectorBench.generateData( null, progressReporter ); + } + + + public static void workload( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery, boolean writeCsv, boolean dumpQueryList ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); + VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, dumpQueryList ); + + final CsvWriter csvWriter; + if ( writeCsv ) { + csvWriter = new CsvWriter( "results.csv" ); + } else { + csvWriter = null; + } + + ProgressReporter progressReporter = new ProgressBar( config.numberOfThreads, config.progressReportBase ); + vectorBench.execute( progressReporter, csvWriter, new File( "." ), config.numberOfThreads ); + } + + + public static void warmup( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery, boolean dumpQueryList ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); + VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, dumpQueryList ); + + ProgressReporter progressReporter = new ProgressBar( config.numberOfThreads, config.progressReportBase ); + vectorBench.warmUp( progressReporter ); + } + + + private static Properties getProperties() { + Properties props = new Properties(); + try { + props.load( Objects.requireNonNull( ClassLoader.getSystemResourceAsStream( "org/polypheny/simpleclient/scenario/vectorbench/vector.properties" ) ) ); + } catch ( IOException e ) { + log.error( "Exception while reading properties file", e ); + } + return props; + } + } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java index 44a32ff..46e1eef 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java @@ -23,7 +23,7 @@ * */ -package org.polypheny.simpleclient.scenario.knnbench; +package org.polypheny.simpleclient.scenario.vectorbench; import java.util.LinkedList; import java.util.List; @@ -32,16 +32,16 @@ import org.polypheny.simpleclient.executor.ExecutorException; import org.polypheny.simpleclient.main.ProgressReporter; import org.polypheny.simpleclient.query.BatchableInsert; -import org.polypheny.simpleclient.scenario.knnbench.queryBuilder.InsertIntFeature; -import org.polypheny.simpleclient.scenario.knnbench.queryBuilder.InsertMetadata; -import org.polypheny.simpleclient.scenario.knnbench.queryBuilder.InsertRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.InsertIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.InsertMetadata; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.InsertRealFeature; @Slf4j public class DataGenerator { private final Executor theExecutor; - private final KnnBenchConfig config; + private final VectorBenchConfig config; private final ProgressReporter progressReporter; private final List batchList; @@ -49,7 +49,7 @@ public class DataGenerator { private boolean aborted; - DataGenerator( Executor executor, KnnBenchConfig config, ProgressReporter progressReporter ) { + DataGenerator(Executor executor, VectorBenchConfig config, ProgressReporter progressReporter ) { theExecutor = executor; this.config = config; this.progressReporter = progressReporter; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index 7057157..527d2cd 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -53,11 +53,11 @@ @Slf4j -public class KnnBench extends PolyphenyScenario { +public class VectorBench extends PolyphenyScenario { - private final KnnBenchConfig config; + private final VectorBenchConfig config; - public KnnBench(Executor.ExecutorFactory executorFactory, KnnBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { + public VectorBench(Executor.ExecutorFactory executorFactory, VectorBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); this.config = config; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index aa9b6b0..d8e1742 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -33,7 +33,7 @@ @Slf4j -public class KnnBenchConfig extends AbstractConfig { +public class VectorBenchConfig extends AbstractConfig { public String dataStoreFeature; public String dataStoreMetadata; @@ -59,11 +59,18 @@ public class KnnBenchConfig extends AbstractConfig { public String distanceNorm; - public KnnBenchConfig( Properties properties, int multiplier ) { + public VectorBenchConfig(Properties properties, int multiplier ) { super( "knnBench", "polypheny-jdbc", properties ); - dataStoreFeature = null; - dataStoreMetadata = null; + dataStoreFeature = getStringProperty( properties,"dataStoreFeature" ); + dataStoreMetadata = getStringProperty( properties, "dataStoreMeta" ); + + if ( dataStoreFeature.equals( dataStoreMetadata ) ) { + dataStores.add( dataStoreFeature ); + } else { + dataStores.add( dataStoreFeature ); + dataStores.add( dataStoreMetadata ); + } //dataStores.add( "cottontail" ); if ( getBooleanProperty( properties, "useRandomSeeds" ) ) { @@ -92,7 +99,7 @@ public KnnBenchConfig( Properties properties, int multiplier ) { } - public KnnBenchConfig( Map cdl ) { + public VectorBenchConfig(Map cdl ) { super( "gavel", cdl.get( "store" ), cdl ); dataStoreFeature = cdl.get( "dataStoreFeature" ); @@ -132,13 +139,13 @@ public KnnBenchConfig( Map cdl ) { // For MultiBench - protected KnnBenchConfig( String scenario, String system, Map cdl ) { + protected VectorBenchConfig(String scenario, String system, Map cdl ) { super( scenario, system, cdl ); } // For MultiBench - protected KnnBenchConfig( String scenario, String system, Properties properties ) { + protected VectorBenchConfig(String scenario, String system, Properties properties ) { super( scenario, system, properties ); } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java index 1fde3be..498de05 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,25 +20,15 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc.ColumnDefinition; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.EntityDefinition; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Type; public class CreateIntFeature extends QueryBuilder { @@ -106,21 +96,6 @@ public String getMongoQl() { } - @Override - public CottontailQuery getCottontail() { - List columns = new ArrayList<>(); - columns.add( ColumnDefinition.newBuilder().setName( "id" ).setType( Type.INTEGER ).build() ); - columns.add( ColumnDefinition.newBuilder().setName( "feature" ).setType( Type.INT_VEC ).setLength( dimension ).build() ); - EntityDefinition entityDefinition = EntityDefinition.newBuilder() - .setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ) - .addAllColumns( columns ) - .build(); - return new CottontailQuery( - QueryType.ENTITY_CREATE, - entityDefinition - ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java index 544c8b1..006d30c 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,25 +20,16 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc.ColumnDefinition; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.EntityDefinition; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Type; + public class CreateMetadata extends QueryBuilder { @@ -101,22 +92,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - List columns = new ArrayList<>(); - columns.add( ColumnDefinition.newBuilder().setName( "id" ).setType( Type.INTEGER ).build() ); - columns.add( ColumnDefinition.newBuilder().setName( "textdata" ).setType( Type.STRING ).build() ); - EntityDefinition entityDefinition = EntityDefinition.newBuilder() - .setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_metadata" ).build() ) - .addAllColumns( columns ) - .build(); - return new CottontailQuery( - QueryType.ENTITY_CREATE, - entityDefinition - ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java index 319dfb1..6de37e1 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,25 +20,15 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc.ColumnDefinition; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.EntityDefinition; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Type; public class CreateRealFeature extends QueryBuilder { @@ -105,22 +95,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - List columns = new ArrayList<>(); - columns.add( ColumnDefinition.newBuilder().setName( "id" ).setType( Type.INTEGER ).build() ); - columns.add( ColumnDefinition.newBuilder().setName( "feature" ).setType( Type.FLOAT_VEC ).setLength( dimension ).build() ); - EntityDefinition entityDefinition = EntityDefinition.newBuilder() - .setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_realfeature" ).build() ) - .addAllColumns( columns ) - .build(); - return new CottontailQuery( - QueryType.ENTITY_CREATE, - entityDefinition - ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java index 31fbbe6..7231f4f 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import com.google.gson.JsonObject; import java.util.Arrays; @@ -34,17 +33,7 @@ import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.BatchableInsert; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Data; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.From; -import org.vitrivr.cottontail.grpc.CottontailGrpc.InsertMessage; -import org.vitrivr.cottontail.grpc.CottontailGrpc.IntVector; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Tuple; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; public class InsertIntFeature extends QueryBuilder { @@ -149,22 +138,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - Map dataMap = new HashMap<>(); - dataMap.put( "id", Data.newBuilder().setIntData( id ).build() ); - dataMap.put( "feature", Data.newBuilder().setVectorData( - Vector.newBuilder().setIntVector( IntVector.newBuilder() - .addAllVector( Arrays.asList( feature ) ) - .build() ).build() ).build() ); - InsertMessage insertMessage = InsertMessage.newBuilder() - .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ).build() ) - .setTuple( Tuple.newBuilder().putAllData( dataMap ).build() ) - .build(); - return new CottontailQuery( QueryType.INSERT, insertMessage ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java index d2b9c9e..a41c6e6 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import com.google.gson.JsonObject; import java.util.HashMap; @@ -32,15 +31,7 @@ import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.BatchableInsert; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Data; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.From; -import org.vitrivr.cottontail.grpc.CottontailGrpc.InsertMessage; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Tuple; public class InsertMetadata extends QueryBuilder { @@ -121,19 +112,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - Map dataMap = new HashMap<>(); - dataMap.put( "id", Data.newBuilder().setIntData( id ).build() ); - dataMap.put( "textdata", Data.newBuilder().setStringData( textdata ).build() ); - InsertMessage insertMessage = InsertMessage.newBuilder() - .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_metadata" ).build() ).build() ) - .setTuple( Tuple.newBuilder().putAllData( dataMap ).build() ) - .build(); - return new CottontailQuery( QueryType.INSERT, insertMessage ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java index 87760b6..4735ac5 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import com.google.gson.JsonObject; import java.util.Arrays; @@ -34,17 +33,7 @@ import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.BatchableInsert; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Data; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.FloatVector; -import org.vitrivr.cottontail.grpc.CottontailGrpc.From; -import org.vitrivr.cottontail.grpc.CottontailGrpc.InsertMessage; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Tuple; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; public class InsertRealFeature extends QueryBuilder { @@ -149,22 +138,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - Map dataMap = new HashMap<>(); - dataMap.put( "id", Data.newBuilder().setIntData( id ).build() ); - dataMap.put( "feature", Data.newBuilder().setVectorData( - Vector.newBuilder().setFloatVector( FloatVector.newBuilder() - .addAllVector( Arrays.asList( feature ) ) - .build() ).build() ).build() ); - InsertMessage insertMessage = InsertMessage.newBuilder() - .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_realfeature" ).build() ).build() ) - .setTuple( Tuple.newBuilder().putAllData( dataMap ).build() ) - .build(); - return new CottontailQuery( QueryType.INSERT, insertMessage ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java index 09fe4f8..9122efc 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import java.util.Arrays; import java.util.HashMap; @@ -31,7 +30,6 @@ import java.util.Random; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; @@ -80,11 +78,15 @@ public synchronized Query getNewQuery() { private static class MetadataKnnIntFeatureQuery extends Query { - private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, distance(feature, "; - private static final String SQL_2 = ", "; - private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, "; + private static final String SQL_2 = "feature, "; + private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest WHERE knn_metadata.id = closest.id ORDER BY closest.dist ASC"; + private static final String SQL_L1 = "l1_distance("; + private static final String SQL_L2 = "l2_distance("; + private static final String SQL_COS = "cos_distance("; + private final Integer[] target; private final int limit; private final String norm; @@ -100,7 +102,19 @@ private MetadataKnnIntFeatureQuery( Integer[] target, int limit, String norm ) { @Override public String getSql() { - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; + String distance_sql = ""; + switch ( norm ) { + case "L1" -> distance_sql = SQL_L1; + case "L2" -> distance_sql = SQL_L2; + case "COS" -> distance_sql = SQL_COS; + } + if ( distance_sql.isEmpty() ){ + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; + + } else { + return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit + SQL_4; + + } } @@ -130,12 +144,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - throw new RuntimeException( "This query is unsupported by cottontail." ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java index f1d897e..52a9edf 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java @@ -23,7 +23,7 @@ * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import java.util.Arrays; import java.util.HashMap; @@ -31,7 +31,6 @@ import java.util.Random; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; @@ -80,11 +79,15 @@ public synchronized Query getNewQuery() { private static class MetadataKnnRealFeatureQuery extends Query { - private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, distance(feature, "; - private static final String SQL_2 = ", "; - private static final String SQL_3 = ") AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, "; + private static final String SQL_2 = "feature, "; + private static final String SQL_3 = ") AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest WHERE knn_metadata.id = closest.id ORDER BY closest.dist ASC"; + private static final String SQL_L1 = "l1_distance("; + private static final String SQL_L2 = "l2_distance("; + private static final String SQL_COS = "cos_distance("; + private final Float[] target; private final int limit; private final String norm; @@ -100,7 +103,19 @@ private MetadataKnnRealFeatureQuery( Float[] target, int limit, String norm ) { @Override public String getSql() { - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; + String distance_sql = ""; + switch ( norm ) { + case "L1" -> distance_sql = SQL_L1; + case "L2" -> distance_sql = SQL_L2; + case "COS" -> distance_sql = SQL_COS; + } + if ( distance_sql.isEmpty() ){ + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; + + } else { + return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit + SQL_4; + + } } @@ -130,12 +145,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - throw new RuntimeException( "This query is unsupported by cottontail." ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java index b1de916..1633542 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import java.util.Arrays; import java.util.HashMap; @@ -31,19 +30,8 @@ import java.util.Random; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.From; -import org.vitrivr.cottontail.grpc.CottontailGrpc.IntVector; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn.Distance; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Projection; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; public class SimpleKnnIdIntFeature extends QueryBuilder { @@ -90,11 +78,15 @@ public synchronized Query getNewQuery() { private static class SimpleKnnIdIntFeatureQuery extends Query { - private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, distance(feature, "; - private static final String SQL_2 = ", "; - private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, "; + private static final String SQL_2 = "feature, "; + private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest"; + private static final String SQL_L1 = "l1_distance("; + private static final String SQL_L2 = "l2_distance("; + private static final String SQL_COS = "cos_distance("; + private final Integer[] target; private final int limit; private final String norm; @@ -110,7 +102,19 @@ public SimpleKnnIdIntFeatureQuery( Integer[] target, int limit, String norm ) { @Override public String getSql() { - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + String distance_sql = ""; + switch ( norm ) { + case "L1" -> distance_sql = SQL_L1; + case "L2" -> distance_sql = SQL_L2; + case "COS" -> distance_sql = SQL_COS; + } + if ( distance_sql.isEmpty() ){ + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; + + } else { + return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit + SQL_4; + + } } @@ -140,49 +144,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - Map projection = new HashMap<>(); - projection.put( "id", "id" ); - CottontailGrpc.Query query = CottontailGrpc.Query.newBuilder() - .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ) ) - .setLimit( limit ) - .setKnn( Knn.newBuilder() - .setAttribute( "feature" ) - .setK( limit ) - .addQuery( Vector.newBuilder().setIntVector( IntVector.newBuilder().addAllVector( Arrays.asList( target ) ).build() ).build() ) - .setDistance( getDistance( norm ) ) - .build() ) - .setProjection( Projection.newBuilder().putAllAttributes( projection ).build() ) - .build(); - return new CottontailQuery( - QueryType.QUERY, - query - ); - } - - - private static Distance getDistance( String norm ) { - if ( "L2".equalsIgnoreCase( norm ) ) { - return Distance.L2; - } - if ( "L1".equalsIgnoreCase( norm ) ) { - return Distance.L1; - } - if ( "L2SQUARED".equalsIgnoreCase( norm ) ) { - return Distance.L2SQUARED; - } - if ( "CHISQUARED".equalsIgnoreCase( norm ) ) { - return Distance.CHISQUARED; - } - if ( "COSINE".equalsIgnoreCase( norm ) ) { - return Distance.COSINE; - } - - throw new RuntimeException( "Unsupported norm: " + norm ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java index 8eb7d00..ec7cea4 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import java.util.Arrays; import java.util.HashMap; @@ -31,19 +30,8 @@ import java.util.Random; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.FloatVector; -import org.vitrivr.cottontail.grpc.CottontailGrpc.From; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn.Distance; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Projection; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; public class SimpleKnnIdRealFeature extends QueryBuilder { @@ -90,11 +78,15 @@ public synchronized Query getNewQuery() { private static class SimpleKnnIdRealFeatureQuery extends Query { - private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, distance(feature, "; - private static final String SQL_2 = ", "; - private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, "; + private static final String SQL_2 = "feature, "; + private static final String SQL_3 = ") AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest"; + private static final String SQL_L1 = "l1_distance("; + private static final String SQL_L2 = "l2_distance("; + private static final String SQL_COS = "cos_distance("; + private final Float[] target; private final int limit; private final String norm; @@ -110,7 +102,19 @@ public SimpleKnnIdRealFeatureQuery( Float[] target, int limit, String norm ) { @Override public String getSql() { - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + String distance_sql = ""; + switch ( norm ) { + case "L1" -> distance_sql = SQL_L1; + case "L2" -> distance_sql = SQL_L2; + case "COS" -> distance_sql = SQL_COS; + } + if ( distance_sql.isEmpty() ){ + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; + + } else { + return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit + SQL_4; + + } } @@ -140,49 +144,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - Map projection = new HashMap<>(); - projection.put( "id", "id" ); - CottontailGrpc.Query query = CottontailGrpc.Query.newBuilder() - .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ) ) - .setLimit( limit ) - .setKnn( Knn.newBuilder() - .setAttribute( "feature" ) - .setK( limit ) - .addQuery( Vector.newBuilder().setFloatVector( FloatVector.newBuilder().addAllVector( Arrays.asList( target ) ).build() ).build() ) - .setDistance( getDistance( norm ) ) - .build() ) - .setProjection( Projection.newBuilder().putAllAttributes( projection ).build() ) - .build(); - return new CottontailQuery( - QueryType.QUERY, - query - ); - } - - - private static Distance getDistance( String norm ) { - if ( "L2".equalsIgnoreCase( norm ) ) { - return Distance.L2; - } - if ( "L1".equalsIgnoreCase( norm ) ) { - return Distance.L1; - } - if ( "L2SQUARED".equalsIgnoreCase( norm ) ) { - return Distance.L2SQUARED; - } - if ( "CHISQUARED".equalsIgnoreCase( norm ) ) { - return Distance.CHISQUARED; - } - if ( "COSINE".equalsIgnoreCase( norm ) ) { - return Distance.COSINE; - } - - throw new RuntimeException( "Unsupported norm: " + norm ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java index bdde21e..8ba24d3 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import java.util.Arrays; import java.util.HashMap; @@ -31,18 +30,8 @@ import java.util.Random; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.From; -import org.vitrivr.cottontail.grpc.CottontailGrpc.IntVector; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn.Distance; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; public class SimpleKnnIntFeature extends QueryBuilder { @@ -89,9 +78,13 @@ public synchronized Query getNewQuery() { private static class SimpleKnnIntFeatureQuery extends Query { - private static final String SQL_1 = "SELECT id, distance(feature, "; - private static final String SQL_2 = ", "; - private static final String SQL_3 = ") as dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT id, "; + private static final String SQL_2 = "feature, "; + private static final String SQL_3 = ") as dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + + private static final String SQL_L1 = "l1_distance("; + private static final String SQL_L2 = "l2_distance("; + private static final String SQL_COS = "cos_distance("; private final Integer[] target; private final int limit; @@ -108,7 +101,19 @@ public SimpleKnnIntFeatureQuery( Integer[] target, int limit, String norm ) { @Override public String getSql() { - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; + String distance_sql = ""; + switch ( norm ) { + case "L1" -> distance_sql = SQL_L1; + case "L2" -> distance_sql = SQL_L2; + case "COS" -> distance_sql = SQL_COS; + } + if ( distance_sql.isEmpty() ){ + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; + + } else { + return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit; + + } } @@ -138,46 +143,6 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - CottontailGrpc.Query query = CottontailGrpc.Query.newBuilder() - .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_intfeature" ).build() ) ) - .setLimit( limit ) - .setKnn( Knn.newBuilder() - .setAttribute( "feature" ) - .setK( limit ) - .addQuery( Vector.newBuilder().setIntVector( IntVector.newBuilder().addAllVector( Arrays.asList( target ) ).build() ).build() ) - .setDistance( getDistance( norm ) ) - .build() ) - .build(); - return new CottontailQuery( - QueryType.QUERY, - query - ); - } - - - private static CottontailGrpc.Knn.Distance getDistance( String norm ) { - if ( "L2".equalsIgnoreCase( norm ) ) { - return Distance.L2; - } - if ( "L1".equalsIgnoreCase( norm ) ) { - return Distance.L1; - } - if ( "L2SQUARED".equalsIgnoreCase( norm ) ) { - return Distance.L2SQUARED; - } - if ( "CHISQUARED".equalsIgnoreCase( norm ) ) { - return Distance.CHISQUARED; - } - if ( "COSINE".equalsIgnoreCase( norm ) ) { - return Distance.COSINE; - } - - throw new RuntimeException( "Unsupported norm: " + norm ); - } - } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java index bd969a0..6e2b8b6 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; import java.util.Arrays; import java.util.HashMap; @@ -31,18 +30,9 @@ import java.util.Random; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.CottontailQuery; -import org.polypheny.simpleclient.query.CottontailQuery.QueryType; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; -import org.vitrivr.cottontail.grpc.CottontailGrpc; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Entity; -import org.vitrivr.cottontail.grpc.CottontailGrpc.FloatVector; -import org.vitrivr.cottontail.grpc.CottontailGrpc.From; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Knn.Distance; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Schema; -import org.vitrivr.cottontail.grpc.CottontailGrpc.Vector; + public class SimpleKnnRealFeature extends QueryBuilder { @@ -89,9 +79,13 @@ public synchronized Query getNewQuery() { private static class SimpleKnnRealFeatureQuery extends Query { - private static final String SQL_1 = "SELECT id, distance(feature, "; - private static final String SQL_2 = ", "; - private static final String SQL_3 = ") as dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT id, "; + private static final String SQL_2 = "feature, "; + private static final String SQL_3 = ") as dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; + + private static final String SQL_L1 = "l1_distance("; + private static final String SQL_L2 = "l2_distance("; + private static final String SQL_COS = "cos_distance("; private final Float[] target; private final int limit; @@ -108,7 +102,19 @@ public SimpleKnnRealFeatureQuery( Float[] target, int limit, String norm ) { @Override public String getSql() { - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; + String distance_sql = ""; + switch ( norm ) { + case "L1" -> distance_sql = SQL_L1; + case "L2" -> distance_sql = SQL_L2; + case "COS" -> distance_sql = SQL_COS; + } + if ( distance_sql.isEmpty() ){ + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; + + } else { + return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit; + + } } @@ -138,46 +144,5 @@ public String getMongoQl() { return null; } - - @Override - public CottontailQuery getCottontail() { - CottontailGrpc.Query query = CottontailGrpc.Query.newBuilder() - .setFrom( From.newBuilder().setEntity( Entity.newBuilder().setSchema( Schema.newBuilder().setName( "public" ).build() ).setName( "knn_realfeature" ).build() ) ) - .setLimit( limit ) - .setKnn( Knn.newBuilder() - .setAttribute( "feature" ) - .setK( limit ) - .addQuery( Vector.newBuilder().setFloatVector( FloatVector.newBuilder().addAllVector( Arrays.asList( target ) ).build() ).build() ) - .setDistance( getDistance( norm ) ) - .build() ) - .build(); - return new CottontailQuery( - QueryType.QUERY, - query - ); - } - - - private static CottontailGrpc.Knn.Distance getDistance( String norm ) { - if ( "L2".equalsIgnoreCase( norm ) ) { - return Distance.L2; - } - if ( "L1".equalsIgnoreCase( norm ) ) { - return Distance.L1; - } - if ( "L2SQUARED".equalsIgnoreCase( norm ) ) { - return Distance.L2SQUARED; - } - if ( "CHISQUARED".equalsIgnoreCase( norm ) ) { - return Distance.CHISQUARED; - } - if ( "COSINE".equalsIgnoreCase( norm ) ) { - return Distance.COSINE; - } - - throw new RuntimeException( "Unsupported norm: " + norm ); - } - } - } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java index a738ff5..75ecd7e 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2022 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,15 +22,15 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.knnbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; public class SimpleMetadata extends QueryBuilder { diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties new file mode 100644 index 0000000..f10955d --- /dev/null +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -0,0 +1,31 @@ +scenario = "vectorBench" + +dataStoreFeature = postgresbench +dataStoreMeta = hsqldb + +numberOfThreads = 4 +progressReportBase = 100 +numberOfWarmUpIterations = 4 + +# Seeds +useRandomSeeds = true +randomSeedInsert = 46891971806236 +randomSeedQuery = 196033374268 + +dimensionFeatureVectors = 10 +batchSizeInserts = 2500 +batchSizeQueries = 10 + +# Numbers of queries +numberOfEntries = 100000 +numberOfSimpleKnnIntFeatureQueries = 10 +numberOfSimpleKnnRealFeatureQueries = 10 +numberOfSimpleMetadataQueries = 10 +numberOfSimpleKnnIdIntFeatureQueries = 10 +numberOfSimpleKnnIdRealFeatureQueries = 10 +numberOfMetadataKnnIntFeatureQueries = 10 +numberOfMetadataKnnRealFeatureQueries = 10 + +limitKnnQueries = 10 +distanceNorm = L2 + From 2f791339c6961324243b5ce869797d01518c0b34 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Tue, 7 Apr 2026 15:55:48 +0200 Subject: [PATCH 05/38] DEBUG: Change log level to debug --- src/main/resources/log4j2.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 2dd720d..dc06653 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -33,7 +33,7 @@ - + From ac934be17c62151229e4be1faafce26de53f0615 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Tue, 7 Apr 2026 15:59:48 +0200 Subject: [PATCH 06/38] FIX: Proper synchronization for writeLine method --- src/main/java/org/polypheny/simpleclient/main/CsvWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/polypheny/simpleclient/main/CsvWriter.java b/src/main/java/org/polypheny/simpleclient/main/CsvWriter.java index d702dd2..b1e53fb 100644 --- a/src/main/java/org/polypheny/simpleclient/main/CsvWriter.java +++ b/src/main/java/org/polypheny/simpleclient/main/CsvWriter.java @@ -55,7 +55,7 @@ public void appendToCsv( String query, long measuredTime ) { } - private void writeLine( String[] entries ) { + private synchronized void writeLine( String[] entries ) { try { String line = String.join( ",", entries ); writer.write( line ); From 24bd3bd36653785ee516078af41ab29925622b3e Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Thu, 16 Apr 2026 19:41:36 +0200 Subject: [PATCH 07/38] Revert "DEBUG: Change log level to debug" This reverts commit 2f791339c6961324243b5ce869797d01518c0b34. --- src/main/resources/log4j2.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index dc06653..2dd720d 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -33,7 +33,7 @@ - + From d24742498fbd62cf6ca1e97c2ffce6b224a916f3 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Thu, 16 Apr 2026 20:05:32 +0200 Subject: [PATCH 08/38] Change queries to follow the parameterized function pattern again --- .../queryBuilder/MetadataKnnIntFeature.java | 24 ++++--------------- .../queryBuilder/MetadataKnnRealFeature.java | 24 ++++--------------- .../queryBuilder/SimpleKnnIdIntFeature.java | 24 ++++--------------- .../queryBuilder/SimpleKnnIdRealFeature.java | 24 ++++--------------- .../queryBuilder/SimpleKnnIntFeature.java | 24 ++++--------------- .../queryBuilder/SimpleKnnRealFeature.java | 24 ++++--------------- 6 files changed, 24 insertions(+), 120 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java index 9122efc..77980b4 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java @@ -78,15 +78,11 @@ public synchronized Query getNewQuery() { private static class MetadataKnnIntFeatureQuery extends Query { - private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, "; - private static final String SQL_2 = "feature, "; - private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest WHERE knn_metadata.id = closest.id ORDER BY closest.dist ASC"; - private static final String SQL_L1 = "l1_distance("; - private static final String SQL_L2 = "l2_distance("; - private static final String SQL_COS = "cos_distance("; - private final Integer[] target; private final int limit; private final String norm; @@ -102,19 +98,7 @@ private MetadataKnnIntFeatureQuery( Integer[] target, int limit, String norm ) { @Override public String getSql() { - String distance_sql = ""; - switch ( norm ) { - case "L1" -> distance_sql = SQL_L1; - case "L2" -> distance_sql = SQL_L2; - case "COS" -> distance_sql = SQL_COS; - } - if ( distance_sql.isEmpty() ){ - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; - - } else { - return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit + SQL_4; - - } + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java index 52a9edf..3b16ae5 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java @@ -79,15 +79,11 @@ public synchronized Query getNewQuery() { private static class MetadataKnnRealFeatureQuery extends Query { - private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, "; - private static final String SQL_2 = "feature, "; - private static final String SQL_3 = ") AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest WHERE knn_metadata.id = closest.id ORDER BY closest.dist ASC"; - private static final String SQL_L1 = "l1_distance("; - private static final String SQL_L2 = "l2_distance("; - private static final String SQL_COS = "cos_distance("; - private final Float[] target; private final int limit; private final String norm; @@ -103,19 +99,7 @@ private MetadataKnnRealFeatureQuery( Float[] target, int limit, String norm ) { @Override public String getSql() { - String distance_sql = ""; - switch ( norm ) { - case "L1" -> distance_sql = SQL_L1; - case "L2" -> distance_sql = SQL_L2; - case "COS" -> distance_sql = SQL_COS; - } - if ( distance_sql.isEmpty() ){ - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; - - } else { - return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit + SQL_4; - - } + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java index 1633542..62ccda0 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java @@ -78,15 +78,11 @@ public synchronized Query getNewQuery() { private static class SimpleKnnIdIntFeatureQuery extends Query { - private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, "; - private static final String SQL_2 = "feature, "; - private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest"; - private static final String SQL_L1 = "l1_distance("; - private static final String SQL_L2 = "l2_distance("; - private static final String SQL_COS = "cos_distance("; - private final Integer[] target; private final int limit; private final String norm; @@ -102,19 +98,7 @@ public SimpleKnnIdIntFeatureQuery( Integer[] target, int limit, String norm ) { @Override public String getSql() { - String distance_sql = ""; - switch ( norm ) { - case "L1" -> distance_sql = SQL_L1; - case "L2" -> distance_sql = SQL_L2; - case "COS" -> distance_sql = SQL_COS; - } - if ( distance_sql.isEmpty() ){ - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; - - } else { - return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit + SQL_4; - - } + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java index ec7cea4..df8e2f4 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java @@ -78,15 +78,11 @@ public synchronized Query getNewQuery() { private static class SimpleKnnIdRealFeatureQuery extends Query { - private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, "; - private static final String SQL_2 = "feature, "; - private static final String SQL_3 = ") AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest"; - private static final String SQL_L1 = "l1_distance("; - private static final String SQL_L2 = "l2_distance("; - private static final String SQL_COS = "cos_distance("; - private final Float[] target; private final int limit; private final String norm; @@ -102,19 +98,7 @@ public SimpleKnnIdRealFeatureQuery( Float[] target, int limit, String norm ) { @Override public String getSql() { - String distance_sql = ""; - switch ( norm ) { - case "L1" -> distance_sql = SQL_L1; - case "L2" -> distance_sql = SQL_L2; - case "COS" -> distance_sql = SQL_COS; - } - if ( distance_sql.isEmpty() ){ - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit + SQL_4; - - } else { - return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit + SQL_4; - - } + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java index 8ba24d3..f0923a2 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java @@ -78,13 +78,9 @@ public synchronized Query getNewQuery() { private static class SimpleKnnIntFeatureQuery extends Query { - private static final String SQL_1 = "SELECT id, "; - private static final String SQL_2 = "feature, "; - private static final String SQL_3 = ") as dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; - - private static final String SQL_L1 = "l1_distance("; - private static final String SQL_L2 = "l2_distance("; - private static final String SQL_COS = "cos_distance("; + private static final String SQL_1 = "SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") as dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; private final Integer[] target; private final int limit; @@ -101,19 +97,7 @@ public SimpleKnnIntFeatureQuery( Integer[] target, int limit, String norm ) { @Override public String getSql() { - String distance_sql = ""; - switch ( norm ) { - case "L1" -> distance_sql = SQL_L1; - case "L2" -> distance_sql = SQL_L2; - case "COS" -> distance_sql = SQL_COS; - } - if ( distance_sql.isEmpty() ){ - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; - - } else { - return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit; - - } + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java index 6e2b8b6..8670a50 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java @@ -79,13 +79,9 @@ public synchronized Query getNewQuery() { private static class SimpleKnnRealFeatureQuery extends Query { - private static final String SQL_1 = "SELECT id, "; - private static final String SQL_2 = "feature, "; - private static final String SQL_3 = ") as dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; - - private static final String SQL_L1 = "l1_distance("; - private static final String SQL_L2 = "l2_distance("; - private static final String SQL_COS = "cos_distance("; + private static final String SQL_1 = "SELECT id, distance(feature, "; + private static final String SQL_2 = ", "; + private static final String SQL_3 = ") as dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; private final Float[] target; private final int limit; @@ -102,19 +98,7 @@ public SimpleKnnRealFeatureQuery( Float[] target, int limit, String norm ) { @Override public String getSql() { - String distance_sql = ""; - switch ( norm ) { - case "L1" -> distance_sql = SQL_L1; - case "L2" -> distance_sql = SQL_L2; - case "COS" -> distance_sql = SQL_COS; - } - if ( distance_sql.isEmpty() ){ - return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; - - } else { - return SQL_1 + distance_sql + SQL_2 + "ARRAY" + Arrays.toString( target ) + SQL_3 + limit; - - } + return SQL_1 + "ARRAY" + Arrays.toString( target ) + SQL_2 + " '" + norm + "' " + SQL_3 + limit; } From 31cddf443c5573b7aadd49a3956ce86a1f88035b Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Fri, 17 Apr 2026 21:53:27 +0200 Subject: [PATCH 09/38] Add new query types containing distance cross-joins --- .../scenario/vectorbench/VectorBench.java | 13 ++ .../vectorbench/VectorBenchConfig.java | 6 + .../queryBuilder/CreateIntFeature.java | 2 +- .../queryBuilder/CreateMetadata.java | 2 +- .../queryBuilder/CreateRealFeature.java | 2 +- .../MetadataKnnRealCrossJoin.java | 128 ++++++++++++++++++ .../queryBuilder/SimpleKnnIdRealFeature.java | 2 +- .../queryBuilder/SimpleKnnRealCrossJoin.java | 121 +++++++++++++++++ .../scenario/vectorbench/vector.properties | 18 +-- 9 files changed, 282 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealCrossJoin.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealCrossJoin.java diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index 527d2cd..085b973 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -45,9 +45,11 @@ import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.CreateMetadata; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.CreateRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnRealCrossJoin; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnIdRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnRealCrossJoin; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleMetadata; @@ -122,6 +124,8 @@ public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, Fil addNumberOfTimes( queryList, new SimpleKnnIdRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIdRealFeatureQueries ); addNumberOfTimes( queryList, new MetadataKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnIntFeatureQueries ); addNumberOfTimes( queryList, new MetadataKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnRealFeatureQueries ); + addNumberOfTimes( queryList, new SimpleKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnRealCrossJoinQueries ); + addNumberOfTimes( queryList, new MetadataKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnRealCrossJoinQueries ); return commonExecute( queryList, progressReporter, outputDirectory, numberOfThreads, Query::getSql, () -> executorFactory.createExecutorInstance( csvWriter ), new Random() ); } @@ -139,6 +143,9 @@ public void warmUp( ProgressReporter progressReporter ) { SimpleKnnIdRealFeature simpleKnnIdRealFeatureBuilder = new SimpleKnnIdRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); MetadataKnnIntFeature metadataKnnIntFeature = new MetadataKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); MetadataKnnRealFeature metadataKnnRealFeature = new MetadataKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + MetadataKnnRealCrossJoin metadataKnnCrossJoin = new MetadataKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + SimpleKnnRealCrossJoin simpleKnnCrossJoin = new SimpleKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + for ( int i = 0; i < config.numberOfWarmUpIterations; i++ ) { try { @@ -166,6 +173,12 @@ public void warmUp( ProgressReporter progressReporter ) { if ( config.numberOfMetadataKnnRealFeatureQueries > 0 ) { executor.executeQuery( metadataKnnRealFeature.getNewQuery() ); } + if ( config.numberOfMetadataKnnRealCrossJoinQueries > 0 ) { + executor.executeQuery( metadataKnnCrossJoin.getNewQuery() ); + } + if ( config.numberOfSimpleKnnRealCrossJoinQueries > 0 ) { + executor.executeQuery( simpleKnnCrossJoin.getNewQuery() ); + } } catch ( ExecutorException e ) { throw new RuntimeException( "Error while executing warm-up queries", e ); } finally { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index d8e1742..8c6e095 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -53,6 +53,8 @@ public class VectorBenchConfig extends AbstractConfig { public int numberOfSimpleKnnIdRealFeatureQueries; public int numberOfMetadataKnnIntFeatureQueries; public int numberOfMetadataKnnRealFeatureQueries; + public int numberOfSimpleKnnRealCrossJoinQueries; + public int numberOfMetadataKnnRealCrossJoinQueries; // public final int numberOfCombinedQueries; public int limitKnnQueries; @@ -94,6 +96,8 @@ public VectorBenchConfig(Properties properties, int multiplier ) { numberOfSimpleKnnIdRealFeatureQueries = getIntProperty( properties, "numberOfSimpleKnnIdRealFeatureQueries" ) * multiplier; numberOfMetadataKnnIntFeatureQueries = getIntProperty( properties, "numberOfMetadataKnnIntFeatureQueries" ) * multiplier; numberOfMetadataKnnRealFeatureQueries = getIntProperty( properties, "numberOfMetadataKnnRealFeatureQueries" ) * multiplier; + numberOfSimpleKnnRealCrossJoinQueries = getIntProperty( properties, "numberOfSimpleKnnRealCrossJoinQueries" ) * multiplier; + numberOfMetadataKnnRealCrossJoinQueries = getIntProperty( properties, "numberOfMetadataKnnRealCrossJoinQueries" ) * multiplier; limitKnnQueries = getIntProperty( properties, "limitKnnQueries" ); distanceNorm = getStringProperty( properties, "distanceNorm" ); } @@ -132,6 +136,8 @@ public VectorBenchConfig(Map cdl ) { numberOfSimpleKnnIdRealFeatureQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnIdRealFeatureQueries" ) ); numberOfMetadataKnnIntFeatureQueries = Integer.parseInt( cdl.get( "numberOfMetadataKnnIntFeatureQueries" ) ); numberOfMetadataKnnRealFeatureQueries = Integer.parseInt( cdl.get( "numberOfMetadataKnnRealFeatureQueries" ) ); + numberOfSimpleKnnRealCrossJoinQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnRealCrossJoinQueries" ) ); + numberOfMetadataKnnRealCrossJoinQueries = Integer.parseInt( cdl.get( "numberOfMetadataKnnRealCrossJoinQueries" ) ); // numberOfCombinedQueries = getIntProperty( properties, "numberOfCombinedQueries" ) * multiplier; limitKnnQueries = Integer.parseInt( cdl.get( "limitKnnQueries" ) ); distanceNorm = cdl.get( "distanceNorm" ).trim(); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java index 498de05..109da2f 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java @@ -66,7 +66,7 @@ private static class CreateIntFeatureQuery extends Query { public String getSql() { String sql = "CREATE TABLE knn_intfeature (id INTEGER NOT NULL, feature INTEGER ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; if ( this.store != null ) { - sql += "ON STORE \"" + this.store + "\""; + sql += " ON STORE \"" + this.store + "\""; } return sql; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java index 006d30c..d1bf6d7 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java @@ -63,7 +63,7 @@ private static class CreateMetadataQuery extends Query { public String getSql() { String sql = "CREATE TABLE knn_metadata (id integer NOT NULL, textdata VARCHAR(100), PRIMARY KEY (id))"; if ( this.store != null ) { - sql += "ON STORE \"" + this.store + "\""; + sql += " ON STORE \"" + this.store + "\""; } return sql; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java index 6de37e1..0a04453 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java @@ -66,7 +66,7 @@ private static class CreateRealFeatureQuery extends Query { public String getSql() { String sql = "CREATE TABLE knn_realfeature (id INTEGER NOT NULL, feature REAL ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; if ( this.store != null ) { - sql += "ON STORE \"" + this.store + "\""; + sql += " ON STORE \"" + this.store + "\""; } return sql; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealCrossJoin.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealCrossJoin.java new file mode 100644 index 0000000..1101e46 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealCrossJoin.java @@ -0,0 +1,128 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-4/17/26, 2:54 PM The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +public class MetadataKnnRealCrossJoin extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final int dimension; + private final int limit; + private final String norm; + + private final Random random; + + + public MetadataKnnRealCrossJoin( long randomSeed, int dimension, int limit, String norm ) { + this.dimension = dimension; + this.limit = limit; + this.norm = norm; + + this.random = new Random( randomSeed ); + } + + + private Float[] getRandomVector() { + Float[] floats = new Float[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + + return floats; + } + + + @Override + public synchronized Query getNewQuery() { + return new MetadataKnnRealCrossJoin.MetadataKnnRealCrossJoinQuery( + getRandomVector(), + limit, + norm + ); + } + + + private static class MetadataKnnRealCrossJoinQuery extends Query { + + private static final String SQL_1 = "SELECT knn_metadata.id, knn_metadata.textdata, closest.dist FROM knn_metadata, ( SELECT t1.id, distance(t1.feature, t2.feature, '"; + private static final String SQL_2 = "') AS dist FROM knn_realfeature t1, knn_realfeature t2 WHERE t2.id = 1 ORDER BY dist ASC LIMIT "; + private static final String SQL_3 = ") AS closest WHERE knn_metadata.id = closest.id ORDER BY closest.dist ASC"; + private final Float[] target; + private final int limit; + private final String norm; + + + private MetadataKnnRealCrossJoinQuery( Float[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + + @Override + public String getSql() { + return SQL_1 + norm + SQL_2 + limit + SQL_3; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + //return SQL_1 + "?" + SQL_2 + "'" + norm + "'" + SQL_3 + limit + SQL_4; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.ARRAY_REAL, target ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} + diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java index df8e2f4..8179a8e 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java @@ -80,7 +80,7 @@ private static class SimpleKnnIdRealFeatureQuery extends Query { private static final String SQL_1 = "SELECT closest.dist FROM ( SELECT id, distance(feature, "; private static final String SQL_2 = ", "; - private static final String SQL_3 = ") AS dist FROM knn_intfeature ORDER BY dist ASC LIMIT "; + private static final String SQL_3 = ") AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT "; private static final String SQL_4 = ") AS closest"; private final Float[] target; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealCrossJoin.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealCrossJoin.java new file mode 100644 index 0000000..7d8b737 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealCrossJoin.java @@ -0,0 +1,121 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-4/17/26, 2:44 PM The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; +import java.util.Random; + +public class SimpleKnnRealCrossJoin extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final int dimension; + private final int limit; + private final String norm; + + private final Random random; + + + public SimpleKnnRealCrossJoin( long randomSeed, int dimension, int limit, String norm ) { + this.dimension = dimension; + this.limit = limit; + this.norm = norm; + + this.random = new Random( randomSeed ); + } + + + private Float[] getRandomVector() { + Float[] floats = new Float[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + + return floats; + } + + + @Override + public synchronized Query getNewQuery() { + return new SimpleKnnRealCrossJoin.SimpleKnnRealCrossJoinQuery( + getRandomVector(), + limit, + norm ); + } + + + private static class SimpleKnnRealCrossJoinQuery extends Query { + + private static final String SQL_1 = "SELECT t1.id, distance(t1.feature, t2.feature,"; + private static final String SQL_2 = ") as dist FROM knn_realfeature t1, knn_realfeature t2 WHERE t2.id = 1 ORDER BY dist ASC LIMIT "; + + private final Float[] target; + private final int limit; + private final String norm; + + + public SimpleKnnRealCrossJoinQuery( Float[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + + @Override + public String getSql() { + return SQL_1 + " '" + norm + "' " + SQL_2 + limit; + } + + + @Override + public String getParameterizedSqlQuery() { + return ""; + } + + + @Override + public Map> getParameterValues() { + return Map.of(); + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } +} diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index f10955d..e014f54 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -12,20 +12,22 @@ useRandomSeeds = true randomSeedInsert = 46891971806236 randomSeedQuery = 196033374268 -dimensionFeatureVectors = 10 +dimensionFeatureVectors = 100 batchSizeInserts = 2500 batchSizeQueries = 10 # Numbers of queries numberOfEntries = 100000 -numberOfSimpleKnnIntFeatureQueries = 10 -numberOfSimpleKnnRealFeatureQueries = 10 +numberOfSimpleKnnIntFeatureQueries = 0 +numberOfSimpleKnnRealFeatureQueries = 0 numberOfSimpleMetadataQueries = 10 -numberOfSimpleKnnIdIntFeatureQueries = 10 -numberOfSimpleKnnIdRealFeatureQueries = 10 -numberOfMetadataKnnIntFeatureQueries = 10 -numberOfMetadataKnnRealFeatureQueries = 10 +numberOfSimpleKnnIdIntFeatureQueries = 0 +numberOfSimpleKnnIdRealFeatureQueries = 0 +numberOfMetadataKnnIntFeatureQueries = 0 +numberOfMetadataKnnRealFeatureQueries = 0 +numberOfSimpleKnnRealCrossJoinQueries = 10 +numberOfMetadataKnnRealCrossJoinQueries = 10 limitKnnQueries = 10 -distanceNorm = L2 +distanceNorm = COSINE From 44a960c87d7a34563f557bbbad10be2f4aff379d Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Tue, 26 May 2026 16:52:49 +0200 Subject: [PATCH 10/38] Add creation, insertion and queries for boolean vectors --- .../queryBuilder/SimpleKnnBooleanFeature.java | 111 ++++++++++++++ .../SimpleKnnBooleanFeatureFiltered.java | 119 +++++++++++++++ .../creation/CreateBooleanFeature.java | 103 +++++++++++++ .../insertion/InsertBooleanFeature.java | 142 ++++++++++++++++++ 4 files changed, 475 insertions(+) create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeatureFiltered.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateBooleanFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertBooleanFeature.java diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeature.java new file mode 100644 index 0000000..977b6f6 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeature.java @@ -0,0 +1,111 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Arrays; +import java.util.Map; +import java.util.Random; + +public class SimpleKnnBooleanFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + private final int dimension; + private final int limit; + private final String norm; // Should be 'JACCARD' or 'HAMMING' + private final Random random; + + public SimpleKnnBooleanFeature( long randomSeed, int dimension, int limit, String norm ) { + this.dimension = dimension; + this.limit = limit; + this.norm = norm; + this.random = new Random( randomSeed ); + } + + private Boolean[] getRandomVector() { + Boolean[] booleans = new Boolean[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + booleans[i] = random.nextBoolean(); + } + return booleans; + } + + @Override + public synchronized Query getNewQuery() { + return new SimpleKnnBooleanFeatureQuery( getRandomVector(), limit, norm ); + } + + private static class SimpleKnnBooleanFeatureQuery extends Query { + + private final Boolean[] target; + private final int limit; + private final String norm; + + public SimpleKnnBooleanFeatureQuery( Boolean[] target, int limit, String norm ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + } + + @Override + public String getSql() { + return "SELECT id, " + norm.toLowerCase() + "_distance(feature, ARRAY" + Arrays.toString( target ) + ") " + + "as dist " + + "FROM knn_booleanfeature " + // Ensure this tableexists in DataGenerator + "ORDER BY dist ASC LIMIT " + limit; + } + + + @Override + public String getParameterizedSqlQuery() { return null; } + + + @Override + public Map> + getParameterValues() { return null; } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { + return "db.knn_booleanfeature.aggregate([{" + + " \"$vectorSearch\": {" + + " \"path\": \"feature\"," + + " \"queryVector\": " + Arrays.toString( target ) + + "," + + " \"metric\": \"" + norm + "\"," + + " \"limit\": " + limit + + " }" + + "}])"; + } + } +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeatureFiltered.java new file mode 100644 index 0000000..f1bcacb --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeatureFiltered.java @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Arrays; +import java.util.Map; +import java.util.Random; + +public class SimpleKnnBooleanFeatureFiltered extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + private final int dimension; + private final int limit; + private final String norm; + private final String filterCategory; + private final Random random; + + public SimpleKnnBooleanFeatureFiltered( long randomSeed, int dimension, int limit, String norm, String filterCategory ) { + this.dimension = dimension; + this.limit = limit; + this.norm = norm; + this.filterCategory = filterCategory; + this.random = new Random( randomSeed ); + } + + + private Boolean[] getRandomVector() { + Boolean[] booleans = new Boolean[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + booleans[i] = random.nextBoolean(); + } + return booleans; + } + + + @Override + public synchronized Query getNewQuery() { + return new SimpleKnnBooleanFeatureFilteredQuery( getRandomVector(), limit, norm, filterCategory ); + } + + + private static class SimpleKnnBooleanFeatureFilteredQuery extends Query { + + private final Boolean[] target; + private final int limit; + private final String norm; + private final String category; + + public SimpleKnnBooleanFeatureFilteredQuery( Boolean[] target, int limit, String norm, String category ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + this.category = category; + } + + + @Override + public String getSql() { + return "SELECT id, " + norm.toLowerCase() + "_distance(feature, ARRAY" + Arrays.toString( target ) + ") " + + "as dist " + + "FROM knn_booleanfeature " + + "WHERE category = '" + category + "' " + + "ORDER BY dist ASC LIMIT " + limit; + } + + + @Override + public String getParameterizedSqlQuery() { return null; } + + + @Override + public Map> getParameterValues() { return null; } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { + return "db.knn_booleanfeature.aggregate([{" + + " \"$vectorSearch\": {" + + " \"path\": \"feature\"," + + " \"queryVector\": " + Arrays.toString( target ) + "," + + " \"metric\": \"" + norm + "\"," + + " \"limit\": " + limit + "," + + " \"filter\": { \"category\": \"" + category + "\" }" + + " }" + + "}])"; + } + } +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateBooleanFeature.java new file mode 100644 index 0000000..55a2711 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateBooleanFeature.java @@ -0,0 +1,103 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; + +public class CreateBooleanFeature extends QueryBuilder { + + private final String store; + private final int dimension; + + + public CreateBooleanFeature( String store, int dimension ) { + this.store = store; + this.dimension = dimension; + } + + + @Override + public Query getNewQuery() { + return new CreateBooleanFeatureQuery( store, dimension ); + } + + + private static class CreateBooleanFeatureQuery extends Query { + + private final String store; + private final int dimension; + + + CreateBooleanFeatureQuery( String store, int dimension ) { + super( false ); + this.store = store; + this.dimension = dimension; + } + + + @Override + public String getSql() { + String sql = "CREATE TABLE knn_booleanfeature (" + + "id INTEGER NOT NULL, " + + "feature BOOLEAN NOT NULL ARRAY(1, " + this.dimension + "), " + + "category VARCHAR(50), " + + "PRIMARY KEY(id))"; + if ( this.store != null ) { + sql += " ON STORE \"" + this.store + "\""; + } + return sql; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertBooleanFeature.java new file mode 100644 index 0000000..6128dd1 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertBooleanFeature.java @@ -0,0 +1,142 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion; + +import com.google.gson.JsonObject; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +public class InsertBooleanFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = false; + private static final AtomicInteger nextId = new AtomicInteger( 1 ); + private final long randomSeed; + private final int dimension; + private final Random random; + private static final String[] CATEGORIES = {"cat_A", "cat_B", "cat_C", "cat_D"}; + + public InsertBooleanFeature( long randomSeed, int dimension ) { + this.randomSeed = randomSeed; + this.dimension = dimension; + this.random = new Random( randomSeed ); + } + + + private Boolean[] getRandomVector() { + Boolean[] booleans = new Boolean[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + // Generate random bitvectors (true/false) + booleans[i] = random.nextBoolean(); + } + return booleans; + } + + + @Override + public synchronized BatchableInsert getNewQuery() { + return new InsertBooleanFeatureQuery( + nextId.getAndIncrement(), + getRandomVector(), + CATEGORIES[random.nextInt(CATEGORIES.length)] + ); + } + + + private static class InsertBooleanFeatureQuery extends BatchableInsert { + + private static final String SQL = "INSERT INTO knn_booleanfeature (id, category, feature) VALUES "; + private final int id; + private final Boolean[] feature; + private final String randomCategory; + + private InsertBooleanFeatureQuery( int id, Boolean[] feature, String randomCategory ) { + super( EXPECT_RESULT ); + this.id = id; + this.feature = feature; + this.randomCategory = randomCategory; + } + + + @Override + public String getSqlRowExpression() { + // Arrays.toString on Boolean[] will result in "[true, false, true...]" + return "(" + id + ", '" + randomCategory + "', ARRAY" + Arrays.toString( feature ) + ")"; + } + + + @Override + public String getParameterizedSqlQuery() { + return SQL + "(?, ?, ?)"; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, id ) ); + map.put( 2, new ImmutablePair<>( DataTypes.VARCHAR, randomCategory ) ); + map.put( 3, new ImmutablePair<>( DataTypes.ARRAY_BOOLEAN, feature ) ); + return map; + } + + + @Override + public JsonObject getRestRowExpression() { return null; } + + + @Override + public String getEntity() { return "public.knn_booleanfeature"; } + + + @Override + public String getSql() { + return SQL + getSqlRowExpression(); + } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { return null; } + + + private String getBitString( Boolean[] feature ) { + StringBuilder sb = new StringBuilder(feature.length); + for ( Boolean b : feature ) { + sb.append( b ? "1" : "0" ); + } + return sb.toString(); + } + } +} From a6d2ec89651c354b1c3b69e4a5e0d70959dc4500 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Tue, 26 May 2026 16:55:14 +0200 Subject: [PATCH 11/38] Move create and insert QueryBuilders to new package and add "category" attribute "realKnn" benchmarking tables --- .../{ => creation}/CreateIntFeature.java | 4 ++-- .../{ => creation}/CreateMetadata.java | 2 +- .../{ => creation}/CreateRealFeature.java | 8 ++++++-- .../{ => insertion}/InsertIntFeature.java | 2 +- .../{ => insertion}/InsertMetadata.java | 2 +- .../{ => insertion}/InsertRealFeature.java | 20 +++++++++++-------- 6 files changed, 23 insertions(+), 15 deletions(-) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => creation}/CreateIntFeature.java (96%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => creation}/CreateMetadata.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => creation}/CreateRealFeature.java (90%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => insertion}/InsertIntFeature.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => insertion}/InsertMetadata.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => insertion}/InsertRealFeature.java (84%) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateIntFeature.java similarity index 96% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateIntFeature.java index 109da2f..6217e08 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateIntFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation; import java.util.Map; import kong.unirest.core.HttpRequest; @@ -64,7 +64,7 @@ private static class CreateIntFeatureQuery extends Query { @Override public String getSql() { - String sql = "CREATE TABLE knn_intfeature (id INTEGER NOT NULL, feature INTEGER ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; + String sql = "CREATE TABLE knn_intfeature (id INTEGER NOT NULL, feature INTEGER NOT NULL ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; if ( this.store != null ) { sql += " ON STORE \"" + this.store + "\""; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateMetadata.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateMetadata.java index d1bf6d7..eea5748 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateMetadata.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation; import java.util.Map; import kong.unirest.core.HttpRequest; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateRealFeature.java similarity index 90% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateRealFeature.java index 0a04453..71b4f86 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/CreateRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateRealFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation; import java.util.Map; import kong.unirest.core.HttpRequest; @@ -64,7 +64,11 @@ private static class CreateRealFeatureQuery extends Query { @Override public String getSql() { - String sql = "CREATE TABLE knn_realfeature (id INTEGER NOT NULL, feature REAL ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; + String sql = "CREATE TABLE knn_realfeature (" + + "id INTEGER NOT NULL, " + + "category VARCHAR(50), " + + "feature REAL NOT NULL ARRAY(1, " + this.dimension + "), " + + "PRIMARY KEY(id))"; if ( this.store != null ) { sql += " ON STORE \"" + this.store + "\""; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertIntFeature.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertIntFeature.java index 7231f4f..e1094ba 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertIntFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion; import com.google.gson.JsonObject; import java.util.Arrays; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertMetadata.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertMetadata.java index a41c6e6..117baee 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertMetadata.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion; import com.google.gson.JsonObject; import java.util.HashMap; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertRealFeature.java similarity index 84% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertRealFeature.java index 4735ac5..3f954f8 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/InsertRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertRealFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion; import com.google.gson.JsonObject; import java.util.Arrays; @@ -43,6 +43,7 @@ public class InsertRealFeature extends QueryBuilder { private static final AtomicInteger nextId = new AtomicInteger( 1 ); private final long randomSeed; private final int dimension; + private static final String[] CATEGORIES = {"cat_A", "cat_B", "cat_C", "cat_D"}; private final Random random; @@ -69,34 +70,36 @@ private Float[] getRandomVector() { public synchronized BatchableInsert getNewQuery() { return new InsertRealFeatureQuery( nextId.getAndIncrement(), - getRandomVector() + getRandomVector(), + CATEGORIES[random.nextInt(CATEGORIES.length)] ); } private static class InsertRealFeatureQuery extends BatchableInsert { - private static final String SQL = "INSERT INTO knn_realfeature (id, feature) VALUES "; + private static final String SQL = "INSERT INTO knn_realfeature (id, category, feature) VALUES "; private final int id; private final Float[] feature; + private String randomCategory; - - private InsertRealFeatureQuery( int id, Float[] feature ) { + private InsertRealFeatureQuery( int id, Float[] feature, String randomCategory ) { super( EXPECT_RESULT ); this.id = id; this.feature = feature; + this.randomCategory = randomCategory; } @Override public String getSqlRowExpression() { - return "(" + id + ", ARRAY" + Arrays.toString( feature ) + ")"; + return "(" + id + ", '" + randomCategory + "', ARRAY" + Arrays.toString( feature ) + ")"; } @Override public String getParameterizedSqlQuery() { - return SQL + "(?, ?)"; + return SQL + "(?, ?, ?)"; } @@ -104,7 +107,8 @@ public String getParameterizedSqlQuery() { public Map> getParameterValues() { Map> map = new HashMap<>(); map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, id ) ); - map.put( 2, new ImmutablePair<>( DataTypes.ARRAY_REAL, feature ) ); + map.put( 2, new ImmutablePair<>( DataTypes.VARCHAR, randomCategory ) ); + map.put( 3, new ImmutablePair<>( DataTypes.ARRAY_REAL, feature ) ); return map; } From a4adda0bbb5d5328151c758f4c2f6c8f4e57c490 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Tue, 26 May 2026 16:55:37 +0200 Subject: [PATCH 12/38] Add new SimpleKnnRealFeatureFiltered QueryBuilder --- .../SimpleKnnRealFeatureFiltered.java | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeatureFiltered.java diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeatureFiltered.java new file mode 100644 index 0000000..835c8af --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeatureFiltered.java @@ -0,0 +1,120 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Arrays; +import java.util.Map; +import java.util.Random; + +public class SimpleKnnRealFeatureFiltered extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + private final int dimension; + private final int limit; + private final String norm; + private final Random random; + private final String filterCategory; + + public SimpleKnnRealFeatureFiltered( long randomSeed, int dimension, int limit, String norm, String filterCategory ) { + this.dimension = dimension; + this.limit = limit; + this.norm = norm; + this.filterCategory = filterCategory; + this.random = new Random( randomSeed ); + } + + private Float[] getRandomVector() { + Float[] floats = new Float[this.dimension]; + for ( int i = 0; i < this.dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + return floats; + } + + @Override + public synchronized Query getNewQuery() { + return new SimpleKnnRealFeatureFilteredQuery( getRandomVector(), limit, norm, filterCategory ); + } + + private static class SimpleKnnRealFeatureFilteredQuery extends Query { + + private final Float[] target; + private final int limit; + private final String norm; + private final String category; + + public SimpleKnnRealFeatureFilteredQuery( Float[] target, int limit, String norm, String category ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.norm = norm; + this.category = category; + } + + @Override + public String getSql() { + return "SELECT id, distance(feature, ARRAY" + Arrays.toString( + target ) + ", '" + norm + "') as dist " + + "FROM knn_realfeature " + + "WHERE category = '" + category + "' " + + "ORDER BY dist ASC LIMIT " + limit; + } + + @Override + public String getParameterizedSqlQuery() { return null; } + + @Override + public Map> getParameterValues() { + return Map.of(); + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + // Note: This query will currently not enable pushdown, therefore runtime is expected to be high. + @Override + public String getMongoQl() { + return "db.knn_realfeature.aggregate([{" + + " \"$vectorSearch\": {" + + " \"path\": \"feature\"," + + " \"queryVector\": " + Arrays.toString( target ) + + "," + + " \"metric\": \"" + norm + "\"," + + " \"limit\": " + limit + "," + + " \"filter\": { \"category\": \"" + category + + "\" }" + + " }" + + "}])"; + } + } +} From 3c1a6b47b9b0273a175c424627b06ec2e4a351e9 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Tue, 26 May 2026 16:57:18 +0200 Subject: [PATCH 13/38] Adapt already existing structure to support new changes --- .../simpleclient/executor/JdbcExecutor.java | 3 ++ .../polypheny/simpleclient/query/Query.java | 2 +- .../scenario/vectorbench/DataGenerator.java | 21 ++++++++++-- .../scenario/vectorbench/VectorBench.java | 32 ++++++++++++++++--- .../vectorbench/VectorBenchConfig.java | 9 ++++++ .../scenario/vectorbench/vector.properties | 7 +++- 6 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java index 7440a5d..1acd743 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java @@ -254,6 +254,9 @@ protected void executeInsertListAsPreparedBatch( List queryList case ARRAY_REAL: preparedStatement.setArray( entry.getKey(), connection.createArrayOf( "REAL", (Object[]) entry.getValue().right ) ); break; + case ARRAY_BOOLEAN: + preparedStatement.setArray( entry.getKey(), connection.createArrayOf( "BOOLEAN", (Object[]) entry.getValue().right) ); + break; case BYTE_ARRAY: preparedStatement.setBytes( entry.getKey(), (byte[]) entry.getValue().right ); break; diff --git a/src/main/java/org/polypheny/simpleclient/query/Query.java b/src/main/java/org/polypheny/simpleclient/query/Query.java index 99f578f..bcd9b83 100644 --- a/src/main/java/org/polypheny/simpleclient/query/Query.java +++ b/src/main/java/org/polypheny/simpleclient/query/Query.java @@ -52,7 +52,7 @@ public Query( boolean expectResultSet ) { } - public enum DataTypes {INTEGER, VARCHAR, TIMESTAMP, DATE, ARRAY_INT, ARRAY_REAL, BYTE_ARRAY, FILE} + public enum DataTypes {INTEGER, VARCHAR, TIMESTAMP, DATE, ARRAY_INT, ARRAY_REAL, ARRAY_BOOLEAN, BYTE_ARRAY, FILE} public abstract String getSql(); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java index 46e1eef..661fc4a 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java @@ -32,9 +32,10 @@ import org.polypheny.simpleclient.executor.ExecutorException; import org.polypheny.simpleclient.main.ProgressReporter; import org.polypheny.simpleclient.query.BatchableInsert; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.InsertIntFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.InsertMetadata; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.InsertRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion.InsertBooleanFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion.InsertIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion.InsertMetadata; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion.InsertRealFeature; @Slf4j @@ -98,6 +99,20 @@ void generateRealFeatures() throws ExecutorException { } + void generateBooleanFeatures() throws ExecutorException { + InsertBooleanFeature queryBuilder = new InsertBooleanFeature( config.randomSeedInsert, config.dimensionFeatureVectors ); + for ( int i = 0; i < config.numberOfEntries; i++ ) { + if ( aborted ) { + break; + } + + addToInsertList( queryBuilder.getNewQuery() ); + } + + executeInsertList(); + } + + private void addToInsertList( BatchableInsert query ) throws ExecutorException { batchList.add( query ); if ( batchList.size() >= config.batchSizeInserts ) { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index 085b973..a694d3d 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -41,9 +41,13 @@ import org.polypheny.simpleclient.query.QueryBuilder; import org.polypheny.simpleclient.query.QueryListEntry; import org.polypheny.simpleclient.scenario.PolyphenyScenario; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.CreateIntFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.CreateMetadata; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.CreateRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnBooleanFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnBooleanFeatureFiltered; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnRealFeatureFiltered; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation.CreateBooleanFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation.CreateIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation.CreateMetadata; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation.CreateRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnIntFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnRealCrossJoin; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnRealFeature; @@ -87,7 +91,9 @@ public void createSchema( DatabaseInstance databaseInstance, boolean includingKe executor = executorFactory.createExecutorInstance(); executor.executeQuery( (new CreateMetadata( config.dataStoreMetadata )).getNewQuery() ); executor.executeQuery( (new CreateIntFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() ); - executor.executeQuery( (new CreateRealFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() );} catch (ExecutorException e ) { + executor.executeQuery( (new CreateRealFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() ); + executor.executeQuery( (new CreateBooleanFeature( config.dataStoreFeature, config.dimensionFeatureVectors )).getNewQuery() ); + } catch (ExecutorException e ) { throw new RuntimeException( "Exception while creating schema", e ); } finally { commitAndCloseExecutor( executor ); @@ -105,6 +111,7 @@ public void generateData( DatabaseInstance databaseInstance, ProgressReporter pr dataGenerator.generateMetadata(); dataGenerator.generateIntFeatures(); dataGenerator.generateRealFeatures(); + dataGenerator.generateBooleanFeatures(); } catch ( ExecutorException e ) { throw new RuntimeException( "Exception while generating data", e ); } finally { @@ -125,7 +132,10 @@ public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, Fil addNumberOfTimes( queryList, new MetadataKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnIntFeatureQueries ); addNumberOfTimes( queryList, new MetadataKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnRealFeatureQueries ); addNumberOfTimes( queryList, new SimpleKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnRealCrossJoinQueries ); - addNumberOfTimes( queryList, new MetadataKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnRealCrossJoinQueries ); + addNumberOfTimes( queryList, new SimpleKnnRealFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm, "cat_A" ), config.numberOfSimpleKnnRealFeatureFilteredQueries ); + addNumberOfTimes( queryList, new SimpleKnnBooleanFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm ), config.numberOfSimpleKnnBooleanFeatureQueries ); + addNumberOfTimes( queryList, new SimpleKnnBooleanFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm, "cat_A" ), config.numberOfSimpleKnnBooleanFeatureFilteredQueries ); + return commonExecute( queryList, progressReporter, outputDirectory, numberOfThreads, Query::getSql, () -> executorFactory.createExecutorInstance( csvWriter ), new Random() ); } @@ -145,6 +155,9 @@ public void warmUp( ProgressReporter progressReporter ) { MetadataKnnRealFeature metadataKnnRealFeature = new MetadataKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); MetadataKnnRealCrossJoin metadataKnnCrossJoin = new MetadataKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); SimpleKnnRealCrossJoin simpleKnnCrossJoin = new SimpleKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + SimpleKnnRealFeatureFiltered simpleKnnRealFeatureFiltered = new SimpleKnnRealFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm, "cat_A" ); + SimpleKnnBooleanFeature simpleKnnBooleanFeature = new SimpleKnnBooleanFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm ); + SimpleKnnBooleanFeatureFiltered simpleKnnBooleanFeatureFiltered = new SimpleKnnBooleanFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm, "cat_A" ); for ( int i = 0; i < config.numberOfWarmUpIterations; i++ ) { @@ -179,6 +192,15 @@ public void warmUp( ProgressReporter progressReporter ) { if ( config.numberOfSimpleKnnRealCrossJoinQueries > 0 ) { executor.executeQuery( simpleKnnCrossJoin.getNewQuery() ); } + if ( config.numberOfSimpleKnnRealFeatureFilteredQueries > 0 ) { + executor.executeQuery( simpleKnnRealFeatureFiltered.getNewQuery() ); + } + if ( config.numberOfSimpleKnnBooleanFeatureQueries > 0 ) { + executor.executeQuery( simpleKnnBooleanFeature.getNewQuery() ); + } + if ( config.numberOfSimpleKnnRealFeatureFilteredQueries > 0 ) { + executor.executeQuery( simpleKnnBooleanFeatureFiltered.getNewQuery() ); + } } catch ( ExecutorException e ) { throw new RuntimeException( "Error while executing warm-up queries", e ); } finally { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index 8c6e095..b4cd28c 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -55,10 +55,15 @@ public class VectorBenchConfig extends AbstractConfig { public int numberOfMetadataKnnRealFeatureQueries; public int numberOfSimpleKnnRealCrossJoinQueries; public int numberOfMetadataKnnRealCrossJoinQueries; + public int numberOfSimpleKnnRealFeatureFilteredQueries; + public int numberOfSimpleKnnBooleanFeatureQueries; + public int numberOfSimpleKnnBooleanFeatureFilteredQueries; + // public final int numberOfCombinedQueries; public int limitKnnQueries; public String distanceNorm; + public String booleanDistanceNorm; public VectorBenchConfig(Properties properties, int multiplier ) { @@ -98,8 +103,12 @@ public VectorBenchConfig(Properties properties, int multiplier ) { numberOfMetadataKnnRealFeatureQueries = getIntProperty( properties, "numberOfMetadataKnnRealFeatureQueries" ) * multiplier; numberOfSimpleKnnRealCrossJoinQueries = getIntProperty( properties, "numberOfSimpleKnnRealCrossJoinQueries" ) * multiplier; numberOfMetadataKnnRealCrossJoinQueries = getIntProperty( properties, "numberOfMetadataKnnRealCrossJoinQueries" ) * multiplier; + numberOfSimpleKnnRealFeatureFilteredQueries = getIntProperty( properties, "numberOfSimpleKnnRealFeatureFilteredQueries" ) * multiplier; + numberOfSimpleKnnBooleanFeatureQueries = getIntProperty( properties, "numberOfSimpleKnnBooleanFeatureQueries" ) * multiplier; + numberOfSimpleKnnBooleanFeatureFilteredQueries = getIntProperty( properties, "numberOfSimpleKnnBooleanFeatureFilteredQueries" ) * multiplier; limitKnnQueries = getIntProperty( properties, "limitKnnQueries" ); distanceNorm = getStringProperty( properties, "distanceNorm" ); + booleanDistanceNorm = getStringProperty( properties, "booleanDistanceNorm" ); } diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index e014f54..f0ea70a 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -1,6 +1,6 @@ scenario = "vectorBench" -dataStoreFeature = postgresbench +dataStoreFeature = postgresql1 dataStoreMeta = hsqldb numberOfThreads = 4 @@ -27,7 +27,12 @@ numberOfMetadataKnnIntFeatureQueries = 0 numberOfMetadataKnnRealFeatureQueries = 0 numberOfSimpleKnnRealCrossJoinQueries = 10 numberOfMetadataKnnRealCrossJoinQueries = 10 +numberOfSimpleKnnRealFeatureFilteredQueries = 10 +numberOfSimpleKnnBooleanFeatureFilteredQueries = 10 +numberOfSimpleKnnBooleanFeatureQueries = 10 + limitKnnQueries = 10 distanceNorm = COSINE +booleanDistanceNorm = HAMMING From d3b49c7820ded8c6fb166cd5282fa609680219aa Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Tue, 26 May 2026 17:21:43 +0200 Subject: [PATCH 14/38] Restructure VectorBench scenario --- .../scenario/vectorbench/DataGenerator.java | 8 ++--- .../scenario/vectorbench/VectorBench.java | 30 +++++++++---------- .../CreateBooleanFeature.java | 2 +- .../{creation => ddl}/CreateIntFeature.java | 2 +- .../{creation => ddl}/CreateMetadata.java | 2 +- .../{creation => ddl}/CreateRealFeature.java | 2 +- .../InsertBooleanFeature.java | 2 +- .../{insertion => dml}/InsertIntFeature.java | 2 +- .../{insertion => dml}/InsertMetadata.java | 2 +- .../{insertion => dml}/InsertRealFeature.java | 2 +- .../{ => dql}/MetadataKnnIntFeature.java | 4 +-- .../{ => dql}/MetadataKnnRealCrossJoin.java | 4 +-- .../{ => dql}/MetadataKnnRealFeature.java | 5 ++-- .../{ => dql}/SimpleKnnBooleanFeature.java | 4 +-- .../SimpleKnnBooleanFeatureFiltered.java | 4 +-- .../{ => dql}/SimpleKnnIdIntFeature.java | 4 +-- .../{ => dql}/SimpleKnnIdRealFeature.java | 4 +-- .../{ => dql}/SimpleKnnIntFeature.java | 4 +-- .../{ => dql}/SimpleKnnRealCrossJoin.java | 4 +-- .../{ => dql}/SimpleKnnRealFeature.java | 4 +-- .../SimpleKnnRealFeatureFiltered.java | 4 +-- .../{ => dql}/SimpleMetadata.java | 4 +-- 22 files changed, 51 insertions(+), 52 deletions(-) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{creation => ddl}/CreateBooleanFeature.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{creation => ddl}/CreateIntFeature.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{creation => ddl}/CreateMetadata.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{creation => ddl}/CreateRealFeature.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{insertion => dml}/InsertBooleanFeature.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{insertion => dml}/InsertIntFeature.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{insertion => dml}/InsertMetadata.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{insertion => dml}/InsertRealFeature.java (99%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/MetadataKnnIntFeature.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/MetadataKnnRealCrossJoin.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/MetadataKnnRealFeature.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleKnnBooleanFeature.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleKnnBooleanFeatureFiltered.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleKnnIdIntFeature.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleKnnIdRealFeature.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleKnnIntFeature.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleKnnRealCrossJoin.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleKnnRealFeature.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleKnnRealFeatureFiltered.java (98%) rename src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/{ => dql}/SimpleMetadata.java (97%) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java index 661fc4a..69456d8 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java @@ -32,10 +32,10 @@ import org.polypheny.simpleclient.executor.ExecutorException; import org.polypheny.simpleclient.main.ProgressReporter; import org.polypheny.simpleclient.query.BatchableInsert; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion.InsertBooleanFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion.InsertIntFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion.InsertMetadata; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion.InsertRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dml.InsertBooleanFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dml.InsertIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dml.InsertMetadata; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dml.InsertRealFeature; @Slf4j diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index a694d3d..d2b2ab8 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -41,21 +41,21 @@ import org.polypheny.simpleclient.query.QueryBuilder; import org.polypheny.simpleclient.query.QueryListEntry; import org.polypheny.simpleclient.scenario.PolyphenyScenario; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnBooleanFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnBooleanFeatureFiltered; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnRealFeatureFiltered; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation.CreateBooleanFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation.CreateIntFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation.CreateMetadata; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation.CreateRealFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnIntFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnRealCrossJoin; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.MetadataKnnRealFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnIdRealFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnIntFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnRealCrossJoin; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleKnnRealFeature; -import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.SimpleMetadata; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnBooleanFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnBooleanFeatureFiltered; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnRealFeatureFiltered; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateBooleanFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateMetadata; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.MetadataKnnIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.MetadataKnnRealCrossJoin; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.MetadataKnnRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnIdRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnRealCrossJoin; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleMetadata; @Slf4j diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeature.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateBooleanFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeature.java index 55a2711..5900f31 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateBooleanFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateIntFeature.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateIntFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateIntFeature.java index 6217e08..bb0aa00 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateIntFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl; import java.util.Map; import kong.unirest.core.HttpRequest; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateMetadata.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateMetadata.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateMetadata.java index eea5748..37ff0a8 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateMetadata.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl; import java.util.Map; import kong.unirest.core.HttpRequest; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeature.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateRealFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeature.java index 71b4f86..f2ea227 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/creation/CreateRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.creation; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl; import java.util.Map; import kong.unirest.core.HttpRequest; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertBooleanFeature.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertBooleanFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertBooleanFeature.java index 6128dd1..4759858 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertBooleanFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertBooleanFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dml; import com.google.gson.JsonObject; import kong.unirest.core.HttpRequest; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertIntFeature.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertIntFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertIntFeature.java index e1094ba..8ed7133 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertIntFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dml; import com.google.gson.JsonObject; import java.util.Arrays; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertMetadata.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertMetadata.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertMetadata.java index 117baee..27856db 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertMetadata.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dml; import com.google.gson.JsonObject; import java.util.HashMap; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertRealFeature.java similarity index 99% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertRealFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertRealFeature.java index 3f954f8..e0d12b9 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/insertion/InsertRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dml/InsertRealFeature.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.insertion; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dml; import com.google.gson.JsonObject; import java.util.Arrays; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnIntFeature.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnIntFeature.java index 77980b4..bb13089 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import java.util.Arrays; import java.util.HashMap; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealCrossJoin.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealCrossJoin.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealCrossJoin.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealCrossJoin.java index 1101e46..556d9ef 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealCrossJoin.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealCrossJoin.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-4/17/26, 2:54 PM The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealFeature.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealFeature.java index 3b16ae5..333b746 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/MetadataKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,9 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import java.util.Arrays; import java.util.HashMap; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeature.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeature.java index 977b6f6..31c81f7 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeatureFiltered.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeatureFiltered.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeatureFiltered.java index f1bcacb..7293510 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnBooleanFeatureFiltered.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeatureFiltered.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdIntFeature.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdIntFeature.java index 62ccda0..913f2a2 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import java.util.Arrays; import java.util.HashMap; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdRealFeature.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdRealFeature.java index 8179a8e..f0086ef 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIdRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import java.util.Arrays; import java.util.HashMap; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIntFeature.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIntFeature.java index f0923a2..367965a 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import java.util.Arrays; import java.util.HashMap; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealCrossJoin.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealCrossJoin.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealCrossJoin.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealCrossJoin.java index 7d8b737..a576b37 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealCrossJoin.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealCrossJoin.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-4/17/26, 2:44 PM The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeature.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeature.java index 8670a50..de97a59 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import java.util.Arrays; import java.util.HashMap; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeatureFiltered.java similarity index 98% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeatureFiltered.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeatureFiltered.java index 835c8af..ad11a3c 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleKnnRealFeatureFiltered.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeatureFiltered.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleMetadata.java similarity index 97% rename from src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java rename to src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleMetadata.java index 75ecd7e..a02debe 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/SimpleMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleMetadata.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2026 The Polypheny Project + * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ * SOFTWARE. */ -package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder; +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql; import kong.unirest.core.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; From 7c8c924f670b384e4012193718751bc640aaf746 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Wed, 27 May 2026 10:05:58 +0200 Subject: [PATCH 15/38] Add QueryBuilders for PostgreSQL native queries --- .../scenario/vectorbench/PgDataGenerator.java | 99 ++++++++++++ .../scenario/vectorbench/PgVectorBench.java | 145 ++++++++++++++++++ .../postgres/ddl/PgCreateRealFeature.java | 96 ++++++++++++ .../postgres/dml/PgInsertRealFeature.java | 145 ++++++++++++++++++ .../postgres/dql/PgSimpleKnnRealFeature.java | 122 +++++++++++++++ .../dql/PgSimpleKnnRealFeatureFiltered.java | 129 ++++++++++++++++ 6 files changed, 736 insertions(+) create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dml/PgInsertRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java new file mode 100644 index 0000000..ef949dd --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java @@ -0,0 +1,99 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-5/26/26, 5:48 PM The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench; + +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.executor.Executor; +import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.main.ProgressReporter; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.RawQuery; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dml.PgInsertRealFeature; +import java.util.LinkedList; +import java.util.List; + + +@Slf4j +public class PgDataGenerator { + + private final Executor executor; + private final VectorBenchConfig config; + private final ProgressReporter progressReporter; + private final List batch; + private boolean aborted; + + + PgDataGenerator( Executor executor, VectorBenchConfig config, ProgressReporter progressReporter ) { + this.executor = executor; + this.config = config; + this.progressReporter = progressReporter; + this.batch = new LinkedList<>(); + this.aborted = false; + } + + + void generateRealFeatures() throws ExecutorException { + PgInsertRealFeature builder = new PgInsertRealFeature( config.randomSeedInsert, config.dimensionFeatureVectors ); + for ( int i = 0; i < config.numberOfEntries; i++ ) { + if ( aborted ) break; + addToBatch( builder.getNewQuery() ); + progressReporter.update( 1 ); + } + flushBatch(); + } + + + private void addToBatch( BatchableInsert query ) throws ExecutorException { + batch.add( query ); + if ( batch.size() >= config.batchSizeInserts ) { + flushBatch(); + } + } + + + private void flushBatch() throws ExecutorException { + if ( batch.isEmpty() ) return; + StringBuilder sb = new StringBuilder(); + boolean first = true; + for ( BatchableInsert insert : batch ) { + if ( first ) { + sb.append( insert.getSql() ); + first = false; + } else { + sb.append( "," ).append( insert.getSqlRowExpression() ); + } + } + executor.executeQuery( RawQuery.builder().sql( sb.toString() ).expectResultSet( false ).build() ); + executor.executeCommit(); + batch.clear(); + } + + + + public void abort() { + aborted = true; + } +} + diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java new file mode 100644 index 0000000..6f2c320 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java @@ -0,0 +1,145 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-5/26/26, 5:48 PM The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench; + +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.QueryMode; +import org.polypheny.simpleclient.executor.Executor; +import org.polypheny.simpleclient.executor.Executor.DatabaseInstance; +import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.main.CsvWriter; +import org.polypheny.simpleclient.main.ProgressReporter; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.polypheny.simpleclient.query.QueryListEntry; +import org.polypheny.simpleclient.query.RawQuery; +import org.polypheny.simpleclient.scenario.PolyphenyScenario; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl.PgCreateRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealFeatureFiltered; +import java.io.File; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.Vector; + + +@Slf4j +public class PgVectorBench extends PolyphenyScenario { + + private final VectorBenchConfig config; + + + public PgVectorBench( Executor.ExecutorFactory executorFactory, VectorBenchConfig config, + boolean commitAfterEveryQuery, boolean dumpQueryList ) { + super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); + this.config = config; + } + + + @Override + public void createSchema( DatabaseInstance databaseInstance, boolean includingKeys ) { + log.info( "Creating schema..." ); + Executor executor = null; + try { + executor = executorFactory.createExecutorInstance(); + executor.executeQuery( new RawQuery( "CREATE EXTENSION IF NOT EXISTS vector", null, false ) ); + executor.executeQuery( new PgCreateRealFeature( config.dimensionFeatureVectors ).getNewQuery() ); + } catch ( ExecutorException e ) { + throw new RuntimeException( "Exception while creating schema", e ); + } finally { + commitAndCloseExecutor( executor ); + } + } + + + @Override + public void generateData( DatabaseInstance databaseInstance, ProgressReporter progressReporter ) { + log.info( "Generating data..." ); + Executor executor = executorFactory.createExecutorInstance(); + PgDataGenerator dataGenerator = new PgDataGenerator( executor, config, progressReporter ); + try { + dataGenerator.generateRealFeatures(); + } catch ( ExecutorException e ) { + throw new RuntimeException( "Exception while generating data", e ); + } finally { + commitAndCloseExecutor( executor ); + } + } + + + @Override + public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, File outputDirectory, int numberOfThreads ) { + log.info( "Preparing query list..." ); + List queryList = new Vector<>(); + addNumberOfTimes( queryList, new PgSimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnRealFeatureQueries ); + addNumberOfTimes( queryList, new PgSimpleKnnRealFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm, "cat_A" ), config.numberOfSimpleKnnRealFeatureFilteredQueries ); + return commonExecute( queryList, progressReporter, outputDirectory, numberOfThreads, + Query::getSql, () -> executorFactory.createExecutorInstance( csvWriter ), new Random() ); + } + + + @Override + public void warmUp( ProgressReporter progressReporter ) { + log.info( "Warm-up..." ); + PgSimpleKnnRealFeature knnBuilder = new PgSimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + Executor executor = null; + for ( int i = 0; i < config.numberOfWarmUpIterations; i++ ) { + try { + executor = executorFactory.createExecutorInstance(); + if ( config.numberOfSimpleKnnRealFeatureQueries > 0 ) { + executor.executeQuery( knnBuilder.getNewQuery() ); + } + } catch ( ExecutorException e ) { + throw new RuntimeException( "Error during warm-up", e ); + } finally { + commitAndCloseExecutor( executor ); + } + try { + Thread.sleep( 10000 ); + } catch ( InterruptedException e ) { + throw new RuntimeException( "Interrupted during warm-up", e ); + } + } + } + + + @Override + public int getNumberOfInsertThreads() { + return 1; + } + + + private void addNumberOfTimes( List list, QueryBuilder builder, int count ) { + int id = queryTypes.size() + 1; + queryTypes.put( id, builder.getNewQuery().getSql() ); + measuredTimePerQueryType.put( id, Collections.synchronizedList( new LinkedList<>() ) ); + for ( int i = 0; i < count; i++ ) { + list.add( new QueryListEntry( builder.getNewQuery(), id ) ); + } + } +} + diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeature.java new file mode 100644 index 0000000..e3b6266 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeature.java @@ -0,0 +1,96 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; + + +public class PgCreateRealFeature extends QueryBuilder { + + private final int dimension; + + + public PgCreateRealFeature( int dimension ) { + this.dimension = dimension; + } + + + @Override + public Query getNewQuery() { + return new PgCreateRealFeatureQuery( dimension ); + } + + + private static class PgCreateRealFeatureQuery extends Query { + + private final int dimension; + + + PgCreateRealFeatureQuery( int dimension ) { + super( false ); + this.dimension = dimension; + } + + + @Override + public String getSql() { + return "CREATE TABLE knn_realfeature (" + + "id INTEGER NOT NULL, " + + "category VARCHAR(50), " + + "feature vector(" + dimension + ") NOT NULL, " + + "PRIMARY KEY (id))"; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dml/PgInsertRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dml/PgInsertRealFeature.java new file mode 100644 index 0000000..3e652e5 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dml/PgInsertRealFeature.java @@ -0,0 +1,145 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dml; + +import com.google.gson.JsonObject; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + + +public class PgInsertRealFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = false; + private static final AtomicInteger nextId = new AtomicInteger( 1 ); + private static final String[] CATEGORIES = { "cat_A", "cat_B", "cat_C", "cat_D" }; + + private final int dimension; + private final Random random; + + + public PgInsertRealFeature( long randomSeed, int dimension ) { + this.dimension = dimension; + this.random = new Random( randomSeed ); + } + + + private Float[] getRandomVector() { + Float[] floats = new Float[dimension]; + for ( int i = 0; i < dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + return floats; + } + + + @Override + public synchronized BatchableInsert getNewQuery() { + return new PgInsertRealFeatureQuery( + nextId.getAndIncrement(), + getRandomVector(), + CATEGORIES[random.nextInt( CATEGORIES.length )] + ); + } + + + private static class PgInsertRealFeatureQuery extends BatchableInsert { + + private static final String SQL = "INSERT INTO knn_realfeature (id, category, feature) VALUES "; + private final int id; + private final Float[] feature; + private final String category; + + + PgInsertRealFeatureQuery( int id, Float[] feature, String category ) { + super( EXPECT_RESULT ); + this.id = id; + this.feature = feature; + this.category = category; + } + + + @Override + public String getSqlRowExpression() { + StringBuilder sb = new StringBuilder( "(" ); + sb.append( id ).append( ", '" ).append( category ).append( "', '[" ); + for ( int i = 0; i < feature.length; i++ ) { + if ( i > 0 ) + sb.append( "," ); + sb.append( feature[i] ); + } + sb.append( "]')" ); + return sb.toString(); + } + + + @Override + public String getSql() { + return SQL + getSqlRowExpression(); + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public JsonObject getRestRowExpression() { + return null; + } + + + @Override + public String getEntity() { + return "public.knn_realfeature"; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java new file mode 100644 index 0000000..b6c7bcc --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java @@ -0,0 +1,122 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; +import java.util.Random; + + +public class PgSimpleKnnRealFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final int dimension; + private final int limit; + private final String operator; + private final Random random; + + + public PgSimpleKnnRealFeature( long randomSeed, int dimension, int limit, String distanceMetric ) { + this.dimension = dimension; + this.limit = limit; + this.random = new Random( randomSeed ); + this.operator = toOperator( distanceMetric ); + } + + + private static String toOperator( String metric ) { + return switch ( metric.toLowerCase() ) { + case "cosine" -> "<=>"; + case "l2" -> "<->"; + case "l1" -> "<+>"; + default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); + }; + } + + + private Float[] getRandomVector() { + Float[] floats = new Float[dimension]; + for ( int i = 0; i < dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + return floats; + } + + + @Override + public synchronized Query getNewQuery() { + return new PgSimpleKnnRealFeatureQuery( getRandomVector(), limit, operator ); + } + + + private static class PgSimpleKnnRealFeatureQuery extends Query { + + private final Float[] target; + private final int limit; + private final String operator; + + + PgSimpleKnnRealFeatureQuery( Float[] target, int limit, String operator ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.operator = operator; + } + + + @Override + public String getSql() { + StringBuilder sb = new StringBuilder( "SELECT id, feature " ); + sb.append( operator ).append( " '[" ); + for ( int i = 0; i < target.length; i++ ) { + if ( i > 0 ) sb.append( "," ); + sb.append( target[i] ); + } + sb.append( "]' AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT " ).append( limit ); + return sb.toString(); + } + + + @Override + public String getParameterizedSqlQuery() { return null; } + + + @Override + public Map> getParameterValues() { return null; } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { return null; } + } +} + diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java new file mode 100644 index 0000000..7229d5d --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java @@ -0,0 +1,129 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; +import java.util.Random; + + +public class PgSimpleKnnRealFeatureFiltered extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final int dimension; + private final int limit; + private final String operator; + private final String filterCategory; + private final Random random; + + + public PgSimpleKnnRealFeatureFiltered( long randomSeed, int dimension, int limit, String distanceMetric, String filterCategory ) { + this.dimension = dimension; + this.limit = limit; + this.filterCategory = filterCategory; + this.random = new Random( randomSeed ); + this.operator = toOperator( distanceMetric ); + } + + + private static String toOperator( String metric ) { + return switch ( metric.toLowerCase() ) { + case "cosine" -> "<=>"; + case "l2" -> "<->"; + case "l1" -> "<+>"; + default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); + }; + } + + + private Float[] getRandomVector() { + Float[] floats = new Float[dimension]; + for ( int i = 0; i < dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + return floats; + } + + + @Override + public synchronized Query getNewQuery() { + return new PgSimpleKnnRealFeatureFilteredQuery( getRandomVector(), limit, operator, filterCategory ); + } + + + private static class PgSimpleKnnRealFeatureFilteredQuery extends Query { + + private final Float[] target; + private final int limit; + private final String operator; + private final String category; + + + PgSimpleKnnRealFeatureFilteredQuery( Float[] target, int limit, String operator, String category ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.operator = operator; + this.category = category; + } + + + @Override + public String getSql() { + StringBuilder sb = new StringBuilder( "SELECT id, feature " ); + sb.append( operator ).append( " '[" ); + for ( int i = 0; i < target.length; i++ ) { + if ( i > 0 ) sb.append( "," ); + sb.append( target[i] ); + } + sb.append( "]' AS dist FROM knn_realfeature WHERE category = '" ) + .append( category ) + .append( "' ORDER BY dist ASC LIMIT " ).append( limit ); + return sb.toString(); + } + + + @Override + public String getParameterizedSqlQuery() { return null; } + + + @Override + public Map> getParameterValues() { return null; } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { return null; } + } +} + From f6d6241037b4e4c7e20c61b99895ede0bdd15097 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Wed, 27 May 2026 10:08:41 +0200 Subject: [PATCH 16/38] Adapt VectorCommand, VectorBenchScenario, and VectorBenchConfig to support PgVectorBench --- .../simpleclient/cli/VectorCommand.java | 22 +++++++--- .../main/VectorBenchScenario.java | 40 +++++++++++++++++++ .../vectorbench/VectorBenchConfig.java | 4 ++ .../scenario/vectorbench/vector.properties | 3 ++ 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java b/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java index 71e85b2..7486a77 100644 --- a/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java +++ b/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java @@ -47,6 +47,10 @@ public class VectorCommand implements CliRunnable { private List args; + @Option(name = { "-m", "--mode" }, title = "Mode", arity = 1, description = "Execution mode: polypheny (default) or postgres.") + public String mode = "polypheny"; + + @Option(name = { "-pdb", "--polyphenydb" }, title = "IP or Hostname", arity = 1, description = "IP or Hostname of the Polypheny-DB server (default: 127.0.0.1).") public static String polyphenyDbHost = "127.0.0.1"; @@ -78,16 +82,22 @@ public int run() throws SQLException { ExecutorFactory executorFactory; executorFactory = new PolyphenyDbJdbcExecutorFactory( polyphenyDbHost, false ); + boolean usePostgres = mode.equalsIgnoreCase( "postgres" ); + String task = args.getFirst(); try { - if ( args.getFirst().equalsIgnoreCase( "data" ) ) { - VectorBenchScenario.data( executorFactory, multiplier, true ); - } else if ( args.getFirst().equalsIgnoreCase( "workload" ) ) { - VectorBenchScenario.workload( executorFactory, multiplier, true, writeCsv, dumpQueryList ); + if ( task.equalsIgnoreCase( "data" ) ) { + if ( usePostgres ) VectorBenchScenario.pgData( multiplier, true ); + else VectorBenchScenario.data( executorFactory, multiplier, true ); + } else if ( task.equalsIgnoreCase( "workload" ) ) { + if ( usePostgres ) VectorBenchScenario.pgWorkload( multiplier, true, writeCsv, dumpQueryList ); + else VectorBenchScenario.workload( executorFactory, multiplier, true, writeCsv, dumpQueryList ); } else if ( args.getFirst().equalsIgnoreCase( "schema" ) ) { - VectorBenchScenario.schema( executorFactory, true ); + if ( usePostgres ) VectorBenchScenario.pgSchema( true ); + else VectorBenchScenario.schema( executorFactory, true ); } else if ( args.getFirst().equalsIgnoreCase( "warmup" ) ) { - VectorBenchScenario.warmup( executorFactory, multiplier, true, dumpQueryList ); + if ( usePostgres ) VectorBenchScenario.pgWarmup( multiplier, true, dumpQueryList ); + else VectorBenchScenario.warmup( executorFactory, multiplier, true, dumpQueryList ); } else { System.err.println( "Unknown task: " + args.getFirst() ); } diff --git a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java index 16af8c4..709665a 100644 --- a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java +++ b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java @@ -26,6 +26,8 @@ import lombok.extern.slf4j.Slf4j; import org.polypheny.simpleclient.executor.Executor.ExecutorFactory; +import org.polypheny.simpleclient.executor.PostgresExecutor.PostgresExecutorFactory; +import org.polypheny.simpleclient.scenario.vectorbench.PgVectorBench; import org.polypheny.simpleclient.scenario.vectorbench.VectorBench; import org.polypheny.simpleclient.scenario.vectorbench.VectorBenchConfig; import java.io.File; @@ -43,6 +45,14 @@ public static void schema( ExecutorFactory executorFactory, boolean commitAfterE } + public static void pgSchema( boolean commitAfterEveryQuery ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), 1 ); + ExecutorFactory factory = new PostgresExecutorFactory( config.postgresHost, false ); + PgVectorBench vectorBench = new PgVectorBench( factory, config, commitAfterEveryQuery, false ); + vectorBench.createSchema( null, true ); + } + + public static void data( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery ) { VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, false ); @@ -52,6 +62,15 @@ public static void data( ExecutorFactory executorFactory, int multiplier, boolea } + public static void pgData( int multiplier, boolean commitAfterEveryQuery ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); + ExecutorFactory factory = new PostgresExecutorFactory( config.postgresHost, false ); + PgVectorBench bench = new PgVectorBench( factory, config, commitAfterEveryQuery, false ); + ProgressReporter progressReporter = new ProgressBar( config.numberOfThreads, config.progressReportBase ); + bench.generateData( null, progressReporter ); + } + + public static void workload( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery, boolean writeCsv, boolean dumpQueryList ) { VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, dumpQueryList ); @@ -68,6 +87,17 @@ public static void workload( ExecutorFactory executorFactory, int multiplier, bo } + public static void pgWorkload( int multiplier, boolean commitAfterEveryQuery, boolean writeCsv, boolean dumpQueryList ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); + ExecutorFactory factory = new PostgresExecutorFactory( config.postgresHost, false ); + PgVectorBench bench = new PgVectorBench( factory, config, commitAfterEveryQuery, dumpQueryList ); + CsvWriter csvWriter = writeCsv ? new CsvWriter( "results-pg.csv" ) : null; + ProgressReporter progressReporter = new ProgressBar( config.numberOfThreads, config.progressReportBase ); + bench.execute( progressReporter, csvWriter, new File( "." ), config.numberOfThreads ); + } + + + public static void warmup( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery, boolean dumpQueryList ) { VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, dumpQueryList ); @@ -77,6 +107,16 @@ public static void warmup( ExecutorFactory executorFactory, int multiplier, bool } + public static void pgWarmup( int multiplier, boolean commitAfterEveryQuery, boolean dumpQueryList ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); + ExecutorFactory factory = new PostgresExecutorFactory( config.postgresHost, false ); + PgVectorBench bench = new PgVectorBench( factory, config, commitAfterEveryQuery, dumpQueryList ); + ProgressReporter progressReporter = new ProgressBar( config.numberOfThreads, config.progressReportBase ); + bench.warmUp( progressReporter ); + } + + + private static Properties getProperties() { Properties props = new Properties(); try { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index b4cd28c..def1adf 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -38,6 +38,8 @@ public class VectorBenchConfig extends AbstractConfig { public String dataStoreFeature; public String dataStoreMetadata; + public String postgresHost; + public long randomSeedInsert; public long randomSeedQuery; @@ -80,6 +82,8 @@ public VectorBenchConfig(Properties properties, int multiplier ) { } //dataStores.add( "cottontail" ); + postgresHost = getStringProperty( properties, "postgresHost" ); + if ( getBooleanProperty( properties, "useRandomSeeds" ) ) { Random tempRand = new Random(); randomSeedInsert = tempRand.nextLong(); diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index f0ea70a..7ab6fb6 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -3,6 +3,9 @@ scenario = "vectorBench" dataStoreFeature = postgresql1 dataStoreMeta = hsqldb +# PostgreSQL direct connect settings +postgresHost = 127.0.0.1 + numberOfThreads = 4 progressReportBase = 100 numberOfWarmUpIterations = 4 From 22fa0243750fbf6b2fcb76fc70ffd838a81e3eb4 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Wed, 27 May 2026 17:16:16 +0200 Subject: [PATCH 17/38] Add remaining adaptations caused by new QueryBuilders --- .../simpleclient/scenario/vectorbench/VectorBenchConfig.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index def1adf..ed629a9 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -151,6 +151,10 @@ public VectorBenchConfig(Map cdl ) { numberOfMetadataKnnRealFeatureQueries = Integer.parseInt( cdl.get( "numberOfMetadataKnnRealFeatureQueries" ) ); numberOfSimpleKnnRealCrossJoinQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnRealCrossJoinQueries" ) ); numberOfMetadataKnnRealCrossJoinQueries = Integer.parseInt( cdl.get( "numberOfMetadataKnnRealCrossJoinQueries" ) ); + numberOfSimpleKnnRealFeatureFilteredQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnRealFeatureFilteredQueries") ); + numberOfSimpleKnnBooleanFeatureQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnBooleanFeatureQueries" ) );a + numberOfSimpleKnnBooleanFeatureFilteredQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnBooleanFeatureFilteredQueries" ) ); + //TODO: insert missing // numberOfCombinedQueries = getIntProperty( properties, "numberOfCombinedQueries" ) * multiplier; limitKnnQueries = Integer.parseInt( cdl.get( "limitKnnQueries" ) ); distanceNorm = cdl.get( "distanceNorm" ).trim(); From ff0e2d4e12fa18adfeeab91ef97b2906f13359b5 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Wed, 27 May 2026 17:16:38 +0200 Subject: [PATCH 18/38] Add useIndex option to vector.properties --- .../simpleclient/scenario/vectorbench/vector.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index 7ab6fb6..b6c2463 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -3,6 +3,8 @@ scenario = "vectorBench" dataStoreFeature = postgresql1 dataStoreMeta = hsqldb +useIndex = false + # PostgreSQL direct connect settings postgresHost = 127.0.0.1 From 995a898969d8291c001f84c09fde4ce68bff8e41 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Wed, 27 May 2026 17:22:10 +0200 Subject: [PATCH 19/38] Fix typo --- .../simpleclient/scenario/vectorbench/VectorBenchConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index ed629a9..c0ca448 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -152,7 +152,7 @@ public VectorBenchConfig(Map cdl ) { numberOfSimpleKnnRealCrossJoinQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnRealCrossJoinQueries" ) ); numberOfMetadataKnnRealCrossJoinQueries = Integer.parseInt( cdl.get( "numberOfMetadataKnnRealCrossJoinQueries" ) ); numberOfSimpleKnnRealFeatureFilteredQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnRealFeatureFilteredQueries") ); - numberOfSimpleKnnBooleanFeatureQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnBooleanFeatureQueries" ) );a + numberOfSimpleKnnBooleanFeatureQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnBooleanFeatureQueries" ) ); numberOfSimpleKnnBooleanFeatureFilteredQueries = Integer.parseInt( cdl.get( "numberOfSimpleKnnBooleanFeatureFilteredQueries" ) ); //TODO: insert missing // numberOfCombinedQueries = getIntProperty( properties, "numberOfCombinedQueries" ) * multiplier; From 48dd08546de75c7cb6be0a13518c13f81b481bed Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Wed, 27 May 2026 18:01:04 +0200 Subject: [PATCH 20/38] Revert changes to build.gradle used for local testing --- build.gradle | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index 4115557..fba747f 100644 --- a/build.gradle +++ b/build.gradle @@ -41,13 +41,8 @@ apply plugin: "io.freefair.lombok" apply plugin: "com.github.johnrengelman.shadow" apply plugin: "app.cash.licensee" apply plugin: "com.jaredsburrows.license" -apply plugin: "application" -application { - mainClass = "org.polypheny.simpleclient.cli.Main" -} - tasks.withType(JavaCompile).configureEach { options.encoding = "UTF-8" } @@ -210,6 +205,7 @@ shadowJar { } } assemble.dependsOn shadowJar + artifacts { //archives jar // regular jar containing only the compiled source archives shadowJar // fat jar which additionally contains all dependencies @@ -245,22 +241,6 @@ compileJava.dependsOn(copyPolyphenyOldJdbcDriver) compileJava.dependsOn(copyPolyphenyNewJdbcDriver) - -/* ------------ Local testing config ------------ */ -processResources { - dependsOn copyPolyphenyOldJdbcDriver, copyPolyphenyNewJdbcDriver - from('libs/polyphenyJdbcDrivers') { - rename { name -> name.replace('.jar', '.zip') } - into 'libs/polyphenyJdbcDrivers' - } - } - -run { - dependsOn processResources -} -/* ---------------------------------------------- */ - - /** * IntelliJ */ From 547feb3fc52772351071eae563cbed27c85846ca Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 1 Jun 2026 10:06:51 +0200 Subject: [PATCH 21/38] Add index creation QueryBuilders --- .../ddl/CreateRealFeatureIndex.java | 123 +++++++++++++++++ .../ddl/PgCreateRealFeatureIndex.java | 125 ++++++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeatureIndex.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeatureIndex.java diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeatureIndex.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeatureIndex.java new file mode 100644 index 0000000..cb556a4 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeatureIndex.java @@ -0,0 +1,123 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl; + +import java.util.Map; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class CreateRealFeatureIndex extends QueryBuilder { + + private final String store; + private final String method; + private final String metric; + private final int m; + private final int efConstruction; + private final int lists; + + + public CreateRealFeatureIndex( String store, String method, String metric, int m, int efConstruction, int lists ) { + this.store = store; + this.method = method; + this.metric = metric; + this.m = m; + this.efConstruction = efConstruction; + this.lists = lists; + } + + + @Override + public Query getNewQuery() { + return new CreateRealFeatureIndexQuery( store, method, metric, m, efConstruction, lists ); + } + + + private static class CreateRealFeatureIndexQuery extends Query { + + private final String store; + private final String method; + private final String metric; + private final int m; + private final int efConstruction; + private final int lists; + private final boolean isHnsw; + + + CreateRealFeatureIndexQuery( String store, String method, String metric, int m, int efConstruction, int lists ) { + super( false ); + this.store = store; + this.method = method; + this.metric = metric; + this.m = m; + this.efConstruction = efConstruction; + this.lists = lists; + this.isHnsw = method.equals( "hnsw" ); + } + + + @Override + public String getSql() { + String sql = "ALTER TABLE knn_realfeature ADD INDEX feature_" + method + + " ON (feature) USING " + method; + if ( store != null ) { + sql += " ON STORE \"" + store + "\""; + } + String params = isHnsw + ? "m=" + m + ", ef_construction=" + efConstruction + : "lists=" + lists; + sql += " WITH (metric='" + metric + "', " + params + ")"; + return sql; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeatureIndex.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeatureIndex.java new file mode 100644 index 0000000..e331e30 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeatureIndex.java @@ -0,0 +1,125 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl; + +import java.util.Map; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class PgCreateRealFeatureIndex extends QueryBuilder { + + private final String method; + private final String opClass; + private final int m; + private final int efConstruction; + private final int lists; + + + public PgCreateRealFeatureIndex( String method, String metric, int m, int efConstruction, int lists ) { + this.method = method; + this.opClass = toOpClass( metric ); + this.m = m; + this.efConstruction = efConstruction; + this.lists = lists; + } + + + private static String toOpClass( String metric ) { + return switch ( metric.toLowerCase() ) { + case "cosine" -> "vector_cosine_ops"; + case "l2" -> "vector_l2_ops"; + case "l1" -> "vector_l1_ops"; + case "ip" -> "vector_ip_ops"; + default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); + }; + } + + + @Override + public Query getNewQuery() { + return new PgCreateRealFeatureIndexQuery( method, opClass, m, efConstruction, lists ); + } + + + private static class PgCreateRealFeatureIndexQuery extends Query { + + private final String method; + private final String opClass; + private final int m; + private final int efConstruction; + private final int lists; + private final boolean isHnsw; + + + PgCreateRealFeatureIndexQuery( String method, String opClass, int m, int efConstruction, int lists ) { + super( false ); + this.method = method; + this.opClass = opClass; + this.m = m; + this.efConstruction = efConstruction; + this.lists = lists; + this.isHnsw = method.equals( "hnsw" ); + } + + + @Override + public String getSql() { + String withClause = isHnsw + ? "(m=" + m + ", ef_construction=" + efConstruction + ")" + : "(lists=" + lists + ")"; + return "CREATE INDEX ON knn_realfeature USING " + method + + " (feature " + opClass + ") WITH " + withClause; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} From 03a774e2d8d71501f11c5181f66941563b6c1d22 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 1 Jun 2026 10:11:38 +0200 Subject: [PATCH 22/38] Implement recall analysis --- .../simpleclient/cli/VectorCommand.java | 17 +- .../main/VectorBenchScenario.java | 80 ++++++++ .../scenario/vectorbench/PgVectorBench.java | 80 ++++++++ .../scenario/vectorbench/RecallEvaluator.java | 181 ++++++++++++++++++ .../scenario/vectorbench/VectorBench.java | 75 +++++++- 5 files changed, 426 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/RecallEvaluator.java diff --git a/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java b/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java index 7486a77..d733082 100644 --- a/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java +++ b/src/main/java/org/polypheny/simpleclient/cli/VectorCommand.java @@ -43,14 +43,10 @@ public class VectorCommand implements CliRunnable { @AirlineModule private HelpOption help; - @Arguments(description = "Task { schema | data | workload } and multiplier.") + @Arguments(description = "Task { schema | data | groundtruth | index | workload | warmup | recall } and multiplier.") private List args; - @Option(name = { "-m", "--mode" }, title = "Mode", arity = 1, description = "Execution mode: polypheny (default) or postgres.") - public String mode = "polypheny"; - - @Option(name = { "-pdb", "--polyphenydb" }, title = "IP or Hostname", arity = 1, description = "IP or Hostname of the Polypheny-DB server (default: 127.0.0.1).") public static String polyphenyDbHost = "127.0.0.1"; @@ -82,7 +78,7 @@ public int run() throws SQLException { ExecutorFactory executorFactory; executorFactory = new PolyphenyDbJdbcExecutorFactory( polyphenyDbHost, false ); - boolean usePostgres = mode.equalsIgnoreCase( "postgres" ); + boolean usePostgres = VectorBenchScenario.isPostgresMode(); String task = args.getFirst(); try { @@ -95,6 +91,15 @@ public int run() throws SQLException { } else if ( args.getFirst().equalsIgnoreCase( "schema" ) ) { if ( usePostgres ) VectorBenchScenario.pgSchema( true ); else VectorBenchScenario.schema( executorFactory, true ); + } else if ( task.equalsIgnoreCase( "index" ) ) { + if ( usePostgres ) VectorBenchScenario.pgIndex( true ); + else VectorBenchScenario.index( executorFactory, true ); + } else if ( task.equalsIgnoreCase( "groundtruth" ) ) { + if ( usePostgres ) VectorBenchScenario.pgGroundTruth(); + else VectorBenchScenario.groundTruth( executorFactory ); + } else if ( task.equalsIgnoreCase( "recall" ) ) { + if ( usePostgres ) VectorBenchScenario.pgRecall(); + else VectorBenchScenario.recall( executorFactory ); } else if ( args.getFirst().equalsIgnoreCase( "warmup" ) ) { if ( usePostgres ) VectorBenchScenario.pgWarmup( multiplier, true, dumpQueryList ); else VectorBenchScenario.warmup( executorFactory, multiplier, true, dumpQueryList ); diff --git a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java index 709665a..34fba12 100644 --- a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java +++ b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java @@ -27,9 +27,15 @@ import lombok.extern.slf4j.Slf4j; import org.polypheny.simpleclient.executor.Executor.ExecutorFactory; import org.polypheny.simpleclient.executor.PostgresExecutor.PostgresExecutorFactory; +import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.executor.JdbcExecutor; +import org.polypheny.simpleclient.query.QueryBuilder; import org.polypheny.simpleclient.scenario.vectorbench.PgVectorBench; +import org.polypheny.simpleclient.scenario.vectorbench.RecallEvaluator; import org.polypheny.simpleclient.scenario.vectorbench.VectorBench; import org.polypheny.simpleclient.scenario.vectorbench.VectorBenchConfig; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealFeature; import java.io.File; import java.io.IOException; import java.util.Objects; @@ -53,6 +59,76 @@ public static void pgSchema( boolean commitAfterEveryQuery ) { } + public static void index( ExecutorFactory executorFactory, boolean commitAfterEveryQuery ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), 1 ); + VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, false ); + vectorBench.createIndex(); + } + + + public static void pgIndex( boolean commitAfterEveryQuery ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), 1 ); + ExecutorFactory factory = new PostgresExecutorFactory( config.postgresHost, false ); + PgVectorBench vectorBench = new PgVectorBench( factory, config, commitAfterEveryQuery, false ); + vectorBench.createIndex(); + } + + + public static void groundTruth( ExecutorFactory executorFactory ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), 1 ); + runRecall( executorFactory, config, polyphenyKnnBuilder( config ), true ); + } + + + public static void recall( ExecutorFactory executorFactory ) { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), 1 ); + runRecall( executorFactory, config, polyphenyKnnBuilder( config ), false ); + } + + + public static void pgGroundTruth() { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), 1 ); + ExecutorFactory factory = new PostgresExecutorFactory( config.postgresHost, false ); + runRecall( factory, config, pgKnnBuilder( config ), true ); + } + + + public static void pgRecall() { + VectorBenchConfig config = new VectorBenchConfig( getProperties(), 1 ); + ExecutorFactory factory = new PostgresExecutorFactory( config.postgresHost, false ); + runRecall( factory, config, pgKnnBuilder( config ), false ); + } + + + private static QueryBuilder polyphenyKnnBuilder( VectorBenchConfig config ) { + return new SimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + } + + + private static QueryBuilder pgKnnBuilder( VectorBenchConfig config ) { + return new PgSimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + } + + + private static void runRecall( ExecutorFactory executorFactory, VectorBenchConfig config, QueryBuilder knnBuilder, boolean capture ) { + JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); + RecallEvaluator evaluator = new RecallEvaluator( config, executor, knnBuilder, RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ); + try { + if ( capture ) { + evaluator.captureGroundTruth(); + } else { + evaluator.evaluate(); + } + } finally { + try { + executor.closeConnection(); + } catch ( ExecutorException e ) { + log.error( "Error while closing connection", e ); + } + } + } + + public static void data( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery ) { VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, false ); @@ -116,6 +192,10 @@ public static void pgWarmup( int multiplier, boolean commitAfterEveryQuery, bool } + public static boolean isPostgresMode() { + return new VectorBenchConfig( getProperties(), 1 ).mode.equalsIgnoreCase( "postgres" ); + } + private static Properties getProperties() { Properties props = new Properties(); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java index 6f2c320..0d7c49b 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java @@ -29,6 +29,7 @@ import org.polypheny.simpleclient.executor.Executor; import org.polypheny.simpleclient.executor.Executor.DatabaseInstance; import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.executor.JdbcExecutor; import org.polypheny.simpleclient.main.CsvWriter; import org.polypheny.simpleclient.main.ProgressReporter; import org.polypheny.simpleclient.query.Query; @@ -37,13 +38,16 @@ import org.polypheny.simpleclient.query.RawQuery; import org.polypheny.simpleclient.scenario.PolyphenyScenario; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl.PgCreateRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl.PgCreateRealFeatureIndex; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealFeatureFiltered; import java.io.File; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Properties; import java.util.Random; +import java.util.Set; import java.util.Vector; @@ -52,6 +56,9 @@ public class PgVectorBench extends PolyphenyScenario { private final VectorBenchConfig config; + // Exact top-k ids captured during data generation; consumed by analyze() to compute recall@k. + private List> recallGroundTruth; + public PgVectorBench( Executor.ExecutorFactory executorFactory, VectorBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { @@ -76,6 +83,33 @@ public void createSchema( DatabaseInstance databaseInstance, boolean includingKe } + public void createIndex() { + if ( !config.useIndex ) { + return; + } + Executor executor = null; + try { + executor = executorFactory.createExecutorInstance(); + long start = System.nanoTime(); + executor.executeQuery( new PgCreateRealFeatureIndex( config.indexMethod, config.distanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + executor.executeCommit(); + long durationMillis = ( System.nanoTime() - start ) / 1_000_000L; + log.info( "Vector index built in {} ms", durationMillis ); + + String conf = config.indexMethod.equals( "hnsw" ) + ? "hnsw.ef_search = " + config.queryEfSearch + : "ivfflat.probes = " + config.queryProbes; + executor.executeQuery( new RawQuery( "ALTER DATABASE postgres SET " + conf, null, false ) ); + executor.executeCommit(); + log.info( "Query-time index parameter set: {}", conf ); + } catch ( ExecutorException e ) { + throw new RuntimeException( "Exception while creating vector index", e ); + } finally { + commitAndCloseExecutor( executor ); + } + } + + @Override public void generateData( DatabaseInstance databaseInstance, ProgressReporter progressReporter ) { log.info( "Generating data..." ); @@ -88,6 +122,52 @@ public void generateData( DatabaseInstance databaseInstance, ProgressReporter pr } finally { commitAndCloseExecutor( executor ); } + + // 1. extract ground truth + // 2. create index + // 3. warmup/execute/analyze + if ( databaseInstance != null && config.useIndex ) { + recallGroundTruth = captureRecallGroundTruth(); + createIndex(); + } + } + + + private QueryBuilder recallKnnBuilder() { + return new PgSimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + } + + + private List> captureRecallGroundTruth() { + JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); + try { + return new RecallEvaluator( config, executor, recallKnnBuilder(), RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ).captureGroundTruthInMemory(); + } finally { + try { + executor.closeConnection(); + } catch ( ExecutorException e ) { + log.error( "Error while closing connection", e ); + } + } + } + + + @Override + public void analyze( Properties properties, File outputDirectory ) { + super.analyze( properties, outputDirectory ); + if ( config.useIndex && recallGroundTruth != null ) { + JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); + try { + double recall = new RecallEvaluator( config, executor, recallKnnBuilder(), RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ).evaluate( recallGroundTruth ); + properties.put( "recall@" + config.limitKnnQueries, recall ); + } finally { + try { + executor.closeConnection(); + } catch ( ExecutorException e ) { + log.error( "Error while closing connection", e ); + } + } + } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/RecallEvaluator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/RecallEvaluator.java new file mode 100644 index 0000000..e17f817 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/RecallEvaluator.java @@ -0,0 +1,181 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.executor.JdbcExecutor; +import org.polypheny.simpleclient.query.QueryBuilder; + + +/** + * Measures recall@k for an approximate vector index. + * + *
    + *
  1. {@link #captureGroundTruth()} is run while no vector index exists, so the regular query path + * performs an exact nearest-neighbor search. The true top-k ids of every query are + * written to the ground-truth file.
  2. + *
  3. The index is created.
  4. + *
  5. {@link #evaluate()} reruns the exact same queries, now answered approximately via the + * index, and computes recall = |returned \intersect ground_truth| / k averaged over all queries.
  6. + *
+ * + *

Determinism relies on the supplied {@link QueryBuilder} being freshly seeded with the same query seed + * in both phases, so {@code getNewQuery()} yields the identical sequence of query vectors. + */ +@Slf4j +public class RecallEvaluator { + + public static final String DEFAULT_GROUND_TRUTH_FILE = "recall-groundtruth.csv"; + + private final VectorBenchConfig config; + private final JdbcExecutor executor; + private final QueryBuilder knnBuilder; + private final String groundTruthFile; + + + public RecallEvaluator( VectorBenchConfig config, JdbcExecutor executor, QueryBuilder knnBuilder, String groundTruthFile ) { + this.config = config; + this.executor = executor; + this.knnBuilder = knnBuilder; + this.groundTruthFile = groundTruthFile; + } + + + /** + * Runs the query set against the table and records the exact top-k ids of each query, returning + * the result in memory. + */ + public List> captureGroundTruthInMemory() { + int n = config.numberOfRecallQueries; + List> groundTruth = new ArrayList<>( n ); + try { + for ( int i = 0; i < n; i++ ) { + groundTruth.add( new HashSet<>( executor.executeQueryAndGetIds( knnBuilder.getNewQuery() ) ) ); + if ( ( i + 1 ) % 100 == 0 ) { + log.info( "Ground truth progress: {}/{}", i + 1, n ); + } + } + } catch ( ExecutorException e ) { + throw new RuntimeException( "Exception while capturing ground truth", e ); + } + return groundTruth; + } + + + /** + * Runs the query set against the table and records the exact top-k ids of each query to the + * ground-truth file (used by the standalone CLI tasks). + */ + public void captureGroundTruth() { + List> groundTruth = captureGroundTruthInMemory(); + try ( BufferedWriter writer = new BufferedWriter( new FileWriter( groundTruthFile ) ) ) { + for ( Set ids : groundTruth ) { + writer.write( ids.stream().map( String::valueOf ).collect( Collectors.joining( "," ) ) ); + writer.newLine(); + } + } catch ( IOException e ) { + throw new RuntimeException( "Could not write ground-truth file " + groundTruthFile, e ); + } + log.info( "Ground truth written to {}", groundTruthFile ); + } + + + /** + * Reruns the query set against the indexed table and compares each result to the stored ground truth. + * + * @return the mean recall@k over all queries. + */ + public double evaluate() { + return evaluate( readGroundTruth() ); + } + + + /** + * Reruns the query set against the indexed table and compares each result to the supplied ground truth. + * + * @return the mean recall@k over all queries. + */ + public double evaluate( List> groundTruth ) { + int n = Math.min( groundTruth.size(), config.numberOfRecallQueries ); + log.info( "Evaluating recall@{} over {} queries...", config.limitKnnQueries, n ); + + double recallSum = 0.0; + int counted = 0; + try { + for ( int i = 0; i < n; i++ ) { + Set expected = groundTruth.get( i ); + List returned = executor.executeQueryAndGetIds( knnBuilder.getNewQuery() ); + if ( expected.isEmpty() ) { + continue; + } + long hits = returned.stream().filter( expected::contains ).distinct().count(); + recallSum += (double) hits / expected.size(); + counted++; + if ( counted % 100 == 0 ) { + log.info( "Recall progress: {}/{}", counted, n ); + } + } + } catch ( ExecutorException e ) { + throw new RuntimeException( "Exception while evaluating recall", e ); + } + + double meanRecall = counted == 0 ? 0.0 : recallSum / counted; + log.info( "Mean recall@{} over {} queries: {}", config.limitKnnQueries, counted, meanRecall ); + return meanRecall; + } + + + private List> readGroundTruth() { + List> groundTruth = new ArrayList<>(); + try ( BufferedReader reader = new BufferedReader( new FileReader( groundTruthFile ) ) ) { + String line; + while ( ( line = reader.readLine() ) != null ) { + Set ids = new HashSet<>(); + if ( !line.isBlank() ) { + for ( String part : line.split( "," ) ) { + ids.add( Long.parseLong( part.trim() ) ); + } + } + groundTruth.add( ids ); + } + } catch ( IOException e ) { + throw new RuntimeException( "Could not read ground-truth file " + groundTruthFile + + ". Run the 'groundtruth' task (before creating the index) first.", e ); + } + return groundTruth; + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index d2b2ab8..2352e07 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -28,13 +28,16 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Properties; import java.util.Random; +import java.util.Set; import java.util.Vector; import lombok.extern.slf4j.Slf4j; import org.polypheny.simpleclient.QueryMode; import org.polypheny.simpleclient.executor.Executor; import org.polypheny.simpleclient.executor.Executor.DatabaseInstance; import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.executor.JdbcExecutor; import org.polypheny.simpleclient.main.CsvWriter; import org.polypheny.simpleclient.main.ProgressReporter; import org.polypheny.simpleclient.query.Query; @@ -48,6 +51,7 @@ import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateIntFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateMetadata; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateRealFeatureIndex; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.MetadataKnnIntFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.MetadataKnnRealCrossJoin; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.MetadataKnnRealFeature; @@ -63,6 +67,9 @@ public class VectorBench extends PolyphenyScenario { private final VectorBenchConfig config; + // Exact top-k ids captured during data generation; consumed by analyze() to compute recall@k. + private List> recallGroundTruth; + public VectorBench(Executor.ExecutorFactory executorFactory, VectorBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); this.config = config; @@ -101,6 +108,26 @@ public void createSchema( DatabaseInstance databaseInstance, boolean includingKe } + public void createIndex() { + if ( !config.useIndex ) { + return; + } + Executor executor = null; + try { + executor = executorFactory.createExecutorInstance(); + long start = System.nanoTime(); + executor.executeQuery( new CreateRealFeatureIndex( config.dataStoreFeature, config.indexMethod, config.distanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + executor.executeCommit(); + long durationMillis = ( System.nanoTime() - start ) / 1_000_000L; + log.info( "Vector index built in {} ms", durationMillis ); + } catch ( ExecutorException e ) { + throw new RuntimeException( "Exception while creating vector index", e ); + } finally { + commitAndCloseExecutor( executor ); + } + } + + @Override public void generateData( DatabaseInstance databaseInstance, ProgressReporter progressReporter ) { log.info( "Generating data..." ); @@ -117,6 +144,33 @@ public void generateData( DatabaseInstance databaseInstance, ProgressReporter pr } finally { commitAndCloseExecutor( executor1 ); } + + // 1. extract ground truth + // 2. create index + // 3. warmup/execute/analyze + if ( databaseInstance != null && config.useIndex ) { + recallGroundTruth = captureRecallGroundTruth(); + createIndex(); + } + } + + + private QueryBuilder recallKnnBuilder() { + return new SimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + } + + + private List> captureRecallGroundTruth() { + JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); + try { + return new RecallEvaluator( config, executor, recallKnnBuilder(), RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ).captureGroundTruthInMemory(); + } finally { + try { + executor.closeConnection(); + } catch ( ExecutorException e ) { + log.error( "Error while closing connection", e ); + } + } } @@ -198,7 +252,7 @@ public void warmUp( ProgressReporter progressReporter ) { if ( config.numberOfSimpleKnnBooleanFeatureQueries > 0 ) { executor.executeQuery( simpleKnnBooleanFeature.getNewQuery() ); } - if ( config.numberOfSimpleKnnRealFeatureFilteredQueries > 0 ) { + if ( config.numberOfSimpleKnnBooleanFeatureFilteredQueries > 0 ) { executor.executeQuery( simpleKnnBooleanFeatureFiltered.getNewQuery() ); } } catch ( ExecutorException e ) { @@ -215,6 +269,25 @@ public void warmUp( ProgressReporter progressReporter ) { } + @Override + public void analyze( Properties properties, File outputDirectory ) { + super.analyze( properties, outputDirectory ); + if ( config.useIndex && recallGroundTruth != null ) { + JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); + try { + double recall = new RecallEvaluator( config, executor, recallKnnBuilder(), RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ).evaluate( recallGroundTruth ); + properties.put( "recall@" + config.limitKnnQueries, recall ); + } finally { + try { + executor.closeConnection(); + } catch ( ExecutorException e ) { + log.error( "Error while closing connection", e ); + } + } + } + } + + @Override public int getNumberOfInsertThreads() { return 1; From ab40958b3fb295864363c89cac4a04f277813b86 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 1 Jun 2026 10:11:52 +0200 Subject: [PATCH 23/38] Extend property parameters --- .../vectorbench/VectorBenchConfig.java | 38 ++++++++++++++ .../scenario/vectorbench/vector.properties | 51 +++++++++++++++---- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index c0ca448..b48479d 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -35,6 +35,8 @@ @Slf4j public class VectorBenchConfig extends AbstractConfig { + public String mode; + public String dataStoreFeature; public String dataStoreMetadata; @@ -67,10 +69,23 @@ public class VectorBenchConfig extends AbstractConfig { public String distanceNorm; public String booleanDistanceNorm; + public boolean useIndex; + public String indexMethod; + public int indexM; + public int indexEfConstruction; + public int indexLists; + + // Query-time index parameters (pgvector, applied on the direct-postgres path only) + public int queryEfSearch; + public int queryProbes; + + public int numberOfRecallQueries; + public VectorBenchConfig(Properties properties, int multiplier ) { super( "knnBench", "polypheny-jdbc", properties ); + mode = getStringProperty( properties, "mode" ); dataStoreFeature = getStringProperty( properties,"dataStoreFeature" ); dataStoreMetadata = getStringProperty( properties, "dataStoreMeta" ); @@ -110,15 +125,26 @@ public VectorBenchConfig(Properties properties, int multiplier ) { numberOfSimpleKnnRealFeatureFilteredQueries = getIntProperty( properties, "numberOfSimpleKnnRealFeatureFilteredQueries" ) * multiplier; numberOfSimpleKnnBooleanFeatureQueries = getIntProperty( properties, "numberOfSimpleKnnBooleanFeatureQueries" ) * multiplier; numberOfSimpleKnnBooleanFeatureFilteredQueries = getIntProperty( properties, "numberOfSimpleKnnBooleanFeatureFilteredQueries" ) * multiplier; + limitKnnQueries = getIntProperty( properties, "limitKnnQueries" ); distanceNorm = getStringProperty( properties, "distanceNorm" ); booleanDistanceNorm = getStringProperty( properties, "booleanDistanceNorm" ); + + useIndex = getBooleanProperty( properties, "useIndex" ); + indexMethod = getStringProperty( properties, "indexMethod" ); + indexM = getIntProperty( properties, "indexM" ); + indexEfConstruction = getIntProperty( properties, "indexEfConstruction" ); + indexLists = getIntProperty( properties, "indexLists" ); + queryEfSearch = getIntProperty( properties, "queryEfSearch" ); + queryProbes = getIntProperty( properties, "queryProbes" ); + numberOfRecallQueries = getIntProperty( properties, "numberOfRecallQueries" ); } public VectorBenchConfig(Map cdl ) { super( "gavel", cdl.get( "store" ), cdl ); + mode = cdlGetOrDefault( cdl, "mode", "polypheny" ); dataStoreFeature = cdl.get( "dataStoreFeature" ); dataStoreMetadata = cdl.get( "dataStoreMetadata" ); if ( dataStoreFeature.equals( dataStoreMetadata ) ) { @@ -158,6 +184,18 @@ public VectorBenchConfig(Map cdl ) { // numberOfCombinedQueries = getIntProperty( properties, "numberOfCombinedQueries" ) * multiplier; limitKnnQueries = Integer.parseInt( cdl.get( "limitKnnQueries" ) ); distanceNorm = cdl.get( "distanceNorm" ).trim(); + booleanDistanceNorm = cdl.get( "booleanDistanceNorm" ).trim(); + postgresHost = cdlGetOrDefault( cdl, "postgresHost", "127.0.0.1" ); + + useIndex = Boolean.parseBoolean( cdlGetOrDefault( cdl, "useIndex", "false" ) ); + indexMethod = cdlGetOrDefault( cdl, "indexMethod", "hnsw" ); + indexM = Integer.parseInt( cdlGetOrDefault( cdl, "indexM", "16" ) ); + indexEfConstruction = Integer.parseInt( cdlGetOrDefault( cdl, "indexEfConstruction", "64" ) ); + indexLists = Integer.parseInt( cdlGetOrDefault( cdl, "indexLists", "100" ) ); + queryEfSearch = Integer.parseInt( cdlGetOrDefault( cdl, "queryEfSearch", "40" ) ); + queryProbes = Integer.parseInt( cdlGetOrDefault( cdl, "queryProbes", "1" ) ); + + numberOfRecallQueries = Integer.parseInt( cdlGetOrDefault( cdl, "numberOfRecallQueries", "100" ) ); } diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index b6c2463..3f73b6d 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -1,11 +1,36 @@ scenario = "vectorBench" +# Execution of queries on: polypheny | postgres +mode = postgres + dataStoreFeature = postgresql1 dataStoreMeta = hsqldb -useIndex = false +# False -> Does not create index +useIndex = true + +# Query-time index parameters (direct-postgres path only, ignored on the Polypheny path). +# --------------------------------------------------------------------------------------- +# Applied via ALTER DATABASE when the index is built. Higher = better recall but slower. +# HNSW dynamic candidate list (pgvector default 40) +queryEfSearch = 40 +# IVFFlat number of probes (pgvector default 1) +queryProbes = 1 +# --------------------------------------------------------------------------------------- + +# Vector index settings, hnsw or ivfflat +indexMethod = hnsw +# Only used for HNSW index +indexM = 16 +indexEfConstruction = 64 +# Only used for IVFFlat index +indexLists = 100 + +# Number of sampled query vectors used to compute recall@k +numberOfRecallQueries = 100 # PostgreSQL direct connect settings +# Used when mode = postgres postgresHost = 127.0.0.1 numberOfThreads = 4 @@ -13,7 +38,8 @@ progressReportBase = 100 numberOfWarmUpIterations = 4 # Seeds -useRandomSeeds = true +# Note that when running using CLI and doing an index recall this should be turned off +useRandomSeeds = false randomSeedInsert = 46891971806236 randomSeedQuery = 196033374268 @@ -23,21 +49,28 @@ batchSizeQueries = 10 # Numbers of queries numberOfEntries = 100000 + +# Int (no vector mapping) numberOfSimpleKnnIntFeatureQueries = 0 -numberOfSimpleKnnRealFeatureQueries = 0 -numberOfSimpleMetadataQueries = 10 numberOfSimpleKnnIdIntFeatureQueries = 0 -numberOfSimpleKnnIdRealFeatureQueries = 0 numberOfMetadataKnnIntFeatureQueries = 0 + +numberOfSimpleMetadataQueries = 10 + +# Real (float vector mapping) +numberOfSimpleKnnRealFeatureQueries = 0 +numberOfSimpleKnnIdRealFeatureQueries = 0 numberOfMetadataKnnRealFeatureQueries = 0 numberOfSimpleKnnRealCrossJoinQueries = 10 numberOfMetadataKnnRealCrossJoinQueries = 10 -numberOfSimpleKnnRealFeatureFilteredQueries = 10 -numberOfSimpleKnnBooleanFeatureFilteredQueries = 10 -numberOfSimpleKnnBooleanFeatureQueries = 10 +numberOfSimpleKnnRealFeatureFilteredQueries = 0 + +# Boolean (bit vector mapping) +numberOfSimpleKnnBooleanFeatureFilteredQueries = 0 +numberOfSimpleKnnBooleanFeatureQueries = 0 limitKnnQueries = 10 -distanceNorm = COSINE +distanceNorm = L2 booleanDistanceNorm = HAMMING From e68ebe8ecc1b51d8234e645713423f40b88c614b Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 1 Jun 2026 10:24:55 +0200 Subject: [PATCH 24/38] Add Chronos vectorbench case and helper method in JdbcExecutor --- .../simpleclient/executor/JdbcExecutor.java | 20 +++++++++++++++++++ .../simpleclient/main/ChronosAgent.java | 11 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java index 1acd743..cca0482 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java @@ -108,6 +108,9 @@ public long executeQuery( Query query ) throws ExecutorException { case ARRAY_REAL: preparedStatement.setArray( entry.getKey(), connection.createArrayOf( "REAL", (Object[]) entry.getValue().right ) ); break; + case ARRAY_BOOLEAN: + preparedStatement.setArray( entry.getKey(), connection.createArrayOf( "BOOLEAN", (Object[]) entry.getValue().right ) ); + break; case BYTE_ARRAY: preparedStatement.setBytes( entry.getKey(), (byte[]) entry.getValue().right ); break; @@ -156,6 +159,23 @@ public long executeQuery( Query query ) throws ExecutorException { } + /** + * Executes the given query and returns the values of the first column of the result set (e.g. the ids of a + * top-k nearest-neighbor query). Used for recall measurement where the actual returned rows are needed. + */ + public List executeQueryAndGetIds( Query query ) throws ExecutorException { + List ids = new ArrayList<>(); + try ( ResultSet resultSet = executeStatement.executeQuery( query.getSql() ) ) { + while ( resultSet.next() ) { + ids.add( resultSet.getLong( 1 ) ); + } + } catch ( SQLException e ) { + throw new ExecutorException( e ); + } + return ids; + } + + @Override public long executeQueryAndGetNumber( Query query ) throws ExecutorException { try { diff --git a/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java b/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java index e9ace38..8d2c700 100644 --- a/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java +++ b/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java @@ -83,6 +83,9 @@ import org.polypheny.simpleclient.scenario.graph.GraphBenchConfig; import org.polypheny.simpleclient.scenario.knnbench.KnnBench; import org.polypheny.simpleclient.scenario.knnbench.KnnBenchConfig; + import org.polypheny.simpleclient.scenario.vectorbench.PgVectorBench; +import org.polypheny.simpleclient.scenario.vectorbench.VectorBench; +import org.polypheny.simpleclient.scenario.vectorbench.VectorBenchConfig; import org.polypheny.simpleclient.scenario.multibench.MultiBench; import org.polypheny.simpleclient.scenario.multibench.MultiBenchConfig; import org.polypheny.simpleclient.scenario.multimedia.MultimediaBench; @@ -253,6 +256,14 @@ protected Object prepare( ChronosJob chronosJob, final File inputDirectory, fina config = new KnnBenchConfig( parsedConfig ); scenario = new KnnBench( executorFactory, (KnnBenchConfig) config, true, dumpQueryList ); break; + case "vectorBench": + config = new VectorBenchConfig( parsedConfig ); + if ( config.system.equals( "postgres" ) ) { + scenario = new PgVectorBench( executorFactory, (VectorBenchConfig) config, true, dumpQueryList ); + } else { + scenario = new VectorBench( executorFactory, (VectorBenchConfig) config, true, dumpQueryList ); + } + break; case "multimedia": config = new MultimediaConfig( parsedConfig ); scenario = new MultimediaBench( executorFactory, (MultimediaConfig) config, true, dumpQueryList ); From ef78c9a9cc8b53d47f4413eda38ae46272a37ab1 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 1 Jun 2026 10:25:36 +0200 Subject: [PATCH 25/38] Add recall-groundtruth.csv to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 39794b5..b256f57 100644 --- a/.gitignore +++ b/.gitignore @@ -257,8 +257,9 @@ nbdist/ !/libs/PolySqlParser-1.0.jar /results.csv +/recall-groundtruth.csv # humble video libraries libhumblevideo-0.dll libhumblevideo.dylib -libhumblevideo.so \ No newline at end of file +libhumblevideo.so From 0d4ffedf6b1f765ad7a57469fed64b8c7725e5d1 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 1 Jun 2026 17:27:42 +0200 Subject: [PATCH 26/38] Adjust Chronos vectorbench workflows to ignore recall --- .../scenario/vectorbench/PgVectorBench.java | 49 +------------------ .../scenario/vectorbench/VectorBench.java | 49 +------------------ 2 files changed, 2 insertions(+), 96 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java index 0d7c49b..91ac635 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java @@ -29,7 +29,6 @@ import org.polypheny.simpleclient.executor.Executor; import org.polypheny.simpleclient.executor.Executor.DatabaseInstance; import org.polypheny.simpleclient.executor.ExecutorException; -import org.polypheny.simpleclient.executor.JdbcExecutor; import org.polypheny.simpleclient.main.CsvWriter; import org.polypheny.simpleclient.main.ProgressReporter; import org.polypheny.simpleclient.query.Query; @@ -45,9 +44,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.Properties; import java.util.Random; -import java.util.Set; import java.util.Vector; @@ -56,9 +53,6 @@ public class PgVectorBench extends PolyphenyScenario { private final VectorBenchConfig config; - // Exact top-k ids captured during data generation; consumed by analyze() to compute recall@k. - private List> recallGroundTruth; - public PgVectorBench( Executor.ExecutorFactory executorFactory, VectorBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { @@ -123,54 +117,13 @@ public void generateData( DatabaseInstance databaseInstance, ProgressReporter pr commitAndCloseExecutor( executor ); } - // 1. extract ground truth - // 2. create index - // 3. warmup/execute/analyze + // Build the index for the benchmark run (Chronos has no separate index task). if ( databaseInstance != null && config.useIndex ) { - recallGroundTruth = captureRecallGroundTruth(); createIndex(); } } - private QueryBuilder recallKnnBuilder() { - return new PgSimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); - } - - - private List> captureRecallGroundTruth() { - JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); - try { - return new RecallEvaluator( config, executor, recallKnnBuilder(), RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ).captureGroundTruthInMemory(); - } finally { - try { - executor.closeConnection(); - } catch ( ExecutorException e ) { - log.error( "Error while closing connection", e ); - } - } - } - - - @Override - public void analyze( Properties properties, File outputDirectory ) { - super.analyze( properties, outputDirectory ); - if ( config.useIndex && recallGroundTruth != null ) { - JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); - try { - double recall = new RecallEvaluator( config, executor, recallKnnBuilder(), RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ).evaluate( recallGroundTruth ); - properties.put( "recall@" + config.limitKnnQueries, recall ); - } finally { - try { - executor.closeConnection(); - } catch ( ExecutorException e ) { - log.error( "Error while closing connection", e ); - } - } - } - } - - @Override public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, File outputDirectory, int numberOfThreads ) { log.info( "Preparing query list..." ); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index 2352e07..0141d3d 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -28,16 +28,13 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.Properties; import java.util.Random; -import java.util.Set; import java.util.Vector; import lombok.extern.slf4j.Slf4j; import org.polypheny.simpleclient.QueryMode; import org.polypheny.simpleclient.executor.Executor; import org.polypheny.simpleclient.executor.Executor.DatabaseInstance; import org.polypheny.simpleclient.executor.ExecutorException; -import org.polypheny.simpleclient.executor.JdbcExecutor; import org.polypheny.simpleclient.main.CsvWriter; import org.polypheny.simpleclient.main.ProgressReporter; import org.polypheny.simpleclient.query.Query; @@ -67,9 +64,6 @@ public class VectorBench extends PolyphenyScenario { private final VectorBenchConfig config; - // Exact top-k ids captured during data generation; consumed by analyze() to compute recall@k. - private List> recallGroundTruth; - public VectorBench(Executor.ExecutorFactory executorFactory, VectorBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); this.config = config; @@ -145,35 +139,13 @@ public void generateData( DatabaseInstance databaseInstance, ProgressReporter pr commitAndCloseExecutor( executor1 ); } - // 1. extract ground truth - // 2. create index - // 3. warmup/execute/analyze + // Build the index for the benchmark run (Chronos has no separate index task). if ( databaseInstance != null && config.useIndex ) { - recallGroundTruth = captureRecallGroundTruth(); createIndex(); } } - private QueryBuilder recallKnnBuilder() { - return new SimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); - } - - - private List> captureRecallGroundTruth() { - JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); - try { - return new RecallEvaluator( config, executor, recallKnnBuilder(), RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ).captureGroundTruthInMemory(); - } finally { - try { - executor.closeConnection(); - } catch ( ExecutorException e ) { - log.error( "Error while closing connection", e ); - } - } - } - - @Override public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, File outputDirectory, int numberOfThreads ) { log.info( "Preparing query list for the benchmark..." ); @@ -269,25 +241,6 @@ public void warmUp( ProgressReporter progressReporter ) { } - @Override - public void analyze( Properties properties, File outputDirectory ) { - super.analyze( properties, outputDirectory ); - if ( config.useIndex && recallGroundTruth != null ) { - JdbcExecutor executor = (JdbcExecutor) executorFactory.createExecutorInstance(); - try { - double recall = new RecallEvaluator( config, executor, recallKnnBuilder(), RecallEvaluator.DEFAULT_GROUND_TRUTH_FILE ).evaluate( recallGroundTruth ); - properties.put( "recall@" + config.limitKnnQueries, recall ); - } finally { - try { - executor.closeConnection(); - } catch ( ExecutorException e ) { - log.error( "Error while closing connection", e ); - } - } - } - } - - @Override public int getNumberOfInsertThreads() { return 1; From 32991ad979034c1014b6a56d206b10b4614bd61f Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 1 Jun 2026 17:28:52 +0200 Subject: [PATCH 27/38] Change postgres image in ChronosAgent --- src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java b/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java index 8d2c700..dad1474 100644 --- a/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java +++ b/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java @@ -221,7 +221,7 @@ protected Object prepare( ChronosJob chronosJob, final File inputDirectory, fina executorFactory = new SurrealDBExecutorFactory( ChronosCommand.hostname, "8989", true ); break; case "postgres": - dockerContainerName = DockerLauncher.launch( "postgres", "polypheny/postgres:latest", Map.of( "POSTGRES_PASSWORD", "postgres" ), List.of( 5432 ), () -> PostgresInstance.tryConnect( ChronosCommand.hostname ) ); + dockerContainerName = DockerLauncher.launch( "postgres", "polypheny/postgres-pgvector-postgis:17-debian", Map.of( "POSTGRES_PASSWORD", "postgres" ), List.of( 5432 ), () -> PostgresInstance.tryConnect( ChronosCommand.hostname ) ); executorFactory = new PostgresExecutorFactory( ChronosCommand.hostname, Boolean.parseBoolean( parsedConfig.get( "prepareStatements" ) ) ); break; case "monetdb": From 36444cb523b37099ef539bf6e11e7d333315f5d7 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 1 Jun 2026 17:47:47 +0200 Subject: [PATCH 28/38] Add inner product to metrics and document available metrics in properties --- .../queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java | 1 + .../postgres/dql/PgSimpleKnnRealFeatureFiltered.java | 1 + .../simpleclient/scenario/vectorbench/vector.properties | 2 ++ 3 files changed, 4 insertions(+) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java index b6c7bcc..db438c9 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java @@ -55,6 +55,7 @@ private static String toOperator( String metric ) { case "cosine" -> "<=>"; case "l2" -> "<->"; case "l1" -> "<+>"; + case "ip" -> "<#>"; default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); }; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java index 7229d5d..d0d9baa 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java @@ -58,6 +58,7 @@ private static String toOperator( String metric ) { case "cosine" -> "<=>"; case "l2" -> "<->"; case "l1" -> "<+>"; + case "ip" -> "<#>"; default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); }; } diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index 3f73b6d..a0c4d40 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -71,6 +71,8 @@ numberOfSimpleKnnBooleanFeatureQueries = 0 limitKnnQueries = 10 +# L1, L2, COSINE, IP distanceNorm = L2 +# HAMMING, JACCARD booleanDistanceNorm = HAMMING From 329e27e7695e6e54afda75ec279026c877c64e78 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Wed, 3 Jun 2026 18:07:13 +0200 Subject: [PATCH 29/38] Use dynamic adapter names --- .../scenario/vectorbench/VectorBench.java | 31 ++++++++++++------- .../scenario/vectorbench/vector.properties | 4 +-- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index 0141d3d..605345f 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -63,6 +63,8 @@ public class VectorBench extends PolyphenyScenario { private final VectorBenchConfig config; + private String featureStore; + private String metadataStore; public VectorBench(Executor.ExecutorFactory executorFactory, VectorBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); @@ -86,14 +88,16 @@ public void createSchema( DatabaseInstance databaseInstance, boolean includingKe } } + resolveStores( databaseInstance ); + log.info( "Creating schema..." ); Executor executor = null; try { executor = executorFactory.createExecutorInstance(); - executor.executeQuery( (new CreateMetadata( config.dataStoreMetadata )).getNewQuery() ); - executor.executeQuery( (new CreateIntFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() ); - executor.executeQuery( (new CreateRealFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() ); - executor.executeQuery( (new CreateBooleanFeature( config.dataStoreFeature, config.dimensionFeatureVectors )).getNewQuery() ); + executor.executeQuery( (new CreateMetadata( metadataStore )).getNewQuery() ); + executor.executeQuery( (new CreateIntFeature( featureStore , config.dimensionFeatureVectors )).getNewQuery() ); + executor.executeQuery( (new CreateRealFeature( featureStore , config.dimensionFeatureVectors )).getNewQuery() ); + executor.executeQuery( (new CreateBooleanFeature( featureStore, config.dimensionFeatureVectors )).getNewQuery() ); } catch (ExecutorException e ) { throw new RuntimeException( "Exception while creating schema", e ); } finally { @@ -110,7 +114,7 @@ public void createIndex() { try { executor = executorFactory.createExecutorInstance(); long start = System.nanoTime(); - executor.executeQuery( new CreateRealFeatureIndex( config.dataStoreFeature, config.indexMethod, config.distanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + executor.executeQuery( new CreateRealFeatureIndex( featureStore, config.indexMethod, config.distanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); executor.executeCommit(); long durationMillis = ( System.nanoTime() - start ) / 1_000_000L; log.info( "Vector index built in {} ms", durationMillis ); @@ -125,6 +129,7 @@ public void createIndex() { @Override public void generateData( DatabaseInstance databaseInstance, ProgressReporter progressReporter ) { log.info( "Generating data..." ); + resolveStores( databaseInstance ); Executor executor1 = executorFactory.createExecutorInstance(); DataGenerator dataGenerator = new DataGenerator( executor1, config, progressReporter ); @@ -153,7 +158,6 @@ public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, Fil addNumberOfTimes( queryList, new SimpleKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIntFeatureQueries ); addNumberOfTimes( queryList, new SimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnRealFeatureQueries ); addNumberOfTimes( queryList, new SimpleMetadata( config.randomSeedQuery, config.numberOfEntries ), config.numberOfSimpleMetadataQueries ); -// addNumberOfTimes( queryList, new SimpleKnnIdIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIdIntFeatureQueries ); addNumberOfTimes( queryList, new SimpleKnnIdRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIdRealFeatureQueries ); addNumberOfTimes( queryList, new MetadataKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnIntFeatureQueries ); addNumberOfTimes( queryList, new MetadataKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnRealFeatureQueries ); @@ -175,7 +179,6 @@ public void warmUp( ProgressReporter progressReporter ) { SimpleKnnIntFeature simpleKnnIntFeatureBuilder = new SimpleKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); SimpleKnnRealFeature simpleKnnRealFeatureBuilder = new SimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); SimpleMetadata simpleMetadataBuilder = new SimpleMetadata( config.randomSeedQuery, config.numberOfEntries ); -// SimpleKnnIdIntFeature simpleKnnIdIntFeatureBuilder = new SimpleKnnIdIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); SimpleKnnIdRealFeature simpleKnnIdRealFeatureBuilder = new SimpleKnnIdRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); MetadataKnnIntFeature metadataKnnIntFeature = new MetadataKnnIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); MetadataKnnRealFeature metadataKnnRealFeature = new MetadataKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); @@ -195,14 +198,9 @@ public void warmUp( ProgressReporter progressReporter ) { if ( config.numberOfSimpleKnnRealFeatureQueries > 0 ) { executor.executeQuery( simpleKnnRealFeatureBuilder.getNewQuery() ); } - if ( config.numberOfSimpleMetadataQueries > 0 ) { executor.executeQuery( simpleMetadataBuilder.getNewQuery() ); } - -// if ( config.numberOfSimpleKnnIdIntFeatureQueries > 0 ) { -// executor.executeQuery( simpleKnnIdIntFeatureBuilder.getNewQuery() ); -// } if ( config.numberOfSimpleKnnIdRealFeatureQueries > 0 ) { executor.executeQuery( simpleKnnIdRealFeatureBuilder.getNewQuery() ); } @@ -256,4 +254,13 @@ private void addNumberOfTimes( List list, QueryBuilder queryBuil } } + + private void resolveStores( DatabaseInstance databaseInstance ) { + if ( databaseInstance != null ) { + featureStore = findMatchingDataStoreName( config.dataStoreFeature ); + metadataStore = findMatchingDataStoreName( config.dataStoreMetadata ); + } + } + + } diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index a0c4d40..ff2c616 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -1,9 +1,9 @@ scenario = "vectorBench" # Execution of queries on: polypheny | postgres -mode = postgres +mode = polypheny -dataStoreFeature = postgresql1 +dataStoreFeature = postgresql dataStoreMeta = hsqldb # False -> Does not create index From 1df1de6d8c134286173ab231abf950a698878473 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Thu, 4 Jun 2026 12:16:38 +0200 Subject: [PATCH 30/38] Enable postgres image variant injection --- .../simpleclient/executor/PolyphenyDbExecutor.java | 9 +++++++-- .../polypheny/simpleclient/scenario/AbstractConfig.java | 9 +++++++++ .../simpleclient/scenario/vectorbench/vector.properties | 5 ++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbExecutor.java index b4ff1ae..419619e 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbExecutor.java @@ -122,13 +122,18 @@ default String deployMonetDb( boolean deployStoresUsingDocker ) throws ExecutorE default String deployPostgres( boolean deployStoresUsingDocker ) throws ExecutorException { + return deployPostgres( deployStoresUsingDocker, "pgvector & PostGIS" ); + } + + + default String deployPostgres( boolean deployStoresUsingDocker, String imageVariant ) throws ExecutorException { String config; String name; if ( deployStoresUsingDocker ) { name = "postgres" + storeCounter.getAndIncrement(); if ( PolyphenyVersionSwitch.getInstance().useNewAdapterDeployParameters ) { int dockerInstanceId = getDockerInstanceId(); - config = "{\"mode\":\"docker\",\"instanceId\":\"" + dockerInstanceId + "\",\"maxConnections\":\"25\"}"; + config = "{\"mode\":\"docker\",\"instanceId\":\"" + dockerInstanceId + "\",\"maxConnections\":\"25\",\"imageVariant\":\"" + imageVariant + "\"}"; } else { config = "{\"port\":\"" + nextPort.getAndIncrement() + "\",\"maxConnections\":\"25\",\"password\":\"postgres\",\"mode\":\"docker\",\"instanceId\":\"0\"}"; } @@ -345,7 +350,7 @@ public PolyphenyDbInstance( PolyphenyControlConnector polyphenyControlConnector, if ( !config.deployStoresUsingDocker ) { PostgresInstance.reset(); } - executor.deployPostgres( config.deployStoresUsingDocker ); + executor.deployPostgres( config.deployStoresUsingDocker, config.postgresImageVariant ); break; case "monetdb": if ( !config.deployStoresUsingDocker ) { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/AbstractConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/AbstractConfig.java index fc3575e..cc44cff 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/AbstractConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/AbstractConfig.java @@ -70,6 +70,7 @@ public abstract class AbstractConfig { public final boolean workloadMonitoringWarmup; public final int progressReportBase = 100; + public final String postgresImageVariant; protected AbstractConfig( String scenario, String system, Properties properties ) { @@ -103,6 +104,7 @@ protected AbstractConfig( String scenario, String system, Properties properties workloadMonitoringExecutingWorkload = false; workloadMonitoringLoadingData = true; workloadMonitoringWarmup = true; + postgresImageVariant = getStringPropertyOrDefault( properties, "postgresImageVariant", "pgvector & PostGIS" ); // This is hacky but ensures that VersionSwitch is initialized when running tasks from CLI. PolyphenyVersionSwitch.initialize( this ); @@ -150,6 +152,7 @@ protected AbstractConfig( String scenario, String system, Map cd workloadMonitoringExecutingWorkload = Boolean.parseBoolean( cdlGetOrDefault( cdl, "workloadMonitoring", "false" ) ); workloadMonitoringLoadingData = Boolean.parseBoolean( cdlGetOrDefault( cdl, "workloadMonitoringLoadingData", "false" ) ); workloadMonitoringWarmup = Boolean.parseBoolean( cdlGetOrDefault( cdl, "workloadMonitoringWarmup", "true" ) ); + postgresImageVariant = cdlGetOrDefault( cdl, "postgresImageVariant", "pgvector & PostGIS" ); } @@ -171,6 +174,12 @@ protected String getStringProperty( Properties properties, String name ) { } + protected String getStringPropertyOrDefault( Properties properties, String name, String defaultName ) { + String str = getProperty( properties, name ); + return str == null ? defaultName : str; + } + + protected int getIntProperty( Properties properties, String name ) { String str = getProperty( properties, name ); if ( str == null ) { diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index ff2c616..fc24cb2 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -6,8 +6,11 @@ mode = polypheny dataStoreFeature = postgresql dataStoreMeta = hsqldb +# Default, pgvector, PostGIS, pgvector & PostGIS +postgresImageVariant = Default + # False -> Does not create index -useIndex = true +useIndex = false # Query-time index parameters (direct-postgres path only, ignored on the Polypheny path). # --------------------------------------------------------------------------------------- From 6093ab59e48d9ac6a3002207a1be1771af126dc6 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Thu, 4 Jun 2026 15:45:33 +0200 Subject: [PATCH 31/38] Add supportsNotNullArray flag --- .../scenario/vectorbench/VectorBench.java | 6 +++--- .../scenario/vectorbench/VectorBenchConfig.java | 5 +++++ .../queryBuilder/ddl/CreateBooleanFeature.java | 13 +++++++++---- .../queryBuilder/ddl/CreateIntFeature.java | 13 +++++++++---- .../queryBuilder/ddl/CreateRealFeature.java | 13 +++++++++---- .../scenario/vectorbench/vector.properties | 4 ++++ 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index 605345f..2bcf714 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -95,9 +95,9 @@ public void createSchema( DatabaseInstance databaseInstance, boolean includingKe try { executor = executorFactory.createExecutorInstance(); executor.executeQuery( (new CreateMetadata( metadataStore )).getNewQuery() ); - executor.executeQuery( (new CreateIntFeature( featureStore , config.dimensionFeatureVectors )).getNewQuery() ); - executor.executeQuery( (new CreateRealFeature( featureStore , config.dimensionFeatureVectors )).getNewQuery() ); - executor.executeQuery( (new CreateBooleanFeature( featureStore, config.dimensionFeatureVectors )).getNewQuery() ); + executor.executeQuery( (new CreateIntFeature( featureStore , config.dimensionFeatureVectors, config.supportsNotNullArray )).getNewQuery() ); + executor.executeQuery( (new CreateRealFeature( featureStore , config.dimensionFeatureVectors, config.supportsNotNullArray )).getNewQuery() ); + executor.executeQuery( (new CreateBooleanFeature( featureStore, config.dimensionFeatureVectors, config.supportsNotNullArray )).getNewQuery() ); } catch (ExecutorException e ) { throw new RuntimeException( "Exception while creating schema", e ); } finally { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index b48479d..5897386 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -80,6 +80,7 @@ public class VectorBenchConfig extends AbstractConfig { public int queryProbes; public int numberOfRecallQueries; + public boolean supportsNotNullArray; public VectorBenchConfig(Properties properties, int multiplier ) { @@ -88,6 +89,7 @@ public VectorBenchConfig(Properties properties, int multiplier ) { mode = getStringProperty( properties, "mode" ); dataStoreFeature = getStringProperty( properties,"dataStoreFeature" ); dataStoreMetadata = getStringProperty( properties, "dataStoreMeta" ); + supportsNotNullArray = getBooleanProperty( properties, "supportsNotNullArray" ); if ( dataStoreFeature.equals( dataStoreMetadata ) ) { dataStores.add( dataStoreFeature ); @@ -147,6 +149,9 @@ public VectorBenchConfig(Map cdl ) { mode = cdlGetOrDefault( cdl, "mode", "polypheny" ); dataStoreFeature = cdl.get( "dataStoreFeature" ); dataStoreMetadata = cdl.get( "dataStoreMetadata" ); + + supportsNotNullArray = Boolean.parseBoolean( cdl.get( "supportsNotNullArray" ) ); + if ( dataStoreFeature.equals( dataStoreMetadata ) ) { dataStores.add( dataStoreFeature ); } else { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeature.java index 5900f31..9dca802 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeature.java @@ -34,17 +34,19 @@ public class CreateBooleanFeature extends QueryBuilder { private final String store; private final int dimension; + private final boolean supportsNotNullArray; - public CreateBooleanFeature( String store, int dimension ) { + public CreateBooleanFeature( String store, int dimension, boolean supportsNotNullArray ) { this.store = store; this.dimension = dimension; + this.supportsNotNullArray = supportsNotNullArray; } @Override public Query getNewQuery() { - return new CreateBooleanFeatureQuery( store, dimension ); + return new CreateBooleanFeatureQuery( store, dimension, supportsNotNullArray ); } @@ -52,20 +54,23 @@ private static class CreateBooleanFeatureQuery extends Query { private final String store; private final int dimension; + private final boolean supportsNotNullArray; - CreateBooleanFeatureQuery( String store, int dimension ) { + CreateBooleanFeatureQuery( String store, int dimension, boolean supportsNotNullArray ) { super( false ); this.store = store; this.dimension = dimension; + this.supportsNotNullArray = supportsNotNullArray; } @Override public String getSql() { + String elementsNullable = supportsNotNullArray ? " NOT NULL " : " "; String sql = "CREATE TABLE knn_booleanfeature (" + "id INTEGER NOT NULL, " - + "feature BOOLEAN NOT NULL ARRAY(1, " + this.dimension + "), " + + "feature BOOLEAN" + elementsNullable + "ARRAY(1, " + this.dimension + "), " + "category VARCHAR(50), " + "PRIMARY KEY(id))"; if ( this.store != null ) { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateIntFeature.java index bb0aa00..f17320e 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateIntFeature.java @@ -35,17 +35,19 @@ public class CreateIntFeature extends QueryBuilder { private final String store; private final int dimension; + private final boolean supportsNotNullArray; - public CreateIntFeature( String store, int dimension ) { + public CreateIntFeature( String store, int dimension, boolean supportsNotNullArray ) { this.store = store; this.dimension = dimension; + this.supportsNotNullArray = supportsNotNullArray; } @Override public Query getNewQuery() { - return new CreateIntFeatureQuery( store, dimension ); + return new CreateIntFeatureQuery( store, dimension, supportsNotNullArray ); } @@ -53,18 +55,21 @@ private static class CreateIntFeatureQuery extends Query { private final String store; private final int dimension; + private final boolean supportsNotNullArray; - CreateIntFeatureQuery( String store, int dimension ) { + CreateIntFeatureQuery( String store, int dimension, boolean supportsNotNullArray ) { super( false ); this.store = store; this.dimension = dimension; + this.supportsNotNullArray = supportsNotNullArray; } @Override public String getSql() { - String sql = "CREATE TABLE knn_intfeature (id INTEGER NOT NULL, feature INTEGER NOT NULL ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; + String elementsNullable = supportsNotNullArray ? " NOT NULL " : " "; + String sql = "CREATE TABLE knn_intfeature (id INTEGER NOT NULL, feature INTEGER" + elementsNullable + "ARRAY(1, " + this.dimension + "), PRIMARY KEY(id))"; if ( this.store != null ) { sql += " ON STORE \"" + this.store + "\""; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeature.java index f2ea227..d9290d1 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateRealFeature.java @@ -35,17 +35,19 @@ public class CreateRealFeature extends QueryBuilder { private final String store; private final int dimension; + private final boolean supportsNotNullArray; - public CreateRealFeature( String store, int dimension ) { + public CreateRealFeature( String store, int dimension, boolean supportsNotNullArray ) { this.store = store; this.dimension = dimension; + this.supportsNotNullArray = supportsNotNullArray; } @Override public Query getNewQuery() { - return new CreateRealFeatureQuery( store, dimension ); + return new CreateRealFeatureQuery( store, dimension, supportsNotNullArray ); } @@ -53,21 +55,24 @@ private static class CreateRealFeatureQuery extends Query { private final String store; private final int dimension; + private final boolean supportsNotNullArray; - CreateRealFeatureQuery( String store, int dimension ) { + CreateRealFeatureQuery( String store, int dimension, boolean supportsNotNullArray ) { super( false ); this.store = store; this.dimension = dimension; + this.supportsNotNullArray = supportsNotNullArray; } @Override public String getSql() { + String elementsNullable = supportsNotNullArray ? " NOT NULL " : " "; String sql = "CREATE TABLE knn_realfeature (" + "id INTEGER NOT NULL, " + "category VARCHAR(50), " - + "feature REAL NOT NULL ARRAY(1, " + this.dimension + "), " + + "feature REAL" + elementsNullable + "ARRAY(1, " + this.dimension + "), " + "PRIMARY KEY(id))"; if ( this.store != null ) { sql += " ON STORE \"" + this.store + "\""; diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index fc24cb2..f95cfa3 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -9,6 +9,10 @@ dataStoreMeta = hsqldb # Default, pgvector, PostGIS, pgvector & PostGIS postgresImageVariant = Default +# true => DDL: REAL NOT NULL ARRAY(1,3) +# false => DDL: REAL ARRAY(1,3) +supportsNotNullArray=true + # False -> Does not create index useIndex = false From 8eaa0e7c2a979e825d434b2b7aaf362a2237bfb9 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Thu, 4 Jun 2026 19:31:11 +0200 Subject: [PATCH 32/38] Add new QueryBuilders for direct PostgreSQL querying --- .../ddl/CreateBooleanFeatureIndex.java | 123 ++++++++++++++++ .../postgres/ddl/PgCreateBooleanFeature.java | 94 ++++++++++++ .../ddl/PgCreateBooleanFeatureIndex.java | 123 ++++++++++++++++ .../postgres/dml/PgInsertBooleanFeature.java | 138 ++++++++++++++++++ .../dql/PgSimpleKnnBooleanFeature.java | 116 +++++++++++++++ .../PgSimpleKnnBooleanFeatureFiltered.java | 118 +++++++++++++++ .../dql/PgSimpleKnnIdRealFeature.java | 122 ++++++++++++++++ .../dql/PgSimpleKnnRealCrossJoin.java | 104 +++++++++++++ 8 files changed, 938 insertions(+) create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeatureIndex.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateBooleanFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateBooleanFeatureIndex.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dml/PgInsertBooleanFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnBooleanFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnBooleanFeatureFiltered.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnIdRealFeature.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealCrossJoin.java diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeatureIndex.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeatureIndex.java new file mode 100644 index 0000000..1d910dc --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/ddl/CreateBooleanFeatureIndex.java @@ -0,0 +1,123 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl; + +import java.util.Map; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class CreateBooleanFeatureIndex extends QueryBuilder { + + private final String store; + private final String method; + private final String metric; + private final int m; + private final int efConstruction; + private final int lists; + + + public CreateBooleanFeatureIndex( String store, String method, String metric, int m, int efConstruction, int lists ) { + this.store = store; + this.method = method; + this.metric = metric; + this.m = m; + this.efConstruction = efConstruction; + this.lists = lists; + } + + + @Override + public Query getNewQuery() { + return new CreateBooleanFeatureIndexQuery( store, method, metric, m, efConstruction, lists ); + } + + + private static class CreateBooleanFeatureIndexQuery extends Query { + + private final String store; + private final String method; + private final String metric; + private final int m; + private final int efConstruction; + private final int lists; + private final boolean isHnsw; + + + CreateBooleanFeatureIndexQuery( String store, String method, String metric, int m, int efConstruction, int lists ) { + super( false ); + this.store = store; + this.method = method; + this.metric = metric; + this.m = m; + this.efConstruction = efConstruction; + this.lists = lists; + this.isHnsw = method.equals( "hnsw" ); + } + + + @Override + public String getSql() { + String sql = "ALTER TABLE knn_booleanfeature ADD INDEX feature_bool_" + method + + " ON (feature) USING " + method; + if ( store != null ) { + sql += " ON STORE \"" + store + "\""; + } + String params = isHnsw + ? "m=" + m + ", ef_construction=" + efConstruction + : "lists=" + lists; + sql += " WITH (metric='" + metric + "', " + params + ")"; + return sql; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateBooleanFeature.java new file mode 100644 index 0000000..a3c8d0f --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateBooleanFeature.java @@ -0,0 +1,94 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; + +public class PgCreateBooleanFeature extends QueryBuilder { + private final int dimension; + + + public PgCreateBooleanFeature( int dimension ) { + this.dimension = dimension; + } + + + @Override + public Query getNewQuery() { + return new PgCreateBooleanFeatureQuery( dimension ); + } + + + private static class PgCreateBooleanFeatureQuery extends Query { + + private final int dimension; + + + PgCreateBooleanFeatureQuery( int dimension ) { + super( false ); + this.dimension = dimension; + } + + + @Override + public String getSql() { + return "CREATE TABLE knn_booleanfeature (" + + "id INTEGER NOT NULL, " + + "category VARCHAR(50), " + + "feature bit(" + dimension + ") NOT NULL, " + + "PRIMARY KEY (id))"; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateBooleanFeatureIndex.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateBooleanFeatureIndex.java new file mode 100644 index 0000000..ff3563d --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateBooleanFeatureIndex.java @@ -0,0 +1,123 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl; + +import java.util.Map; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class PgCreateBooleanFeatureIndex extends QueryBuilder { + + private final String method; + private final String opClass; + private final int m; + private final int efConstruction; + private final int lists; + + + public PgCreateBooleanFeatureIndex( String method, String metric, int m, int efConstruction, int lists ) { + this.method = method; + this.opClass = toOpClass( metric ); + this.m = m; + this.efConstruction = efConstruction; + this.lists = lists; + } + + + private static String toOpClass( String metric ) { + return switch ( metric.toLowerCase() ) { + case "hamming" -> "bit_hamming_ops"; + case "jaccard" -> "bit_jaccard_ops"; + default -> throw new IllegalArgumentException( "Provided boolean metric is invalid: " + metric ); + }; + } + + + @Override + public Query getNewQuery() { + return new PgCreateBooleanFeatureIndexQuery( method, opClass, m, efConstruction, lists ); + } + + + private static class PgCreateBooleanFeatureIndexQuery extends Query { + + private final String method; + private final String opClass; + private final int m; + private final int efConstruction; + private final int lists; + private final boolean isHnsw; + + + PgCreateBooleanFeatureIndexQuery( String method, String opClass, int m, int efConstruction, int lists ) { + super( false ); + this.method = method; + this.opClass = opClass; + this.m = m; + this.efConstruction = efConstruction; + this.lists = lists; + this.isHnsw = method.equals( "hnsw" ); + } + + + @Override + public String getSql() { + String withClause = isHnsw + ? "(m=" + m + ", ef_construction=" + efConstruction + ")" + : "(lists=" + lists + ")"; + return "CREATE INDEX ON knn_booleanfeature USING " + method + + " (feature " + opClass + ") WITH " + withClause; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dml/PgInsertBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dml/PgInsertBooleanFeature.java new file mode 100644 index 0000000..cdf5e3d --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dml/PgInsertBooleanFeature.java @@ -0,0 +1,138 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dml; + +import com.google.gson.JsonObject; +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +public class PgInsertBooleanFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = false; + private static final AtomicInteger nextId = new AtomicInteger( 1 ); + private static final String[] CATEGORIES = { "cat_A", "cat_B", "cat_C", "cat_D" }; + + private final int dimension; + private final Random random; + + + public PgInsertBooleanFeature( long randomSeed, int dimension ) { + this.dimension = dimension; + this.random = new Random( randomSeed ); + } + + + private String getRandomBits() { + StringBuilder sb = new StringBuilder( dimension ); + for ( int i = 0; i < dimension; i++ ) { + sb.append( random.nextBoolean() ? '1' : '0' ); + } + return sb.toString(); + } + + + @Override + public synchronized BatchableInsert getNewQuery() { + return new PgInsertBooleanFeatureQuery( + nextId.getAndIncrement(), + getRandomBits(), + CATEGORIES[random.nextInt( CATEGORIES.length )] + ); + } + + + private static class PgInsertBooleanFeatureQuery extends BatchableInsert { + + private static final String SQL = "INSERT INTO knn_booleanfeature (id, category, feature) VALUES "; + private final int id; + private final String feature; + private final String category; + + + PgInsertBooleanFeatureQuery( int id, String feature, String category ) { + super( EXPECT_RESULT ); + this.id = id; + this.feature = feature; + this.category = category; + } + + + @Override + public String getSqlRowExpression() { + StringBuilder sb = new StringBuilder( "(" ); + sb.append( id ).append( ", '" ).append( category ).append( "', B'" ).append( feature ).append( "')" ); + return sb.toString(); + } + + + @Override + public String getSql() { + return SQL + getSqlRowExpression(); + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public JsonObject getRestRowExpression() { + return null; + } + + + @Override + public String getEntity() { + return "public.knn_booleanfeature"; + } + + + @Override + public HttpRequest getRest() { + return null; + } + + + @Override + public String getMongoQl() { + return null; + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnBooleanFeature.java new file mode 100644 index 0000000..007407d --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnBooleanFeature.java @@ -0,0 +1,116 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; +import java.util.Random; + + +public class PgSimpleKnnBooleanFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final int dimension; + private final int limit; + private final String operator; + private final Random random; + + + public PgSimpleKnnBooleanFeature( long randomSeed, int dimension, int limit, String booleanDistanceMetric ) { + this.dimension = dimension; + this.limit = limit; + this.random = new Random( randomSeed ); + this.operator = toOperator( booleanDistanceMetric ); + } + + + private static String toOperator( String metric ) { + return switch ( metric.toLowerCase() ) { + case "hamming" -> "<~>"; + case "jaccard" -> "<%>"; + default -> throw new IllegalArgumentException( "Provided boolean metric is invalid: " + metric ); + }; + } + + + private String getRandomBits() { + StringBuilder sb = new StringBuilder( dimension ); + for ( int i = 0; i < dimension; i++ ) { + sb.append( random.nextBoolean() ? '1' : '0' ); + } + return sb.toString(); + } + + + @Override + public synchronized Query getNewQuery() { + return new PgSimpleKnnBooleanFeatureQuery( getRandomBits(), dimension, limit, operator ); + } + + + private static class PgSimpleKnnBooleanFeatureQuery extends Query { + + private final String bits; + private final int dimension; + private final int limit; + private final String operator; + + + PgSimpleKnnBooleanFeatureQuery( String bits, int dimension, int limit, String operator ) { + super( EXPECT_RESULT ); + this.bits = bits; + this.dimension = dimension; + this.limit = limit; + this.operator = operator; + } + + + @Override + public String getSql() { + return "SELECT id, feature " + operator + " '" + bits + "'::bit(" + dimension + ") AS dist " + + "FROM knn_booleanfeature ORDER BY dist ASC LIMIT " + limit; + } + + + @Override + public String getParameterizedSqlQuery() { return null; } + + + @Override + public Map> getParameterValues() { return null; } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { return null; } + } +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnBooleanFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnBooleanFeatureFiltered.java new file mode 100644 index 0000000..abcc864 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnBooleanFeatureFiltered.java @@ -0,0 +1,118 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; +import java.util.Random; + +public class PgSimpleKnnBooleanFeatureFiltered extends QueryBuilder { + private static final boolean EXPECT_RESULT = true; + + private final int dimension; + private final int limit; + private final String operator; + private final String filterCategory; + private final Random random; + + + public PgSimpleKnnBooleanFeatureFiltered( long randomSeed, int dimension, int limit, String booleanDistanceMetric, String filterCategory ) { + this.dimension = dimension; + this.limit = limit; + this.filterCategory = filterCategory; + this.random = new Random( randomSeed ); + this.operator = toOperator( booleanDistanceMetric ); + } + + + private static String toOperator( String metric ) { + return switch ( metric.toLowerCase() ) { + case "hamming" -> "<~>"; + case "jaccard" -> "<%>"; + default -> throw new IllegalArgumentException( "Provided boolean metric is invalid: " + metric ); + }; + } + + + private String getRandomBits() { + StringBuilder sb = new StringBuilder( dimension ); + for ( int i = 0; i < dimension; i++ ) { + sb.append( random.nextBoolean() ? '1' : '0' ); + } + return sb.toString(); + } + + + @Override + public synchronized Query getNewQuery() { + return new PgSimpleKnnBooleanFeatureFilteredQuery( getRandomBits(), dimension, limit, operator, filterCategory ); + } + + + private static class PgSimpleKnnBooleanFeatureFilteredQuery extends Query { + + private final String bits; + private final int dimension; + private final int limit; + private final String operator; + private final String category; + + + PgSimpleKnnBooleanFeatureFilteredQuery( String bits, int dimension, int limit, String operator, String category ) { + super( EXPECT_RESULT ); + this.bits = bits; + this.dimension = dimension; + this.limit = limit; + this.operator = operator; + this.category = category; + } + + + @Override + public String getSql() { + return "SELECT id, feature " + operator + " '" + bits + "'::bit(" + dimension + ") AS dist " + + "FROM knn_booleanfeature WHERE category = '" + category + "' ORDER BY dist ASC LIMIT " + limit; + } + + + @Override + public String getParameterizedSqlQuery() { return null; } + + + @Override + public Map> getParameterValues() { return null; } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { return null; } + } +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnIdRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnIdRealFeature.java new file mode 100644 index 0000000..ebbbbe9 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnIdRealFeature.java @@ -0,0 +1,122 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; +import java.util.Random; + + +public class PgSimpleKnnIdRealFeature extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final int dimension; + private final int limit; + private final String operator; + private final Random random; + + + public PgSimpleKnnIdRealFeature( long randomSeed, int dimension, int limit, String distanceMetric ) { + this.dimension = dimension; + this.limit = limit; + this.random = new Random( randomSeed ); + this.operator = toOperator( distanceMetric ); + } + + + private static String toOperator( String metric ) { + return switch ( metric.toLowerCase() ) { + case "cosine" -> "<=>"; + case "l2" -> "<->"; + case "l1" -> "<+>"; + case "inner_product" -> "<#>"; + default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); + }; + } + + + private Float[] getRandomVector() { + Float[] floats = new Float[dimension]; + for ( int i = 0; i < dimension; i++ ) { + floats[i] = random.nextInt( 100 ) / 100.0f; + } + return floats; + } + + + @Override + public synchronized Query getNewQuery() { + return new PgSimpleKnnIdRealFeatureQuery( getRandomVector(), limit, operator ); + } + + + private static class PgSimpleKnnIdRealFeatureQuery extends Query { + + private final Float[] target; + private final int limit; + private final String operator; + + + PgSimpleKnnIdRealFeatureQuery( Float[] target, int limit, String operator ) { + super( EXPECT_RESULT ); + this.target = target; + this.limit = limit; + this.operator = operator; + } + + + @Override + public String getSql() { + StringBuilder sb = new StringBuilder( "SELECT closest.dist FROM (SELECT id, feature " ); + sb.append( operator ).append( " '[" ); + for ( int i = 0; i < target.length; i++ ) { + if ( i > 0 ) sb.append( "," ); + sb.append( target[i] ); + } + sb.append( "]' AS dist FROM knn_realfeature ORDER BY dist ASC LIMIT " ).append( limit ).append( ") AS closest" ); + return sb.toString(); + } + + + @Override + public String getParameterizedSqlQuery() { return null; } + + + @Override + public Map> getParameterValues() { return null; } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { return null; } + } +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealCrossJoin.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealCrossJoin.java new file mode 100644 index 0000000..6bfb4b3 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealCrossJoin.java @@ -0,0 +1,104 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-2026 The Polypheny Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql; + +import kong.unirest.core.HttpRequest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import java.util.Map; + + +public class PgSimpleKnnRealCrossJoin extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + + private final int limit; + private final String operator; + + + // randomSeed and dimension are accepted for signature parity with the Polypheny-path + // SimpleKnnRealCrossJoin; the cross-join compares against the feature of row id = 1, + // so no random query vector is needed. + public PgSimpleKnnRealCrossJoin( long randomSeed, int dimension, int limit, String distanceMetric ) { + this.limit = limit; + this.operator = toOperator( distanceMetric ); + } + + + private static String toOperator( String metric ) { + return switch ( metric.toLowerCase() ) { + case "cosine" -> "<=>"; + case "l2" -> "<->"; + case "l1" -> "<+>"; + case "inner_product" -> "<#>"; + default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); + }; + } + + + @Override + public synchronized Query getNewQuery() { + return new PgSimpleKnnRealCrossJoinQuery( limit, operator ); + } + + + private static class PgSimpleKnnRealCrossJoinQuery extends Query { + + private final int limit; + private final String operator; + + + PgSimpleKnnRealCrossJoinQuery( int limit, String operator ) { + super( EXPECT_RESULT ); + this.limit = limit; + this.operator = operator; + } + + + @Override + public String getSql() { + return "SELECT t1.id, t1.feature " + operator + " t2.feature AS dist " + + "FROM knn_realfeature t1, knn_realfeature t2 WHERE t2.id = 1 " + + "ORDER BY dist ASC LIMIT " + limit; + } + + + @Override + public String getParameterizedSqlQuery() { return null; } + + + @Override + public Map> getParameterValues() { return null; } + + + @Override + public HttpRequest getRest() { return null; } + + + @Override + public String getMongoQl() { return null; } + } +} From 14e9cd130c330bd2e48bf78746e0afb71a494bf5 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Thu, 4 Jun 2026 19:51:19 +0200 Subject: [PATCH 33/38] Integrate new PostgreSQL QueryBuilders --- .../scenario/vectorbench/PgDataGenerator.java | 12 ++++ .../scenario/vectorbench/PgVectorBench.java | 61 +++++++++++++++++-- .../scenario/vectorbench/VectorBench.java | 29 ++++++++- .../vectorbench/VectorBenchConfig.java | 2 +- 4 files changed, 97 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java index ef949dd..62aa0b7 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java @@ -30,6 +30,7 @@ import org.polypheny.simpleclient.main.ProgressReporter; import org.polypheny.simpleclient.query.BatchableInsert; import org.polypheny.simpleclient.query.RawQuery; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dml.PgInsertBooleanFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dml.PgInsertRealFeature; import java.util.LinkedList; import java.util.List; @@ -65,6 +66,17 @@ void generateRealFeatures() throws ExecutorException { } + void generateBooleanFeatures() throws ExecutorException { + PgInsertBooleanFeature builder = new PgInsertBooleanFeature( config.randomSeedInsert, config.dimensionFeatureVectors ); + for ( int i = 0; i < config.numberOfEntries; i++ ) { + if ( aborted ) break; + addToBatch( builder.getNewQuery() ); + progressReporter.update( 1 ); + } + flushBatch(); + } + + private void addToBatch( BatchableInsert query ) throws ExecutorException { batch.add( query ); if ( batch.size() >= config.batchSizeInserts ) { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java index 91ac635..7ca8d95 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java @@ -36,8 +36,14 @@ import org.polypheny.simpleclient.query.QueryListEntry; import org.polypheny.simpleclient.query.RawQuery; import org.polypheny.simpleclient.scenario.PolyphenyScenario; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl.PgCreateBooleanFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl.PgCreateBooleanFeatureIndex; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl.PgCreateRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.ddl.PgCreateRealFeatureIndex; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnBooleanFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnBooleanFeatureFiltered; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnIdRealFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealCrossJoin; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealFeatureFiltered; import java.io.File; @@ -69,6 +75,7 @@ public void createSchema( DatabaseInstance databaseInstance, boolean includingKe executor = executorFactory.createExecutorInstance(); executor.executeQuery( new RawQuery( "CREATE EXTENSION IF NOT EXISTS vector", null, false ) ); executor.executeQuery( new PgCreateRealFeature( config.dimensionFeatureVectors ).getNewQuery() ); + executor.executeQuery( new PgCreateBooleanFeature( config.dimensionFeatureVectors ).getNewQuery() ); } catch ( ExecutorException e ) { throw new RuntimeException( "Exception while creating schema", e ); } finally { @@ -85,10 +92,19 @@ public void createIndex() { try { executor = executorFactory.createExecutorInstance(); long start = System.nanoTime(); - executor.executeQuery( new PgCreateRealFeatureIndex( config.indexMethod, config.distanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + if ( indexSupportsMetric( config.indexMethod, config.distanceNorm ) ) { + executor.executeQuery( new PgCreateRealFeatureIndex( config.indexMethod, config.distanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + } else { + log.info( "Skipping real index: {} does not support metric '{}'.", config.indexMethod, config.distanceNorm ); + } + if ( indexSupportsMetric( config.indexMethod, config.booleanDistanceNorm ) ) { + executor.executeQuery( new PgCreateBooleanFeatureIndex( config.indexMethod, config.booleanDistanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + } else { + log.info( "Skipping boolean index: {} does not support metric '{}'.", config.indexMethod, config.booleanDistanceNorm ); + } executor.executeCommit(); long durationMillis = ( System.nanoTime() - start ) / 1_000_000L; - log.info( "Vector index built in {} ms", durationMillis ); + log.info( "Vector indexes built in {} ms", durationMillis ); String conf = config.indexMethod.equals( "hnsw" ) ? "hnsw.ef_search = " + config.queryEfSearch @@ -111,6 +127,7 @@ public void generateData( DatabaseInstance databaseInstance, ProgressReporter pr PgDataGenerator dataGenerator = new PgDataGenerator( executor, config, progressReporter ); try { dataGenerator.generateRealFeatures(); + dataGenerator.generateBooleanFeatures(); } catch ( ExecutorException e ) { throw new RuntimeException( "Exception while generating data", e ); } finally { @@ -130,6 +147,11 @@ public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, Fil List queryList = new Vector<>(); addNumberOfTimes( queryList, new PgSimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnRealFeatureQueries ); addNumberOfTimes( queryList, new PgSimpleKnnRealFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm, "cat_A" ), config.numberOfSimpleKnnRealFeatureFilteredQueries ); + addNumberOfTimes( queryList, new PgSimpleKnnIdRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIdRealFeatureQueries ); + addNumberOfTimes( queryList, new PgSimpleKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnRealCrossJoinQueries ); + addNumberOfTimes( queryList, new PgSimpleKnnBooleanFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm ), config.numberOfSimpleKnnBooleanFeatureQueries ); + addNumberOfTimes( queryList, new PgSimpleKnnBooleanFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm, "cat_A" ), config.numberOfSimpleKnnBooleanFeatureFilteredQueries ); + return commonExecute( queryList, progressReporter, outputDirectory, numberOfThreads, Query::getSql, () -> executorFactory.createExecutorInstance( csvWriter ), new Random() ); } @@ -138,14 +160,36 @@ public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, Fil @Override public void warmUp( ProgressReporter progressReporter ) { log.info( "Warm-up..." ); - PgSimpleKnnRealFeature knnBuilder = new PgSimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); Executor executor = null; + PgSimpleKnnRealFeature pgSimpleKnnRealFeature = new PgSimpleKnnRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + PgSimpleKnnRealFeatureFiltered pgSimpleKnnRealFeatureFiltered = new PgSimpleKnnRealFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm, "cat_A" ); + PgSimpleKnnRealCrossJoin pgSimpleKnnRealCrossJoin = new PgSimpleKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + PgSimpleKnnIdRealFeature pgSimpleKnnIdRealFeature = new PgSimpleKnnIdRealFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ); + PgSimpleKnnBooleanFeature pgSimpleKnnBooleanFeature = new PgSimpleKnnBooleanFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm ); + PgSimpleKnnBooleanFeatureFiltered pgSimpleKnnBooleanFeatureFiltered = new PgSimpleKnnBooleanFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm, "cat_A" ); + for ( int i = 0; i < config.numberOfWarmUpIterations; i++ ) { try { executor = executorFactory.createExecutorInstance(); if ( config.numberOfSimpleKnnRealFeatureQueries > 0 ) { - executor.executeQuery( knnBuilder.getNewQuery() ); + executor.executeQuery( pgSimpleKnnRealFeature.getNewQuery() ); + } + if ( config.numberOfSimpleKnnRealFeatureFilteredQueries > 0 ) { + executor.executeQuery( pgSimpleKnnRealFeatureFiltered.getNewQuery() ); + } + if ( config.numberOfSimpleKnnRealCrossJoinQueries > 0 ) { + executor.executeQuery( pgSimpleKnnRealCrossJoin.getNewQuery() ); + } + if ( config.numberOfSimpleKnnIdRealFeatureQueries > 0 ) { + executor.executeQuery( pgSimpleKnnIdRealFeature.getNewQuery() ); } + if ( config.numberOfSimpleKnnBooleanFeatureQueries > 0 ) { + executor.executeQuery( pgSimpleKnnBooleanFeature.getNewQuery() ); + } + if ( config.numberOfSimpleKnnBooleanFeatureFilteredQueries > 0 ) { + executor.executeQuery( pgSimpleKnnBooleanFeatureFiltered.getNewQuery() ); + } + } catch ( ExecutorException e ) { throw new RuntimeException( "Error during warm-up", e ); } finally { @@ -166,6 +210,15 @@ public int getNumberOfInsertThreads() { } + private static boolean indexSupportsMetric( String method, String metric ) { + // HNSW supports all metrics; IVFFlat does not support L1 or JACCARD. + if ( method.equalsIgnoreCase( "ivfflat" ) ) { + return !( metric.equalsIgnoreCase( "L1" ) || metric.equalsIgnoreCase( "JACCARD" ) ); + } + return true; + } + + private void addNumberOfTimes( List list, QueryBuilder builder, int count ) { int id = queryTypes.size() + 1; queryTypes.put( id, builder.getNewQuery().getSql() ); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index 2bcf714..e99a4e1 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -46,6 +46,7 @@ import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnRealFeatureFiltered; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateBooleanFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateIntFeature; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateBooleanFeatureIndex; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateMetadata; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateRealFeatureIndex; @@ -110,14 +111,29 @@ public void createIndex() { if ( !config.useIndex ) { return; } + // Polypheny vector-maps array columns only when declared with element NOT NULL (REAL NOT NULL ARRAY). + // A plain ARRAY column is not vector-mapped, so no vector index can be built. + if ( !config.supportsNotNullArray ) { + log.info( "Skipping index creation: plain ARRAY columns are not vector-mapped in Polypheny (requires NOT NULL ARRAY)." ); + return; + } Executor executor = null; try { executor = executorFactory.createExecutorInstance(); long start = System.nanoTime(); - executor.executeQuery( new CreateRealFeatureIndex( featureStore, config.indexMethod, config.distanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + if ( indexSupportsMetric( config.indexMethod, config.distanceNorm ) ) { + executor.executeQuery( new CreateRealFeatureIndex( featureStore, config.indexMethod, config.distanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + } else { + log.info( "Skipping real index: {} does not support metric '{}'.", config.indexMethod, config.distanceNorm ); + } + if ( indexSupportsMetric( config.indexMethod, config.booleanDistanceNorm ) ) { + executor.executeQuery( new CreateBooleanFeatureIndex( featureStore, config.indexMethod, config.booleanDistanceNorm, config.indexM, config.indexEfConstruction, config.indexLists ).getNewQuery() ); + } else { + log.info( "Skipping boolean index: {} does not support metric '{}'.", config.indexMethod, config.booleanDistanceNorm ); + } executor.executeCommit(); long durationMillis = ( System.nanoTime() - start ) / 1_000_000L; - log.info( "Vector index built in {} ms", durationMillis ); + log.info( "Vector indexes built in {} ms", durationMillis ); } catch ( ExecutorException e ) { throw new RuntimeException( "Exception while creating vector index", e ); } finally { @@ -126,6 +142,15 @@ public void createIndex() { } + private static boolean indexSupportsMetric( String method, String metric ) { + // HNSW supports all metrics, IVFFlat does not support L1 or JACCARD. + if ( method.equalsIgnoreCase( "ivfflat" ) ) { + return !( metric.equalsIgnoreCase( "L1" ) || metric.equalsIgnoreCase( "JACCARD" ) ); + } + return true; + } + + @Override public void generateData( DatabaseInstance databaseInstance, ProgressReporter progressReporter ) { log.info( "Generating data..." ); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index 5897386..27af713 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -150,7 +150,7 @@ public VectorBenchConfig(Map cdl ) { dataStoreFeature = cdl.get( "dataStoreFeature" ); dataStoreMetadata = cdl.get( "dataStoreMetadata" ); - supportsNotNullArray = Boolean.parseBoolean( cdl.get( "supportsNotNullArray" ) ); + supportsNotNullArray = cdl.get( "supportsNotNullArray" ) == null || Boolean.parseBoolean( cdl.get( "supportsNotNullArray" ) ); if ( dataStoreFeature.equals( dataStoreMetadata ) ) { dataStores.add( dataStoreFeature ); From 720172ff5040440449e2563be94846f078522914 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Thu, 4 Jun 2026 19:52:11 +0200 Subject: [PATCH 34/38] Rename ip to inner_product and update properties and README --- .gitignore | 1 + .../ddl/PgCreateRealFeatureIndex.java | 2 +- .../postgres/dql/PgSimpleKnnRealFeature.java | 2 +- .../dql/PgSimpleKnnRealFeatureFiltered.java | 2 +- .../scenario/vectorbench/vector.properties | 30 +++++++++++-------- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index b256f57..7fec93d 100644 --- a/.gitignore +++ b/.gitignore @@ -257,6 +257,7 @@ nbdist/ !/libs/PolySqlParser-1.0.jar /results.csv +/results-pg.csv /recall-groundtruth.csv # humble video libraries diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeatureIndex.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeatureIndex.java index e331e30..25b7585 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeatureIndex.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/ddl/PgCreateRealFeatureIndex.java @@ -54,7 +54,7 @@ private static String toOpClass( String metric ) { case "cosine" -> "vector_cosine_ops"; case "l2" -> "vector_l2_ops"; case "l1" -> "vector_l1_ops"; - case "ip" -> "vector_ip_ops"; + case "inner_product" -> "vector_ip_ops"; default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); }; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java index db438c9..5b60a9d 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeature.java @@ -55,7 +55,7 @@ private static String toOperator( String metric ) { case "cosine" -> "<=>"; case "l2" -> "<->"; case "l1" -> "<+>"; - case "ip" -> "<#>"; + case "inner_product" -> "<#>"; default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); }; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java index d0d9baa..a3ac00c 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/postgres/dql/PgSimpleKnnRealFeatureFiltered.java @@ -58,7 +58,7 @@ private static String toOperator( String metric ) { case "cosine" -> "<=>"; case "l2" -> "<->"; case "l1" -> "<+>"; - case "ip" -> "<#>"; + case "inner_product" -> "<#>"; default -> throw new IllegalArgumentException( "Provided metric is invalid: " + metric ); }; } diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index f95cfa3..976b94e 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -11,10 +11,12 @@ postgresImageVariant = Default # true => DDL: REAL NOT NULL ARRAY(1,3) # false => DDL: REAL ARRAY(1,3) -supportsNotNullArray=true +# Note: Ignored by direct postgres path +supportsNotNullArray = false # False -> Does not create index -useIndex = false +# Note: When run in cli, vector index will not create indexes if set to false +useIndex = true # Query-time index parameters (direct-postgres path only, ignored on the Polypheny path). # --------------------------------------------------------------------------------------- @@ -25,8 +27,9 @@ queryEfSearch = 40 queryProbes = 1 # --------------------------------------------------------------------------------------- -# Vector index settings, hnsw or ivfflat -indexMethod = hnsw +# Vector index settings, +# Method: hnsw or ivfflat +indexMethod = ivfflat # Only used for HNSW index indexM = 16 indexEfConstruction = 64 @@ -45,7 +48,7 @@ progressReportBase = 100 numberOfWarmUpIterations = 4 # Seeds -# Note that when running using CLI and doing an index recall this should be turned off +# Note: When running using CLI and doing an index recall this should be turned off useRandomSeeds = false randomSeedInsert = 46891971806236 randomSeedQuery = 196033374268 @@ -65,21 +68,22 @@ numberOfMetadataKnnIntFeatureQueries = 0 numberOfSimpleMetadataQueries = 10 # Real (float vector mapping) -numberOfSimpleKnnRealFeatureQueries = 0 -numberOfSimpleKnnIdRealFeatureQueries = 0 -numberOfMetadataKnnRealFeatureQueries = 0 +numberOfSimpleKnnRealFeatureQueries = 10 +numberOfSimpleKnnIdRealFeatureQueries = 10 +numberOfMetadataKnnRealFeatureQueries = 10 numberOfSimpleKnnRealCrossJoinQueries = 10 numberOfMetadataKnnRealCrossJoinQueries = 10 -numberOfSimpleKnnRealFeatureFilteredQueries = 0 +numberOfSimpleKnnRealFeatureFilteredQueries = 10 # Boolean (bit vector mapping) -numberOfSimpleKnnBooleanFeatureFilteredQueries = 0 -numberOfSimpleKnnBooleanFeatureQueries = 0 +numberOfSimpleKnnBooleanFeatureFilteredQueries = 10 +numberOfSimpleKnnBooleanFeatureQueries = 10 limitKnnQueries = 10 -# L1, L2, COSINE, IP +# L1, L2, COSINE, INNER_PRODUCT distanceNorm = L2 # HAMMING, JACCARD -booleanDistanceNorm = HAMMING +booleanDistanceNorm = JACCARD +# Note: When ivfflat is selected as indexMethod, JACCARD and L1 indexes are not created and the step is skipped. From 1a394e9b6dcc16ef8407a814ffaa1b0bf01353c7 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Thu, 4 Jun 2026 20:45:56 +0200 Subject: [PATCH 35/38] Set featureStore and metadataStore for CLI path --- .../simpleclient/scenario/vectorbench/VectorBench.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index e99a4e1..a7da072 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -70,6 +70,8 @@ public class VectorBench extends PolyphenyScenario { public VectorBench(Executor.ExecutorFactory executorFactory, VectorBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); this.config = config; + this.featureStore = config.dataStoreFeature; + this.metadataStore = config.dataStoreMetadata; } From 57ef308e8f6a55f2e304d0cfb5b479b6b09384d1 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 8 Jun 2026 14:31:47 +0200 Subject: [PATCH 36/38] Write recall summary to file on CLI path of vectorbench --- .gitignore | 2 ++ .../main/VectorBenchScenario.java | 15 ++++++++- .../scenario/vectorbench/VectorBench.java | 9 ++++- .../scenario/vectorbench/vector.properties | 33 ++++++++++--------- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 7fec93d..285a9bf 100644 --- a/.gitignore +++ b/.gitignore @@ -256,9 +256,11 @@ nbdist/ # Avoid ignoring PolySqlParser jar file (.jar files are usually ignored) !/libs/PolySqlParser-1.0.jar +# vectorbench CLI path /results.csv /results-pg.csv /recall-groundtruth.csv +/recall.csv # humble video libraries libhumblevideo-0.dll diff --git a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java index 34fba12..3b3bccc 100644 --- a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java +++ b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java @@ -37,6 +37,7 @@ import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnRealFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.postgres.dql.PgSimpleKnnRealFeature; import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.util.Objects; import java.util.Properties; @@ -117,7 +118,8 @@ private static void runRecall( ExecutorFactory executorFactory, VectorBenchConfi if ( capture ) { evaluator.captureGroundTruth(); } else { - evaluator.evaluate(); + double recall = evaluator.evaluate(); + writeRecall( config, recall ); } } finally { try { @@ -129,6 +131,17 @@ private static void runRecall( ExecutorFactory executorFactory, VectorBenchConfi } + /** Writes the recall@k of the last `recall` run to recall.csv in the working directory. */ + private static void writeRecall( VectorBenchConfig config, double recall ) { + try ( FileWriter fw = new FileWriter( "recall.csv" ) ) { + fw.write( "k,recall\n" ); + fw.write( config.limitKnnQueries + "," + recall + "\n" ); + } catch ( IOException e ) { + log.error( "Could not write recall.csv", e ); + } + } + + public static void data( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery ) { VectorBenchConfig config = new VectorBenchConfig( getProperties(), multiplier ); VectorBench vectorBench = new VectorBench( executorFactory, config, commitAfterEveryQuery, false ); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java index a7da072..7cd7133 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBench.java @@ -43,6 +43,7 @@ import org.polypheny.simpleclient.scenario.PolyphenyScenario; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnBooleanFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnBooleanFeatureFiltered; +import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnIdIntFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.dql.SimpleKnnRealFeatureFiltered; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateBooleanFeature; import org.polypheny.simpleclient.scenario.vectorbench.queryBuilder.ddl.CreateIntFeature; @@ -192,6 +193,9 @@ public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, Fil addNumberOfTimes( queryList, new SimpleKnnRealFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm, "cat_A" ), config.numberOfSimpleKnnRealFeatureFilteredQueries ); addNumberOfTimes( queryList, new SimpleKnnBooleanFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm ), config.numberOfSimpleKnnBooleanFeatureQueries ); addNumberOfTimes( queryList, new SimpleKnnBooleanFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm, "cat_A" ), config.numberOfSimpleKnnBooleanFeatureFilteredQueries ); + addNumberOfTimes( queryList, new MetadataKnnRealCrossJoin( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfMetadataKnnRealCrossJoinQueries ); + addNumberOfTimes( queryList, new SimpleKnnIdIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm ), config.numberOfSimpleKnnIdIntFeatureQueries ); + return commonExecute( queryList, progressReporter, outputDirectory, numberOfThreads, Query::getSql, () -> executorFactory.createExecutorInstance( csvWriter ), new Random() ); @@ -214,7 +218,7 @@ public void warmUp( ProgressReporter progressReporter ) { SimpleKnnRealFeatureFiltered simpleKnnRealFeatureFiltered = new SimpleKnnRealFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.distanceNorm, "cat_A" ); SimpleKnnBooleanFeature simpleKnnBooleanFeature = new SimpleKnnBooleanFeature( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm ); SimpleKnnBooleanFeatureFiltered simpleKnnBooleanFeatureFiltered = new SimpleKnnBooleanFeatureFiltered( config.randomSeedQuery, config.dimensionFeatureVectors, config.limitKnnQueries, config.booleanDistanceNorm, "cat_A" ); - + SimpleKnnIdIntFeature simpleKnnIdIntFeature = new SimpleKnnIdIntFeature( config.randomSeedQuery, config.dimensionFeatureVectors,config.limitKnnQueries, config.distanceNorm ); for ( int i = 0; i < config.numberOfWarmUpIterations; i++ ) { try { @@ -234,6 +238,9 @@ public void warmUp( ProgressReporter progressReporter ) { if ( config.numberOfMetadataKnnIntFeatureQueries > 0 ) { executor.executeQuery( metadataKnnIntFeature.getNewQuery() ); } + if ( config.numberOfSimpleKnnIdIntFeatureQueries > 0 ) { + executor.executeQuery( simpleKnnIdIntFeature.getNewQuery() ); + } if ( config.numberOfMetadataKnnRealFeatureQueries > 0 ) { executor.executeQuery( metadataKnnRealFeature.getNewQuery() ); } diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties index 976b94e..e2a954e 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/vectorbench/vector.properties @@ -3,16 +3,16 @@ scenario = "vectorBench" # Execution of queries on: polypheny | postgres mode = polypheny -dataStoreFeature = postgresql +dataStoreFeature = postgresql1 dataStoreMeta = hsqldb # Default, pgvector, PostGIS, pgvector & PostGIS -postgresImageVariant = Default +postgresImageVariant = pgvector & PostGIS # true => DDL: REAL NOT NULL ARRAY(1,3) # false => DDL: REAL ARRAY(1,3) # Note: Ignored by direct postgres path -supportsNotNullArray = false +supportsNotNullArray = true # False -> Does not create index # Note: When run in cli, vector index will not create indexes if set to false @@ -27,21 +27,22 @@ queryEfSearch = 40 queryProbes = 1 # --------------------------------------------------------------------------------------- +# Number of sampled query vectors used to compute recall@k +# Note: CLI path only +numberOfRecallQueries = 100 + # Vector index settings, # Method: hnsw or ivfflat -indexMethod = ivfflat +indexMethod = hnsw # Only used for HNSW index indexM = 16 indexEfConstruction = 64 # Only used for IVFFlat index indexLists = 100 -# Number of sampled query vectors used to compute recall@k -numberOfRecallQueries = 100 - # PostgreSQL direct connect settings # Used when mode = postgres -postgresHost = 127.0.0.1 +postgresHost = localhost numberOfThreads = 4 progressReportBase = 100 @@ -65,19 +66,19 @@ numberOfSimpleKnnIntFeatureQueries = 0 numberOfSimpleKnnIdIntFeatureQueries = 0 numberOfMetadataKnnIntFeatureQueries = 0 -numberOfSimpleMetadataQueries = 10 +numberOfSimpleMetadataQueries = 0 # Real (float vector mapping) -numberOfSimpleKnnRealFeatureQueries = 10 -numberOfSimpleKnnIdRealFeatureQueries = 10 -numberOfMetadataKnnRealFeatureQueries = 10 -numberOfSimpleKnnRealCrossJoinQueries = 10 -numberOfMetadataKnnRealCrossJoinQueries = 10 -numberOfSimpleKnnRealFeatureFilteredQueries = 10 +numberOfSimpleKnnRealFeatureQueries = 0 +numberOfSimpleKnnIdRealFeatureQueries = 0 +numberOfMetadataKnnRealFeatureQueries = 0 +numberOfSimpleKnnRealCrossJoinQueries = 0 +numberOfMetadataKnnRealCrossJoinQueries = 0 +numberOfSimpleKnnRealFeatureFilteredQueries = 0 # Boolean (bit vector mapping) numberOfSimpleKnnBooleanFeatureFilteredQueries = 10 -numberOfSimpleKnnBooleanFeatureQueries = 10 +numberOfSimpleKnnBooleanFeatureQueries = 0 limitKnnQueries = 10 From ba6299b9259360cbf24ebcd256f9e127fd06d312 Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 20 Jul 2026 16:55:46 +0200 Subject: [PATCH 37/38] Fix date in copyright headers --- .../org/polypheny/simpleclient/main/VectorBenchScenario.java | 2 +- .../simpleclient/scenario/vectorbench/DataGenerator.java | 2 +- .../simpleclient/scenario/vectorbench/PgDataGenerator.java | 2 +- .../simpleclient/scenario/vectorbench/PgVectorBench.java | 2 +- .../simpleclient/scenario/vectorbench/VectorBenchConfig.java | 2 +- .../vectorbench/queryBuilder/dql/MetadataKnnIntFeature.java | 2 +- .../vectorbench/queryBuilder/dql/MetadataKnnRealCrossJoin.java | 2 +- .../vectorbench/queryBuilder/dql/MetadataKnnRealFeature.java | 2 +- .../vectorbench/queryBuilder/dql/SimpleKnnBooleanFeature.java | 2 +- .../queryBuilder/dql/SimpleKnnBooleanFeatureFiltered.java | 2 +- .../vectorbench/queryBuilder/dql/SimpleKnnIdIntFeature.java | 2 +- .../vectorbench/queryBuilder/dql/SimpleKnnIdRealFeature.java | 2 +- .../vectorbench/queryBuilder/dql/SimpleKnnIntFeature.java | 2 +- .../vectorbench/queryBuilder/dql/SimpleKnnRealCrossJoin.java | 2 +- .../vectorbench/queryBuilder/dql/SimpleKnnRealFeature.java | 2 +- .../queryBuilder/dql/SimpleKnnRealFeatureFiltered.java | 2 +- .../scenario/vectorbench/queryBuilder/dql/SimpleMetadata.java | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java index 3b3bccc..5ad0f81 100644 --- a/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java +++ b/src/main/java/org/polypheny/simpleclient/main/VectorBenchScenario.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-4/4/26, 11:01 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java index 69456d8..4271dc2 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/DataGenerator.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java index 62aa0b7..816d742 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgDataGenerator.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:48 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java index 7ca8d95..c94e378 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/PgVectorBench.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:48 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java index 27af713..f6f835d 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/VectorBenchConfig.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-2021 The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnIntFeature.java index bb13089..9feb180 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealCrossJoin.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealCrossJoin.java index 556d9ef..a57cf7d 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealCrossJoin.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealCrossJoin.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealFeature.java index 333b746..81ed28a 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/MetadataKnnRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeature.java index 31c81f7..219e6e5 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeatureFiltered.java index 7293510..93f9bf7 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeatureFiltered.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnBooleanFeatureFiltered.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdIntFeature.java index 913f2a2..9749d78 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdRealFeature.java index f0086ef..26f1354 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIdRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIntFeature.java index 367965a..26448b0 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnIntFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealCrossJoin.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealCrossJoin.java index a576b37..40e8f2e 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealCrossJoin.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealCrossJoin.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeature.java index de97a59..3edc323 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeature.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeatureFiltered.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeatureFiltered.java index ad11a3c..fb93c7f 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeatureFiltered.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleKnnRealFeatureFiltered.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleMetadata.java index a02debe..d02a5e2 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/vectorbench/queryBuilder/dql/SimpleMetadata.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019-5/26/26, 5:15 PM The Polypheny Project + * Copyright (c) 2019-2026 The Polypheny Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), to deal From 134635afb50d69a10b5ee169e815f06ec68434bb Mon Sep 17 00:00:00 2001 From: Yanick Spichty Date: Mon, 20 Jul 2026 17:00:01 +0200 Subject: [PATCH 38/38] Revert changes to KnnBench and cleanup code --- build.gradle | 2 -- .../simpleclient/main/ChronosAgent.java | 2 +- .../simpleclient/scenario/knnbench/KnnBench.java | 16 +++++++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index fba747f..cb4f0a0 100644 --- a/build.gradle +++ b/build.gradle @@ -205,7 +205,6 @@ shadowJar { } } assemble.dependsOn shadowJar - artifacts { //archives jar // regular jar containing only the compiled source archives shadowJar // fat jar which additionally contains all dependencies @@ -240,7 +239,6 @@ task copyPolyphenyNewJdbcDriver(type: Copy) { compileJava.dependsOn(copyPolyphenyOldJdbcDriver) compileJava.dependsOn(copyPolyphenyNewJdbcDriver) - /** * IntelliJ */ diff --git a/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java b/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java index dad1474..8c9a991 100644 --- a/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java +++ b/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java @@ -83,7 +83,7 @@ import org.polypheny.simpleclient.scenario.graph.GraphBenchConfig; import org.polypheny.simpleclient.scenario.knnbench.KnnBench; import org.polypheny.simpleclient.scenario.knnbench.KnnBenchConfig; - import org.polypheny.simpleclient.scenario.vectorbench.PgVectorBench; +import org.polypheny.simpleclient.scenario.vectorbench.PgVectorBench; import org.polypheny.simpleclient.scenario.vectorbench.VectorBench; import org.polypheny.simpleclient.scenario.vectorbench.VectorBenchConfig; import org.polypheny.simpleclient.scenario.multibench.MultiBench; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBench.java b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBench.java index d507aa5..555d0dd 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBench.java @@ -61,10 +61,19 @@ public class KnnBench extends PolyphenyScenario { private final KnnBenchConfig config; + private final List measuredTimes; + private long executeRuntime; + private final Map queryTypes; + private final Map> measuredTimePerQueryType; + + public KnnBench( Executor.ExecutorFactory executorFactory, KnnBenchConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { super( executorFactory, commitAfterEveryQuery, dumpQueryList, QueryMode.TABLE ); this.config = config; + measuredTimes = Collections.synchronizedList( new LinkedList<>() ); + queryTypes = new HashMap<>(); + measuredTimePerQueryType = new ConcurrentHashMap<>(); } @@ -87,9 +96,10 @@ public void createSchema( DatabaseInstance databaseInstance, boolean includingKe Executor executor = null; try { executor = executorFactory.createExecutorInstance(); - executor.executeQuery( (new CreateMetadata( config.dataStoreMetadata )).getNewQuery() ); - executor.executeQuery( (new CreateIntFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() ); - executor.executeQuery( (new CreateRealFeature( config.dataStoreFeature , config.dimensionFeatureVectors )).getNewQuery() );} catch ( ExecutorException e ) { + executor.executeQuery( (new CreateMetadata( findMatchingDataStoreName( config.dataStoreMetadata ) )).getNewQuery() ); + executor.executeQuery( (new CreateIntFeature( findMatchingDataStoreName( config.dataStoreFeature ), config.dimensionFeatureVectors )).getNewQuery() ); + executor.executeQuery( (new CreateRealFeature( findMatchingDataStoreName( config.dataStoreFeature ), config.dimensionFeatureVectors )).getNewQuery() ); + } catch ( ExecutorException e ) { throw new RuntimeException( "Exception while creating schema", e ); } finally { commitAndCloseExecutor( executor );