Repository: brettwooldridge/HikariCP-benchmark Branch: master Commit: ede3501d4f55 Files: 23 Total size: 116.8 KB Directory structure: gitextract_jdhmdfc8/ ├── .gitignore ├── README.md ├── benchmark.cmd ├── benchmark.sh ├── lib/ │ └── one-datasource.jar ├── pom.xml ├── spiketest.sh └── src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── zaxxer/ │ │ └── hikari/ │ │ └── benchmark/ │ │ ├── BenchBase.java │ │ ├── ConnectionBench.java │ │ ├── StatementBench.java │ │ └── stubs/ │ │ ├── StubConnection.java │ │ ├── StubDataSource.java │ │ ├── StubDriver.java │ │ ├── StubPreparedStatement.java │ │ ├── StubResultSet.java │ │ └── StubStatement.java │ └── resources/ │ └── log4j2-test.xml └── test/ └── java/ ├── com/ │ └── zaxxer/ │ └── hikari/ │ ├── benchmark/ │ │ ├── BandwidthTest.java │ │ ├── DbDownTest.java │ │ └── SpikeLoadTest.java │ └── pool/ │ └── HikariPoolAccessor.java └── org/ └── apache/ └── commons/ └── dbcp2/ ├── DbcpPoolAccessor.java └── TomcatPoolAccessor.java ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ target .classpath .project .settings/org.eclipse.core.resources.prefs .settings/org.eclipse.jdt.core.prefs .settings/org.eclipse.m2e.core.prefs .idea HikariCP-benchmark.iml jmh.out ================================================ FILE: README.md ================================================ [![Dependency Status](https://www.versioneye.com/user/projects/55501400f7db0da74e00017f/badge.svg?style=flat)](https://www.versioneye.com/user/projects/55501400f7db0da74e00017f) ![](https://github.com/brettwooldridge/HikariCP/wiki/HikariCP-bench-2.6.0.png) *ConnectionCycle* measures cycles of ``DataSource.getConnection()/Connection.close()``. *StatementCycle* measures cycles of ``Connection.prepareStatement()``, ``Statement.execute()``, ``Statement.close()``. #### JMH Connection Pool Microbenchmarks This set of microbenchmaks was developed to refine the [HikariCP](https://github.com/brettwooldridge/HikariCP) JDBC connection pool implementation, but it actually runs the same benchmarks across multiple pools. We have come to understand that benchmarking on the JVM, which employs Dead Code Elimination (DCE), lock-coalescing, inlining, loop-unrolling, on-stack replacement (OSR) and a myriad of other tricks, renders most attempts at benchmarking completely invalid -- *including our own original benchmarks*. Read all the things that [even smart] [people get wrong](https://groups.google.com/forum/#!msg/mechanical-sympathy/m4opvy4xq3U/7lY8x8SvHgwJ) about benchmarking on the JVM. The Oracle JVM performance team, primarily Aleksey Shipilёv, developed a microbenchmarking framework called JMH. It provides the infrastructure (if used properly) for accurate comparative measurement of JVM-based execution. If you are interested in microbenchmarking at all, or just curious about all the wonderful things the JVM does, I highly recommend reading [this slideshare](http://www.slideshare.net/ConstantineNosovsky/nosovsky-java-microbenchmarking). #### How to run? * ``git clone https://github.com/brettwooldridge/HikariCP-benchmark.git`` * ``cd HikariCP-benchmark`` * ``mvn clean package`` * ``./benchmark.sh`` The ``benchmark.sh`` script is a wrapper around JMH execution. A full run of the benchmark will take about 45 minutes for all pools. There are several more options you can provide to the ``benchmark.sh``. There are a lot actually, but these are most useful... **Specify Shorter Runs**
There are two options provided by the script: ``quick`` and ``medium``. *quick* will take about 5 minutes to run, *medium* will take about 20 minutes -- for all pools. It is extrememly boring to watch, and you can't do anything else on the PC where the benchmark is running without affecting the results, so have dinner, run some errands, etc. ``` ./benchmark.sh quick ``` If specified with other options, ``quick`` or ``medium`` must be the first option. ----------------------------------------------------------- **Specify Specific Pools**
``` ./benchmark.sh -p pool=hikari,bone ``` Where ``pool`` is a comma-separated list (*hikari*, *dbcp2*, *tomcat*, *c3p0*, *vibur*). Specifying a specific pool or subset of pools will shorten run times. ----------------------------------------------------------- **Specify Pool Size**
``` ./benchmark.sh -p maxPoolSize=16 ``` Pool size is only applicable for the *Connection Cycle* test, attempting to run the *Statement Cycle* test with a pool smaller than the number of threads (8) will result in testing failures. The *Connection Cycle* test runs with 8 threads, so to test a contrained pool condition set *maxPoolSize* to a smaller number (eg. 4). ----------------------------------------------------------- **Specify which Benchmark**
There are two benchmarks in the suite currently: *ConnectionBench* and *StatementBench*. By default both benchmarks are run, but if you want to run one or the other you can use a JMH option using a regex (regular experession) to do so. For example, to only run the *StatementBench* use: ``` ./benchmark.sh ".*Statement.*" ``` ----------------------------------------------------------- All of the options can be combined: ``` ./benchmark.sh medium -p pool=hikari,vibur -p maxPoolSize=4 ".*Connection.*" ``` ----------------------------------------------------------- ================================================ FILE: benchmark.cmd ================================================ @echo off setlocal set JAVA_OPTIONS=-server -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms1096m -Xmx1096m call mvn clean package set JMH_THREADS=-t 8 if "%2" == "-t" ( set JMH_THREADS=-t %3 shift /2 shift /2 ) set command=%~1 if "quick" == "%command%" ( java -jar target\microbenchmarks.jar -jvmArgs "%JAVA_OPTIONS%" -wi 3 -i 8 %JMH_THREADS% -f 2 %2 %3 %4 %5 %6 %7 ) if "medium" == "%command%" ( java -jar target\microbenchmarks.jar -jvmArgs "%JAVA_OPTIONS%" -wi 3 -f 8 -i 6 %JMH_THREADS% %2 %3 %4 %5 %6 %7 ) if "long" == "%command%" ( java -jar target\microbenchmarks.jar -jvmArgs "%JAVA_OPTIONS%" -wi 5 -f 20 -i 15 %JMH_THREADS% %2 %3 %4 %5 %6 %7 ) rem java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -i 15 -t 8 $1 $2 $3 $4 $5 $6 $7 $8 $9 ================================================ FILE: benchmark.sh ================================================ #!/bin/bash JAVA_OPTIONS="-server -XX:-RestrictContended -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms1096m -Xmx1096m" if [[ "clean" == "$1" ]]; then mvn clean package shift fi if [[ "gcprof" == "$1" ]]; then JAVA_OPTIONS="$JAVA_OPTIONS -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps" shift fi JMH_THREADS="-t 8" if [[ "$2" == "-t" ]]; then JMH_THREADS="-t $3" set -- "$1" "${@:4}" fi if [[ "quick" == "$1" ]]; then java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -i 8 $JMH_THREADS -f 2 $2 $3 $4 $5 $6 $7 $8 $9 elif [[ "medium" == "$1" ]]; then java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -f 8 -i 6 $JMH_THREADS $2 $3 $4 $5 $6 $7 $8 $9 elif [[ "long" == "$1" ]]; then java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -i 15 $JMH_THREADS $2 $3 $4 $5 $6 $7 $8 $9 elif [[ "profile" == "$1" ]]; then java -server $JAVA_OPTIONS -agentpath:/Applications/jprofiler8/bin/macos/libjprofilerti.jnilib=port=8849 -jar ./target/microbenchmarks.jar -r 5 -wi 3 -i 8 $JMH_THREADS -f 0 $2 $3 $4 $5 $6 $7 $8 $9 elif [[ "debug" == "$1" ]]; then java -server $JAVA_OPTIONS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y -jar ./target/microbenchmarks.jar -r 5 -wi 3 -i 8 -t 8 -f 0 $2 $3 $4 $5 $6 $7 $8 $9 else java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -i 15 -t 8 $1 $2 $3 $4 $5 $6 $7 $8 $9 fi ================================================ FILE: pom.xml ================================================ 4.0.0 com.zaxxer HikariCP-benchmark 1.0-SNAPSHOT jar Auto-generated JMH benchmark com.zaxxer HikariCP 3.1.0 com.jolbox bonecp 0.8.0.RELEASE org.apache.tomcat tomcat-jdbc 8.5.34 io.dropwizard.metrics metrics-core 3.1.2 org.apache.commons commons-dbcp2 2.5.0 commons-dbcp commons-dbcp 1.4 com.mchange c3p0 0.9.5.2 com.alibaba druid 1.1.10 one.datasource one 1.0.0 system ${project.basedir}/lib/one-datasource.jar mysql mysql-connector-java 5.1.42 org.vibur vibur-dbcp 22.2 log4j log4j slf4j-log4j12 org.slf4j org.apache.logging.log4j log4j-core 2.7 test org.openjdk.jmh jmh-core 1.17.2 org.openjdk.jmh jmh-generator-annprocess 1.17.2 javax.transaction jta 1.1 junit junit 4.12 org.postgresql postgresql 9.4-1200-jdbc41 UTF-8 com.googlecode.addjars-maven-plugin addjars-maven-plugin 1.0.5 add-jars ${basedir}/lib org.apache.maven.plugins maven-compiler-plugin 3.3 1.8 1.8 1.8 org.apache.maven.plugins maven-shade-plugin 2.3 package shade microbenchmarks org.openjdk.jmh.Main *:* META-INF/services/javax.annotation.processing.Processor ================================================ FILE: spiketest.sh ================================================ #!/bin/bash JAVA_OPTIONS="-server -XX:-RestrictContended -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms1096m -Xmx1096m" if [[ "clean" == "$1" ]]; then mvn clean package shift fi java -cp ./target/microbenchmarks.jar:./target/test-classes $JAVA_OPTIONS com.zaxxer.hikari.benchmark.SpikeLoadTest $1 $2 $3 $4 $5 $6 $7 $8 $9 ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/BenchBase.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; import java.util.concurrent.Executors; import javax.sql.DataSource; import com.alibaba.druid.filter.stat.MergeStatFilter; import com.alibaba.druid.filter.stat.StatFilter; import com.alibaba.druid.pool.DruidDataSource; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.tomcat.jdbc.pool.PoolProperties; import org.apache.tomcat.jdbc.pool.PooledConnection; import org.apache.tomcat.jdbc.pool.Validator; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.infra.BenchmarkParams; import org.vibur.dbcp.ViburDBCPDataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import one.datasource.DataSourceImpl; @State(Scope.Benchmark) public class BenchBase { protected static final int MIN_POOL_SIZE = 0; @Param({ "hikari", "dbcp2", "tomcat", "c3p0", "vibur", "druid", "druid-stat", "druid-stat-merge" }) public String pool; @Param({ "32" }) public int maxPoolSize; @Param({ "jdbc:stub" }) public String jdbcUrl; public static DataSource DS; @Setup(Level.Trial) public void setup(BenchmarkParams params) { try { Class.forName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); System.err.printf("Using driver (%s): %s", jdbcUrl, DriverManager.getDriver(jdbcUrl)); } catch (Exception e) { throw new RuntimeException(e); } if (this.getClass().getName().contains("Statement")) { System.err.println("# Overriding maxPoolSize paramter for StatementBench: maxPoolSize=" + params.getThreads()); maxPoolSize = params.getThreads(); } switch (pool) { case "hikari": setupHikari(); break; case "tomcat": setupTomcat(); break; case "dbcp": setupDbcp(); break; case "dbcp2": setupDbcp2(); break; case "c3p0": setupC3P0(); break; case "vibur": setupVibur(); break; case "one": setupOne(); break; case "druid": setupDruid(); break; case "druid-stat": setupDruidStat(); break; case "druid-stat-merge": setupDruidStatMerge(); break; } } @TearDown(Level.Trial) public void teardown() throws SQLException { switch (pool) { case "hikari": ((HikariDataSource) DS).close(); break; case "tomcat": ((org.apache.tomcat.jdbc.pool.DataSource) DS).close(); break; case "dbcp": ((org.apache.commons.dbcp.BasicDataSource) DS).close(); break; case "dbcp2": ((BasicDataSource) DS).close(); break; case "c3p0": ((ComboPooledDataSource) DS).close(); break; case "vibur": ((ViburDBCPDataSource) DS).terminate(); break; case "druid": ((DruidDataSource) DS).close(); break; case "druid-stat": ((DruidDataSource) DS).close(); break; case "druid-stat-merge": ((DruidDataSource) DS).close(); break; } } protected void setupDruid() { DS = createDruid(); } protected void setupDruidStat() { DruidDataSource druid = createDruid(); try { druid.addFilters("stat"); } catch (SQLException e) { throw new RuntimeException(e); } DS = druid; } protected void setupDruidStatMerge() { DruidDataSource druid = createDruid(); StatFilter statFilter = new MergeStatFilter(); druid.getProxyFilters().add(statFilter); DS = druid; } protected DruidDataSource createDruid() { DruidDataSource druid = new DruidDataSource(); druid.setInitialSize(MIN_POOL_SIZE); druid.setMaxActive(maxPoolSize); druid.setMinIdle(MIN_POOL_SIZE); druid.setPoolPreparedStatements(true); druid.setDriverClassName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); druid.setUrl(jdbcUrl); druid.setUsername("brettw"); druid.setPassword(""); druid.setValidationQuery("SELECT 1"); druid.setTestOnBorrow(true); druid.setDefaultAutoCommit(false); druid.setMaxWait(8000); druid.setUseUnfairLock(true); return druid; } protected void setupTomcat() { PoolProperties props = new PoolProperties(); props.setUrl(jdbcUrl); props.setDriverClassName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); props.setUsername("brettw"); props.setPassword(""); props.setInitialSize(MIN_POOL_SIZE); props.setMinIdle(MIN_POOL_SIZE); props.setMaxIdle(maxPoolSize); props.setMaxActive(maxPoolSize); props.setMaxWait(8000); props.setDefaultAutoCommit(false); props.setRollbackOnReturn(true); props.setUseDisposableConnectionFacade(true); props.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState"); //;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"); props.setTestOnBorrow(true); props.setValidationInterval(1000); props.setValidator(new Validator() { @Override public boolean validate(Connection connection, int validateAction) { try { return (validateAction == PooledConnection.VALIDATE_BORROW ? connection.isValid(0) : true); } catch (SQLException e) { return false; } } }); DS = new org.apache.tomcat.jdbc.pool.DataSource(props); } protected void setupDbcp() { org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource(); ds.setUrl(jdbcUrl); ds.setUsername("brettw"); ds.setPassword(""); ds.setInitialSize(MIN_POOL_SIZE); ds.setMinIdle(MIN_POOL_SIZE); ds.setMaxIdle(maxPoolSize); ds.setMaxActive(maxPoolSize); ds.setDefaultAutoCommit(false); ds.setTestOnBorrow(true); ds.setValidationQuery("SELECT 1"); DS = ds; } protected void setupDbcp2() { BasicDataSource ds = new BasicDataSource(); ds.setUrl(jdbcUrl); ds.setUsername("brettw"); ds.setPassword(""); ds.setInitialSize(MIN_POOL_SIZE); ds.setMinIdle(MIN_POOL_SIZE); ds.setMaxIdle(maxPoolSize); ds.setMaxTotal(maxPoolSize); ds.setMaxWaitMillis(8000); ds.setDefaultAutoCommit(false); ds.setRollbackOnReturn(true); ds.setEnableAutoCommitOnReturn(false); ds.setTestOnBorrow(true); ds.setCacheState(true); ds.setFastFailValidation(true); DS = ds; } protected void setupHikari() { HikariConfig config = new HikariConfig(); config.setJdbcUrl(jdbcUrl); config.setUsername("brettw"); config.setPassword(""); config.setMinimumIdle(MIN_POOL_SIZE); config.setMaximumPoolSize(maxPoolSize); config.setConnectionTimeout(8000); config.setAutoCommit(false); DS = new HikariDataSource(config); } protected void setupC3P0() { try { ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setJdbcUrl( jdbcUrl ); cpds.setUser("brettw"); cpds.setPassword(""); cpds.setAcquireIncrement(1); cpds.setInitialPoolSize(MIN_POOL_SIZE); cpds.setMinPoolSize(MIN_POOL_SIZE); cpds.setMaxPoolSize(maxPoolSize); cpds.setCheckoutTimeout(8000); cpds.setLoginTimeout(8); cpds.setTestConnectionOnCheckout(true); // cpds.setPreferredTestQuery("VALUES 1"); DS = cpds; } catch (Exception e) { throw new RuntimeException(e); } } private void setupVibur() { ViburDBCPDataSource vibur = new ViburDBCPDataSource(); vibur.setJdbcUrl( jdbcUrl ); vibur.setUsername("brettw"); vibur.setPassword(""); vibur.setConnectionTimeoutInMs(5000); vibur.setValidateTimeoutInSeconds(3); vibur.setLoginTimeoutInSeconds(2); vibur.setPoolInitialSize(MIN_POOL_SIZE); vibur.setPoolMaxSize(maxPoolSize); vibur.setConnectionIdleLimitInSeconds(1); vibur.setAcquireRetryAttempts(0); vibur.setReducerTimeIntervalInSeconds(0); vibur.setUseNetworkTimeout(true); vibur.setNetworkTimeoutExecutor(Executors.newFixedThreadPool(1)); vibur.setClearSQLWarnings(true); vibur.setResetDefaultsAfterUse(true); vibur.start(); DS = vibur; } private void setupOne() { Properties props = new Properties(); props.put("url", jdbcUrl); props.put("driver", "com.zaxxer.hikari.benchmark.stubs.StubDriver"); DS = new DataSourceImpl("one", props); } } ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/ConnectionBench.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark; import java.sql.Connection; import java.sql.SQLException; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.CompilerControl; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Warmup; //@State(Scope.Benchmark) //@Warmup(iterations=3, batchSize=1_000_000) //@Measurement(iterations=8, batchSize=1_000_000) //@BenchmarkMode(Mode.SingleShotTime) //@OutputTimeUnit(TimeUnit.NANOSECONDS) @Warmup(iterations=3) @Measurement(iterations=8) @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.MILLISECONDS) //@Warmup(iterations=3) //@Measurement(iterations=8) //@BenchmarkMode(Mode.SampleTime) //@OutputTimeUnit(TimeUnit.MILLISECONDS) public class ConnectionBench extends BenchBase { @Benchmark @CompilerControl(CompilerControl.Mode.INLINE) public static Connection cycleCnnection() throws SQLException { Connection connection = DS.getConnection(); connection.close(); return connection; } } ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/StatementBench.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.CompilerControl; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; //@State(Scope.Benchmark) //@Warmup(iterations=3, batchSize=1_000_000) //@Measurement(iterations=8, batchSize=1_000_000) //@BenchmarkMode(Mode.SingleShotTime) //@OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) @Warmup(iterations=3) @Measurement(iterations=8) @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.MILLISECONDS) public class StatementBench extends BenchBase { @Benchmark @CompilerControl(CompilerControl.Mode.INLINE) public Statement cycleStatement(Blackhole bh, ConnectionState state) throws SQLException { Statement statement = state.connection.createStatement(); bh.consume(statement.execute("INSERT INTO test (column) VALUES (?)")); statement.close(); return statement; } @State(Scope.Thread) public static class ConnectionState { Connection connection; @Setup(Level.Iteration) public void setup() throws SQLException { connection = DS.getConnection(); } @TearDown(Level.Iteration) public void teardown() throws SQLException { connection.close(); } } } ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/stubs/StubConnection.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark.stubs; import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; import java.sql.Clob; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.NClob; import java.sql.PreparedStatement; import java.sql.SQLClientInfoException; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.SQLXML; import java.sql.Savepoint; import java.sql.Statement; import java.sql.Struct; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; import java.util.concurrent.ThreadLocalRandom; /** * * @author Brett Wooldridge */ public class StubConnection implements Connection { public static volatile boolean throwRandomExceptions; private static long foo; private boolean autoCommit; private boolean isClosed; private int isolation; static { foo = System.currentTimeMillis(); } /** {@inheritDoc} */ public T unwrap(Class iface) throws SQLException { return null; } /** {@inheritDoc} */ public boolean isWrapperFor(Class iface) throws SQLException { return false; } /** {@inheritDoc} */ public Statement createStatement() throws SQLException { return new StubStatement(); } /** {@inheritDoc} */ public PreparedStatement prepareStatement(String sql) throws SQLException { return new StubPreparedStatement(); } /** {@inheritDoc} */ public CallableStatement prepareCall(String sql) throws SQLException { return null; } /** {@inheritDoc} */ public String nativeSQL(String sql) throws SQLException { return null; } /** {@inheritDoc} */ public void setAutoCommit(boolean autoCommit) throws SQLException { this.autoCommit = autoCommit; } /** {@inheritDoc} */ public boolean getAutoCommit() throws SQLException { return autoCommit; } /** {@inheritDoc} */ public void commit() throws SQLException { } /** {@inheritDoc} */ public void rollback() throws SQLException { autoCommit = false; } /** {@inheritDoc} */ public void close() throws SQLException { isClosed = true; } /** {@inheritDoc} */ public boolean isClosed() throws SQLException { return isClosed; } /** {@inheritDoc} */ public DatabaseMetaData getMetaData() throws SQLException { return null; } /** {@inheritDoc} */ public void setReadOnly(boolean readOnly) throws SQLException { } /** {@inheritDoc} */ public boolean isReadOnly() throws SQLException { return false; } /** {@inheritDoc} */ public void setCatalog(String catalog) throws SQLException { } /** {@inheritDoc} */ public String getCatalog() throws SQLException { return null; } /** {@inheritDoc} */ public void setTransactionIsolation(int level) throws SQLException { this.isolation = level; } /** {@inheritDoc} */ public int getTransactionIsolation() throws SQLException { return isolation; } /** {@inheritDoc} */ public SQLWarning getWarnings() throws SQLException { return null; } /** {@inheritDoc} */ public void clearWarnings() throws SQLException { autoCommit = false; } /** {@inheritDoc} */ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { return null; } /** {@inheritDoc} */ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return new StubPreparedStatement(); } /** {@inheritDoc} */ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return null; } /** {@inheritDoc} */ public Map> getTypeMap() throws SQLException { return null; } /** {@inheritDoc} */ public void setTypeMap(Map> map) throws SQLException { } /** {@inheritDoc} */ public void setHoldability(int holdability) throws SQLException { } /** {@inheritDoc} */ public int getHoldability() throws SQLException { return (int) foo; } /** {@inheritDoc} */ public Savepoint setSavepoint() throws SQLException { return null; } /** {@inheritDoc} */ public Savepoint setSavepoint(String name) throws SQLException { return null; } /** {@inheritDoc} */ public void rollback(Savepoint savepoint) throws SQLException { } /** {@inheritDoc} */ public void releaseSavepoint(Savepoint savepoint) throws SQLException { } /** {@inheritDoc} */ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null; } /** {@inheritDoc} */ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return new StubPreparedStatement(); } /** {@inheritDoc} */ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null; } /** {@inheritDoc} */ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { return new StubPreparedStatement(); } /** {@inheritDoc} */ public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { return new StubPreparedStatement(); } /** {@inheritDoc} */ public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { return new StubPreparedStatement(); } /** {@inheritDoc} */ public Clob createClob() throws SQLException { return null; } /** {@inheritDoc} */ public Blob createBlob() throws SQLException { return null; } /** {@inheritDoc} */ public NClob createNClob() throws SQLException { return null; } /** {@inheritDoc} */ public SQLXML createSQLXML() throws SQLException { return null; } /** {@inheritDoc} */ public boolean isValid(int timeout) throws SQLException { if (throwRandomExceptions && ThreadLocalRandom.current().nextInt(100) == 9) { throw new RuntimeException("isValidThrowsException=true"); } return true; } /** {@inheritDoc} */ public void setClientInfo(String name, String value) throws SQLClientInfoException { } /** {@inheritDoc} */ public void setClientInfo(Properties properties) throws SQLClientInfoException { } /** {@inheritDoc} */ public String getClientInfo(String name) throws SQLException { return null; } /** {@inheritDoc} */ public Properties getClientInfo() throws SQLException { return null; } /** {@inheritDoc} */ public Array createArrayOf(String typeName, Object[] elements) throws SQLException { return null; } /** {@inheritDoc} */ public Struct createStruct(String typeName, Object[] attributes) throws SQLException { return null; } /** {@inheritDoc} */ public void setSchema(String schema) throws SQLException { } /** {@inheritDoc} */ public String getSchema() throws SQLException { return null; } /** {@inheritDoc} */ public void abort(Executor executor) throws SQLException { } /** {@inheritDoc} */ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { } /** {@inheritDoc} */ public int getNetworkTimeout() throws SQLException { return 0; } } ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/stubs/StubDataSource.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark.stubs; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLTransientConnectionException; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import javax.sql.DataSource; /** * * @author Brett Wooldridge */ public class StubDataSource implements DataSource { private long connectionDelay; public void setConnectionDelay(long millis) { this.connectionDelay = millis; } /** {@inheritDoc} */ public PrintWriter getLogWriter() throws SQLException { return null; } /** {@inheritDoc} */ public void setLogWriter(PrintWriter out) throws SQLException { } /** {@inheritDoc} */ public void setLoginTimeout(int seconds) throws SQLException { } /** {@inheritDoc} */ public int getLoginTimeout() throws SQLException { return 0; } /** {@inheritDoc} */ public Logger getParentLogger() throws SQLFeatureNotSupportedException { return null; } /** {@inheritDoc} */ public T unwrap(Class iface) throws SQLException { return null; } /** {@inheritDoc} */ public boolean isWrapperFor(Class iface) throws SQLException { return false; } /** {@inheritDoc} */ public Connection getConnection() throws SQLException { if (connectionDelay > 0) { try { TimeUnit.MILLISECONDS.sleep(connectionDelay); } catch (InterruptedException e) { throw new SQLTransientConnectionException(); } } return new StubConnection(); } /** {@inheritDoc} */ public Connection getConnection(String username, String password) throws SQLException { return getConnection(); } } ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/stubs/StubDriver.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark.stubs; import static java.lang.System.nanoTime; import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Properties; import java.util.logging.Logger; import com.zaxxer.hikari.util.UtilityElf; /** * @author Brett Wooldridge */ public class StubDriver implements Driver { private static final Driver driver; private static long connectionDelay; static { driver = new StubDriver(); try { DriverManager.registerDriver(driver); } catch (SQLException e) { e.printStackTrace(); } } public static void setConnectDelayMs(final long delay) { connectionDelay = delay; //MILLISECONDS.toNanos(delay); } /** {@inheritDoc} */ public Connection connect(String url, Properties info) throws SQLException { if (connectionDelay > 0) { // final long start = nanoTime(); // do { // // spin // } while (nanoTime() - start < connectionDelayNs); UtilityElf.quietlySleep(connectionDelay); } return new StubConnection(); } /** {@inheritDoc} */ public boolean acceptsURL(String url) throws SQLException { return true; } /** {@inheritDoc} */ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { return null; } /** {@inheritDoc} */ public int getMajorVersion() { return 0; } /** {@inheritDoc} */ public int getMinorVersion() { return 0; } /** {@inheritDoc} */ public boolean jdbcCompliant() { return true; } /** {@inheritDoc} */ public Logger getParentLogger() throws SQLFeatureNotSupportedException { return null; } } ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/stubs/StubPreparedStatement.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark.stubs; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Connection; import java.sql.Date; import java.sql.NClob; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.RowId; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.SQLXML; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; /** * * @author Brett Wooldridge */ public class StubPreparedStatement extends StubStatement implements PreparedStatement { /** {@inheritDoc} */ public ResultSet executeQuery(String sql) throws SQLException { return new StubResultSet(); } /** {@inheritDoc} */ public int executeUpdate(String sql) throws SQLException { return 0; } /** {@inheritDoc} */ public int getMaxFieldSize() throws SQLException { return 0; } /** {@inheritDoc} */ public void setMaxFieldSize(int max) throws SQLException { } /** {@inheritDoc} */ public int getMaxRows() throws SQLException { return 0; } /** {@inheritDoc} */ public void setMaxRows(int max) throws SQLException { } /** {@inheritDoc} */ public void setEscapeProcessing(boolean enable) throws SQLException { } /** {@inheritDoc} */ public int getQueryTimeout() throws SQLException { return 0; } /** {@inheritDoc} */ public void setQueryTimeout(int seconds) throws SQLException { } /** {@inheritDoc} */ public void cancel() throws SQLException { } /** {@inheritDoc} */ public SQLWarning getWarnings() throws SQLException { return null; } /** {@inheritDoc} */ public void clearWarnings() throws SQLException { } /** {@inheritDoc} */ public void setCursorName(String name) throws SQLException { } /** {@inheritDoc} */ public boolean execute(String sql) throws SQLException { return false; } /** {@inheritDoc} */ public ResultSet getResultSet() throws SQLException { return new StubResultSet(); } /** {@inheritDoc} */ public int getUpdateCount() throws SQLException { return 0; } /** {@inheritDoc} */ public boolean getMoreResults() throws SQLException { return false; } /** {@inheritDoc} */ public void setFetchDirection(int direction) throws SQLException { } /** {@inheritDoc} */ public int getFetchDirection() throws SQLException { return 0; } /** {@inheritDoc} */ public void setFetchSize(int rows) throws SQLException { } /** {@inheritDoc} */ public int getFetchSize() throws SQLException { return 0; } /** {@inheritDoc} */ public int getResultSetConcurrency() throws SQLException { return 0; } /** {@inheritDoc} */ public int getResultSetType() throws SQLException { return 0; } /** {@inheritDoc} */ public void addBatch(String sql) throws SQLException { } /** {@inheritDoc} */ public void clearBatch() throws SQLException { } /** {@inheritDoc} */ public int[] executeBatch() throws SQLException { if (count > 10000) { return new int[] {1, count, 3}; } return new int[] {count, count, 3}; } /** {@inheritDoc} */ public Connection getConnection() throws SQLException { return null; } /** {@inheritDoc} */ public boolean getMoreResults(int current) throws SQLException { return false; } /** {@inheritDoc} */ public ResultSet getGeneratedKeys() throws SQLException { return new StubResultSet(); } /** {@inheritDoc} */ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { return 0; } /** {@inheritDoc} */ public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { return 0; } /** {@inheritDoc} */ public int executeUpdate(String sql, String[] columnNames) throws SQLException { return 0; } /** {@inheritDoc} */ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { return false; } /** {@inheritDoc} */ public boolean execute(String sql, int[] columnIndexes) throws SQLException { return false; } /** {@inheritDoc} */ public boolean execute(String sql, String[] columnNames) throws SQLException { return false; } /** {@inheritDoc} */ public int getResultSetHoldability() throws SQLException { return 0; } /** {@inheritDoc} */ public void setPoolable(boolean poolable) throws SQLException { } /** {@inheritDoc} */ public boolean isPoolable() throws SQLException { return false; } /** {@inheritDoc} */ public void closeOnCompletion() throws SQLException { } /** {@inheritDoc} */ public boolean isCloseOnCompletion() throws SQLException { return false; } /** {@inheritDoc} */ public ResultSet executeQuery() throws SQLException { return new StubResultSet(); } /** {@inheritDoc} */ public int executeUpdate() throws SQLException { return 0; } /** {@inheritDoc} */ public void setNull(int parameterIndex, int sqlType) throws SQLException { } /** {@inheritDoc} */ public void setBoolean(int parameterIndex, boolean x) throws SQLException { } /** {@inheritDoc} */ public void setByte(int parameterIndex, byte x) throws SQLException { } /** {@inheritDoc} */ public void setShort(int parameterIndex, short x) throws SQLException { } /** {@inheritDoc} */ public void setInt(int parameterIndex, int x) throws SQLException { if (count > 0) { count += parameterIndex + x; } else { count += x; } } /** {@inheritDoc} */ public void setLong(int parameterIndex, long x) throws SQLException { } /** {@inheritDoc} */ public void setFloat(int parameterIndex, float x) throws SQLException { } /** {@inheritDoc} */ public void setDouble(int parameterIndex, double x) throws SQLException { } /** {@inheritDoc} */ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { } /** {@inheritDoc} */ public void setString(int parameterIndex, String x) throws SQLException { } /** {@inheritDoc} */ public void setBytes(int parameterIndex, byte[] x) throws SQLException { } /** {@inheritDoc} */ public void setDate(int parameterIndex, Date x) throws SQLException { } /** {@inheritDoc} */ public void setTime(int parameterIndex, Time x) throws SQLException { } /** {@inheritDoc} */ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { } /** {@inheritDoc} */ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { } /** {@inheritDoc} */ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { } /** {@inheritDoc} */ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { } /** {@inheritDoc} */ public void clearParameters() throws SQLException { } /** {@inheritDoc} */ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { } /** {@inheritDoc} */ public void setObject(int parameterIndex, Object x) throws SQLException { } /** {@inheritDoc} */ public boolean execute() throws SQLException { return false; } /** {@inheritDoc} */ public void addBatch() throws SQLException { } /** {@inheritDoc} */ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { } /** {@inheritDoc} */ public void setRef(int parameterIndex, Ref x) throws SQLException { } /** {@inheritDoc} */ public void setBlob(int parameterIndex, Blob x) throws SQLException { } /** {@inheritDoc} */ public void setClob(int parameterIndex, Clob x) throws SQLException { } /** {@inheritDoc} */ public void setArray(int parameterIndex, Array x) throws SQLException { } /** {@inheritDoc} */ public ResultSetMetaData getMetaData() throws SQLException { return null; } /** {@inheritDoc} */ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { } /** {@inheritDoc} */ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { } /** {@inheritDoc} */ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { } /** {@inheritDoc} */ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { } /** {@inheritDoc} */ public void setURL(int parameterIndex, URL x) throws SQLException { } /** {@inheritDoc} */ public ParameterMetaData getParameterMetaData() throws SQLException { return null; } /** {@inheritDoc} */ public void setRowId(int parameterIndex, RowId x) throws SQLException { } /** {@inheritDoc} */ public void setNString(int parameterIndex, String value) throws SQLException { } /** {@inheritDoc} */ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { } /** {@inheritDoc} */ public void setNClob(int parameterIndex, NClob value) throws SQLException { } /** {@inheritDoc} */ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { } /** {@inheritDoc} */ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { } /** {@inheritDoc} */ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { } /** {@inheritDoc} */ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { } /** {@inheritDoc} */ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { } /** {@inheritDoc} */ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { } /** {@inheritDoc} */ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { } /** {@inheritDoc} */ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { } /** {@inheritDoc} */ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { } /** {@inheritDoc} */ public void setClob(int parameterIndex, Reader reader) throws SQLException { } /** {@inheritDoc} */ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { } /** {@inheritDoc} */ public void setNClob(int parameterIndex, Reader reader) throws SQLException { } } ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/stubs/StubResultSet.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark.stubs; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.NClob; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.RowId; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.SQLXML; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Map; /** * * @author Brett Wooldridge */ public class StubResultSet implements ResultSet { private int counter; private boolean closed; /** {@inheritDoc} */ public T unwrap(Class iface) throws SQLException { return null; } /** {@inheritDoc} */ public boolean isWrapperFor(Class iface) throws SQLException { return false; } /** {@inheritDoc} */ public boolean next() throws SQLException { return (counter < 10); } /** {@inheritDoc} */ public void close() throws SQLException { closed = true; } /** {@inheritDoc} */ public boolean wasNull() throws SQLException { return false; } /** {@inheritDoc} */ public String getString(int columnIndex) throws SQLException { return "aString"; } /** {@inheritDoc} */ public boolean getBoolean(int columnIndex) throws SQLException { return false; } /** {@inheritDoc} */ public byte getByte(int columnIndex) throws SQLException { return 0; } /** {@inheritDoc} */ public short getShort(int columnIndex) throws SQLException { return 0; } /** {@inheritDoc} */ public int getInt(int columnIndex) throws SQLException { return ++counter; } /** {@inheritDoc} */ public long getLong(int columnIndex) throws SQLException { return 0; } /** {@inheritDoc} */ public float getFloat(int columnIndex) throws SQLException { return 0; } /** {@inheritDoc} */ public double getDouble(int columnIndex) throws SQLException { return 0; } /** {@inheritDoc} */ public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { return null; } /** {@inheritDoc} */ public byte[] getBytes(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Date getDate(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Time getTime(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Timestamp getTimestamp(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public InputStream getAsciiStream(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public InputStream getUnicodeStream(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public InputStream getBinaryStream(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public String getString(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public boolean getBoolean(String columnLabel) throws SQLException { return false; } /** {@inheritDoc} */ public byte getByte(String columnLabel) throws SQLException { return 0; } /** {@inheritDoc} */ public short getShort(String columnLabel) throws SQLException { return 0; } /** {@inheritDoc} */ public int getInt(String columnLabel) throws SQLException { return 0; } /** {@inheritDoc} */ public long getLong(String columnLabel) throws SQLException { return 0; } /** {@inheritDoc} */ public float getFloat(String columnLabel) throws SQLException { return 0; } /** {@inheritDoc} */ public double getDouble(String columnLabel) throws SQLException { return 0; } /** {@inheritDoc} */ public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { return null; } /** {@inheritDoc} */ public byte[] getBytes(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public Date getDate(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public Time getTime(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public Timestamp getTimestamp(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public InputStream getAsciiStream(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public InputStream getUnicodeStream(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public InputStream getBinaryStream(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public SQLWarning getWarnings() throws SQLException { return null; } /** {@inheritDoc} */ public void clearWarnings() throws SQLException { } /** {@inheritDoc} */ public String getCursorName() throws SQLException { return null; } /** {@inheritDoc} */ public ResultSetMetaData getMetaData() throws SQLException { return null; } /** {@inheritDoc} */ public Object getObject(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Object getObject(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public int findColumn(String columnLabel) throws SQLException { return 0; } /** {@inheritDoc} */ public Reader getCharacterStream(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Reader getCharacterStream(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public BigDecimal getBigDecimal(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public BigDecimal getBigDecimal(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public boolean isBeforeFirst() throws SQLException { return false; } /** {@inheritDoc} */ public boolean isAfterLast() throws SQLException { return false; } /** {@inheritDoc} */ public boolean isFirst() throws SQLException { return false; } /** {@inheritDoc} */ public boolean isLast() throws SQLException { return false; } /** {@inheritDoc} */ public void beforeFirst() throws SQLException { } /** {@inheritDoc} */ public void afterLast() throws SQLException { } /** {@inheritDoc} */ public boolean first() throws SQLException { return false; } /** {@inheritDoc} */ public boolean last() throws SQLException { return false; } /** {@inheritDoc} */ public int getRow() throws SQLException { return 0; } /** {@inheritDoc} */ public boolean absolute(int row) throws SQLException { return false; } /** {@inheritDoc} */ public boolean relative(int rows) throws SQLException { return false; } /** {@inheritDoc} */ public boolean previous() throws SQLException { return false; } /** {@inheritDoc} */ public void setFetchDirection(int direction) throws SQLException { } /** {@inheritDoc} */ public int getFetchDirection() throws SQLException { return 0; } /** {@inheritDoc} */ public void setFetchSize(int rows) throws SQLException { } /** {@inheritDoc} */ public int getFetchSize() throws SQLException { return 0; } /** {@inheritDoc} */ public int getType() throws SQLException { return 0; } /** {@inheritDoc} */ public int getConcurrency() throws SQLException { return 0; } /** {@inheritDoc} */ public boolean rowUpdated() throws SQLException { return false; } /** {@inheritDoc} */ public boolean rowInserted() throws SQLException { return false; } /** {@inheritDoc} */ public boolean rowDeleted() throws SQLException { return false; } /** {@inheritDoc} */ public void updateNull(int columnIndex) throws SQLException { } /** {@inheritDoc} */ public void updateBoolean(int columnIndex, boolean x) throws SQLException { } /** {@inheritDoc} */ public void updateByte(int columnIndex, byte x) throws SQLException { } /** {@inheritDoc} */ public void updateShort(int columnIndex, short x) throws SQLException { } /** {@inheritDoc} */ public void updateInt(int columnIndex, int x) throws SQLException { } /** {@inheritDoc} */ public void updateLong(int columnIndex, long x) throws SQLException { } /** {@inheritDoc} */ public void updateFloat(int columnIndex, float x) throws SQLException { } /** {@inheritDoc} */ public void updateDouble(int columnIndex, double x) throws SQLException { } /** {@inheritDoc} */ public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { } /** {@inheritDoc} */ public void updateString(int columnIndex, String x) throws SQLException { } /** {@inheritDoc} */ public void updateBytes(int columnIndex, byte[] x) throws SQLException { } /** {@inheritDoc} */ public void updateDate(int columnIndex, Date x) throws SQLException { } /** {@inheritDoc} */ public void updateTime(int columnIndex, Time x) throws SQLException { } /** {@inheritDoc} */ public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { } /** {@inheritDoc} */ public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { } /** {@inheritDoc} */ public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { } /** {@inheritDoc} */ public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { } /** {@inheritDoc} */ public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { } /** {@inheritDoc} */ public void updateObject(int columnIndex, Object x) throws SQLException { } /** {@inheritDoc} */ public void updateNull(String columnLabel) throws SQLException { } /** {@inheritDoc} */ public void updateBoolean(String columnLabel, boolean x) throws SQLException { } /** {@inheritDoc} */ public void updateByte(String columnLabel, byte x) throws SQLException { } /** {@inheritDoc} */ public void updateShort(String columnLabel, short x) throws SQLException { } /** {@inheritDoc} */ public void updateInt(String columnLabel, int x) throws SQLException { } /** {@inheritDoc} */ public void updateLong(String columnLabel, long x) throws SQLException { } /** {@inheritDoc} */ public void updateFloat(String columnLabel, float x) throws SQLException { } /** {@inheritDoc} */ public void updateDouble(String columnLabel, double x) throws SQLException { } /** {@inheritDoc} */ public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { } /** {@inheritDoc} */ public void updateString(String columnLabel, String x) throws SQLException { } /** {@inheritDoc} */ public void updateBytes(String columnLabel, byte[] x) throws SQLException { } /** {@inheritDoc} */ public void updateDate(String columnLabel, Date x) throws SQLException { } /** {@inheritDoc} */ public void updateTime(String columnLabel, Time x) throws SQLException { } /** {@inheritDoc} */ public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { } /** {@inheritDoc} */ public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { } /** {@inheritDoc} */ public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { } /** {@inheritDoc} */ public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { } /** {@inheritDoc} */ public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { } /** {@inheritDoc} */ public void updateObject(String columnLabel, Object x) throws SQLException { } /** {@inheritDoc} */ public void insertRow() throws SQLException { } /** {@inheritDoc} */ public void updateRow() throws SQLException { } /** {@inheritDoc} */ public void deleteRow() throws SQLException { } /** {@inheritDoc} */ public void refreshRow() throws SQLException { } /** {@inheritDoc} */ public void cancelRowUpdates() throws SQLException { } /** {@inheritDoc} */ public void moveToInsertRow() throws SQLException { } /** {@inheritDoc} */ public void moveToCurrentRow() throws SQLException { } /** {@inheritDoc} */ public Statement getStatement() throws SQLException { return null; } /** {@inheritDoc} */ public Object getObject(int columnIndex, Map> map) throws SQLException { return null; } /** {@inheritDoc} */ public Ref getRef(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Blob getBlob(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Clob getClob(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Array getArray(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Object getObject(String columnLabel, Map> map) throws SQLException { return null; } /** {@inheritDoc} */ public Ref getRef(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public Blob getBlob(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public Clob getClob(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public Array getArray(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public Date getDate(int columnIndex, Calendar cal) throws SQLException { return null; } /** {@inheritDoc} */ public Date getDate(String columnLabel, Calendar cal) throws SQLException { return null; } /** {@inheritDoc} */ public Time getTime(int columnIndex, Calendar cal) throws SQLException { return null; } /** {@inheritDoc} */ public Time getTime(String columnLabel, Calendar cal) throws SQLException { return null; } /** {@inheritDoc} */ public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { return null; } /** {@inheritDoc} */ public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { return null; } /** {@inheritDoc} */ public URL getURL(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public URL getURL(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public void updateRef(int columnIndex, Ref x) throws SQLException { } /** {@inheritDoc} */ public void updateRef(String columnLabel, Ref x) throws SQLException { } /** {@inheritDoc} */ public void updateBlob(int columnIndex, Blob x) throws SQLException { } /** {@inheritDoc} */ public void updateBlob(String columnLabel, Blob x) throws SQLException { } /** {@inheritDoc} */ public void updateClob(int columnIndex, Clob x) throws SQLException { } /** {@inheritDoc} */ public void updateClob(String columnLabel, Clob x) throws SQLException { } /** {@inheritDoc} */ public void updateArray(int columnIndex, Array x) throws SQLException { } /** {@inheritDoc} */ public void updateArray(String columnLabel, Array x) throws SQLException { } /** {@inheritDoc} */ public RowId getRowId(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public RowId getRowId(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public void updateRowId(int columnIndex, RowId x) throws SQLException { } /** {@inheritDoc} */ public void updateRowId(String columnLabel, RowId x) throws SQLException { } /** {@inheritDoc} */ public int getHoldability() throws SQLException { return 0; } /** {@inheritDoc} */ public boolean isClosed() throws SQLException { return closed; } /** {@inheritDoc} */ public void updateNString(int columnIndex, String nString) throws SQLException { } /** {@inheritDoc} */ public void updateNString(String columnLabel, String nString) throws SQLException { } /** {@inheritDoc} */ public void updateNClob(int columnIndex, NClob nClob) throws SQLException { } /** {@inheritDoc} */ public void updateNClob(String columnLabel, NClob nClob) throws SQLException { } /** {@inheritDoc} */ public NClob getNClob(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public NClob getNClob(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public SQLXML getSQLXML(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public SQLXML getSQLXML(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { } /** {@inheritDoc} */ public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { } /** {@inheritDoc} */ public String getNString(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public String getNString(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public Reader getNCharacterStream(int columnIndex) throws SQLException { return null; } /** {@inheritDoc} */ public Reader getNCharacterStream(String columnLabel) throws SQLException { return null; } /** {@inheritDoc} */ public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { } /** {@inheritDoc} */ public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { } /** {@inheritDoc} */ public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { } /** {@inheritDoc} */ public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { } /** {@inheritDoc} */ public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { } /** {@inheritDoc} */ public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { } /** {@inheritDoc} */ public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { } /** {@inheritDoc} */ public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { } /** {@inheritDoc} */ public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { } /** {@inheritDoc} */ public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { } /** {@inheritDoc} */ public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { } /** {@inheritDoc} */ public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { } /** {@inheritDoc} */ public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { } /** {@inheritDoc} */ public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { } /** {@inheritDoc} */ public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { } /** {@inheritDoc} */ public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { } /** {@inheritDoc} */ public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { } /** {@inheritDoc} */ public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { } /** {@inheritDoc} */ public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { } /** {@inheritDoc} */ public void updateClob(int columnIndex, Reader reader) throws SQLException { } /** {@inheritDoc} */ public void updateClob(String columnLabel, Reader reader) throws SQLException { } /** {@inheritDoc} */ public void updateNClob(int columnIndex, Reader reader) throws SQLException { } /** {@inheritDoc} */ public void updateNClob(String columnLabel, Reader reader) throws SQLException { } /** {@inheritDoc} */ public T getObject(int columnIndex, Class type) throws SQLException { return null; } /** {@inheritDoc} */ public T getObject(String columnLabel, Class type) throws SQLException { return null; } } ================================================ FILE: src/main/java/com/zaxxer/hikari/benchmark/stubs/StubStatement.java ================================================ /* * Copyright (C) 2014 Brett Wooldridge * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaxxer.hikari.benchmark.stubs; import static java.lang.System.nanoTime; import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import com.zaxxer.hikari.util.UtilityElf; /** * * @author Brett Wooldridge */ public class StubStatement implements Statement { protected int count; private boolean closed; private static long executeDelay; public static void setExecuteDelayMs(final long delay) { executeDelay = delay; } /** {@inheritDoc} */ @SuppressWarnings("unchecked") public T unwrap(Class iface) throws SQLException { if (iface.isInstance(this)) { return (T) this; } throw new SQLException("Wrapped connection is not an instance of " + iface); } /** {@inheritDoc} */ public boolean isWrapperFor(Class iface) throws SQLException { return false; } /** {@inheritDoc} */ public ResultSet executeQuery(String sql) throws SQLException { if (executeDelay > 0) { // final long start = nanoTime(); // do { // // spin // } while (nanoTime() - start < MILLISECONDS.toNanos(executeDelayMs)); UtilityElf.quietlySleep(executeDelay); } return new StubResultSet(); } /** {@inheritDoc} */ public int executeUpdate(String sql) throws SQLException { return 0; } /** {@inheritDoc} */ public void close() throws SQLException { closed = true; } /** {@inheritDoc} */ public int getMaxFieldSize() throws SQLException { return 0; } /** {@inheritDoc} */ public void setMaxFieldSize(int max) throws SQLException { } /** {@inheritDoc} */ public int getMaxRows() throws SQLException { return 0; } /** {@inheritDoc} */ public void setMaxRows(int max) throws SQLException { } /** {@inheritDoc} */ public void setEscapeProcessing(boolean enable) throws SQLException { } /** {@inheritDoc} */ public int getQueryTimeout() throws SQLException { return 0; } /** {@inheritDoc} */ public void setQueryTimeout(int seconds) throws SQLException { } /** {@inheritDoc} */ public void cancel() throws SQLException { } /** {@inheritDoc} */ public SQLWarning getWarnings() throws SQLException { return null; } /** {@inheritDoc} */ public void clearWarnings() throws SQLException { } /** {@inheritDoc} */ public void setCursorName(String name) throws SQLException { } /** {@inheritDoc} */ public boolean execute(String sql) throws SQLException { return sql.startsWith("I"); } /** {@inheritDoc} */ public ResultSet getResultSet() throws SQLException { return new StubResultSet(); } /** {@inheritDoc} */ public int getUpdateCount() throws SQLException { return 0; } /** {@inheritDoc} */ public boolean getMoreResults() throws SQLException { return false; } /** {@inheritDoc} */ public void setFetchDirection(int direction) throws SQLException { } /** {@inheritDoc} */ public int getFetchDirection() throws SQLException { return 0; } /** {@inheritDoc} */ public void setFetchSize(int rows) throws SQLException { } /** {@inheritDoc} */ public int getFetchSize() throws SQLException { return 0; } /** {@inheritDoc} */ public int getResultSetConcurrency() throws SQLException { return 0; } /** {@inheritDoc} */ public int getResultSetType() throws SQLException { return 0; } /** {@inheritDoc} */ public void addBatch(String sql) throws SQLException { } /** {@inheritDoc} */ public void clearBatch() throws SQLException { } /** {@inheritDoc} */ public int[] executeBatch() throws SQLException { return null; } /** {@inheritDoc} */ public Connection getConnection() throws SQLException { return null; } /** {@inheritDoc} */ public boolean getMoreResults(int current) throws SQLException { return false; } /** {@inheritDoc} */ public ResultSet getGeneratedKeys() throws SQLException { return new StubResultSet(); } /** {@inheritDoc} */ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { return 0; } /** {@inheritDoc} */ public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { return 0; } /** {@inheritDoc} */ public int executeUpdate(String sql, String[] columnNames) throws SQLException { return 0; } /** {@inheritDoc} */ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { return false; } /** {@inheritDoc} */ public boolean execute(String sql, int[] columnIndexes) throws SQLException { return false; } /** {@inheritDoc} */ public boolean execute(String sql, String[] columnNames) throws SQLException { return false; } /** {@inheritDoc} */ public int getResultSetHoldability() throws SQLException { return 0; } /** {@inheritDoc} */ public boolean isClosed() throws SQLException { return closed; } /** {@inheritDoc} */ public void setPoolable(boolean poolable) throws SQLException { } /** {@inheritDoc} */ public boolean isPoolable() throws SQLException { return false; } /** {@inheritDoc} */ public void closeOnCompletion() throws SQLException { } /** {@inheritDoc} */ public boolean isCloseOnCompletion() throws SQLException { return false; } public int getCount() { return count; } } ================================================ FILE: src/main/resources/log4j2-test.xml ================================================ ================================================ FILE: src/test/java/com/zaxxer/hikari/benchmark/BandwidthTest.java ================================================ package com.zaxxer.hikari.benchmark; import static com.zaxxer.hikari.util.ClockSource.currentTime; import static java.lang.System.out; import static java.sql.Connection.TRANSACTION_READ_COMMITTED; import static java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; import java.util.concurrent.Executors; import javax.sql.DataSource; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.DbcpPoolAccessor; import org.apache.commons.dbcp2.TomcatPoolAccessor; import org.apache.tomcat.jdbc.pool.PoolProperties; import org.apache.tomcat.jdbc.pool.PooledConnection; import org.apache.tomcat.jdbc.pool.Validator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vibur.dbcp.ViburDBCPDataSource; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.util.ClockSource; public class BandwidthTest { private static final Logger LOGGER = LoggerFactory.getLogger(BandwidthTest.class); private static final String jdbcUrl = "jdbc:postgresql://localhost/test"; private static final int MIN_POOL_SIZE = 1; private static final int MAX_POOL_SIZE = 1; private DataSource DS; private String pool; public static void main(String[] args) throws InterruptedException, SQLException { BandwidthTest test = new BandwidthTest(); test.setup(args); int blackhole = test.start(); LOGGER.debug("Blackhole value {}", blackhole); } private void setup(String[] args) throws SQLException { pool = args[0]; switch (pool) { case "hikari": setupHikari(); break; case "dbcp2": setupDbcp2(); break; case "tomcat": setupTomcat(); break; case "vibur": setupVibur(); break; default: throw new IllegalArgumentException("Unknown connection pool specified"); } try (Connection connection = DS.getConnection()) { connection.setAutoCommit(true); try (Statement stmt = connection.createStatement()) { stmt.execute("DROP TABLE IF EXISTS test; CREATE TABLE test (value VARCHAR(255));"); stmt.executeUpdate("INSERT INTO test (value) VALUES ('this is a test')"); connection.setAutoCommit(false); } } LOGGER.info("Primed connection: {}.", pool); } private int start() throws InterruptedException, SQLException { try (Scanner scanner = new Scanner(System.in)) { LOGGER.info("\n[Re]start iptop capture and press enter: sudo iftop -i lo0 -nf \"port 5432 and host localhost\""); scanner.nextLine(); int blackhole = 0; long start = currentTime(); for (int i = 0; i < 10_000; i++) { try (Connection connection = DS.getConnection()) { // connection.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED); // connection.setReadOnly(true); try (Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM test")) { if (rs.next()) { blackhole += rs.getString(1).hashCode(); } } // connection.rollback(); } } LOGGER.info("Elapsed runtime {}" , ClockSource.elapsedDisplayString(start, currentTime())); return blackhole; } finally { shutdownPool(DS); } } private void shutdownPool(DataSource ds) { if (ds instanceof AutoCloseable) { try { ((AutoCloseable) ds).close(); } catch (Exception e) { } } } private void setupHikari() { HikariConfig config = new HikariConfig(); config.setJdbcUrl(jdbcUrl); config.setUsername("brettw"); config.setPassword(""); config.setMinimumIdle(MIN_POOL_SIZE); config.setMaximumPoolSize(MAX_POOL_SIZE); config.setConnectionTimeout(8000); config.setAutoCommit(false); config.setReadOnly(false); config.setTransactionIsolation("TRANSACTION_READ_COMMITTED"); DS = new HikariDataSource(config); } private void setupDbcp2() { BasicDataSource ds = new DbcpPoolAccessor(); ds.setUrl(jdbcUrl); ds.setUsername("brettw"); ds.setPassword(""); ds.setInitialSize(MIN_POOL_SIZE); ds.setMinIdle(MIN_POOL_SIZE); ds.setMaxIdle(MIN_POOL_SIZE); ds.setMaxTotal(MAX_POOL_SIZE); ds.setMaxWaitMillis(8000); ds.setSoftMinEvictableIdleTimeMillis(MINUTES.toMillis(10)); ds.setTimeBetweenEvictionRunsMillis(SECONDS.toMillis(30)); ds.setDefaultAutoCommit(false); ds.setDefaultTransactionIsolation(TRANSACTION_READ_COMMITTED); ds.setDefaultReadOnly(false); ds.setRollbackOnReturn(true); ds.setEnableAutoCommitOnReturn(false); ds.setTestOnBorrow(true); ds.setCacheState(true); ds.setFastFailValidation(true); DS = ds; } protected void setupTomcat() { PoolProperties props = new PoolProperties(); props.setUrl(jdbcUrl); props.setUsername("brettw"); props.setPassword(""); props.setInitialSize(MIN_POOL_SIZE); props.setMinIdle(MIN_POOL_SIZE); props.setMaxIdle(MAX_POOL_SIZE); props.setMaxActive(MAX_POOL_SIZE); props.setMaxWait(8000); props.setDefaultAutoCommit(false); props.setDefaultReadOnly(false); props.setDefaultTransactionIsolation(TRANSACTION_READ_COMMITTED); props.setRollbackOnReturn(true); props.setUseDisposableConnectionFacade(true); props.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"); props.setTestOnBorrow(true); props.setLogAbandoned(true); props.setSuspectTimeout(120); props.setValidationInterval(250); props.setValidator(new Validator() { @Override public boolean validate(Connection connection, int validateAction) { try { return (validateAction == PooledConnection.VALIDATE_BORROW ? connection.isValid(0) : true); } catch (SQLException e) { return false; } } }); DS = new TomcatPoolAccessor(props); } private void setupVibur() { ViburDBCPDataSource vibur = new ViburDBCPDataSource(); vibur.setJdbcUrl(jdbcUrl); vibur.setUsername("brettw"); vibur.setPassword(""); vibur.setPoolFair(false); vibur.setPoolInitialSize(MIN_POOL_SIZE); vibur.setPoolMaxSize(MAX_POOL_SIZE); vibur.setConnectionIdleLimitInSeconds(1); vibur.setUseNetworkTimeout(true); vibur.setNetworkTimeoutExecutor(Executors.newFixedThreadPool(1)); vibur.setClearSQLWarnings(true); vibur.setDefaultAutoCommit(false); vibur.setDefaultReadOnly(false); vibur.setDefaultTransactionIsolationIntValue(TRANSACTION_READ_COMMITTED); vibur.setResetDefaultsAfterUse(true); vibur.setReducerTimeIntervalInSeconds((int) MINUTES.toSeconds(10)); vibur.start(); DS = vibur; } } ================================================ FILE: src/test/java/com/zaxxer/hikari/benchmark/DbDownTest.java ================================================ package com.zaxxer.hikari.benchmark; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import javax.sql.DataSource; import org.apache.commons.dbcp2.BasicDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vibur.dbcp.ViburDBCPDataSource; import com.jolbox.bonecp.BoneCPConfig; import com.jolbox.bonecp.BoneCPDataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; public class DbDownTest { private static final String JDBC_URL = "jdbc:mysql://172.16.207.207/test"; private static final Logger LOGGER = LoggerFactory.getLogger(DbDownTest.class); private static final int MIN_POOL_SIZE = 5; private int maxPoolSize = MIN_POOL_SIZE; private DataSource hikariDS; private DataSource c3p0DS; private DataSource dbcp2DS; private DataSource viburDS; public static void main(String[] args) { DbDownTest dbDownTest = new DbDownTest(); dbDownTest.start(); } private DbDownTest() { hikariDS = setupHikari(); viburDS = setupVibur(); c3p0DS = setupC3P0(); dbcp2DS = setupDbcp2(); } private void start() { class MyTask extends TimerTask { private DataSource ds; public ResultSet resultSet; MyTask(DataSource ds) { this.ds = ds; } @Override public void run() { try (Connection c = ds.getConnection()) { LOGGER.info("{} got a connection.", ds.getClass().getSimpleName(), c); try (Statement stmt = c.createStatement()) { LOGGER.debug("{} Statement ({})", ds.getClass().getSimpleName(), System.identityHashCode(stmt)); stmt.setQueryTimeout(1); resultSet = stmt.executeQuery("SELECT id FROM test"); if (resultSet.next()) { LOGGER.debug("Ran query got {}", resultSet.getInt(1)); } else { LOGGER.warn("{} Query executed, got no results.", ds.getClass().getSimpleName()); } } catch (SQLException e) { LOGGER.error("{} Exception executing query, got a bad connection from the pool: {}", ds.getClass().getSimpleName(), e.getMessage()); } } catch (Throwable t) { LOGGER.error("{} Exception getting connection: {}", ds.getClass().getSimpleName(), t.getMessage()); } } } new Timer(true).schedule(new MyTask(hikariDS), 5000, 2000); new Timer(true).schedule(new MyTask(viburDS), 5000, 2000); new Timer(true).schedule(new MyTask(c3p0DS), 5000, 2000); new Timer(true).schedule(new MyTask(dbcp2DS), 5000, 2000); try { Thread.sleep(TimeUnit.SECONDS.toMillis(300)); } catch (InterruptedException e) { return; } } protected DataSource setupDbcp2() { BasicDataSource ds = new BasicDataSource(); ds.setUrl(JDBC_URL); ds.setUsername("root"); ds.setPassword(""); ds.setInitialSize(MIN_POOL_SIZE); ds.setMinIdle(MIN_POOL_SIZE); ds.setMaxIdle(maxPoolSize); ds.setMaxTotal(maxPoolSize); ds.setMaxWaitMillis(5000); ds.setDefaultAutoCommit(false); ds.setRollbackOnReturn(true); ds.setEnableAutoCommitOnReturn(false); ds.setTestOnBorrow(true); ds.setCacheState(true); ds.setFastFailValidation(true); return ds; } protected DataSource setupBone() { BoneCPConfig config = new BoneCPConfig(); config.setJdbcUrl(JDBC_URL); config.setUsername("root"); config.setPassword(""); config.setConnectionTimeoutInMs(5000); config.setAcquireIncrement(1); config.setAcquireRetryAttempts(3); config.setAcquireRetryDelayInMs(5000); config.setMinConnectionsPerPartition(MIN_POOL_SIZE); config.setMaxConnectionsPerPartition(maxPoolSize); config.setConnectionTestStatement("SELECT 1"); return new BoneCPDataSource(config); } protected DataSource setupHikari() { HikariConfig config = new HikariConfig(); config.setJdbcUrl(JDBC_URL); // config.setDriverClassName("com.mysql.jdbc.Driver"); config.setUsername("root"); config.setConnectionTimeout(5000); config.setMinimumIdle(MIN_POOL_SIZE); config.setMaximumPoolSize(maxPoolSize); config.setInitializationFailTimeout(0L); config.setConnectionTestQuery("SELECT 1"); return new HikariDataSource(config); } protected DataSource setupC3P0() { try { ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setJdbcUrl( JDBC_URL ); cpds.setUser("root"); cpds.setCheckoutTimeout(5000); cpds.setTestConnectionOnCheckout(true); cpds.setAcquireIncrement(1); cpds.setAcquireRetryAttempts(3); cpds.setAcquireRetryDelay(5000); cpds.setInitialPoolSize(MIN_POOL_SIZE); cpds.setMinPoolSize(MIN_POOL_SIZE); cpds.setMaxPoolSize(maxPoolSize); cpds.setPreferredTestQuery("SELECT 1"); return cpds; } catch (Exception e) { throw new RuntimeException(e); } } private DataSource setupVibur() { ViburDBCPDataSource vibur = new ViburDBCPDataSource(); vibur.setJdbcUrl( JDBC_URL ); vibur.setUsername("root"); vibur.setPassword(""); vibur.setConnectionTimeoutInMs(5000); vibur.setValidateTimeoutInSeconds(3); vibur.setLoginTimeoutInSeconds(2); vibur.setPoolInitialSize(MIN_POOL_SIZE); vibur.setPoolMaxSize(maxPoolSize); vibur.setConnectionIdleLimitInSeconds(1); vibur.setAcquireRetryAttempts(0); vibur.setReducerTimeIntervalInSeconds(0); vibur.setUseNetworkTimeout(true); vibur.setNetworkTimeoutExecutor(Executors.newCachedThreadPool()); vibur.setClearSQLWarnings(true); vibur.setResetDefaultsAfterUse(true); vibur.setTestConnectionQuery("isValid"); // this is the default option, can be left commented out vibur.start(); return vibur; } } ================================================ FILE: src/test/java/com/zaxxer/hikari/benchmark/SpikeLoadTest.java ================================================ package com.zaxxer.hikari.benchmark; import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_IN_USE; import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_NOT_IN_USE; import static com.zaxxer.hikari.util.UtilityElf.quietlySleep; import static java.lang.Integer.parseInt; import static java.lang.System.nanoTime; import static java.lang.Thread.MAX_PRIORITY; import static java.lang.Thread.currentThread; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.LongAdder; import java.util.stream.IntStream; import javax.sql.DataSource; import com.alibaba.druid.pool.DruidDataSource; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.DbcpPoolAccessor; import org.apache.commons.dbcp2.TomcatPoolAccessor; import org.apache.tomcat.jdbc.pool.PoolProperties; import org.apache.tomcat.jdbc.pool.PooledConnection; import org.apache.tomcat.jdbc.pool.Validator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vibur.dbcp.ViburDBCPDataSource; import org.vibur.dbcp.pool.Hook.CloseConnection; import org.vibur.dbcp.pool.Hook.GetConnection; import org.vibur.dbcp.pool.Hook.InitConnection; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.benchmark.stubs.StubDriver; import com.zaxxer.hikari.benchmark.stubs.StubStatement; import com.zaxxer.hikari.pool.HikariPool; import com.zaxxer.hikari.pool.HikariPoolAccessor; public class SpikeLoadTest { private static final Logger LOGGER = LoggerFactory.getLogger(SpikeLoadTest.class); public static final String jdbcUrl = "jdbc:stub"; private static final int MIN_POOL_SIZE = 5; private static final int MAX_POOL_SIZE = 50; private DataSource DS; private int requestCount; private String pool; private DbcpPoolAccessor dbcpPool; private ViburPoolHooks viburPool; private HikariPoolAccessor hikariPoolAccessor; private AtomicInteger threadsRemaining; private AtomicInteger threadsPending; private ComboPooledDataSource c3p0; private TomcatPoolAccessor tomcat; private DruidDataSource druid; public static void main(String[] args) throws InterruptedException { SpikeLoadTest test = new SpikeLoadTest(); test.setup(args); test.start(parseInt(args[0])); } private void setup(String[] args) { try { Class.forName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); StubDriver driver = (StubDriver) DriverManager.getDriver(jdbcUrl); LOGGER.info("Using driver ({}): {}", jdbcUrl, driver); } catch (Exception e) { throw new RuntimeException(e); } pool = args[1]; IntStream.of(0, 1).forEach( i -> { switch (pool) { case "hikari": setupHikari(); hikariPoolAccessor = new HikariPoolAccessor(getHikariPool(DS)); break; case "dbcp2": setupDbcp2(); dbcpPool = (DbcpPoolAccessor) DS; break; case "c3p0": setupC3P0(); c3p0 = (ComboPooledDataSource) DS; break; case "tomcat": setupTomcat(); tomcat = (TomcatPoolAccessor) DS; break; case "vibur": setupVibur(); break; case "druid": setupDruid(); break; default: throw new IllegalArgumentException("Unknown connection pool specified"); } if (i == 0) { try { LOGGER.info("Warming up pool..."); LOGGER.info("Warmup blackhole {}", warmupPool()); shutdownPool(DS); } catch (InterruptedException e) { } } }); quietlySleep(SECONDS.toMillis(2)); this.requestCount = parseInt(args[2]); } private void start(int connectDelay) throws InterruptedException { List list = new ArrayList<>(); for (int i = 0; i < requestCount; i++) { RequestThread rt = new RequestThread(); list.add(rt); } StubDriver.setConnectDelayMs(connectDelay); StubStatement.setExecuteDelayMs(2L); Timer timer = new Timer(true); ExecutorService executor = Executors.newFixedThreadPool(50); /*, new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setPriority(Thread.MIN_PRIORITY); return t; } }); */ quietlySleep(SECONDS.toMillis(3)); threadsRemaining = new AtomicInteger(requestCount); threadsPending = new AtomicInteger(0); LOGGER.info("SpikeLoadTest starting."); currentThread().setPriority(MAX_PRIORITY); timer.schedule(new TimerTask() { public void run() { for (int i = 0; i < requestCount; i++) { final Runnable runner = list.get(i); executor.execute(runner); } } }, 1); final long startTime = nanoTime(); List statsList = new ArrayList<>(); PoolStatistics poolStatistics; do { poolStatistics = getPoolStatistics(startTime, threadsPending.get()); statsList.add(poolStatistics); final long spinStart = nanoTime(); do { // spin } while (nanoTime() - spinStart < 250_000 /* 0.1ms */); } while (threadsRemaining.get() > 0 || poolStatistics.activeConnections > 0); long endTime = nanoTime(); executor.shutdown(); LOGGER.info("SpikeLoadTest completed in {}ms", MILLISECONDS.convert(endTime - startTime, NANOSECONDS)); dumpStats(statsList, list); } private void dumpStats(List statsList, List list) { System.out.println(String.join("\t", "Time", "Total", "Active", "Idle", "Wait")); for (PoolStatistics stats : statsList) { System.out.println(stats); } System.out.println("\n" + String.join("\t", "Total", "Conn", "Query", "Thread")); for (RequestThread req : list) { System.out.println(req); } } private class RequestThread extends TimerTask implements Runnable { @SuppressWarnings("unused") Exception exception; String name; long startTime; long endTime; long connectTime; long queryTime; @Override public void run() { name = currentThread().getName(); threadsPending.incrementAndGet(); startTime = nanoTime(); try (Connection connection = DS.getConnection()) { connectTime = nanoTime(); threadsPending.decrementAndGet(); try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT x FROM faux")) { queryTime = nanoTime(); } } catch (SQLException e) { exception = e; } finally { endTime = nanoTime(); threadsRemaining.decrementAndGet(); } } @Override public String toString() { return String.format("%d\t%d\t%d\t%s", NANOSECONDS.toMicros(endTime - startTime), NANOSECONDS.toMicros(connectTime - startTime), NANOSECONDS.toMicros(queryTime - connectTime), name); } } private static class PoolStatistics { long timestamp = nanoTime(); int activeConnections; int idleConnections; int pendingThreads; int totalConnections; PoolStatistics(final long baseTime) { timestamp = nanoTime() - baseTime; } @Override public String toString() { return String.format("%d\t%d\t%d\t%d\t%d", NANOSECONDS.toMicros(timestamp), totalConnections, activeConnections, idleConnections, pendingThreads); } } private PoolStatistics getPoolStatistics(final long baseTime, int remaining) { PoolStatistics stats = new PoolStatistics(baseTime); switch (pool) { case "hikari": final int[] poolStateCounts = hikariPoolAccessor.getPoolStateCounts(); stats.activeConnections = poolStateCounts[STATE_IN_USE]; stats.idleConnections = poolStateCounts[STATE_NOT_IN_USE]; stats.totalConnections = poolStateCounts[4]; stats.pendingThreads = remaining; break; case "dbcp2": stats.activeConnections = dbcpPool.getNumActive(); stats.idleConnections = dbcpPool.getNumIdle(); stats.totalConnections = dbcpPool.getNumTotal(); stats.pendingThreads = remaining; break; case "tomcat": stats.activeConnections = tomcat.getNumActive(); stats.idleConnections = tomcat.getNumIdle(); stats.totalConnections = tomcat.getNumTotal(); stats.pendingThreads = remaining; break; case "c3p0": try { stats.activeConnections = c3p0.getNumBusyConnectionsDefaultUser(); stats.idleConnections = c3p0.getNumIdleConnectionsDefaultUser(); stats.totalConnections = c3p0.getNumConnectionsDefaultUser(); stats.pendingThreads = remaining; } catch (SQLException e) { throw new RuntimeException(e); } break; case "vibur": stats.activeConnections = viburPool.getActive(); stats.idleConnections = viburPool.getIdle(); stats.totalConnections = viburPool.getTotal(); stats.pendingThreads = remaining; break; case "druid": stats.activeConnections = druid.getActiveCount(); stats.idleConnections = druid.getMinIdle(); stats.totalConnections = (int) druid.getCreateCount(); stats.pendingThreads = remaining; break; } return stats; } private long warmupPool() throws InterruptedException { final LongAdder j = new LongAdder(); ExecutorService executor = Executors.newFixedThreadPool(10); for (int k = 0; k < 10; k++) { executor.execute(() -> { for (int i = 0; i < 100_000; i++) { try (Connection connection = DS.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT x FROM faux")) { j.add(resultSet.getInt(i)); } catch (SQLException e) { throw new RuntimeException(e); } } }); } executor.shutdown(); executor.awaitTermination(60, SECONDS); return j.sum(); } private void setupDbcp2() { BasicDataSource ds = new DbcpPoolAccessor(); ds.setUrl(jdbcUrl); ds.setUsername("brettw"); ds.setPassword(""); ds.setInitialSize(MIN_POOL_SIZE); ds.setMinIdle(MIN_POOL_SIZE); ds.setMaxIdle(MAX_POOL_SIZE); ds.setMaxTotal(MAX_POOL_SIZE); ds.setMaxWaitMillis(8000); ds.setSoftMinEvictableIdleTimeMillis(MINUTES.toMillis(10)); ds.setTimeBetweenEvictionRunsMillis(SECONDS.toMillis(30)); ds.setDefaultAutoCommit(false); ds.setRollbackOnReturn(true); ds.setEnableAutoCommitOnReturn(false); ds.setTestOnBorrow(true); ds.setCacheState(true); ds.setFastFailValidation(true); try { // forces internal pool creation ds.getLogWriter(); } catch (SQLException e) { throw new RuntimeException(e); } DS = ds; } private void setupHikari() { HikariConfig config = new HikariConfig(); config.setJdbcUrl(jdbcUrl); config.setUsername("brettw"); config.setPassword(""); config.setMinimumIdle(MIN_POOL_SIZE); config.setMaximumPoolSize(MAX_POOL_SIZE); config.setConnectionTimeout(8000); config.setAutoCommit(false); DS = new HikariDataSource(config); } protected void setupDruid() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setInitialSize(MIN_POOL_SIZE); dataSource.setMaxActive(MAX_POOL_SIZE); dataSource.setMinIdle(MIN_POOL_SIZE); dataSource.setMaxIdle(MAX_POOL_SIZE); dataSource.setPoolPreparedStatements(true); dataSource.setDriverClassName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); dataSource.setUrl(jdbcUrl); dataSource.setUsername("brettw"); dataSource.setPassword(""); dataSource.setValidationQuery("SELECT 1"); dataSource.setTestOnBorrow(true); dataSource.setDefaultAutoCommit(false); dataSource.setMaxWait(8000); dataSource.setUseUnfairLock(true); druid = dataSource; DS = dataSource; } protected void setupTomcat() { PoolProperties props = new PoolProperties(); props.setUrl(jdbcUrl); props.setDriverClassName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); props.setUsername("brettw"); props.setPassword(""); props.setInitialSize(MIN_POOL_SIZE); props.setMinIdle(MIN_POOL_SIZE); props.setMaxIdle(MAX_POOL_SIZE); props.setMaxActive(MAX_POOL_SIZE); props.setMaxWait(8000); props.setDefaultAutoCommit(false); props.setRollbackOnReturn(true); props.setUseDisposableConnectionFacade(true); props.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState"); //;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"); props.setTestOnBorrow(true); props.setValidationInterval(250); props.setValidator(new Validator() { @Override public boolean validate(Connection connection, int validateAction) { try { return (validateAction == PooledConnection.VALIDATE_BORROW ? connection.isValid(0) : true); } catch (SQLException e) { return false; } } }); DS = new TomcatPoolAccessor(props); } private void setupC3P0() { try { ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setJdbcUrl(jdbcUrl); cpds.setUser("brettw"); cpds.setPassword(""); cpds.setAcquireIncrement(1); cpds.setInitialPoolSize(MIN_POOL_SIZE); cpds.setNumHelperThreads(2); cpds.setMinPoolSize(MIN_POOL_SIZE); cpds.setMaxPoolSize(MAX_POOL_SIZE); cpds.setCheckoutTimeout(8000); cpds.setLoginTimeout(8); cpds.setTestConnectionOnCheckout(true); try (Connection connection = cpds.getConnection()) { // acquire and close to poke the pool into action } DS = cpds; } catch (Exception e) { throw new RuntimeException(e); } } private void setupVibur() { ViburDBCPDataSource vibur = new ViburDBCPDataSource(); vibur.setJdbcUrl(jdbcUrl); vibur.setUsername("brettw"); vibur.setPassword(""); vibur.setPoolFair(false); vibur.setPoolInitialSize(MIN_POOL_SIZE); vibur.setPoolMaxSize(MAX_POOL_SIZE); vibur.setDefaultAutoCommit(false); vibur.setResetDefaultsAfterUse(true); vibur.setConnectionIdleLimitInSeconds(30); vibur.setReducerTimeIntervalInSeconds((int) MINUTES.toSeconds(10)); viburPool = new ViburPoolHooks(); vibur.getConnHooks().addOnInit(viburPool.getInitHook()); vibur.getConnHooks().addOnGet(viburPool.getGetHook()); vibur.getConnHooks().addOnClose(viburPool.getCloseHook()); vibur.start(); DS = vibur; } private void shutdownPool(DataSource ds) { if (ds instanceof AutoCloseable) { try { ((AutoCloseable) ds).close(); } catch (Exception e) { } } else if (ds instanceof ComboPooledDataSource) { ((ComboPooledDataSource) ds).close(); } } private static HikariPool getHikariPool(DataSource ds) { try { Field field = ds.getClass().getDeclaredField("pool"); field.setAccessible(true); return (HikariPool) field.get(ds); } catch (Exception e) { throw new RuntimeException(e); } } private static class ViburPoolHooks { private AtomicInteger created = new AtomicInteger(); private AtomicInteger active = new AtomicInteger(); int getTotal() { return created.get(); } int getActive() { return active.get(); } int getIdle() { return created.get() - active.get(); } InitHook getInitHook() { return new InitHook(); } GetHook getGetHook() { return new GetHook(); } CloseHook getCloseHook() { return new CloseHook(); } private class InitHook implements InitConnection { @Override public void on(Connection rawConnection, long takenNanos) throws SQLException { created.incrementAndGet(); } } private class GetHook implements GetConnection { @Override public void on(Connection rawConnection, long takenNanos) throws SQLException { active.incrementAndGet(); } } private class CloseHook implements CloseConnection { @Override public void on(Connection rawConnection, long takenNanos) throws SQLException { active.decrementAndGet(); } } } } ================================================ FILE: src/test/java/com/zaxxer/hikari/pool/HikariPoolAccessor.java ================================================ package com.zaxxer.hikari.pool; public class HikariPoolAccessor { private final HikariPool pool; public HikariPoolAccessor(HikariPool pool) { this.pool = pool; } public int[] getPoolStateCounts() { return pool.getPoolStateCounts(); } } ================================================ FILE: src/test/java/org/apache/commons/dbcp2/DbcpPoolAccessor.java ================================================ package org.apache.commons.dbcp2; import java.sql.Connection; import java.sql.SQLException; public final class DbcpPoolAccessor extends BasicDataSource { public DbcpPoolAccessor() { super(); } @Override public Connection getConnection() throws SQLException { return super.getConnection(); } public int getNumTotal() { return (int) getConnectionPool().getCreatedCount(); } } ================================================ FILE: src/test/java/org/apache/commons/dbcp2/TomcatPoolAccessor.java ================================================ package org.apache.commons.dbcp2; import java.sql.Connection; import java.sql.SQLException; import org.apache.tomcat.jdbc.pool.DataSource; import org.apache.tomcat.jdbc.pool.PoolProperties; public final class TomcatPoolAccessor extends DataSource { public TomcatPoolAccessor(PoolProperties props) { super(props); try { // forces internal pool creation super.createPool(); } catch (SQLException e) { e.printStackTrace(); } } @Override public Connection getConnection() throws SQLException { return super.getConnection(); } public int getNumTotal() { return pool.getActive() + pool.getIdle(); } }