Skip to content

Commit ddb4bfa

Browse files
committed
Add DocBench benchmark
1 parent dd7f060 commit ddb4bfa

43 files changed

Lines changed: 1229 additions & 60 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ A simple benchmarking and testing client for Polypheny-DB. It includes support f
66
* **kNN-Bench**: A benchmark tailored towards typical workloads of multimedia retrieval applications and especially k-Nearest-Neighbor search.
77
* **Multimedia**: This benchmarks produces workload containing or requesting randomly generated BLOBs.
88
* **Graph**: A simple synthetic graph benchmark that executes a mixture of DQL and DML Cypher queries against a pseudo-random network.
9+
* **DocBench**: A simple benchmark for document schemas generating MongoQL queries.
910
* [**AuctionMark**](http://hstore.cs.brown.edu/projects/auctionmark/): A benchmark executing workload that simulates the activities found in a well-known auction site.
1011
* [**SmallBank**](http://ses.library.usyd.edu.au/bitstream/2123/5353/1/michael-cahill-2009-thesis.pdf): The SmallBank benchmark models a simple banking application.
1112
* [**TPC-C**](http://www.tpc.org/tpcc/): A well-known on-line transaction processing (OLTP) benchmark.
@@ -56,19 +57,19 @@ OPTIONS
5657

5758
### Stand-alone
5859

59-
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:
60+
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:
6061

6162
```
62-
java -jar polypheny-simple-client.jar help gavel
63+
java -jar polypheny-simple-client.jar BENCHMARK TASK [ MULTIPLIER ]
6364
```
6465

65-
The general syntax is identical for all three benchmarks:
66+
Use the `help` command to get an overview on all available parameters for a benchmark. For example:
6667

6768
```
68-
java -jar polypheny-simple-client.jar BENCHMARK TASK [ MULTIPLIER ]
69+
java -jar polypheny-simple-client.jar help gavel
6970
```
7071

71-
_BENCHMARK_: `{ gavel | knnbench | multimedia | auctionmark | smallbank | tpcc | tpch | ycsb }`
72+
_BENCHMARK_: `{ gavel | knnbench | multimedia | graph | docbench | auctionmark | smallbank | tpcc | tpch | ycsb }`
7273

7374
_TASK_: `{ schema | data | workload | warmup }`
7475

build.gradle

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ buildscript {
1919
classpath group: "gradle.plugin.com.github.johnrengelman", name: "shadow", version: "7.1.2"
2020
// Lombok (https://plugins.gradle.org/plugin/io.freefair.lombok)
2121
classpath group: "io.freefair.gradle", name: "lombok-plugin", version: "6.4.3"
22+
// https://plugins.gradle.org/plugin/org.jetbrains.gradle.plugin.idea-ext
23+
classpath group: "gradle.plugin.org.jetbrains.gradle.plugin.idea-ext", name: "gradle-idea-ext", version: "1.1.4"
2224
}
2325
}
2426

25-
2627
repositories {
2728
mavenCentral()
2829
maven {
@@ -31,7 +32,7 @@ repositories {
3132
}
3233

3334
apply plugin: "java-library"
34-
apply plugin: "idea"
35+
apply plugin: "org.jetbrains.gradle.plugin.idea-ext"
3536
apply plugin: "io.freefair.lombok"
3637
apply plugin: "com.github.johnrengelman.shadow"
3738

@@ -168,4 +169,37 @@ idea {
168169
outputDir = file("${project.buildDir}/classes")
169170
testOutputDir = file("${project.buildDir}/test-classes")
170171
}
172+
project {
173+
settings {
174+
copyright {
175+
useDefault = "MITLicense"
176+
profiles {
177+
MITLicense {
178+
notice = 'The MIT License (MIT)\n' +
179+
'\n' +
180+
'Copyright (c) 2019-$today The Polypheny Project\n' +
181+
'\n' +
182+
'Permission is hereby granted, free of charge, to any person obtaining a\n' +
183+
'copy of this software and associated documentation files (the "Software"), to deal\n' +
184+
'in the Software without restriction, including without limitation the rights\n' +
185+
'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n' +
186+
'copies of the Software, and to permit persons to whom the Software is\n' +
187+
'furnished to do so, subject to the following conditions:\n' +
188+
'\n' +
189+
'The above copyright notice and this permission notice shall be included in all\n' +
190+
'copies or substantial portions of the Software.\n' +
191+
'\n' +
192+
'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n' +
193+
'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n' +
194+
'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n' +
195+
'AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n' +
196+
'LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n' +
197+
'OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n' +
198+
'SOFTWARE.'
199+
keyword = "Copyright"
200+
}
201+
}
202+
}
203+
}
204+
}
171205
}

src/main/java/org/polypheny/simpleclient/cli/AbstractOltpBenchCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public int run() throws SQLException {
8484
System.err.println( "Unknown task: " + args.get( 0 ) );
8585
}
8686
} catch ( Throwable t ) {
87-
log.error( "Exception while executing KnnBench!", t );
87+
log.error( "Exception while executing OltpBench!", t );
8888
System.exit( 1 );
8989
}
9090

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019-2022 The Polypheny Project
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a
7+
* copy of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package org.polypheny.simpleclient.cli;
26+
27+
import com.github.rvesse.airline.HelpOption;
28+
import com.github.rvesse.airline.annotations.Arguments;
29+
import com.github.rvesse.airline.annotations.Command;
30+
import com.github.rvesse.airline.annotations.Option;
31+
import java.sql.SQLException;
32+
import java.util.List;
33+
import javax.inject.Inject;
34+
import lombok.extern.slf4j.Slf4j;
35+
import org.polypheny.simpleclient.executor.Executor.ExecutorFactory;
36+
import org.polypheny.simpleclient.executor.PolyphenyDbMongoQlExecutor.PolyphenyDbMongoQlExecutorFactory;
37+
import org.polypheny.simpleclient.main.DocBenchScenario;
38+
39+
40+
@Slf4j
41+
@Command(name = "docbench", description = "Mode for quick testing of Polypheny-DB using the DocBench benchmark.")
42+
public class DocBenchCommand implements CliRunnable {
43+
44+
@SuppressWarnings("SpringAutowiredFieldsWarningInspection")
45+
@Inject
46+
private HelpOption<DocBenchCommand> help;
47+
48+
@Arguments(description = "Task { schema | data | workload } and multiplier.")
49+
private List<String> args;
50+
51+
52+
@Option(name = { "-pdb", "--polyphenydb" }, title = "IP or Hostname", arity = 1, description = "IP or Hostname of the Polypheny-DB server (default: 127.0.0.1).")
53+
public static String polyphenyDbHost = "127.0.0.1";
54+
55+
56+
@Option(name = { "--writeCSV" }, arity = 0, description = "Write a CSV file containing execution times for all executed queries (default: false).")
57+
public boolean writeCsv = false;
58+
59+
60+
@Option(name = { "--queryList" }, arity = 0, description = "Dump all queries into a file (default: false).")
61+
public boolean dumpQueryList = false;
62+
63+
64+
@Override
65+
public int run() throws SQLException {
66+
if ( args == null || args.size() < 1 ) {
67+
System.err.println( "Missing task" );
68+
System.exit( 1 );
69+
}
70+
71+
int multiplier = 1;
72+
if ( args.size() > 1 ) {
73+
multiplier = Integer.parseInt( args.get( 1 ) );
74+
if ( multiplier < 1 ) {
75+
System.err.println( "Multiplier needs to be a integer > 0!" );
76+
System.exit( 1 );
77+
}
78+
}
79+
80+
ExecutorFactory executorFactory = new PolyphenyDbMongoQlExecutorFactory( polyphenyDbHost );
81+
82+
try {
83+
if ( args.get( 0 ).equalsIgnoreCase( "data" ) ) {
84+
DocBenchScenario.data( executorFactory, multiplier, true );
85+
} else if ( args.get( 0 ).equalsIgnoreCase( "workload" ) ) {
86+
DocBenchScenario.workload( executorFactory, multiplier, true, writeCsv, dumpQueryList );
87+
} else if ( args.get( 0 ).equalsIgnoreCase( "schema" ) ) {
88+
DocBenchScenario.schema( executorFactory, true );
89+
} else if ( args.get( 0 ).equalsIgnoreCase( "warmup" ) ) {
90+
DocBenchScenario.warmup( executorFactory, multiplier, true, dumpQueryList );
91+
} else {
92+
System.err.println( "Unknown task: " + args.get( 0 ) );
93+
}
94+
} catch ( Throwable t ) {
95+
log.error( "Exception while executing DocBench!", t );
96+
System.exit( 1 );
97+
}
98+
99+
try {
100+
Thread.sleep( 2000 );
101+
} catch ( InterruptedException e ) {
102+
throw new RuntimeException( "Unexpected interrupt", e );
103+
}
104+
105+
return 0;
106+
}
107+
108+
}

src/main/java/org/polypheny/simpleclient/cli/GraphCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public int run() throws SQLException {
9292
System.err.println( "Unknown task: " + args.get( 0 ) );
9393
}
9494
} catch ( Throwable t ) {
95-
log.error( "Exception while executing KnnBench!", t );
95+
log.error( "Exception while executing GraphBench!", t );
9696
System.exit( 1 );
9797
}
9898

src/main/java/org/polypheny/simpleclient/cli/Main.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public static void main( String[] args ) throws SQLException {
4343
builder.withCommands( KnnCommand.class );
4444
builder.withCommands( MultimediaCommand.class );
4545
builder.withCommands( GraphCommand.class );
46+
builder.withCommands( DocBenchCommand.class );
4647
builder.withCommands( AuctionMarkCommand.class );
4748
builder.withCommands( SmallBankCommand.class );
4849
builder.withCommands( TpccCommand.class );

src/main/java/org/polypheny/simpleclient/executor/Executor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ public Executor createExecutorInstance() {
5959

6060
public abstract Executor createExecutorInstance( CsvWriter csvWriter );
6161

62+
63+
public Executor createExecutorInstance( CsvWriter csvWriter, String namespace ) {
64+
return createExecutorInstance( csvWriter );
65+
}
66+
67+
6268
// Allows to limit number of concurrent executor threads, 0 means no limit
6369
public abstract int getMaxNumberOfThreads();
6470

src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbCypherExecutor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ public PolyphenyDbCypherExecutor( String host, CsvWriter csvWriter ) {
4949

5050

5151
@Override
52-
protected HttpRequest<?> buildQuery( String query ) {
52+
protected HttpRequest<?> buildQuery( String query, String namespace ) {
5353
JsonObject data = new JsonObject();
5454
data.addProperty( "query", query );
55-
data.addProperty( "database", "test" );
55+
data.addProperty( "database", namespace );
5656
return Unirest.post( "{protocol}://{host}:{port}/cypher" )
5757
.header( "Content-Type", "application/json" )
5858
.body( data );

src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbHttpExecutor.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public abstract class PolyphenyDbHttpExecutor implements PolyphenyDbExecutor {
4949
@Getter
5050
public final String name;
5151

52+
@Getter
53+
String namespace;
54+
5255
@Getter
5356
public final Function<Query, String> queryAccessor;
5457

@@ -140,7 +143,7 @@ public long executeQuery( Query query ) throws ExecutorException {
140143
}
141144
long time;
142145

143-
HttpRequest<?> request = getRequest( queryAccessor.apply( query ) );
146+
HttpRequest<?> request = getRequest( queryAccessor.apply( query ), namespace );
144147
try {
145148
long start = System.nanoTime();
146149
@SuppressWarnings("rawtypes") HttpResponse result = request.asBytes();
@@ -159,19 +162,19 @@ public long executeQuery( Query query ) throws ExecutorException {
159162
}
160163

161164

162-
HttpRequest<?> buildQuery( String mql ) {
165+
HttpRequest<?> buildQuery( String mql, String namespace ) {
163166
JsonObject data = new JsonObject();
164167
data.addProperty( "query", mql );
165-
data.addProperty( "database", "test" );
168+
data.addProperty( "database", namespace );
166169

167170
return Unirest.post( "{protocol}://{host}:{port}/" + name.toLowerCase( Locale.ROOT ) )
168171
.header( "Content-Type", "application/json" )
169172
.body( data );
170173
}
171174

172175

173-
HttpRequest<?> getRequest( String query ) {
174-
HttpRequest<?> request = buildQuery( query );
176+
HttpRequest<?> getRequest( String query, String namespace ) {
177+
HttpRequest<?> request = buildQuery( query, namespace );
175178
request.basicAuth( "pa", "" );
176179
request.routeParam( "protocol", "http" );
177180
request.routeParam( "host", "127.0.0.1" );
@@ -187,7 +190,7 @@ public long executeQueryAndGetNumber( Query query ) throws ExecutorException {
187190
throw new RuntimeException( "not supported" );
188191
}
189192

190-
HttpRequest<?> request = getRequest( queryAccessor.apply( query ) );
193+
HttpRequest<?> request = getRequest( queryAccessor.apply( query ), namespace );
191194

192195
try {
193196
long start = System.nanoTime();

src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbMongoQlExecutor.java

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@
4444
@Slf4j
4545
public class PolyphenyDbMongoQlExecutor extends PolyphenyDbHttpExecutor {
4646

47+
public static final String DEFAULT_NAMESPACE = "test";
4748

48-
public PolyphenyDbMongoQlExecutor( String host, CsvWriter csvWriter ) {
49+
50+
public PolyphenyDbMongoQlExecutor( String host, CsvWriter csvWriter, String namespace ) {
4951
super( "Mongo", Query::getMongoQl, host, csvWriter );
52+
this.namespace = namespace;
5053
}
5154

5255

@@ -60,7 +63,7 @@ public long executeQuery( Query query ) throws ExecutorException {
6063
}
6164
long time;
6265

63-
HttpRequest<?> request = getRequest( query.getMongoQl() );
66+
HttpRequest<?> request = getRequest( query.getMongoQl(), namespace );
6467
log.debug( request.getUrl() );
6568
try {
6669
long start = System.nanoTime();
@@ -87,7 +90,7 @@ public long executeQueryAndGetNumber( Query query ) throws ExecutorException {
8790
throw new RuntimeException( "not supported" );
8891
}
8992

90-
HttpRequest<?> request = getRequest( query.getMongoQl() );
93+
HttpRequest<?> request = getRequest( query.getMongoQl(), namespace );
9194
log.debug( request.getUrl() );
9295
try {
9396
long start = System.nanoTime();
@@ -131,25 +134,25 @@ public void closeConnection() throws ExecutorException {
131134

132135
@Override
133136
public void executeInsertList( List<BatchableInsert> batchList, AbstractConfig config ) throws ExecutorException {
134-
String currentTable = null;
135-
List<String> rows = new ArrayList<>();
137+
String currentDocument = null;
138+
List<String> documents = new ArrayList<>();
136139
for ( BatchableInsert query : batchList ) {
137140
query.debug();
138141
if ( query instanceof MultipartInsert ) {
139142
continue;
140143
}
141-
if ( currentTable == null ) {
142-
currentTable = query.getTable();
144+
if ( currentDocument == null ) {
145+
currentDocument = query.getEntity();
143146
}
144147

145-
if ( currentTable.equals( query.getTable() ) ) {
146-
rows.add( Objects.requireNonNull( query.getMongoQlRowExpression() ) );
148+
if ( currentDocument.equals( query.getEntity() ) ) {
149+
documents.add( Objects.requireNonNull( query.getMongoQlRowExpression() ) );
147150
} else {
148151
throw new RuntimeException( "Different tables in multi-inserts. This should not happen!" );
149152
}
150153
}
151-
if ( rows.size() > 0 ) {
152-
executeQuery( new RawQuery( null, null, Query.buildMongoQlManyInsert( currentTable, rows ), null, false ) );
154+
if ( documents.size() > 0 ) {
155+
executeQuery( new RawQuery( null, null, Query.buildMongoQlManyInsert( currentDocument, documents ), null, false ) );
153156
}
154157
}
155158

@@ -166,7 +169,13 @@ public PolyphenyDbMongoQlExecutorFactory( String host ) {
166169

167170
@Override
168171
public PolyphenyDbMongoQlExecutor createExecutorInstance( CsvWriter csvWriter ) {
169-
return new PolyphenyDbMongoQlExecutor( host, csvWriter );
172+
return new PolyphenyDbMongoQlExecutor( host, csvWriter, DEFAULT_NAMESPACE );
173+
}
174+
175+
176+
@Override
177+
public Executor createExecutorInstance( CsvWriter csvWriter, String namespace ) {
178+
return new PolyphenyDbMongoQlExecutor( host, csvWriter, namespace );
170179
}
171180

172181

0 commit comments

Comments
 (0)