From 0d84912f2e16a5c791d3cc1519206ca71fedbd90 Mon Sep 17 00:00:00 2001 From: Marco Vogt Date: Mon, 13 Jun 2022 17:57:02 +0200 Subject: [PATCH] Add DocBench benchmark --- README.md | 11 +- build.gradle | 38 +- .../cli/AbstractOltpBenchCommand.java | 2 +- .../simpleclient/cli/DocBenchCommand.java | 108 ++++++ .../simpleclient/cli/GraphCommand.java | 2 +- .../org/polypheny/simpleclient/cli/Main.java | 1 + .../simpleclient/executor/Executor.java | 6 + .../executor/PolyphenyDbCypherExecutor.java | 4 +- .../executor/PolyphenyDbHttpExecutor.java | 15 +- .../executor/PolyphenyDbMongoQlExecutor.java | 33 +- .../executor/PolyphenyDbRestExecutor.java | 4 +- .../simpleclient/main/ChronosAgent.java | 10 +- .../simpleclient/main/DocBenchScenario.java | 91 +++++ .../simpleclient/query/BatchableInsert.java | 2 +- .../simpleclient/query/MultipartInsert.java | 2 +- .../scenario/docbench/DataGenerator.java | 115 ++++++ .../scenario/docbench/DocBench.java | 349 ++++++++++++++++++ .../scenario/docbench/DocBenchConfig.java | 141 +++++++ .../scenario/docbench/MongoQlInsertQuery.java | 106 ++++++ .../scenario/docbench/MongoQlQuery.java | 77 ++++ .../queryBuilder/PutProductQueryBuilder.java | 77 ++++ .../SearchProductQueryBuilder.java | 58 +++ .../scenario/gavel/DataGenerator.java | 1 - .../simpleclient/scenario/gavel/Gavel.java | 2 - .../scenario/gavel/GavelConfig.java | 2 +- .../gavel/queryBuilder/InsertAuction.java | 2 +- .../gavel/queryBuilder/InsertBid.java | 2 +- .../gavel/queryBuilder/InsertCategory.java | 2 +- .../gavel/queryBuilder/InsertPicture.java | 2 +- .../gavel/queryBuilder/InsertUser.java | 2 +- .../scenario/graph/GraphBenchConfig.java | 2 +- .../scenario/graph/GraphInsert.java | 2 +- .../scenario/knnbench/KnnBenchConfig.java | 2 +- .../queryBuilder/InsertIntFeature.java | 2 +- .../knnbench/queryBuilder/InsertMetadata.java | 2 +- .../queryBuilder/InsertRealFeature.java | 2 +- .../multimedia/queryBuilder/InsertAlbum.java | 2 +- .../queryBuilder/InsertFriends.java | 2 +- .../multimedia/queryBuilder/InsertMedia.java | 4 +- .../queryBuilder/InsertRandomTimeline.java | 4 +- .../queryBuilder/InsertTimeline.java | 4 +- .../multimedia/queryBuilder/InsertUser.java | 4 +- .../scenario/docbench/docbench.properties | 20 + 43 files changed, 1259 insertions(+), 60 deletions(-) create mode 100644 src/main/java/org/polypheny/simpleclient/cli/DocBenchCommand.java create mode 100644 src/main/java/org/polypheny/simpleclient/main/DocBenchScenario.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/docbench/DataGenerator.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/docbench/DocBench.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/docbench/DocBenchConfig.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/docbench/MongoQlInsertQuery.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/docbench/MongoQlQuery.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/docbench/queryBuilder/PutProductQueryBuilder.java create mode 100644 src/main/java/org/polypheny/simpleclient/scenario/docbench/queryBuilder/SearchProductQueryBuilder.java create mode 100644 src/main/resources/org/polypheny/simpleclient/scenario/docbench/docbench.properties diff --git a/README.md b/README.md index 77fac7de..2259c9d6 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ A simple benchmarking and testing client for Polypheny-DB. It includes support f * **kNN-Bench**: A benchmark tailored towards typical workloads of multimedia retrieval applications and especially k-Nearest-Neighbor search. * **Multimedia**: This benchmarks produces workload containing or requesting randomly generated BLOBs. * **Graph**: A simple synthetic graph benchmark that executes a mixture of DQL and DML Cypher queries against a pseudo-random network. +* **DocBench**: A simple benchmark for document schemas generating MongoQL queries. * [**AuctionMark**](http://hstore.cs.brown.edu/projects/auctionmark/): A benchmark executing workload that simulates the activities found in a well-known auction site. * [**SmallBank**](http://ses.library.usyd.edu.au/bitstream/2123/5353/1/michael-cahill-2009-thesis.pdf): The SmallBank benchmark models a simple banking application. * [**TPC-C**](http://www.tpc.org/tpcc/): A well-known on-line transaction processing (OLTP) benchmark. @@ -56,19 +57,19 @@ OPTIONS ### Stand-alone -This client can be used by specifying the name of the benchmark as first parameter (`gavel`, `knnbench`, `multimedia`). Use the `help` command to get an overview on all available parameters for this benchmark. For example: +This client can be used by specifying the name of the benchmark as first parameter and the task as second parameter. Optionally, it is also possible to specify a multiplier for the data and workload (integer > 0). The general syntax is identical for all benchmarks: ``` -java -jar polypheny-simple-client.jar help gavel +java -jar polypheny-simple-client.jar BENCHMARK TASK [ MULTIPLIER ] ``` -The general syntax is identical for all three benchmarks: +Use the `help` command to get an overview on all available parameters for a benchmark. For example: ``` -java -jar polypheny-simple-client.jar BENCHMARK TASK [ MULTIPLIER ] +java -jar polypheny-simple-client.jar help gavel ``` -_BENCHMARK_: `{ gavel | knnbench | multimedia | auctionmark | smallbank | tpcc | tpch | ycsb }` +_BENCHMARK_: `{ gavel | knnbench | multimedia | graph | docbench | auctionmark | smallbank | tpcc | tpch | ycsb }` _TASK_: `{ schema | data | workload | warmup }` diff --git a/build.gradle b/build.gradle index 651449f4..ce84534c 100644 --- a/build.gradle +++ b/build.gradle @@ -19,10 +19,11 @@ buildscript { classpath group: "gradle.plugin.com.github.johnrengelman", name: "shadow", version: "7.1.2" // Lombok (https://plugins.gradle.org/plugin/io.freefair.lombok) classpath group: "io.freefair.gradle", name: "lombok-plugin", version: "6.4.3" + // https://plugins.gradle.org/plugin/org.jetbrains.gradle.plugin.idea-ext + classpath group: "gradle.plugin.org.jetbrains.gradle.plugin.idea-ext", name: "gradle-idea-ext", version: "1.1.4" } } - repositories { mavenCentral() maven { @@ -31,7 +32,7 @@ repositories { } apply plugin: "java-library" -apply plugin: "idea" +apply plugin: "org.jetbrains.gradle.plugin.idea-ext" apply plugin: "io.freefair.lombok" apply plugin: "com.github.johnrengelman.shadow" @@ -168,4 +169,37 @@ idea { outputDir = file("${project.buildDir}/classes") testOutputDir = file("${project.buildDir}/test-classes") } + project { + settings { + copyright { + useDefault = "MITLicense" + profiles { + MITLicense { + notice = 'The MIT License (MIT)\n' + + '\n' + + 'Copyright (c) 2019-$today The Polypheny Project\n' + + '\n' + + 'Permission is hereby granted, free of charge, to any person obtaining a\n' + + 'copy of this software and associated documentation files (the "Software"), to deal\n' + + 'in the Software without restriction, including without limitation the rights\n' + + 'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n' + + 'copies of the Software, and to permit persons to whom the Software is\n' + + 'furnished to do so, subject to the following conditions:\n' + + '\n' + + 'The above copyright notice and this permission notice shall be included in all\n' + + 'copies or substantial portions of the Software.\n' + + '\n' + + 'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n' + + 'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n' + + 'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n' + + 'AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n' + + 'LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n' + + 'OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n' + + 'SOFTWARE.' + keyword = "Copyright" + } + } + } + } + } } diff --git a/src/main/java/org/polypheny/simpleclient/cli/AbstractOltpBenchCommand.java b/src/main/java/org/polypheny/simpleclient/cli/AbstractOltpBenchCommand.java index 97e577e5..f4ce2e9b 100644 --- a/src/main/java/org/polypheny/simpleclient/cli/AbstractOltpBenchCommand.java +++ b/src/main/java/org/polypheny/simpleclient/cli/AbstractOltpBenchCommand.java @@ -84,7 +84,7 @@ public int run() throws SQLException { System.err.println( "Unknown task: " + args.get( 0 ) ); } } catch ( Throwable t ) { - log.error( "Exception while executing KnnBench!", t ); + log.error( "Exception while executing OltpBench!", t ); System.exit( 1 ); } diff --git a/src/main/java/org/polypheny/simpleclient/cli/DocBenchCommand.java b/src/main/java/org/polypheny/simpleclient/cli/DocBenchCommand.java new file mode 100644 index 00000000..3d8e6750 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/cli/DocBenchCommand.java @@ -0,0 +1,108 @@ +/* + * 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.cli; + +import com.github.rvesse.airline.HelpOption; +import com.github.rvesse.airline.annotations.Arguments; +import com.github.rvesse.airline.annotations.Command; +import com.github.rvesse.airline.annotations.Option; +import java.sql.SQLException; +import java.util.List; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.executor.Executor.ExecutorFactory; +import org.polypheny.simpleclient.executor.PolyphenyDbMongoQlExecutor.PolyphenyDbMongoQlExecutorFactory; +import org.polypheny.simpleclient.main.DocBenchScenario; + + +@Slf4j +@Command(name = "docbench", description = "Mode for quick testing of Polypheny-DB using the DocBench benchmark.") +public class DocBenchCommand implements CliRunnable { + + @SuppressWarnings("SpringAutowiredFieldsWarningInspection") + @Inject + 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 = new PolyphenyDbMongoQlExecutorFactory( polyphenyDbHost ); + + try { + if ( args.get( 0 ).equalsIgnoreCase( "data" ) ) { + DocBenchScenario.data( executorFactory, multiplier, true ); + } else if ( args.get( 0 ).equalsIgnoreCase( "workload" ) ) { + DocBenchScenario.workload( executorFactory, multiplier, true, writeCsv, dumpQueryList ); + } else if ( args.get( 0 ).equalsIgnoreCase( "schema" ) ) { + DocBenchScenario.schema( executorFactory, true ); + } else if ( args.get( 0 ).equalsIgnoreCase( "warmup" ) ) { + DocBenchScenario.warmup( executorFactory, multiplier, true, dumpQueryList ); + } else { + System.err.println( "Unknown task: " + args.get( 0 ) ); + } + } catch ( Throwable t ) { + log.error( "Exception while executing DocBench!", 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/cli/GraphCommand.java b/src/main/java/org/polypheny/simpleclient/cli/GraphCommand.java index 4b4361ec..fda6a694 100644 --- a/src/main/java/org/polypheny/simpleclient/cli/GraphCommand.java +++ b/src/main/java/org/polypheny/simpleclient/cli/GraphCommand.java @@ -92,7 +92,7 @@ public int run() throws SQLException { System.err.println( "Unknown task: " + args.get( 0 ) ); } } catch ( Throwable t ) { - log.error( "Exception while executing KnnBench!", t ); + log.error( "Exception while executing GraphBench!", t ); System.exit( 1 ); } diff --git a/src/main/java/org/polypheny/simpleclient/cli/Main.java b/src/main/java/org/polypheny/simpleclient/cli/Main.java index 0f1fddd9..a8ea234c 100644 --- a/src/main/java/org/polypheny/simpleclient/cli/Main.java +++ b/src/main/java/org/polypheny/simpleclient/cli/Main.java @@ -43,6 +43,7 @@ public static void main( String[] args ) throws SQLException { builder.withCommands( KnnCommand.class ); builder.withCommands( MultimediaCommand.class ); builder.withCommands( GraphCommand.class ); + builder.withCommands( DocBenchCommand.class ); builder.withCommands( AuctionMarkCommand.class ); builder.withCommands( SmallBankCommand.class ); builder.withCommands( TpccCommand.class ); diff --git a/src/main/java/org/polypheny/simpleclient/executor/Executor.java b/src/main/java/org/polypheny/simpleclient/executor/Executor.java index e6d40552..b2c4d666 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/Executor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/Executor.java @@ -59,6 +59,12 @@ public Executor createExecutorInstance() { public abstract Executor createExecutorInstance( CsvWriter csvWriter ); + + public Executor createExecutorInstance( CsvWriter csvWriter, String namespace ) { + return createExecutorInstance( csvWriter ); + } + + // Allows to limit number of concurrent executor threads, 0 means no limit public abstract int getMaxNumberOfThreads(); diff --git a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbCypherExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbCypherExecutor.java index b5f6e456..f01a6a1b 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbCypherExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbCypherExecutor.java @@ -49,10 +49,10 @@ public PolyphenyDbCypherExecutor( String host, CsvWriter csvWriter ) { @Override - protected HttpRequest buildQuery( String query ) { + protected HttpRequest buildQuery( String query, String namespace ) { JsonObject data = new JsonObject(); data.addProperty( "query", query ); - data.addProperty( "database", "test" ); + data.addProperty( "database", namespace ); return Unirest.post( "{protocol}://{host}:{port}/cypher" ) .header( "Content-Type", "application/json" ) .body( data ); diff --git a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbHttpExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbHttpExecutor.java index a93b6a2e..9242306e 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbHttpExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbHttpExecutor.java @@ -49,6 +49,9 @@ public abstract class PolyphenyDbHttpExecutor implements PolyphenyDbExecutor { @Getter public final String name; + @Getter + String namespace; + @Getter public final Function queryAccessor; @@ -140,7 +143,7 @@ public long executeQuery( Query query ) throws ExecutorException { } long time; - HttpRequest request = getRequest( queryAccessor.apply( query ) ); + HttpRequest request = getRequest( queryAccessor.apply( query ), namespace ); try { long start = System.nanoTime(); @SuppressWarnings("rawtypes") HttpResponse result = request.asBytes(); @@ -159,10 +162,10 @@ public long executeQuery( Query query ) throws ExecutorException { } - HttpRequest buildQuery( String mql ) { + HttpRequest buildQuery( String mql, String namespace ) { JsonObject data = new JsonObject(); data.addProperty( "query", mql ); - data.addProperty( "database", "test" ); + data.addProperty( "database", namespace ); return Unirest.post( "{protocol}://{host}:{port}/" + name.toLowerCase( Locale.ROOT ) ) .header( "Content-Type", "application/json" ) @@ -170,8 +173,8 @@ HttpRequest buildQuery( String mql ) { } - HttpRequest getRequest( String query ) { - HttpRequest request = buildQuery( query ); + HttpRequest getRequest( String query, String namespace ) { + HttpRequest request = buildQuery( query, namespace ); request.basicAuth( "pa", "" ); request.routeParam( "protocol", "http" ); request.routeParam( "host", "127.0.0.1" ); @@ -187,7 +190,7 @@ public long executeQueryAndGetNumber( Query query ) throws ExecutorException { throw new RuntimeException( "not supported" ); } - HttpRequest request = getRequest( queryAccessor.apply( query ) ); + HttpRequest request = getRequest( queryAccessor.apply( query ), namespace ); try { long start = System.nanoTime(); diff --git a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbMongoQlExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbMongoQlExecutor.java index 11d8b0d4..addf4563 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbMongoQlExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbMongoQlExecutor.java @@ -44,9 +44,12 @@ @Slf4j public class PolyphenyDbMongoQlExecutor extends PolyphenyDbHttpExecutor { + public static final String DEFAULT_NAMESPACE = "test"; - public PolyphenyDbMongoQlExecutor( String host, CsvWriter csvWriter ) { + + public PolyphenyDbMongoQlExecutor( String host, CsvWriter csvWriter, String namespace ) { super( "Mongo", Query::getMongoQl, host, csvWriter ); + this.namespace = namespace; } @@ -60,7 +63,7 @@ public long executeQuery( Query query ) throws ExecutorException { } long time; - HttpRequest request = getRequest( query.getMongoQl() ); + HttpRequest request = getRequest( query.getMongoQl(), namespace ); log.debug( request.getUrl() ); try { long start = System.nanoTime(); @@ -87,7 +90,7 @@ public long executeQueryAndGetNumber( Query query ) throws ExecutorException { throw new RuntimeException( "not supported" ); } - HttpRequest request = getRequest( query.getMongoQl() ); + HttpRequest request = getRequest( query.getMongoQl(), namespace ); log.debug( request.getUrl() ); try { long start = System.nanoTime(); @@ -131,25 +134,25 @@ public void closeConnection() throws ExecutorException { @Override public void executeInsertList( List batchList, AbstractConfig config ) throws ExecutorException { - String currentTable = null; - List rows = new ArrayList<>(); + String currentDocument = null; + List documents = new ArrayList<>(); for ( BatchableInsert query : batchList ) { query.debug(); if ( query instanceof MultipartInsert ) { continue; } - if ( currentTable == null ) { - currentTable = query.getTable(); + if ( currentDocument == null ) { + currentDocument = query.getEntity(); } - if ( currentTable.equals( query.getTable() ) ) { - rows.add( Objects.requireNonNull( query.getMongoQlRowExpression() ) ); + if ( currentDocument.equals( query.getEntity() ) ) { + documents.add( Objects.requireNonNull( query.getMongoQlRowExpression() ) ); } else { throw new RuntimeException( "Different tables in multi-inserts. This should not happen!" ); } } - if ( rows.size() > 0 ) { - executeQuery( new RawQuery( null, null, Query.buildMongoQlManyInsert( currentTable, rows ), null, false ) ); + if ( documents.size() > 0 ) { + executeQuery( new RawQuery( null, null, Query.buildMongoQlManyInsert( currentDocument, documents ), null, false ) ); } } @@ -166,7 +169,13 @@ public PolyphenyDbMongoQlExecutorFactory( String host ) { @Override public PolyphenyDbMongoQlExecutor createExecutorInstance( CsvWriter csvWriter ) { - return new PolyphenyDbMongoQlExecutor( host, csvWriter ); + return new PolyphenyDbMongoQlExecutor( host, csvWriter, DEFAULT_NAMESPACE ); + } + + + @Override + public Executor createExecutorInstance( CsvWriter csvWriter, String namespace ) { + return new PolyphenyDbMongoQlExecutor( host, csvWriter, namespace ); } diff --git a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbRestExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbRestExecutor.java index a9f9af56..9c1059b1 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbRestExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbRestExecutor.java @@ -201,10 +201,10 @@ public void executeInsertList( List batchList, AbstractConfig c continue; } if ( currentTable == null ) { - currentTable = query.getTable(); + currentTable = query.getEntity(); } - if ( currentTable.equals( query.getTable() ) ) { + if ( currentTable.equals( query.getEntity() ) ) { rows.add( Objects.requireNonNull( query.getRestRowExpression() ) ); } else { throw new RuntimeException( "Different tables in multi-inserts. This should not happen!" ); diff --git a/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java b/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java index 81f253d4..e963b761 100644 --- a/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java +++ b/src/main/java/org/polypheny/simpleclient/main/ChronosAgent.java @@ -62,6 +62,8 @@ import org.polypheny.simpleclient.executor.PostgresExecutor.PostgresInstance; import org.polypheny.simpleclient.scenario.AbstractConfig; import org.polypheny.simpleclient.scenario.Scenario; +import org.polypheny.simpleclient.scenario.docbench.DocBench; +import org.polypheny.simpleclient.scenario.docbench.DocBenchConfig; import org.polypheny.simpleclient.scenario.gavel.Gavel; import org.polypheny.simpleclient.scenario.gavel.GavelConfig; import org.polypheny.simpleclient.scenario.graph.GraphBench; @@ -174,7 +176,7 @@ protected Object prepare( ChronosJob chronosJob, final File inputDirectory, fina // Create Executor Factory Executor.ExecutorFactory executorFactory; switch ( parsedConfig.get( "store" ) ) { - case "polypheny": + case "polypheny-jdbc": executorFactory = new PolyphenyDbJdbcExecutorFactory( ChronosCommand.hostname, Boolean.parseBoolean( parsedConfig.get( "prepareStatements" ) ) ); break; case "polypheny-rest": @@ -224,6 +226,10 @@ protected Object prepare( ChronosJob chronosJob, final File inputDirectory, fina config = new GraphBenchConfig( parsedConfig ); scenario = new GraphBench( executorFactory, (GraphBenchConfig) config, true, dumpQueryList ); break; + case "docbench": + config = new DocBenchConfig( parsedConfig ); + scenario = new DocBench( executorFactory, (DocBenchConfig) config, true, dumpQueryList ); + break; case "auctionmark": config = new AuctionMarkConfig( parsedConfig ); scenario = new AuctionMark( executorFactory, (AuctionMarkConfig) config, dumpQueryList, queryMode ); @@ -278,7 +284,7 @@ protected Object prepare( ChronosJob chronosJob, final File inputDirectory, fina DatabaseInstance databaseInstance; switch ( config.system ) { - case "polypheny": + case "polypheny-jdbc": case "polypheny-rest": case "polypheny-mongoql": case "polypheny-cypher": diff --git a/src/main/java/org/polypheny/simpleclient/main/DocBenchScenario.java b/src/main/java/org/polypheny/simpleclient/main/DocBenchScenario.java new file mode 100644 index 00000000..53fd5145 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/main/DocBenchScenario.java @@ -0,0 +1,91 @@ +/* + * 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.main; + +import java.io.File; +import java.io.IOException; +import java.util.Objects; +import java.util.Properties; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.executor.Executor.ExecutorFactory; +import org.polypheny.simpleclient.scenario.docbench.DocBench; +import org.polypheny.simpleclient.scenario.docbench.DocBenchConfig; + + +@Slf4j +public class DocBenchScenario { + + public static void schema( ExecutorFactory executorFactory, boolean commitAfterEveryQuery ) { + DocBenchConfig config = new DocBenchConfig( getProperties(), 1 ); + DocBench DocBench = new DocBench( executorFactory, config, commitAfterEveryQuery, false ); + DocBench.createSchema( true ); + } + + + public static void data( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery ) { + DocBenchConfig config = new DocBenchConfig( getProperties(), multiplier ); + DocBench DocBench = new DocBench( executorFactory, config, commitAfterEveryQuery, false ); + + ProgressReporter progressReporter = new ProgressBar( config.numberOfThreads, config.progressReportBase ); + DocBench.generateData( progressReporter ); + } + + + public static void workload( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery, boolean writeCsv, boolean dumpQueryList ) { + DocBenchConfig config = new DocBenchConfig( getProperties(), multiplier ); + DocBench DocBench = new DocBench( 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 ); + DocBench.execute( progressReporter, csvWriter, new File( "." ), config.numberOfThreads ); + } + + + public static void warmup( ExecutorFactory executorFactory, int multiplier, boolean commitAfterEveryQuery, boolean dumpQueryList ) { + DocBenchConfig config = new DocBenchConfig( getProperties(), multiplier ); + DocBench DocBench = new DocBench( executorFactory, config, commitAfterEveryQuery, dumpQueryList ); + + ProgressReporter progressReporter = new ProgressBar( config.numberOfThreads, config.progressReportBase ); + DocBench.warmUp( progressReporter ); + } + + + private static Properties getProperties() { + Properties props = new Properties(); + try { + props.load( Objects.requireNonNull( ClassLoader.getSystemResourceAsStream( "org/polypheny/simpleclient/scenario/docbench/docbench.properties" ) ) ); + } catch ( IOException e ) { + log.error( "Exception while reading properties file", e ); + } + return props; + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/query/BatchableInsert.java b/src/main/java/org/polypheny/simpleclient/query/BatchableInsert.java index 216fbdaf..ebeaa62c 100644 --- a/src/main/java/org/polypheny/simpleclient/query/BatchableInsert.java +++ b/src/main/java/org/polypheny/simpleclient/query/BatchableInsert.java @@ -67,6 +67,6 @@ public String getCypherRowExpression() { } - public abstract String getTable(); + public abstract String getEntity(); } diff --git a/src/main/java/org/polypheny/simpleclient/query/MultipartInsert.java b/src/main/java/org/polypheny/simpleclient/query/MultipartInsert.java index 4aabeced..2cc06ace 100644 --- a/src/main/java/org/polypheny/simpleclient/query/MultipartInsert.java +++ b/src/main/java/org/polypheny/simpleclient/query/MultipartInsert.java @@ -50,7 +50,7 @@ public void setFile( String column, File f ) { public HttpRequest buildMultipartInsert() { MultipartBody body = Unirest.post( "{protocol}://{host}:{port}/restapi/v1/multipart" ).multiPartContent(); - body.field( "resName", getTable() ); + body.field( "resName", getEntity() ); if ( getRestRowExpression() != null ) { JsonArray jsonArray = new JsonArray(); jsonArray.add( getRestRowExpression() ); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/docbench/DataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/docbench/DataGenerator.java new file mode 100644 index 00000000..05c99567 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/docbench/DataGenerator.java @@ -0,0 +1,115 @@ +/* + * 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.docbench; + +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +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.docbench.queryBuilder.PutProductQueryBuilder; + + +@Slf4j +public class DataGenerator { + + private final Executor theExecutor; + private final DocBenchConfig config; + + private final List batchList; + + private boolean aborted; + + private final Random random; + + private final List valuesPool; + + + DataGenerator( Random random, Executor executor, DocBenchConfig config, ProgressReporter progressReporter, List valuesPool ) { + theExecutor = executor; + this.config = config; + batchList = new LinkedList<>(); + aborted = false; + this.valuesPool = valuesPool; + this.random = random; + } + + + public static int boundedRandom( Random random, int min, int max ) { + if ( min > max ) { + throw new RuntimeException( "Min must be smaller than max" ); + } + if ( min == max ) { + return min; + } + return random.nextInt( max - min ) + min; + } + + + private void addToInsertList( BatchableInsert query ) throws ExecutorException { + batchList.add( query ); + if ( batchList.size() >= config.batchSize ) { + executeInsertList(); + } + } + + + private void executeInsertList() throws ExecutorException { + theExecutor.executeInsertList( batchList, config ); + theExecutor.executeCommit(); + batchList.clear(); + } + + + public void abort() { + aborted = true; + } + + + void generateData() throws ExecutorException { + PutProductQueryBuilder queryBuilder = new PutProductQueryBuilder( random, valuesPool, config ); + for ( int i = 0; i < config.numberOfDocuments; i++ ) { + if ( aborted ) { + break; + } + addToInsertList( queryBuilder.getNewQuery() ); + } + executeInsertList(); + } + + + public static String randomString( Random random, int length ) { + int leftLimit = 97; // letter 'a' + int rightLimit = 122; // letter 'z' + return random.ints( leftLimit, rightLimit + 1 ) + .limit( length ) + .collect( StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append ) + .toString(); + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/docbench/DocBench.java b/src/main/java/org/polypheny/simpleclient/scenario/docbench/DocBench.java new file mode 100644 index 00000000..08f334c2 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/docbench/DocBench.java @@ -0,0 +1,349 @@ +/* + * 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.docbench; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Random; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.polypheny.simpleclient.QueryMode; +import org.polypheny.simpleclient.executor.Executor; +import org.polypheny.simpleclient.executor.ExecutorException; +import org.polypheny.simpleclient.main.CsvWriter; +import org.polypheny.simpleclient.main.ProgressReporter; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.polypheny.simpleclient.query.QueryListEntry; +import org.polypheny.simpleclient.query.RawQuery; +import org.polypheny.simpleclient.scenario.Scenario; +import org.polypheny.simpleclient.scenario.docbench.queryBuilder.SearchProductQueryBuilder; + + +@Slf4j +public class DocBench extends Scenario { + + private final DocBenchConfig config; + private final List measuredTimes; + private final Map queryTypes; + private final Map> measuredTimePerQueryType; + private final Random random; + public final List valuesPool = new ArrayList<>(); + + public static final String NAMESPACE = "docbench"; + + + public DocBench( Executor.ExecutorFactory executorFactory, DocBenchConfig 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<>(); + random = new Random( config.seed ); + + // Build attributes value pool + for ( int i = 0; i < config.sizeOfValuesPool; i++ ) { + int stringLength = DataGenerator.boundedRandom( random, config.valuesStringMinLength, config.valuesStringMaxLength ); + valuesPool.add( DataGenerator.randomString( random, stringLength ) ); + } + } + + + @Override + public void createSchema( boolean includingKeys ) { + log.info( "Creating schema..." ); + Executor executor = null; + try { + executor = executorFactory.createExecutorInstance( null, NAMESPACE ); + executor.executeQuery( new RawQuery( null, null, "use " + NAMESPACE, null, false ) ); + executor.executeQuery( new RawQuery( null, null, "db.createCollection(product)", null, false ) ); + } catch ( ExecutorException e ) { + throw new RuntimeException( "Exception while creating schema", e ); + } finally { + commitAndCloseExecutor( executor ); + } + } + + + @Override + public void generateData( ProgressReporter progressReporter ) { + log.info( "Generating data..." ); + Executor executor = executorFactory.createExecutorInstance( null, NAMESPACE ); + DataGenerator dataGenerator = new DataGenerator( random, executor, config, progressReporter, valuesPool ); + try { + dataGenerator.generateData(); + } 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 for the benchmark..." ); + List queryList = new Vector<>(); + addNumberOfTimes( queryList, new SearchProductQueryBuilder( random, valuesPool, config ), config.numberOfQueries ); + Collections.shuffle( queryList, random ); + + // This dumps the MQL queries independent of the selected interface + if ( outputDirectory != null && dumpQueryList ) { + log.info( "Dump query list..." ); + try { + FileWriter fw = new FileWriter( outputDirectory.getPath() + File.separator + "queryList" ); + queryList.forEach( query -> { + try { + fw.append( query.query.getMongoQl() ).append( "\n" ); + } catch ( IOException e ) { + log.error( "Error while dumping query list", e ); + } + } ); + fw.close(); + } catch ( IOException e ) { + log.error( "Error while dumping query list", e ); + } + } + + log.info( "Executing benchmark..." ); + (new Thread( new ProgressReporter.ReportQueryListProgress( queryList, progressReporter ) )).start(); + long startTime = System.nanoTime(); + + ArrayList threads = new ArrayList<>(); + for ( int i = 0; i < numberOfThreads; i++ ) { + threads.add( new EvaluationThread( queryList, executorFactory.createExecutorInstance( csvWriter ) ) ); + } + + EvaluationThreadMonitor threadMonitor = new EvaluationThreadMonitor( threads ); + threads.forEach( t -> t.setThreadMonitor( threadMonitor ) ); + + for ( EvaluationThread thread : threads ) { + thread.start(); + } + + for ( Thread thread : threads ) { + try { + thread.join(); + } catch ( InterruptedException e ) { + throw new RuntimeException( "Unexpected interrupt", e ); + } + } + + long runTime = System.nanoTime() - startTime; + + for ( EvaluationThread thread : threads ) { + thread.closeExecutor(); + } + + if ( threadMonitor.aborted ) { + throw new RuntimeException( "Exception while executing benchmark", threadMonitor.exception ); + } + + log.info( "run time: {} s", runTime / 1000000000 ); + + return runTime; + } + + + @Override + public void warmUp( ProgressReporter progressReporter ) { + log.info( "Warm-up..." ); + Executor executor = null; + SearchProductQueryBuilder searchProduct = new SearchProductQueryBuilder( random, valuesPool, config ); + for ( int i = 0; i < config.numberOfWarmUpIterations; i++ ) { + try { + executor = executorFactory.createExecutorInstance( null, NAMESPACE ); + executor.executeQuery( searchProduct.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 ); + } + } + } + + + private class EvaluationThread extends Thread { + + private final Executor executor; + private final List theQueryList; + private boolean abort = false; + @Setter + private EvaluationThreadMonitor threadMonitor; + + + EvaluationThread( List queryList, Executor executor ) { + super( "EvaluationThread" ); + this.executor = executor; + theQueryList = queryList; + } + + + @Override + public void run() { + long measuredTimeStart; + long measuredTime; + QueryListEntry queryListEntry; + + while ( !theQueryList.isEmpty() && !abort ) { + measuredTimeStart = System.nanoTime(); + try { + queryListEntry = theQueryList.remove( 0 ); + } catch ( IndexOutOfBoundsException e ) { // This is neither nice nor efficient... + // This can happen due to concurrency if two threads enter the while-loop and there is only one thread left + // Simply leaf the loop + break; + } + try { + executor.executeQuery( queryListEntry.query ); + } catch ( ExecutorException e ) { + log.error( "Caught exception while executing queries", e ); + threadMonitor.notifyAboutError( e ); + try { + executor.executeRollback(); + } catch ( ExecutorException ex ) { + log.error( "Error while rollback", e ); + } + throw new RuntimeException( e ); + } + measuredTime = System.nanoTime() - measuredTimeStart; + measuredTimes.add( measuredTime ); + measuredTimePerQueryType.get( queryListEntry.templateId ).add( measuredTime ); + if ( commitAfterEveryQuery ) { + try { + executor.executeCommit(); + } catch ( ExecutorException e ) { + log.error( "Caught exception while committing", e ); + threadMonitor.notifyAboutError( e ); + try { + executor.executeRollback(); + } catch ( ExecutorException ex ) { + log.error( "Error while rollback", e ); + } + throw new RuntimeException( e ); + } + } + } + + try { + executor.executeCommit(); + } catch ( ExecutorException e ) { + log.error( "Caught exception while committing", e ); + threadMonitor.notifyAboutError( e ); + try { + executor.executeRollback(); + } catch ( ExecutorException ex ) { + log.error( "Error while rollback", e ); + } + throw new RuntimeException( e ); + } + + executor.flushCsvWriter(); + } + + + public void abort() { + this.abort = true; + } + + + public void closeExecutor() { + commitAndCloseExecutor( executor ); + } + + } + + + private class EvaluationThreadMonitor { + + private final List threads; + @Getter + private Exception exception; + @Getter + private boolean aborted; + + + public EvaluationThreadMonitor( List threads ) { + this.threads = threads; + this.aborted = false; + } + + + public void abortAll() { + this.aborted = true; + threads.forEach( EvaluationThread::abort ); + } + + + public void notifyAboutError( Exception e ) { + exception = e; + abortAll(); + } + + } + + + @Override + public void analyze( Properties properties, File outputDirectory ) { + properties.put( "measuredTime", calculateMean( measuredTimes ) ); + measuredTimePerQueryType.forEach( ( templateId, time ) -> { + calculateResults( queryTypes, properties, templateId, time ); + } ); + properties.put( "queryTypes_maxId", queryTypes.size() ); + } + + + @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().getMongoQl() ); + 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/docbench/DocBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/docbench/DocBenchConfig.java new file mode 100644 index 00000000..c7cf531f --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/docbench/DocBenchConfig.java @@ -0,0 +1,141 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-13.06.22, 13:51 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.docbench; + + +import java.util.Arrays; +import java.util.Map; +import java.util.Properties; +import org.polypheny.simpleclient.scenario.AbstractConfig; + +public class DocBenchConfig extends AbstractConfig { + + public final long seed; + + public final int numberOfWarmUpIterations; + public final int batchSize; + public final int numberOfQueries; + public final int numberOfDocuments; + public final int maxNumberOfAttributes; + public final int minNumberOfAttributes; + public final int sizeOfAttributesPool; + public final int sizeOfValuesPool; + public final int valuesStringMaxLength; + public final int valuesStringMinLength; + + + public DocBenchConfig( Properties properties, int multiplier ) { + super( "docbench", "polypheny-mongoql" ); + + pdbBranch = null; + puiBranch = null; + buildUi = false; + resetCatalog = false; + memoryCatalog = false; + deployStoresUsingDocker = false; + + dataStores.add( "hsqldb" ); + planAndImplementationCaching = "Both"; + + router = "icarus"; // For old routing, to be removed + + routers = new String[]{ "Simple", "Icarus", "FullPlacement" }; + newTablePlacementStrategy = "Single"; + planSelectionStrategy = "Best"; + preCostRatio = 50; + postCostRatio = 50; + routingCache = true; + postCostAggregation = "onWarmup"; + + progressReportBase = getIntProperty( properties, "progressReportBase" ); + numberOfThreads = getIntProperty( properties, "numberOfThreads" ); + + seed = getLongProperty( properties, "seed" ); + numberOfWarmUpIterations = getIntProperty( properties, "numberOfWarmUpIterations" ); + batchSize = getIntProperty( properties, "batchSize" ); + + numberOfQueries = getIntProperty( properties, "numberOfQueries" ); + + numberOfDocuments = getIntProperty( properties, "numberOfDocuments" ); + minNumberOfAttributes = getIntProperty( properties, "minNumberOfAttributes" ); + maxNumberOfAttributes = getIntProperty( properties, "maxNumberOfAttributes" ); + sizeOfAttributesPool = getIntProperty( properties, "sizeOfAttributesPool" ); + sizeOfValuesPool = getIntProperty( properties, "sizeOfValuesPool" ); + valuesStringMinLength = getIntProperty( properties, "valuesStringMinLength" ); + valuesStringMaxLength = getIntProperty( properties, "valuesStringMaxLength" ); + } + + + public DocBenchConfig( Map cdl ) { + super( "docbench", cdl.get( "store" ) ); + + pdbBranch = cdl.get( "pdbBranch" ); + puiBranch = "master"; + buildUi = false; + + resetCatalog = true; + memoryCatalog = Boolean.parseBoolean( cdl.get( "memoryCatalog" ) ); + + dataStores.addAll( Arrays.asList( cdl.get( "dataStore" ).split( "_" ) ) ); + deployStoresUsingDocker = Boolean.parseBoolean( cdlGetOrDefault( cdl, "deployStoresUsingDocker", "true" ) ); + + router = cdl.get( "router" ); // For old routing, to be removed + + routers = cdlGetOrDefault( cdl, "routers", "Simple_Icarus_FullPlacement" ).split( "_" ); + newTablePlacementStrategy = cdlGetOrDefault( cdl, "newTablePlacementStrategy", "Single" ); + planSelectionStrategy = cdlGetOrDefault( cdl, "planSelectionStrategy", "Best" ); + + preCostRatio = Integer.parseInt( cdlGetOrDefault( cdl, "preCostRatio", "50%" ).replace( "%", "" ).trim() ); + postCostRatio = Integer.parseInt( cdlGetOrDefault( cdl, "postCostRatio", "50%" ).replace( "%", "" ).trim() ); + routingCache = Boolean.parseBoolean( cdlGetOrDefault( cdl, "routingCache", "true" ) ); + postCostAggregation = cdlGetOrDefault( cdl, "postCostAggregation", "onWarmup" ); + + planAndImplementationCaching = cdlGetOrDefault( cdl, "planAndImplementationCaching", "Both" ); + + progressReportBase = 100; + numberOfThreads = Integer.parseInt( cdl.get( "numberOfThreads" ) ); + + seed = Integer.parseInt( cdl.get( "seed" ) ); + numberOfWarmUpIterations = Integer.parseInt( cdl.get( "numberOfWarmUpIterations" ) ); + batchSize = Integer.parseInt( cdl.get( "batchSize" ) ); + + numberOfQueries = Integer.parseInt( cdl.get( "numberOfQueries" ) ); + + numberOfDocuments = Integer.parseInt( cdl.get( "numberOfDocuments" ) ); + minNumberOfAttributes = Integer.parseInt( cdl.get( "minNumberOfAttributes" ) ); + maxNumberOfAttributes = Integer.parseInt( cdl.get( "maxNumberOfAttributes" ) ); + sizeOfAttributesPool = Integer.parseInt( cdl.get( "sizeOfAttributesPool" ) ); + sizeOfValuesPool = Integer.parseInt( cdl.get( "sizeOfValuesPool" ) ); + valuesStringMinLength = Integer.parseInt( cdl.get( "valuesStringMinLength" ) ); + valuesStringMaxLength = Integer.parseInt( cdl.get( "valuesStringMaxLength" ) ); + } + + + @Override + public boolean usePreparedBatchForDataInsertion() { + return false; + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/docbench/MongoQlInsertQuery.java b/src/main/java/org/polypheny/simpleclient/scenario/docbench/MongoQlInsertQuery.java new file mode 100644 index 00000000..ebff069a --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/docbench/MongoQlInsertQuery.java @@ -0,0 +1,106 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-13.06.22, 15:47 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.docbench; + +import com.google.gson.JsonObject; +import java.util.Map; +import kong.unirest.HttpRequest; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.BatchableInsert; + + +@Slf4j +public class MongoQlInsertQuery extends BatchableInsert { + + @Getter + private final String mongoQl; + private final String collection; + private final String expression; + + + public MongoQlInsertQuery( String collection, String expression, boolean expectResult ) { + super( expectResult ); + this.mongoQl = "db." + collection + ".insert({" + expression + ")"; + this.collection = collection; + this.expression = expression; + } + + + @Override + public String getSqlRowExpression() { + throw new UnsupportedOperationException(); + } + + + @Override + public String getParameterizedSqlQuery() { + throw new UnsupportedOperationException(); + } + + + @Override + public Map> getParameterValues() { + throw new UnsupportedOperationException(); + } + + + @Override + public JsonObject getRestRowExpression() { + throw new UnsupportedOperationException(); + } + + + @Override + public String getMongoQlRowExpression() { + return expression; + } + + + @Override + public String getEntity() { + return collection; + } + + + @Override + public String getSql() { + throw new UnsupportedOperationException(); + } + + + @Override + public HttpRequest getRest() { + throw new UnsupportedOperationException(); + } + + + @Override + public void debug() { + log.debug( mongoQl ); + } + +} \ No newline at end of file diff --git a/src/main/java/org/polypheny/simpleclient/scenario/docbench/MongoQlQuery.java b/src/main/java/org/polypheny/simpleclient/scenario/docbench/MongoQlQuery.java new file mode 100644 index 00000000..da741071 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/docbench/MongoQlQuery.java @@ -0,0 +1,77 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019-13.06.22, 15:47 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.docbench; + +import java.util.Map; +import kong.unirest.HttpRequest; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; + + +@Slf4j +public class MongoQlQuery extends Query { + + @Getter + private final String mongoQl; + + + public MongoQlQuery( String query, boolean expectResult ) { + super( expectResult ); + this.mongoQl = query; + } + + + @Override + public String getParameterizedSqlQuery() { + throw new UnsupportedOperationException(); + } + + + @Override + public Map> getParameterValues() { + throw new UnsupportedOperationException(); + } + + + @Override + public String getSql() { + throw new UnsupportedOperationException(); + } + + + @Override + public HttpRequest getRest() { + throw new UnsupportedOperationException(); + } + + + @Override + public void debug() { + log.debug( mongoQl ); + } + +} \ No newline at end of file diff --git a/src/main/java/org/polypheny/simpleclient/scenario/docbench/queryBuilder/PutProductQueryBuilder.java b/src/main/java/org/polypheny/simpleclient/scenario/docbench/queryBuilder/PutProductQueryBuilder.java new file mode 100644 index 00000000..8b5697f5 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/docbench/queryBuilder/PutProductQueryBuilder.java @@ -0,0 +1,77 @@ +/* + * 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.docbench.queryBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.polypheny.simpleclient.scenario.docbench.DataGenerator; +import org.polypheny.simpleclient.scenario.docbench.DocBenchConfig; +import org.polypheny.simpleclient.scenario.docbench.MongoQlInsertQuery; + + +public class PutProductQueryBuilder extends QueryBuilder { + + private final Random random; + private final DocBenchConfig config; + + private final List valuesPool; + + + public PutProductQueryBuilder( Random random, List valuesPool, DocBenchConfig config ) { + this.random = random; + this.config = config; + this.valuesPool = valuesPool; + } + + + @Override + public BatchableInsert getNewQuery() { + int numberOfAttributes = DataGenerator.boundedRandom( random, config.minNumberOfAttributes, config.maxNumberOfAttributes ); + + // Build attributes pool + List attributesPool = new ArrayList<>( config.sizeOfAttributesPool ); + for ( int i = 0; i < config.sizeOfAttributesPool; i++ ) { + attributesPool.add( "attribute" + i ); + } + + // Build query + StringBuilder expression = new StringBuilder( "{" ); + for ( int i = 0; i < numberOfAttributes; i++ ) { + String key = attributesPool.get( random.nextInt( config.sizeOfAttributesPool - i ) ); + String value = valuesPool.get( random.nextInt( config.sizeOfValuesPool - 1 ) ); + if ( i > 0 ) { + expression.append( "," ); + } + expression.append( "\"" ).append( key ).append( "\":\"" ).append( value ).append( "\"" ); + } + expression.append( "}" ); + return new MongoQlInsertQuery( "product", expression.toString(), false ); + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/docbench/queryBuilder/SearchProductQueryBuilder.java b/src/main/java/org/polypheny/simpleclient/scenario/docbench/queryBuilder/SearchProductQueryBuilder.java new file mode 100644 index 00000000..6f0add75 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/docbench/queryBuilder/SearchProductQueryBuilder.java @@ -0,0 +1,58 @@ +/* + * 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.docbench.queryBuilder; + +import java.util.List; +import java.util.Random; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; +import org.polypheny.simpleclient.scenario.docbench.DocBenchConfig; +import org.polypheny.simpleclient.scenario.docbench.MongoQlQuery; + + +public class SearchProductQueryBuilder extends QueryBuilder { + + private final Random random; + private final DocBenchConfig config; + private final List valuesPool; + + + public SearchProductQueryBuilder( Random random, List valuesPool, DocBenchConfig config ) { + this.random = random; + this.config = config; + this.valuesPool = valuesPool; + } + + + @Override + public Query getNewQuery() { + String attribute = "attribute" + random.nextInt( config.sizeOfAttributesPool ); + String value = valuesPool.get( random.nextInt( config.sizeOfValuesPool ) ); + + // Find all products (documents) having a field with the name "attribute" and containing "value" + return new MongoQlQuery( "db.product.find({\"" + attribute + "\":\"" + value + "\"})", true ); + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/gavel/DataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/gavel/DataGenerator.java index 0c9c99ff..64671870 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/gavel/DataGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/gavel/DataGenerator.java @@ -206,7 +206,6 @@ void generateAuctions( int start, int end ) throws ExecutorException { } executeInsertList(); } - } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/gavel/Gavel.java b/src/main/java/org/polypheny/simpleclient/scenario/gavel/Gavel.java index 69109fe9..255387f6 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/gavel/Gavel.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/gavel/Gavel.java @@ -83,7 +83,6 @@ public class Gavel extends Scenario { private final GavelConfig config; - private final List measuredTimes; private final Map queryTypes; private final Map> measuredTimePerQueryType; @@ -101,7 +100,6 @@ public Gavel( JdbcExecutor.ExecutorFactory executorFactory, GavelConfig config, @Override public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, File outputDirectory, int numberOfThreads ) { - log.info( "Analyzing currently stored data..." ); Map numbers = getNumbers(); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/gavel/GavelConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/gavel/GavelConfig.java index 2aff75f2..bd5c166c 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/gavel/GavelConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/gavel/GavelConfig.java @@ -78,7 +78,7 @@ public class GavelConfig extends AbstractConfig { public GavelConfig( Properties properties, int multiplier ) { - super( "gavel", "polypheny" ); + super( "gavel", "polypheny-jdbc" ); pdbBranch = null; puiBranch = null; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertAuction.java b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertAuction.java index 2ed43a39..586d8a97 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertAuction.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertAuction.java @@ -177,7 +177,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.auction"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertBid.java b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertBid.java index 199f53e5..e9842223 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertBid.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertBid.java @@ -157,7 +157,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.bid"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertCategory.java b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertCategory.java index e202389e..8cf8e7bf 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertCategory.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertCategory.java @@ -149,7 +149,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.category"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertPicture.java b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertPicture.java index 34a14653..2a456918 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertPicture.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertPicture.java @@ -143,7 +143,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.picture"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertUser.java b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertUser.java index e7cda3ff..5ccdae59 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertUser.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/gavel/queryBuilder/InsertUser.java @@ -216,7 +216,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.user"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/graph/GraphBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/graph/GraphBenchConfig.java index a10db6db..9a288007 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/graph/GraphBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/graph/GraphBenchConfig.java @@ -68,7 +68,7 @@ public class GraphBenchConfig extends AbstractConfig { public GraphBenchConfig( Properties properties, int multiplier ) { - super( "graph", "polypheny" ); + super( "graph", "polypheny-cypher" ); pdbBranch = null; puiBranch = null; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/graph/GraphInsert.java b/src/main/java/org/polypheny/simpleclient/scenario/graph/GraphInsert.java index 1bb381f5..814a8e59 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/graph/GraphInsert.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/graph/GraphInsert.java @@ -65,7 +65,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { throw new RuntimeException( "getTable() is not supported for graph queries!" ); } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBenchConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBenchConfig.java index 73cb41f1..b77b09bf 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBenchConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/KnnBenchConfig.java @@ -62,7 +62,7 @@ public class KnnBenchConfig extends AbstractConfig { public KnnBenchConfig( Properties properties, int multiplier ) { - super( "knnBench", "polypheny" ); + super( "knnBench", "polypheny-jdbc" ); pdbBranch = null; puiBranch = null; diff --git a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertIntFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertIntFeature.java index 85046c29..59203027 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertIntFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertIntFeature.java @@ -127,7 +127,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.knn_intfeature"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertMetadata.java b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertMetadata.java index 7c916407..ba3bb9fd 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertMetadata.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertMetadata.java @@ -99,7 +99,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.knn_metadata"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertRealFeature.java b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertRealFeature.java index 4b1aed2f..7d85b998 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertRealFeature.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/knnbench/queryBuilder/InsertRealFeature.java @@ -127,7 +127,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.knn_realfeature"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertAlbum.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertAlbum.java index 1c759015..61a07fe7 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertAlbum.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertAlbum.java @@ -146,7 +146,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.album"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertFriends.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertFriends.java index 141155b3..fbac75e2 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertFriends.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertFriends.java @@ -124,7 +124,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.followers"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertMedia.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertMedia.java index cc71a134..6b24e043 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertMedia.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertMedia.java @@ -153,7 +153,7 @@ public String getMongoQl() { @Override public JsonObject getRestRowExpression() { JsonObject set = new JsonObject(); - String table = getTable() + "."; + String table = getEntity() + "."; set.add( table + "id", new JsonPrimitive( id ) ); set.add( table + "timestamp", new JsonPrimitive( timestamp.toLocalDateTime().format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) ) ); set.add( table + "album_id", new JsonPrimitive( album_id ) ); @@ -165,7 +165,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.media"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertRandomTimeline.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertRandomTimeline.java index d554f9f5..11fe91ae 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertRandomTimeline.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertRandomTimeline.java @@ -171,7 +171,7 @@ public String getMongoQl() { @Override public JsonObject getRestRowExpression() { JsonObject set = new JsonObject(); - String table = getTable() + "."; + String table = getEntity() + "."; set.add( table + "id", new JsonPrimitive( timelineId ) ); set.add( table + "timestamp", new JsonPrimitive( timestamp.toLocalDateTime().format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) ) ); set.add( table + "user_id", new JsonPrimitive( userId ) ); @@ -184,7 +184,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.timeline"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertTimeline.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertTimeline.java index 75a59050..f4372159 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertTimeline.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertTimeline.java @@ -158,7 +158,7 @@ public String getMongoQl() { @Override public JsonObject getRestRowExpression() { JsonObject set = new JsonObject(); - String table = getTable() + "."; + String table = getEntity() + "."; set.add( table + "id", new JsonPrimitive( timelineId ) ); set.add( table + "timestamp", new JsonPrimitive( timestamp.toLocalDateTime().format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) ) ); set.add( table + "user_id", new JsonPrimitive( userId ) ); @@ -172,7 +172,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.timeline"; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertUser.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertUser.java index b4ef2f59..2173ffab 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertUser.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertUser.java @@ -155,7 +155,7 @@ public String getMongoQl() { @Override public JsonObject getRestRowExpression() { JsonObject set = new JsonObject(); - String table = getTable() + "."; + String table = getEntity() + "."; set.add( table + "id", new JsonPrimitive( id ) ); set.add( table + "firstname", new JsonPrimitive( firstName ) ); set.add( table + "lastname", new JsonPrimitive( lastName ) ); @@ -168,7 +168,7 @@ public JsonObject getRestRowExpression() { @Override - public String getTable() { + public String getEntity() { return "public.users"; } diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/docbench/docbench.properties b/src/main/resources/org/polypheny/simpleclient/scenario/docbench/docbench.properties new file mode 100644 index 00000000..09d69427 --- /dev/null +++ b/src/main/resources/org/polypheny/simpleclient/scenario/docbench/docbench.properties @@ -0,0 +1,20 @@ +scenario = "docbench" + +seed = 4589589544 + +numberOfThreads = 4 +numberOfWarmUpIterations = 4 +progressReportBase = 100 + +batchSize = 100 +queryMode = Table + +numberOfQueries = 10000 + +numberOfDocuments = 10000 +maxNumberOfAttributes = 100 +minNumberOfAttributes = 5 +sizeOfAttributesPool = 1000 +sizeOfValuesPool = 1000 +valuesStringMaxLength = 25 +valuesStringMinLength = 25 \ No newline at end of file