├── .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 /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings/org.eclipse.core.resources.prefs 5 | .settings/org.eclipse.jdt.core.prefs 6 | .settings/org.eclipse.m2e.core.prefs 7 | .idea 8 | HikariCP-benchmark.iml 9 | jmh.out 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Dependency Status](https://www.versioneye.com/user/projects/55501400f7db0da74e00017f/badge.svg?style=flat)](https://www.versioneye.com/user/projects/55501400f7db0da74e00017f) 2 | 3 | ![](https://github.com/brettwooldridge/HikariCP/wiki/HikariCP-bench-2.6.0.png) 4 | 5 | *ConnectionCycle* measures cycles of ``DataSource.getConnection()/Connection.close()``. *StatementCycle* measures cycles of ``Connection.prepareStatement()``, ``Statement.execute()``, ``Statement.close()``. 6 | 7 | #### JMH Connection Pool Microbenchmarks 8 | 9 | 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. 10 | 11 | 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. 12 | 13 | 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). 14 | 15 | #### How to run? 16 | * ``git clone https://github.com/brettwooldridge/HikariCP-benchmark.git`` 17 | * ``cd HikariCP-benchmark`` 18 | * ``mvn clean package`` 19 | * ``./benchmark.sh`` 20 | 21 | The ``benchmark.sh`` script is a wrapper around JMH execution. A full run of the benchmark will take about 45 minutes for all pools. 22 | 23 | There are several more options you can provide to the ``benchmark.sh``. There are a lot actually, but these are most useful... 24 | 25 | **Specify Shorter Runs**
26 | 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. 27 | ``` 28 | ./benchmark.sh quick 29 | ``` 30 | If specified with other options, ``quick`` or ``medium`` must be the first option. 31 | 32 | ----------------------------------------------------------- 33 | 34 | **Specify Specific Pools**
35 | ``` 36 | ./benchmark.sh -p pool=hikari,bone 37 | ``` 38 | Where ``pool`` is a comma-separated list (*hikari*, *dbcp2*, *tomcat*, *c3p0*, *vibur*). Specifying a specific pool or subset of pools will shorten run times. 39 | 40 | ----------------------------------------------------------- 41 | 42 | **Specify Pool Size**
43 | ``` 44 | ./benchmark.sh -p maxPoolSize=16 45 | ``` 46 | 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). 47 | 48 | ----------------------------------------------------------- 49 | **Specify which Benchmark**
50 | 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: 51 | ``` 52 | ./benchmark.sh ".*Statement.*" 53 | ``` 54 | 55 | ----------------------------------------------------------- 56 | 57 | All of the options can be combined: 58 | ``` 59 | ./benchmark.sh medium -p pool=hikari,vibur -p maxPoolSize=4 ".*Connection.*" 60 | ``` 61 | ----------------------------------------------------------- 62 | -------------------------------------------------------------------------------- /benchmark.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set JAVA_OPTIONS=-server -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms1096m -Xmx1096m 5 | 6 | call mvn clean package 7 | 8 | set JMH_THREADS=-t 8 9 | if "%2" == "-t" ( 10 | set JMH_THREADS=-t %3 11 | shift /2 12 | shift /2 13 | ) 14 | 15 | set command=%~1 16 | 17 | if "quick" == "%command%" ( 18 | java -jar target\microbenchmarks.jar -jvmArgs "%JAVA_OPTIONS%" -wi 3 -i 8 %JMH_THREADS% -f 2 %2 %3 %4 %5 %6 %7 19 | ) 20 | if "medium" == "%command%" ( 21 | java -jar target\microbenchmarks.jar -jvmArgs "%JAVA_OPTIONS%" -wi 3 -f 8 -i 6 %JMH_THREADS% %2 %3 %4 %5 %6 %7 22 | ) 23 | if "long" == "%command%" ( 24 | java -jar target\microbenchmarks.jar -jvmArgs "%JAVA_OPTIONS%" -wi 5 -f 20 -i 15 %JMH_THREADS% %2 %3 %4 %5 %6 %7 25 | ) 26 | 27 | 28 | rem java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -i 15 -t 8 $1 $2 $3 $4 $5 $6 $7 $8 $9 29 | -------------------------------------------------------------------------------- /benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | JAVA_OPTIONS="-server -XX:-RestrictContended -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms1096m -Xmx1096m" 4 | 5 | if [[ "clean" == "$1" ]]; then 6 | mvn clean package 7 | shift 8 | fi 9 | 10 | if [[ "gcprof" == "$1" ]]; then 11 | JAVA_OPTIONS="$JAVA_OPTIONS -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps" 12 | shift 13 | fi 14 | 15 | JMH_THREADS="-t 8" 16 | if [[ "$2" == "-t" ]]; then 17 | JMH_THREADS="-t $3" 18 | set -- "$1" "${@:4}" 19 | fi 20 | 21 | if [[ "quick" == "$1" ]]; then 22 | java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -i 8 $JMH_THREADS -f 2 $2 $3 $4 $5 $6 $7 $8 $9 23 | elif [[ "medium" == "$1" ]]; then 24 | java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -f 8 -i 6 $JMH_THREADS $2 $3 $4 $5 $6 $7 $8 $9 25 | elif [[ "long" == "$1" ]]; then 26 | java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -i 15 $JMH_THREADS $2 $3 $4 $5 $6 $7 $8 $9 27 | elif [[ "profile" == "$1" ]]; then 28 | 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 29 | elif [[ "debug" == "$1" ]]; then 30 | 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 31 | else 32 | java -jar ./target/microbenchmarks.jar -jvmArgs "$JAVA_OPTIONS" -wi 3 -i 15 -t 8 $1 $2 $3 $4 $5 $6 $7 $8 $9 33 | fi 34 | 35 | -------------------------------------------------------------------------------- /lib/one-datasource.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brettwooldridge/HikariCP-benchmark/ede3501d4f55555cc9be24d2993f3f0e32944afc/lib/one-datasource.jar -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 19 | 4.0.0 20 | 21 | com.zaxxer 22 | HikariCP-benchmark 23 | 1.0-SNAPSHOT 24 | jar 25 | 26 | Auto-generated JMH benchmark 27 | 28 | 29 | 30 | com.zaxxer 31 | HikariCP 32 | 3.1.0 33 | 34 | 36 | 37 | com.jolbox 38 | bonecp 39 | 0.8.0.RELEASE 40 | 41 | 42 | org.apache.tomcat 43 | tomcat-jdbc 44 | 8.5.34 45 | 46 | 47 | io.dropwizard.metrics 48 | metrics-core 49 | 3.1.2 50 | 51 | 52 | org.apache.commons 53 | commons-dbcp2 54 | 2.5.0 55 | 56 | 57 | commons-dbcp 58 | commons-dbcp 59 | 1.4 60 | 61 | 62 | com.mchange 63 | c3p0 64 | 0.9.5.2 65 | 66 | 67 | com.alibaba 68 | druid 69 | 1.1.10 70 | 71 | 72 | one.datasource 73 | one 74 | 1.0.0 75 | system 76 | ${project.basedir}/lib/one-datasource.jar 77 | 78 | 79 | mysql 80 | mysql-connector-java 81 | 5.1.42 82 | 83 | 84 | org.vibur 85 | vibur-dbcp 86 | 22.2 87 | 88 | 89 | log4j 90 | log4j 91 | 92 | 93 | slf4j-log4j12 94 | org.slf4j 95 | 96 | 97 | 98 | 99 | org.apache.logging.log4j 100 | log4j-core 101 | 2.7 102 | test 103 | 104 | 105 | org.openjdk.jmh 106 | jmh-core 107 | 1.17.2 108 | 109 | 110 | org.openjdk.jmh 111 | jmh-generator-annprocess 112 | 1.17.2 113 | 114 | 115 | javax.transaction 116 | jta 117 | 1.1 118 | 119 | 120 | junit 121 | junit 122 | 4.12 123 | 124 | 125 | org.postgresql 126 | postgresql 127 | 9.4-1200-jdbc41 128 | 129 | 130 | 131 | 132 | UTF-8 133 | 134 | 135 | 136 | 137 | 138 | com.googlecode.addjars-maven-plugin 139 | addjars-maven-plugin 140 | 1.0.5 141 | 142 | 143 | 144 | add-jars 145 | 146 | 147 | 148 | 149 | ${basedir}/lib 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | org.apache.maven.plugins 158 | maven-compiler-plugin 159 | 3.3 160 | 161 | 1.8 162 | 1.8 163 | 1.8 164 | 165 | 166 | 167 | org.apache.maven.plugins 168 | maven-shade-plugin 169 | 2.3 170 | 171 | 172 | package 173 | 174 | shade 175 | 176 | 177 | microbenchmarks 178 | 179 | 181 | org.openjdk.jmh.Main 182 | 183 | 184 | 185 | 186 | *:* 187 | 188 | META-INF/services/javax.annotation.processing.Processor 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /spiketest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | JAVA_OPTIONS="-server -XX:-RestrictContended -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms1096m -Xmx1096m" 4 | 5 | if [[ "clean" == "$1" ]]; then 6 | mvn clean package 7 | shift 8 | fi 9 | 10 | 11 | java -cp ./target/microbenchmarks.jar:./target/test-classes $JAVA_OPTIONS com.zaxxer.hikari.benchmark.SpikeLoadTest $1 $2 $3 $4 $5 $6 $7 $8 $9 12 | -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/BenchBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark; 18 | 19 | import java.sql.Connection; 20 | import java.sql.DriverManager; 21 | import java.sql.SQLException; 22 | import java.util.Properties; 23 | import java.util.concurrent.Executors; 24 | 25 | import javax.sql.DataSource; 26 | 27 | import com.alibaba.druid.filter.stat.MergeStatFilter; 28 | import com.alibaba.druid.filter.stat.StatFilter; 29 | import com.alibaba.druid.pool.DruidDataSource; 30 | import org.apache.commons.dbcp2.BasicDataSource; 31 | import org.apache.tomcat.jdbc.pool.PoolProperties; 32 | import org.apache.tomcat.jdbc.pool.PooledConnection; 33 | import org.apache.tomcat.jdbc.pool.Validator; 34 | import org.openjdk.jmh.annotations.Level; 35 | import org.openjdk.jmh.annotations.Param; 36 | import org.openjdk.jmh.annotations.Scope; 37 | import org.openjdk.jmh.annotations.Setup; 38 | import org.openjdk.jmh.annotations.State; 39 | import org.openjdk.jmh.annotations.TearDown; 40 | import org.openjdk.jmh.infra.BenchmarkParams; 41 | import org.vibur.dbcp.ViburDBCPDataSource; 42 | 43 | import com.mchange.v2.c3p0.ComboPooledDataSource; 44 | import com.zaxxer.hikari.HikariConfig; 45 | import com.zaxxer.hikari.HikariDataSource; 46 | 47 | import one.datasource.DataSourceImpl; 48 | 49 | @State(Scope.Benchmark) 50 | public class BenchBase 51 | { 52 | protected static final int MIN_POOL_SIZE = 0; 53 | 54 | @Param({ "hikari", "dbcp2", "tomcat", "c3p0", "vibur", "druid", "druid-stat", "druid-stat-merge" }) 55 | public String pool; 56 | 57 | @Param({ "32" }) 58 | public int maxPoolSize; 59 | 60 | @Param({ "jdbc:stub" }) 61 | public String jdbcUrl; 62 | 63 | public static DataSource DS; 64 | 65 | @Setup(Level.Trial) 66 | public void setup(BenchmarkParams params) 67 | { 68 | try 69 | { 70 | Class.forName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); 71 | System.err.printf("Using driver (%s): %s", jdbcUrl, DriverManager.getDriver(jdbcUrl)); 72 | } 73 | catch (Exception e) 74 | { 75 | throw new RuntimeException(e); 76 | } 77 | 78 | if (this.getClass().getName().contains("Statement")) { 79 | System.err.println("# Overriding maxPoolSize paramter for StatementBench: maxPoolSize=" + params.getThreads()); 80 | maxPoolSize = params.getThreads(); 81 | } 82 | 83 | switch (pool) 84 | { 85 | case "hikari": 86 | setupHikari(); 87 | break; 88 | case "tomcat": 89 | setupTomcat(); 90 | break; 91 | case "dbcp": 92 | setupDbcp(); 93 | break; 94 | case "dbcp2": 95 | setupDbcp2(); 96 | break; 97 | case "c3p0": 98 | setupC3P0(); 99 | break; 100 | case "vibur": 101 | setupVibur(); 102 | break; 103 | case "one": 104 | setupOne(); 105 | break; 106 | case "druid": 107 | setupDruid(); 108 | break; 109 | case "druid-stat": 110 | setupDruidStat(); 111 | break; 112 | case "druid-stat-merge": 113 | setupDruidStatMerge(); 114 | break; 115 | } 116 | 117 | } 118 | 119 | @TearDown(Level.Trial) 120 | public void teardown() throws SQLException 121 | { 122 | switch (pool) 123 | { 124 | case "hikari": 125 | ((HikariDataSource) DS).close(); 126 | break; 127 | case "tomcat": 128 | ((org.apache.tomcat.jdbc.pool.DataSource) DS).close(); 129 | break; 130 | case "dbcp": 131 | ((org.apache.commons.dbcp.BasicDataSource) DS).close(); 132 | break; 133 | case "dbcp2": 134 | ((BasicDataSource) DS).close(); 135 | break; 136 | case "c3p0": 137 | ((ComboPooledDataSource) DS).close(); 138 | break; 139 | case "vibur": 140 | ((ViburDBCPDataSource) DS).terminate(); 141 | break; 142 | case "druid": 143 | ((DruidDataSource) DS).close(); 144 | break; 145 | case "druid-stat": 146 | ((DruidDataSource) DS).close(); 147 | break; 148 | case "druid-stat-merge": 149 | ((DruidDataSource) DS).close(); 150 | break; 151 | 152 | } 153 | } 154 | 155 | protected void setupDruid() { 156 | DS = createDruid(); 157 | } 158 | 159 | protected void setupDruidStat() 160 | { 161 | DruidDataSource druid = createDruid(); 162 | 163 | try { 164 | druid.addFilters("stat"); 165 | } catch (SQLException e) { 166 | throw new RuntimeException(e); 167 | } 168 | DS = druid; 169 | } 170 | 171 | protected void setupDruidStatMerge() 172 | { 173 | DruidDataSource druid = createDruid(); 174 | 175 | StatFilter statFilter = new MergeStatFilter(); 176 | druid.getProxyFilters().add(statFilter); 177 | DS = druid; 178 | } 179 | 180 | protected DruidDataSource createDruid() 181 | { 182 | DruidDataSource druid = new DruidDataSource(); 183 | 184 | druid.setInitialSize(MIN_POOL_SIZE); 185 | druid.setMaxActive(maxPoolSize); 186 | druid.setMinIdle(MIN_POOL_SIZE); 187 | druid.setPoolPreparedStatements(true); 188 | druid.setDriverClassName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); 189 | druid.setUrl(jdbcUrl); 190 | druid.setUsername("brettw"); 191 | druid.setPassword(""); 192 | druid.setValidationQuery("SELECT 1"); 193 | druid.setTestOnBorrow(true); 194 | druid.setDefaultAutoCommit(false); 195 | druid.setMaxWait(8000); 196 | druid.setUseUnfairLock(true); 197 | 198 | return druid; 199 | } 200 | 201 | protected void setupTomcat() 202 | { 203 | PoolProperties props = new PoolProperties(); 204 | props.setUrl(jdbcUrl); 205 | props.setDriverClassName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); 206 | props.setUsername("brettw"); 207 | props.setPassword(""); 208 | props.setInitialSize(MIN_POOL_SIZE); 209 | props.setMinIdle(MIN_POOL_SIZE); 210 | props.setMaxIdle(maxPoolSize); 211 | props.setMaxActive(maxPoolSize); 212 | props.setMaxWait(8000); 213 | 214 | props.setDefaultAutoCommit(false); 215 | 216 | props.setRollbackOnReturn(true); 217 | props.setUseDisposableConnectionFacade(true); 218 | props.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState"); //;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"); 219 | props.setTestOnBorrow(true); 220 | props.setValidationInterval(1000); 221 | props.setValidator(new Validator() { 222 | @Override 223 | public boolean validate(Connection connection, int validateAction) 224 | { 225 | try { 226 | return (validateAction == PooledConnection.VALIDATE_BORROW ? connection.isValid(0) : true); 227 | } 228 | catch (SQLException e) 229 | { 230 | return false; 231 | } 232 | } 233 | }); 234 | 235 | DS = new org.apache.tomcat.jdbc.pool.DataSource(props); 236 | } 237 | 238 | protected void setupDbcp() 239 | { 240 | org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource(); 241 | ds.setUrl(jdbcUrl); 242 | ds.setUsername("brettw"); 243 | ds.setPassword(""); 244 | ds.setInitialSize(MIN_POOL_SIZE); 245 | ds.setMinIdle(MIN_POOL_SIZE); 246 | ds.setMaxIdle(maxPoolSize); 247 | ds.setMaxActive(maxPoolSize); 248 | 249 | ds.setDefaultAutoCommit(false); 250 | ds.setTestOnBorrow(true); 251 | ds.setValidationQuery("SELECT 1"); 252 | 253 | DS = ds; 254 | } 255 | 256 | protected void setupDbcp2() 257 | { 258 | BasicDataSource ds = new BasicDataSource(); 259 | ds.setUrl(jdbcUrl); 260 | ds.setUsername("brettw"); 261 | ds.setPassword(""); 262 | ds.setInitialSize(MIN_POOL_SIZE); 263 | ds.setMinIdle(MIN_POOL_SIZE); 264 | ds.setMaxIdle(maxPoolSize); 265 | ds.setMaxTotal(maxPoolSize); 266 | ds.setMaxWaitMillis(8000); 267 | 268 | ds.setDefaultAutoCommit(false); 269 | ds.setRollbackOnReturn(true); 270 | ds.setEnableAutoCommitOnReturn(false); 271 | ds.setTestOnBorrow(true); 272 | ds.setCacheState(true); 273 | ds.setFastFailValidation(true); 274 | 275 | DS = ds; 276 | } 277 | 278 | protected void setupHikari() 279 | { 280 | HikariConfig config = new HikariConfig(); 281 | config.setJdbcUrl(jdbcUrl); 282 | config.setUsername("brettw"); 283 | config.setPassword(""); 284 | config.setMinimumIdle(MIN_POOL_SIZE); 285 | config.setMaximumPoolSize(maxPoolSize); 286 | config.setConnectionTimeout(8000); 287 | config.setAutoCommit(false); 288 | 289 | DS = new HikariDataSource(config); 290 | } 291 | 292 | protected void setupC3P0() 293 | { 294 | try 295 | { 296 | ComboPooledDataSource cpds = new ComboPooledDataSource(); 297 | cpds.setJdbcUrl( jdbcUrl ); 298 | cpds.setUser("brettw"); 299 | cpds.setPassword(""); 300 | cpds.setAcquireIncrement(1); 301 | cpds.setInitialPoolSize(MIN_POOL_SIZE); 302 | cpds.setMinPoolSize(MIN_POOL_SIZE); 303 | cpds.setMaxPoolSize(maxPoolSize); 304 | cpds.setCheckoutTimeout(8000); 305 | cpds.setLoginTimeout(8); 306 | cpds.setTestConnectionOnCheckout(true); 307 | // cpds.setPreferredTestQuery("VALUES 1"); 308 | 309 | DS = cpds; 310 | } 311 | catch (Exception e) 312 | { 313 | throw new RuntimeException(e); 314 | } 315 | } 316 | 317 | private void setupVibur() 318 | { 319 | ViburDBCPDataSource vibur = new ViburDBCPDataSource(); 320 | vibur.setJdbcUrl( jdbcUrl ); 321 | vibur.setUsername("brettw"); 322 | vibur.setPassword(""); 323 | vibur.setConnectionTimeoutInMs(5000); 324 | vibur.setValidateTimeoutInSeconds(3); 325 | vibur.setLoginTimeoutInSeconds(2); 326 | vibur.setPoolInitialSize(MIN_POOL_SIZE); 327 | vibur.setPoolMaxSize(maxPoolSize); 328 | vibur.setConnectionIdleLimitInSeconds(1); 329 | vibur.setAcquireRetryAttempts(0); 330 | vibur.setReducerTimeIntervalInSeconds(0); 331 | vibur.setUseNetworkTimeout(true); 332 | vibur.setNetworkTimeoutExecutor(Executors.newFixedThreadPool(1)); 333 | vibur.setClearSQLWarnings(true); 334 | vibur.setResetDefaultsAfterUse(true); 335 | vibur.start(); 336 | 337 | DS = vibur; 338 | } 339 | 340 | private void setupOne() 341 | { 342 | Properties props = new Properties(); 343 | props.put("url", jdbcUrl); 344 | props.put("driver", "com.zaxxer.hikari.benchmark.stubs.StubDriver"); 345 | 346 | DS = new DataSourceImpl("one", props); 347 | } 348 | } 349 | -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/ConnectionBench.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark; 18 | 19 | import java.sql.Connection; 20 | import java.sql.SQLException; 21 | import java.util.concurrent.TimeUnit; 22 | 23 | import org.openjdk.jmh.annotations.Benchmark; 24 | import org.openjdk.jmh.annotations.BenchmarkMode; 25 | import org.openjdk.jmh.annotations.CompilerControl; 26 | import org.openjdk.jmh.annotations.Measurement; 27 | import org.openjdk.jmh.annotations.Mode; 28 | import org.openjdk.jmh.annotations.OutputTimeUnit; 29 | import org.openjdk.jmh.annotations.Warmup; 30 | 31 | //@State(Scope.Benchmark) 32 | //@Warmup(iterations=3, batchSize=1_000_000) 33 | //@Measurement(iterations=8, batchSize=1_000_000) 34 | //@BenchmarkMode(Mode.SingleShotTime) 35 | //@OutputTimeUnit(TimeUnit.NANOSECONDS) 36 | 37 | @Warmup(iterations=3) 38 | @Measurement(iterations=8) 39 | @BenchmarkMode(Mode.Throughput) 40 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 41 | 42 | //@Warmup(iterations=3) 43 | //@Measurement(iterations=8) 44 | //@BenchmarkMode(Mode.SampleTime) 45 | //@OutputTimeUnit(TimeUnit.MILLISECONDS) 46 | public class ConnectionBench extends BenchBase 47 | { 48 | @Benchmark 49 | @CompilerControl(CompilerControl.Mode.INLINE) 50 | public static Connection cycleCnnection() throws SQLException 51 | { 52 | Connection connection = DS.getConnection(); 53 | connection.close(); 54 | return connection; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/StatementBench.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark; 18 | 19 | import java.sql.Connection; 20 | import java.sql.SQLException; 21 | import java.sql.Statement; 22 | import java.util.concurrent.TimeUnit; 23 | 24 | import org.openjdk.jmh.annotations.Benchmark; 25 | import org.openjdk.jmh.annotations.BenchmarkMode; 26 | import org.openjdk.jmh.annotations.CompilerControl; 27 | import org.openjdk.jmh.annotations.Level; 28 | import org.openjdk.jmh.annotations.Measurement; 29 | import org.openjdk.jmh.annotations.Mode; 30 | import org.openjdk.jmh.annotations.OutputTimeUnit; 31 | import org.openjdk.jmh.annotations.Scope; 32 | import org.openjdk.jmh.annotations.Setup; 33 | import org.openjdk.jmh.annotations.State; 34 | import org.openjdk.jmh.annotations.TearDown; 35 | import org.openjdk.jmh.annotations.Warmup; 36 | import org.openjdk.jmh.infra.Blackhole; 37 | 38 | //@State(Scope.Benchmark) 39 | //@Warmup(iterations=3, batchSize=1_000_000) 40 | //@Measurement(iterations=8, batchSize=1_000_000) 41 | //@BenchmarkMode(Mode.SingleShotTime) 42 | //@OutputTimeUnit(TimeUnit.NANOSECONDS) 43 | 44 | @State(Scope.Benchmark) 45 | @Warmup(iterations=3) 46 | @Measurement(iterations=8) 47 | @BenchmarkMode(Mode.Throughput) 48 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 49 | public class StatementBench extends BenchBase 50 | { 51 | @Benchmark 52 | @CompilerControl(CompilerControl.Mode.INLINE) 53 | public Statement cycleStatement(Blackhole bh, ConnectionState state) throws SQLException 54 | { 55 | Statement statement = state.connection.createStatement(); 56 | bh.consume(statement.execute("INSERT INTO test (column) VALUES (?)")); 57 | statement.close(); 58 | return statement; 59 | } 60 | 61 | @State(Scope.Thread) 62 | public static class ConnectionState 63 | { 64 | Connection connection; 65 | 66 | @Setup(Level.Iteration) 67 | public void setup() throws SQLException 68 | { 69 | connection = DS.getConnection(); 70 | } 71 | 72 | @TearDown(Level.Iteration) 73 | public void teardown() throws SQLException 74 | { 75 | connection.close(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/stubs/StubConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark.stubs; 18 | 19 | import java.sql.Array; 20 | import java.sql.Blob; 21 | import java.sql.CallableStatement; 22 | import java.sql.Clob; 23 | import java.sql.Connection; 24 | import java.sql.DatabaseMetaData; 25 | import java.sql.NClob; 26 | import java.sql.PreparedStatement; 27 | import java.sql.SQLClientInfoException; 28 | import java.sql.SQLException; 29 | import java.sql.SQLWarning; 30 | import java.sql.SQLXML; 31 | import java.sql.Savepoint; 32 | import java.sql.Statement; 33 | import java.sql.Struct; 34 | import java.util.Map; 35 | import java.util.Properties; 36 | import java.util.concurrent.Executor; 37 | import java.util.concurrent.ThreadLocalRandom; 38 | 39 | /** 40 | * 41 | * @author Brett Wooldridge 42 | */ 43 | public class StubConnection implements Connection 44 | { 45 | public static volatile boolean throwRandomExceptions; 46 | 47 | private static long foo; 48 | 49 | private boolean autoCommit; 50 | private boolean isClosed; 51 | private int isolation; 52 | 53 | static { 54 | foo = System.currentTimeMillis(); 55 | } 56 | 57 | /** {@inheritDoc} */ 58 | public T unwrap(Class iface) throws SQLException 59 | { 60 | return null; 61 | } 62 | 63 | /** {@inheritDoc} */ 64 | public boolean isWrapperFor(Class iface) throws SQLException 65 | { 66 | return false; 67 | } 68 | 69 | /** {@inheritDoc} */ 70 | public Statement createStatement() throws SQLException 71 | { 72 | return new StubStatement(); 73 | } 74 | 75 | /** {@inheritDoc} */ 76 | public PreparedStatement prepareStatement(String sql) throws SQLException 77 | { 78 | return new StubPreparedStatement(); 79 | } 80 | 81 | /** {@inheritDoc} */ 82 | public CallableStatement prepareCall(String sql) throws SQLException 83 | { 84 | return null; 85 | } 86 | 87 | /** {@inheritDoc} */ 88 | public String nativeSQL(String sql) throws SQLException 89 | { 90 | return null; 91 | } 92 | 93 | /** {@inheritDoc} */ 94 | public void setAutoCommit(boolean autoCommit) throws SQLException 95 | { 96 | this.autoCommit = autoCommit; 97 | } 98 | 99 | /** {@inheritDoc} */ 100 | public boolean getAutoCommit() throws SQLException 101 | { 102 | return autoCommit; 103 | } 104 | 105 | /** {@inheritDoc} */ 106 | public void commit() throws SQLException 107 | { 108 | 109 | } 110 | 111 | /** {@inheritDoc} */ 112 | public void rollback() throws SQLException 113 | { 114 | autoCommit = false; 115 | } 116 | 117 | /** {@inheritDoc} */ 118 | public void close() throws SQLException 119 | { 120 | isClosed = true; 121 | } 122 | 123 | /** {@inheritDoc} */ 124 | public boolean isClosed() throws SQLException 125 | { 126 | return isClosed; 127 | } 128 | 129 | /** {@inheritDoc} */ 130 | public DatabaseMetaData getMetaData() throws SQLException 131 | { 132 | return null; 133 | } 134 | 135 | /** {@inheritDoc} */ 136 | public void setReadOnly(boolean readOnly) throws SQLException 137 | { 138 | } 139 | 140 | /** {@inheritDoc} */ 141 | public boolean isReadOnly() throws SQLException 142 | { 143 | return false; 144 | } 145 | 146 | /** {@inheritDoc} */ 147 | public void setCatalog(String catalog) throws SQLException 148 | { 149 | } 150 | 151 | /** {@inheritDoc} */ 152 | public String getCatalog() throws SQLException 153 | { 154 | return null; 155 | } 156 | 157 | /** {@inheritDoc} */ 158 | public void setTransactionIsolation(int level) throws SQLException 159 | { 160 | this.isolation = level; 161 | } 162 | 163 | /** {@inheritDoc} */ 164 | public int getTransactionIsolation() throws SQLException 165 | { 166 | return isolation; 167 | } 168 | 169 | /** {@inheritDoc} */ 170 | public SQLWarning getWarnings() throws SQLException 171 | { 172 | return null; 173 | } 174 | 175 | /** {@inheritDoc} */ 176 | public void clearWarnings() throws SQLException 177 | { 178 | autoCommit = false; 179 | } 180 | 181 | /** {@inheritDoc} */ 182 | public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException 183 | { 184 | return null; 185 | } 186 | 187 | /** {@inheritDoc} */ 188 | public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException 189 | { 190 | return new StubPreparedStatement(); 191 | } 192 | 193 | /** {@inheritDoc} */ 194 | public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException 195 | { 196 | return null; 197 | } 198 | 199 | /** {@inheritDoc} */ 200 | public Map> getTypeMap() throws SQLException 201 | { 202 | return null; 203 | } 204 | 205 | /** {@inheritDoc} */ 206 | public void setTypeMap(Map> map) throws SQLException 207 | { 208 | } 209 | 210 | /** {@inheritDoc} */ 211 | public void setHoldability(int holdability) throws SQLException 212 | { 213 | } 214 | 215 | /** {@inheritDoc} */ 216 | public int getHoldability() throws SQLException 217 | { 218 | return (int) foo; 219 | } 220 | 221 | /** {@inheritDoc} */ 222 | public Savepoint setSavepoint() throws SQLException 223 | { 224 | return null; 225 | } 226 | 227 | /** {@inheritDoc} */ 228 | public Savepoint setSavepoint(String name) throws SQLException 229 | { 230 | return null; 231 | } 232 | 233 | /** {@inheritDoc} */ 234 | public void rollback(Savepoint savepoint) throws SQLException 235 | { 236 | } 237 | 238 | /** {@inheritDoc} */ 239 | public void releaseSavepoint(Savepoint savepoint) throws SQLException 240 | { 241 | } 242 | 243 | /** {@inheritDoc} */ 244 | public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException 245 | { 246 | return null; 247 | } 248 | 249 | /** {@inheritDoc} */ 250 | public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException 251 | { 252 | return new StubPreparedStatement(); 253 | } 254 | 255 | /** {@inheritDoc} */ 256 | public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException 257 | { 258 | return null; 259 | } 260 | 261 | /** {@inheritDoc} */ 262 | public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException 263 | { 264 | return new StubPreparedStatement(); 265 | } 266 | 267 | /** {@inheritDoc} */ 268 | public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException 269 | { 270 | return new StubPreparedStatement(); 271 | } 272 | 273 | /** {@inheritDoc} */ 274 | public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException 275 | { 276 | return new StubPreparedStatement(); 277 | } 278 | 279 | /** {@inheritDoc} */ 280 | public Clob createClob() throws SQLException 281 | { 282 | return null; 283 | } 284 | 285 | /** {@inheritDoc} */ 286 | public Blob createBlob() throws SQLException 287 | { 288 | return null; 289 | } 290 | 291 | /** {@inheritDoc} */ 292 | public NClob createNClob() throws SQLException 293 | { 294 | return null; 295 | } 296 | 297 | /** {@inheritDoc} */ 298 | public SQLXML createSQLXML() throws SQLException 299 | { 300 | return null; 301 | } 302 | 303 | /** {@inheritDoc} */ 304 | public boolean isValid(int timeout) throws SQLException 305 | { 306 | if (throwRandomExceptions && ThreadLocalRandom.current().nextInt(100) == 9) { 307 | throw new RuntimeException("isValidThrowsException=true"); 308 | } 309 | 310 | return true; 311 | } 312 | 313 | /** {@inheritDoc} */ 314 | public void setClientInfo(String name, String value) throws SQLClientInfoException 315 | { 316 | } 317 | 318 | /** {@inheritDoc} */ 319 | public void setClientInfo(Properties properties) throws SQLClientInfoException 320 | { 321 | } 322 | 323 | /** {@inheritDoc} */ 324 | public String getClientInfo(String name) throws SQLException 325 | { 326 | return null; 327 | } 328 | 329 | /** {@inheritDoc} */ 330 | public Properties getClientInfo() throws SQLException 331 | { 332 | return null; 333 | } 334 | 335 | /** {@inheritDoc} */ 336 | public Array createArrayOf(String typeName, Object[] elements) throws SQLException 337 | { 338 | return null; 339 | } 340 | 341 | /** {@inheritDoc} */ 342 | public Struct createStruct(String typeName, Object[] attributes) throws SQLException 343 | { 344 | return null; 345 | } 346 | 347 | /** {@inheritDoc} */ 348 | public void setSchema(String schema) throws SQLException 349 | { 350 | } 351 | 352 | /** {@inheritDoc} */ 353 | public String getSchema() throws SQLException 354 | { 355 | return null; 356 | } 357 | 358 | /** {@inheritDoc} */ 359 | public void abort(Executor executor) throws SQLException 360 | { 361 | } 362 | 363 | /** {@inheritDoc} */ 364 | public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException 365 | { 366 | } 367 | 368 | /** {@inheritDoc} */ 369 | public int getNetworkTimeout() throws SQLException 370 | { 371 | return 0; 372 | } 373 | 374 | } -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/stubs/StubDataSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark.stubs; 18 | 19 | import java.io.PrintWriter; 20 | import java.sql.Connection; 21 | import java.sql.SQLException; 22 | import java.sql.SQLFeatureNotSupportedException; 23 | import java.sql.SQLTransientConnectionException; 24 | import java.util.concurrent.TimeUnit; 25 | import java.util.logging.Logger; 26 | 27 | import javax.sql.DataSource; 28 | 29 | /** 30 | * 31 | * @author Brett Wooldridge 32 | */ 33 | public class StubDataSource implements DataSource 34 | { 35 | private long connectionDelay; 36 | 37 | public void setConnectionDelay(long millis) 38 | { 39 | this.connectionDelay = millis; 40 | } 41 | 42 | /** {@inheritDoc} */ 43 | public PrintWriter getLogWriter() throws SQLException 44 | { 45 | return null; 46 | } 47 | 48 | /** {@inheritDoc} */ 49 | public void setLogWriter(PrintWriter out) throws SQLException 50 | { 51 | } 52 | 53 | /** {@inheritDoc} */ 54 | public void setLoginTimeout(int seconds) throws SQLException 55 | { 56 | } 57 | 58 | /** {@inheritDoc} */ 59 | public int getLoginTimeout() throws SQLException 60 | { 61 | return 0; 62 | } 63 | 64 | /** {@inheritDoc} */ 65 | public Logger getParentLogger() throws SQLFeatureNotSupportedException 66 | { 67 | return null; 68 | } 69 | 70 | /** {@inheritDoc} */ 71 | public T unwrap(Class iface) throws SQLException 72 | { 73 | return null; 74 | } 75 | 76 | /** {@inheritDoc} */ 77 | public boolean isWrapperFor(Class iface) throws SQLException 78 | { 79 | return false; 80 | } 81 | 82 | /** {@inheritDoc} */ 83 | public Connection getConnection() throws SQLException 84 | { 85 | if (connectionDelay > 0) { 86 | try { 87 | TimeUnit.MILLISECONDS.sleep(connectionDelay); 88 | } 89 | catch (InterruptedException e) { 90 | throw new SQLTransientConnectionException(); 91 | } 92 | } 93 | 94 | return new StubConnection(); 95 | } 96 | 97 | /** {@inheritDoc} */ 98 | public Connection getConnection(String username, String password) throws SQLException 99 | { 100 | return getConnection(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/stubs/StubDriver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark.stubs; 18 | 19 | import static java.lang.System.nanoTime; 20 | import static java.util.concurrent.TimeUnit.MILLISECONDS; 21 | 22 | import java.sql.Connection; 23 | import java.sql.Driver; 24 | import java.sql.DriverManager; 25 | import java.sql.DriverPropertyInfo; 26 | import java.sql.SQLException; 27 | import java.sql.SQLFeatureNotSupportedException; 28 | import java.util.Properties; 29 | import java.util.logging.Logger; 30 | 31 | import com.zaxxer.hikari.util.UtilityElf; 32 | 33 | /** 34 | * @author Brett Wooldridge 35 | */ 36 | public class StubDriver implements Driver 37 | { 38 | private static final Driver driver; 39 | private static long connectionDelay; 40 | 41 | static { 42 | driver = new StubDriver(); 43 | try { 44 | DriverManager.registerDriver(driver); 45 | } 46 | catch (SQLException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | public static void setConnectDelayMs(final long delay) 52 | { 53 | connectionDelay = delay; //MILLISECONDS.toNanos(delay); 54 | } 55 | 56 | /** {@inheritDoc} */ 57 | public Connection connect(String url, Properties info) throws SQLException 58 | { 59 | if (connectionDelay > 0) { 60 | // final long start = nanoTime(); 61 | // do { 62 | // // spin 63 | // } while (nanoTime() - start < connectionDelayNs); 64 | UtilityElf.quietlySleep(connectionDelay); 65 | } 66 | 67 | return new StubConnection(); 68 | } 69 | 70 | /** {@inheritDoc} */ 71 | public boolean acceptsURL(String url) throws SQLException 72 | { 73 | return true; 74 | } 75 | 76 | /** {@inheritDoc} */ 77 | public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException 78 | { 79 | return null; 80 | } 81 | 82 | /** {@inheritDoc} */ 83 | public int getMajorVersion() 84 | { 85 | return 0; 86 | } 87 | 88 | /** {@inheritDoc} */ 89 | public int getMinorVersion() 90 | { 91 | return 0; 92 | } 93 | 94 | /** {@inheritDoc} */ 95 | public boolean jdbcCompliant() 96 | { 97 | return true; 98 | } 99 | 100 | /** {@inheritDoc} */ 101 | public Logger getParentLogger() throws SQLFeatureNotSupportedException 102 | { 103 | return null; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/stubs/StubPreparedStatement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark.stubs; 18 | 19 | import java.io.InputStream; 20 | import java.io.Reader; 21 | import java.math.BigDecimal; 22 | import java.net.URL; 23 | import java.sql.Array; 24 | import java.sql.Blob; 25 | import java.sql.Clob; 26 | import java.sql.Connection; 27 | import java.sql.Date; 28 | import java.sql.NClob; 29 | import java.sql.ParameterMetaData; 30 | import java.sql.PreparedStatement; 31 | import java.sql.Ref; 32 | import java.sql.ResultSet; 33 | import java.sql.ResultSetMetaData; 34 | import java.sql.RowId; 35 | import java.sql.SQLException; 36 | import java.sql.SQLWarning; 37 | import java.sql.SQLXML; 38 | import java.sql.Time; 39 | import java.sql.Timestamp; 40 | import java.util.Calendar; 41 | 42 | /** 43 | * 44 | * @author Brett Wooldridge 45 | */ 46 | public class StubPreparedStatement extends StubStatement implements PreparedStatement 47 | { 48 | 49 | /** {@inheritDoc} */ 50 | public ResultSet executeQuery(String sql) throws SQLException 51 | { 52 | return new StubResultSet(); 53 | } 54 | 55 | /** {@inheritDoc} */ 56 | public int executeUpdate(String sql) throws SQLException 57 | { 58 | return 0; 59 | } 60 | 61 | /** {@inheritDoc} */ 62 | public int getMaxFieldSize() throws SQLException 63 | { 64 | return 0; 65 | } 66 | 67 | /** {@inheritDoc} */ 68 | public void setMaxFieldSize(int max) throws SQLException 69 | { 70 | } 71 | 72 | /** {@inheritDoc} */ 73 | public int getMaxRows() throws SQLException 74 | { 75 | return 0; 76 | } 77 | 78 | /** {@inheritDoc} */ 79 | public void setMaxRows(int max) throws SQLException 80 | { 81 | } 82 | 83 | /** {@inheritDoc} */ 84 | public void setEscapeProcessing(boolean enable) throws SQLException 85 | { 86 | } 87 | 88 | /** {@inheritDoc} */ 89 | public int getQueryTimeout() throws SQLException 90 | { 91 | return 0; 92 | } 93 | 94 | /** {@inheritDoc} */ 95 | public void setQueryTimeout(int seconds) throws SQLException 96 | { 97 | } 98 | 99 | /** {@inheritDoc} */ 100 | public void cancel() throws SQLException 101 | { 102 | } 103 | 104 | /** {@inheritDoc} */ 105 | public SQLWarning getWarnings() throws SQLException 106 | { 107 | return null; 108 | } 109 | 110 | /** {@inheritDoc} */ 111 | public void clearWarnings() throws SQLException 112 | { 113 | } 114 | 115 | /** {@inheritDoc} */ 116 | public void setCursorName(String name) throws SQLException 117 | { 118 | } 119 | 120 | /** {@inheritDoc} */ 121 | public boolean execute(String sql) throws SQLException 122 | { 123 | return false; 124 | } 125 | 126 | /** {@inheritDoc} */ 127 | public ResultSet getResultSet() throws SQLException 128 | { 129 | return new StubResultSet(); 130 | } 131 | 132 | /** {@inheritDoc} */ 133 | public int getUpdateCount() throws SQLException 134 | { 135 | return 0; 136 | } 137 | 138 | /** {@inheritDoc} */ 139 | public boolean getMoreResults() throws SQLException 140 | { 141 | return false; 142 | } 143 | 144 | /** {@inheritDoc} */ 145 | public void setFetchDirection(int direction) throws SQLException 146 | { 147 | } 148 | 149 | /** {@inheritDoc} */ 150 | public int getFetchDirection() throws SQLException 151 | { 152 | return 0; 153 | } 154 | 155 | /** {@inheritDoc} */ 156 | public void setFetchSize(int rows) throws SQLException 157 | { 158 | } 159 | 160 | /** {@inheritDoc} */ 161 | public int getFetchSize() throws SQLException 162 | { 163 | return 0; 164 | } 165 | 166 | /** {@inheritDoc} */ 167 | public int getResultSetConcurrency() throws SQLException 168 | { 169 | return 0; 170 | } 171 | 172 | /** {@inheritDoc} */ 173 | public int getResultSetType() throws SQLException 174 | { 175 | return 0; 176 | } 177 | 178 | /** {@inheritDoc} */ 179 | public void addBatch(String sql) throws SQLException 180 | { 181 | } 182 | 183 | /** {@inheritDoc} */ 184 | public void clearBatch() throws SQLException 185 | { 186 | } 187 | 188 | /** {@inheritDoc} */ 189 | public int[] executeBatch() throws SQLException 190 | { 191 | if (count > 10000) 192 | { 193 | return new int[] {1, count, 3}; 194 | } 195 | 196 | return new int[] {count, count, 3}; 197 | } 198 | 199 | /** {@inheritDoc} */ 200 | public Connection getConnection() throws SQLException 201 | { 202 | return null; 203 | } 204 | 205 | /** {@inheritDoc} */ 206 | public boolean getMoreResults(int current) throws SQLException 207 | { 208 | return false; 209 | } 210 | 211 | /** {@inheritDoc} */ 212 | public ResultSet getGeneratedKeys() throws SQLException 213 | { 214 | return new StubResultSet(); 215 | } 216 | 217 | /** {@inheritDoc} */ 218 | public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException 219 | { 220 | return 0; 221 | } 222 | 223 | /** {@inheritDoc} */ 224 | public int executeUpdate(String sql, int[] columnIndexes) throws SQLException 225 | { 226 | return 0; 227 | } 228 | 229 | /** {@inheritDoc} */ 230 | public int executeUpdate(String sql, String[] columnNames) throws SQLException 231 | { 232 | return 0; 233 | } 234 | 235 | /** {@inheritDoc} */ 236 | public boolean execute(String sql, int autoGeneratedKeys) throws SQLException 237 | { 238 | return false; 239 | } 240 | 241 | /** {@inheritDoc} */ 242 | public boolean execute(String sql, int[] columnIndexes) throws SQLException 243 | { 244 | return false; 245 | } 246 | 247 | /** {@inheritDoc} */ 248 | public boolean execute(String sql, String[] columnNames) throws SQLException 249 | { 250 | return false; 251 | } 252 | 253 | /** {@inheritDoc} */ 254 | public int getResultSetHoldability() throws SQLException 255 | { 256 | return 0; 257 | } 258 | 259 | /** {@inheritDoc} */ 260 | public void setPoolable(boolean poolable) throws SQLException 261 | { 262 | } 263 | 264 | /** {@inheritDoc} */ 265 | public boolean isPoolable() throws SQLException 266 | { 267 | return false; 268 | } 269 | 270 | /** {@inheritDoc} */ 271 | public void closeOnCompletion() throws SQLException 272 | { 273 | } 274 | 275 | /** {@inheritDoc} */ 276 | public boolean isCloseOnCompletion() throws SQLException 277 | { 278 | return false; 279 | } 280 | 281 | /** {@inheritDoc} */ 282 | public ResultSet executeQuery() throws SQLException 283 | { 284 | return new StubResultSet(); 285 | } 286 | 287 | /** {@inheritDoc} */ 288 | public int executeUpdate() throws SQLException 289 | { 290 | return 0; 291 | } 292 | 293 | /** {@inheritDoc} */ 294 | public void setNull(int parameterIndex, int sqlType) throws SQLException 295 | { 296 | } 297 | 298 | /** {@inheritDoc} */ 299 | public void setBoolean(int parameterIndex, boolean x) throws SQLException 300 | { 301 | } 302 | 303 | /** {@inheritDoc} */ 304 | public void setByte(int parameterIndex, byte x) throws SQLException 305 | { 306 | } 307 | 308 | /** {@inheritDoc} */ 309 | public void setShort(int parameterIndex, short x) throws SQLException 310 | { 311 | } 312 | 313 | /** {@inheritDoc} */ 314 | public void setInt(int parameterIndex, int x) throws SQLException 315 | { 316 | if (count > 0) 317 | { 318 | count += parameterIndex + x; 319 | } 320 | else 321 | { 322 | count += x; 323 | } 324 | } 325 | 326 | /** {@inheritDoc} */ 327 | public void setLong(int parameterIndex, long x) throws SQLException 328 | { 329 | } 330 | 331 | /** {@inheritDoc} */ 332 | public void setFloat(int parameterIndex, float x) throws SQLException 333 | { 334 | } 335 | 336 | /** {@inheritDoc} */ 337 | public void setDouble(int parameterIndex, double x) throws SQLException 338 | { 339 | } 340 | 341 | /** {@inheritDoc} */ 342 | public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException 343 | { 344 | } 345 | 346 | /** {@inheritDoc} */ 347 | public void setString(int parameterIndex, String x) throws SQLException 348 | { 349 | } 350 | 351 | /** {@inheritDoc} */ 352 | public void setBytes(int parameterIndex, byte[] x) throws SQLException 353 | { 354 | } 355 | 356 | /** {@inheritDoc} */ 357 | public void setDate(int parameterIndex, Date x) throws SQLException 358 | { 359 | } 360 | 361 | /** {@inheritDoc} */ 362 | public void setTime(int parameterIndex, Time x) throws SQLException 363 | { 364 | } 365 | 366 | /** {@inheritDoc} */ 367 | public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException 368 | { 369 | } 370 | 371 | /** {@inheritDoc} */ 372 | public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException 373 | { 374 | } 375 | 376 | /** {@inheritDoc} */ 377 | public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException 378 | { 379 | } 380 | 381 | /** {@inheritDoc} */ 382 | public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException 383 | { 384 | } 385 | 386 | /** {@inheritDoc} */ 387 | public void clearParameters() throws SQLException 388 | { 389 | } 390 | 391 | /** {@inheritDoc} */ 392 | public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException 393 | { 394 | } 395 | 396 | /** {@inheritDoc} */ 397 | public void setObject(int parameterIndex, Object x) throws SQLException 398 | { 399 | } 400 | 401 | /** {@inheritDoc} */ 402 | public boolean execute() throws SQLException 403 | { 404 | return false; 405 | } 406 | 407 | /** {@inheritDoc} */ 408 | public void addBatch() throws SQLException 409 | { 410 | } 411 | 412 | /** {@inheritDoc} */ 413 | public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException 414 | { 415 | } 416 | 417 | /** {@inheritDoc} */ 418 | public void setRef(int parameterIndex, Ref x) throws SQLException 419 | { 420 | } 421 | 422 | /** {@inheritDoc} */ 423 | public void setBlob(int parameterIndex, Blob x) throws SQLException 424 | { 425 | } 426 | 427 | /** {@inheritDoc} */ 428 | public void setClob(int parameterIndex, Clob x) throws SQLException 429 | { 430 | } 431 | 432 | /** {@inheritDoc} */ 433 | public void setArray(int parameterIndex, Array x) throws SQLException 434 | { 435 | } 436 | 437 | /** {@inheritDoc} */ 438 | public ResultSetMetaData getMetaData() throws SQLException 439 | { 440 | return null; 441 | } 442 | 443 | /** {@inheritDoc} */ 444 | public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException 445 | { 446 | } 447 | 448 | /** {@inheritDoc} */ 449 | public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException 450 | { 451 | } 452 | 453 | /** {@inheritDoc} */ 454 | public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException 455 | { 456 | } 457 | 458 | /** {@inheritDoc} */ 459 | public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException 460 | { 461 | } 462 | 463 | /** {@inheritDoc} */ 464 | public void setURL(int parameterIndex, URL x) throws SQLException 465 | { 466 | } 467 | 468 | /** {@inheritDoc} */ 469 | public ParameterMetaData getParameterMetaData() throws SQLException 470 | { 471 | return null; 472 | } 473 | 474 | /** {@inheritDoc} */ 475 | public void setRowId(int parameterIndex, RowId x) throws SQLException 476 | { 477 | } 478 | 479 | /** {@inheritDoc} */ 480 | public void setNString(int parameterIndex, String value) throws SQLException 481 | { 482 | } 483 | 484 | /** {@inheritDoc} */ 485 | public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException 486 | { 487 | } 488 | 489 | /** {@inheritDoc} */ 490 | public void setNClob(int parameterIndex, NClob value) throws SQLException 491 | { 492 | } 493 | 494 | /** {@inheritDoc} */ 495 | public void setClob(int parameterIndex, Reader reader, long length) throws SQLException 496 | { 497 | } 498 | 499 | /** {@inheritDoc} */ 500 | public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException 501 | { 502 | } 503 | 504 | /** {@inheritDoc} */ 505 | public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException 506 | { 507 | } 508 | 509 | /** {@inheritDoc} */ 510 | public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException 511 | { 512 | } 513 | 514 | /** {@inheritDoc} */ 515 | public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException 516 | { 517 | } 518 | 519 | /** {@inheritDoc} */ 520 | public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException 521 | { 522 | } 523 | 524 | /** {@inheritDoc} */ 525 | public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException 526 | { 527 | } 528 | 529 | /** {@inheritDoc} */ 530 | public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException 531 | { 532 | } 533 | 534 | /** {@inheritDoc} */ 535 | public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException 536 | { 537 | } 538 | 539 | /** {@inheritDoc} */ 540 | public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException 541 | { 542 | } 543 | 544 | /** {@inheritDoc} */ 545 | public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException 546 | { 547 | } 548 | 549 | /** {@inheritDoc} */ 550 | public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException 551 | { 552 | } 553 | 554 | /** {@inheritDoc} */ 555 | public void setClob(int parameterIndex, Reader reader) throws SQLException 556 | { 557 | } 558 | 559 | /** {@inheritDoc} */ 560 | public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException 561 | { 562 | } 563 | 564 | /** {@inheritDoc} */ 565 | public void setNClob(int parameterIndex, Reader reader) throws SQLException 566 | { 567 | } 568 | } 569 | -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/stubs/StubResultSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark.stubs; 18 | 19 | import java.io.InputStream; 20 | import java.io.Reader; 21 | import java.math.BigDecimal; 22 | import java.net.URL; 23 | import java.sql.Array; 24 | import java.sql.Blob; 25 | import java.sql.Clob; 26 | import java.sql.Date; 27 | import java.sql.NClob; 28 | import java.sql.Ref; 29 | import java.sql.ResultSet; 30 | import java.sql.ResultSetMetaData; 31 | import java.sql.RowId; 32 | import java.sql.SQLException; 33 | import java.sql.SQLWarning; 34 | import java.sql.SQLXML; 35 | import java.sql.Statement; 36 | import java.sql.Time; 37 | import java.sql.Timestamp; 38 | import java.util.Calendar; 39 | import java.util.Map; 40 | 41 | /** 42 | * 43 | * @author Brett Wooldridge 44 | */ 45 | public class StubResultSet implements ResultSet 46 | { 47 | private int counter; 48 | private boolean closed; 49 | 50 | /** {@inheritDoc} */ 51 | public T unwrap(Class iface) throws SQLException 52 | { 53 | 54 | return null; 55 | } 56 | 57 | /** {@inheritDoc} */ 58 | public boolean isWrapperFor(Class iface) throws SQLException 59 | { 60 | return false; 61 | } 62 | 63 | /** {@inheritDoc} */ 64 | public boolean next() throws SQLException 65 | { 66 | return (counter < 10); 67 | } 68 | 69 | /** {@inheritDoc} */ 70 | public void close() throws SQLException 71 | { 72 | closed = true; 73 | } 74 | 75 | /** {@inheritDoc} */ 76 | public boolean wasNull() throws SQLException 77 | { 78 | return false; 79 | } 80 | 81 | /** {@inheritDoc} */ 82 | public String getString(int columnIndex) throws SQLException 83 | { 84 | return "aString"; 85 | } 86 | 87 | /** {@inheritDoc} */ 88 | public boolean getBoolean(int columnIndex) throws SQLException 89 | { 90 | return false; 91 | } 92 | 93 | /** {@inheritDoc} */ 94 | public byte getByte(int columnIndex) throws SQLException 95 | { 96 | return 0; 97 | } 98 | 99 | /** {@inheritDoc} */ 100 | public short getShort(int columnIndex) throws SQLException 101 | { 102 | return 0; 103 | } 104 | 105 | /** {@inheritDoc} */ 106 | public int getInt(int columnIndex) throws SQLException 107 | { 108 | return ++counter; 109 | } 110 | 111 | /** {@inheritDoc} */ 112 | public long getLong(int columnIndex) throws SQLException 113 | { 114 | return 0; 115 | } 116 | 117 | /** {@inheritDoc} */ 118 | public float getFloat(int columnIndex) throws SQLException 119 | { 120 | return 0; 121 | } 122 | 123 | /** {@inheritDoc} */ 124 | public double getDouble(int columnIndex) throws SQLException 125 | { 126 | return 0; 127 | } 128 | 129 | /** {@inheritDoc} */ 130 | public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException 131 | { 132 | return null; 133 | } 134 | 135 | /** {@inheritDoc} */ 136 | public byte[] getBytes(int columnIndex) throws SQLException 137 | { 138 | return null; 139 | } 140 | 141 | /** {@inheritDoc} */ 142 | public Date getDate(int columnIndex) throws SQLException 143 | { 144 | return null; 145 | } 146 | 147 | /** {@inheritDoc} */ 148 | public Time getTime(int columnIndex) throws SQLException 149 | { 150 | return null; 151 | } 152 | 153 | /** {@inheritDoc} */ 154 | public Timestamp getTimestamp(int columnIndex) throws SQLException 155 | { 156 | return null; 157 | } 158 | 159 | /** {@inheritDoc} */ 160 | public InputStream getAsciiStream(int columnIndex) throws SQLException 161 | { 162 | return null; 163 | } 164 | 165 | /** {@inheritDoc} */ 166 | public InputStream getUnicodeStream(int columnIndex) throws SQLException 167 | { 168 | return null; 169 | } 170 | 171 | /** {@inheritDoc} */ 172 | public InputStream getBinaryStream(int columnIndex) throws SQLException 173 | { 174 | return null; 175 | } 176 | 177 | /** {@inheritDoc} */ 178 | public String getString(String columnLabel) throws SQLException 179 | { 180 | return null; 181 | } 182 | 183 | /** {@inheritDoc} */ 184 | public boolean getBoolean(String columnLabel) throws SQLException 185 | { 186 | return false; 187 | } 188 | 189 | /** {@inheritDoc} */ 190 | public byte getByte(String columnLabel) throws SQLException 191 | { 192 | return 0; 193 | } 194 | 195 | /** {@inheritDoc} */ 196 | public short getShort(String columnLabel) throws SQLException 197 | { 198 | return 0; 199 | } 200 | 201 | /** {@inheritDoc} */ 202 | public int getInt(String columnLabel) throws SQLException 203 | { 204 | return 0; 205 | } 206 | 207 | /** {@inheritDoc} */ 208 | public long getLong(String columnLabel) throws SQLException 209 | { 210 | return 0; 211 | } 212 | 213 | /** {@inheritDoc} */ 214 | public float getFloat(String columnLabel) throws SQLException 215 | { 216 | return 0; 217 | } 218 | 219 | /** {@inheritDoc} */ 220 | public double getDouble(String columnLabel) throws SQLException 221 | { 222 | return 0; 223 | } 224 | 225 | /** {@inheritDoc} */ 226 | public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException 227 | { 228 | return null; 229 | } 230 | 231 | /** {@inheritDoc} */ 232 | public byte[] getBytes(String columnLabel) throws SQLException 233 | { 234 | return null; 235 | } 236 | 237 | /** {@inheritDoc} */ 238 | public Date getDate(String columnLabel) throws SQLException 239 | { 240 | return null; 241 | } 242 | 243 | /** {@inheritDoc} */ 244 | public Time getTime(String columnLabel) throws SQLException 245 | { 246 | return null; 247 | } 248 | 249 | /** {@inheritDoc} */ 250 | public Timestamp getTimestamp(String columnLabel) throws SQLException 251 | { 252 | return null; 253 | } 254 | 255 | /** {@inheritDoc} */ 256 | public InputStream getAsciiStream(String columnLabel) throws SQLException 257 | { 258 | return null; 259 | } 260 | 261 | /** {@inheritDoc} */ 262 | public InputStream getUnicodeStream(String columnLabel) throws SQLException 263 | { 264 | return null; 265 | } 266 | 267 | /** {@inheritDoc} */ 268 | public InputStream getBinaryStream(String columnLabel) throws SQLException 269 | { 270 | return null; 271 | } 272 | 273 | /** {@inheritDoc} */ 274 | public SQLWarning getWarnings() throws SQLException 275 | { 276 | return null; 277 | } 278 | 279 | /** {@inheritDoc} */ 280 | public void clearWarnings() throws SQLException 281 | { 282 | } 283 | 284 | /** {@inheritDoc} */ 285 | public String getCursorName() throws SQLException 286 | { 287 | return null; 288 | } 289 | 290 | /** {@inheritDoc} */ 291 | public ResultSetMetaData getMetaData() throws SQLException 292 | { 293 | return null; 294 | } 295 | 296 | /** {@inheritDoc} */ 297 | public Object getObject(int columnIndex) throws SQLException 298 | { 299 | return null; 300 | } 301 | 302 | /** {@inheritDoc} */ 303 | public Object getObject(String columnLabel) throws SQLException 304 | { 305 | return null; 306 | } 307 | 308 | /** {@inheritDoc} */ 309 | public int findColumn(String columnLabel) throws SQLException 310 | { 311 | return 0; 312 | } 313 | 314 | /** {@inheritDoc} */ 315 | public Reader getCharacterStream(int columnIndex) throws SQLException 316 | { 317 | return null; 318 | } 319 | 320 | /** {@inheritDoc} */ 321 | public Reader getCharacterStream(String columnLabel) throws SQLException 322 | { 323 | return null; 324 | } 325 | 326 | /** {@inheritDoc} */ 327 | public BigDecimal getBigDecimal(int columnIndex) throws SQLException 328 | { 329 | return null; 330 | } 331 | 332 | /** {@inheritDoc} */ 333 | public BigDecimal getBigDecimal(String columnLabel) throws SQLException 334 | { 335 | return null; 336 | } 337 | 338 | /** {@inheritDoc} */ 339 | public boolean isBeforeFirst() throws SQLException 340 | { 341 | return false; 342 | } 343 | 344 | /** {@inheritDoc} */ 345 | public boolean isAfterLast() throws SQLException 346 | { 347 | return false; 348 | } 349 | 350 | /** {@inheritDoc} */ 351 | public boolean isFirst() throws SQLException 352 | { 353 | return false; 354 | } 355 | 356 | /** {@inheritDoc} */ 357 | public boolean isLast() throws SQLException 358 | { 359 | return false; 360 | } 361 | 362 | /** {@inheritDoc} */ 363 | public void beforeFirst() throws SQLException 364 | { 365 | } 366 | 367 | /** {@inheritDoc} */ 368 | public void afterLast() throws SQLException 369 | { 370 | } 371 | 372 | /** {@inheritDoc} */ 373 | public boolean first() throws SQLException 374 | { 375 | return false; 376 | } 377 | 378 | /** {@inheritDoc} */ 379 | public boolean last() throws SQLException 380 | { 381 | return false; 382 | } 383 | 384 | /** {@inheritDoc} */ 385 | public int getRow() throws SQLException 386 | { 387 | return 0; 388 | } 389 | 390 | /** {@inheritDoc} */ 391 | public boolean absolute(int row) throws SQLException 392 | { 393 | return false; 394 | } 395 | 396 | /** {@inheritDoc} */ 397 | public boolean relative(int rows) throws SQLException 398 | { 399 | return false; 400 | } 401 | 402 | /** {@inheritDoc} */ 403 | public boolean previous() throws SQLException 404 | { 405 | return false; 406 | } 407 | 408 | /** {@inheritDoc} */ 409 | public void setFetchDirection(int direction) throws SQLException 410 | { 411 | } 412 | 413 | /** {@inheritDoc} */ 414 | public int getFetchDirection() throws SQLException 415 | { 416 | return 0; 417 | } 418 | 419 | /** {@inheritDoc} */ 420 | public void setFetchSize(int rows) throws SQLException 421 | { 422 | } 423 | 424 | /** {@inheritDoc} */ 425 | public int getFetchSize() throws SQLException 426 | { 427 | return 0; 428 | } 429 | 430 | /** {@inheritDoc} */ 431 | public int getType() throws SQLException 432 | { 433 | return 0; 434 | } 435 | 436 | /** {@inheritDoc} */ 437 | public int getConcurrency() throws SQLException 438 | { 439 | return 0; 440 | } 441 | 442 | /** {@inheritDoc} */ 443 | public boolean rowUpdated() throws SQLException 444 | { 445 | return false; 446 | } 447 | 448 | /** {@inheritDoc} */ 449 | public boolean rowInserted() throws SQLException 450 | { 451 | return false; 452 | } 453 | 454 | /** {@inheritDoc} */ 455 | public boolean rowDeleted() throws SQLException 456 | { 457 | return false; 458 | } 459 | 460 | /** {@inheritDoc} */ 461 | public void updateNull(int columnIndex) throws SQLException 462 | { 463 | } 464 | 465 | /** {@inheritDoc} */ 466 | public void updateBoolean(int columnIndex, boolean x) throws SQLException 467 | { 468 | } 469 | 470 | /** {@inheritDoc} */ 471 | public void updateByte(int columnIndex, byte x) throws SQLException 472 | { 473 | } 474 | 475 | /** {@inheritDoc} */ 476 | public void updateShort(int columnIndex, short x) throws SQLException 477 | { 478 | } 479 | 480 | /** {@inheritDoc} */ 481 | public void updateInt(int columnIndex, int x) throws SQLException 482 | { 483 | } 484 | 485 | /** {@inheritDoc} */ 486 | public void updateLong(int columnIndex, long x) throws SQLException 487 | { 488 | } 489 | 490 | /** {@inheritDoc} */ 491 | public void updateFloat(int columnIndex, float x) throws SQLException 492 | { 493 | } 494 | 495 | /** {@inheritDoc} */ 496 | public void updateDouble(int columnIndex, double x) throws SQLException 497 | { 498 | } 499 | 500 | /** {@inheritDoc} */ 501 | public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException 502 | { 503 | } 504 | 505 | /** {@inheritDoc} */ 506 | public void updateString(int columnIndex, String x) throws SQLException 507 | { 508 | } 509 | 510 | /** {@inheritDoc} */ 511 | public void updateBytes(int columnIndex, byte[] x) throws SQLException 512 | { 513 | } 514 | 515 | /** {@inheritDoc} */ 516 | public void updateDate(int columnIndex, Date x) throws SQLException 517 | { 518 | } 519 | 520 | /** {@inheritDoc} */ 521 | public void updateTime(int columnIndex, Time x) throws SQLException 522 | { 523 | } 524 | 525 | /** {@inheritDoc} */ 526 | public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException 527 | { 528 | } 529 | 530 | /** {@inheritDoc} */ 531 | public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException 532 | { 533 | } 534 | 535 | /** {@inheritDoc} */ 536 | public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException 537 | { 538 | } 539 | 540 | /** {@inheritDoc} */ 541 | public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException 542 | { 543 | } 544 | 545 | /** {@inheritDoc} */ 546 | public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException 547 | { 548 | } 549 | 550 | /** {@inheritDoc} */ 551 | public void updateObject(int columnIndex, Object x) throws SQLException 552 | { 553 | } 554 | 555 | /** {@inheritDoc} */ 556 | public void updateNull(String columnLabel) throws SQLException 557 | { 558 | } 559 | 560 | /** {@inheritDoc} */ 561 | public void updateBoolean(String columnLabel, boolean x) throws SQLException 562 | { 563 | } 564 | 565 | /** {@inheritDoc} */ 566 | public void updateByte(String columnLabel, byte x) throws SQLException 567 | { 568 | } 569 | 570 | /** {@inheritDoc} */ 571 | public void updateShort(String columnLabel, short x) throws SQLException 572 | { 573 | } 574 | 575 | /** {@inheritDoc} */ 576 | public void updateInt(String columnLabel, int x) throws SQLException 577 | { 578 | } 579 | 580 | /** {@inheritDoc} */ 581 | public void updateLong(String columnLabel, long x) throws SQLException 582 | { 583 | } 584 | 585 | /** {@inheritDoc} */ 586 | public void updateFloat(String columnLabel, float x) throws SQLException 587 | { 588 | } 589 | 590 | /** {@inheritDoc} */ 591 | public void updateDouble(String columnLabel, double x) throws SQLException 592 | { 593 | } 594 | 595 | /** {@inheritDoc} */ 596 | public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException 597 | { 598 | } 599 | 600 | /** {@inheritDoc} */ 601 | public void updateString(String columnLabel, String x) throws SQLException 602 | { 603 | } 604 | 605 | /** {@inheritDoc} */ 606 | public void updateBytes(String columnLabel, byte[] x) throws SQLException 607 | { 608 | } 609 | 610 | /** {@inheritDoc} */ 611 | public void updateDate(String columnLabel, Date x) throws SQLException 612 | { 613 | } 614 | 615 | /** {@inheritDoc} */ 616 | public void updateTime(String columnLabel, Time x) throws SQLException 617 | { 618 | } 619 | 620 | /** {@inheritDoc} */ 621 | public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException 622 | { 623 | } 624 | 625 | /** {@inheritDoc} */ 626 | public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException 627 | { 628 | } 629 | 630 | /** {@inheritDoc} */ 631 | public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException 632 | { 633 | } 634 | 635 | /** {@inheritDoc} */ 636 | public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException 637 | { 638 | } 639 | 640 | /** {@inheritDoc} */ 641 | public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException 642 | { 643 | } 644 | 645 | /** {@inheritDoc} */ 646 | public void updateObject(String columnLabel, Object x) throws SQLException 647 | { 648 | } 649 | 650 | /** {@inheritDoc} */ 651 | public void insertRow() throws SQLException 652 | { 653 | } 654 | 655 | /** {@inheritDoc} */ 656 | public void updateRow() throws SQLException 657 | { 658 | } 659 | 660 | /** {@inheritDoc} */ 661 | public void deleteRow() throws SQLException 662 | { 663 | } 664 | 665 | /** {@inheritDoc} */ 666 | public void refreshRow() throws SQLException 667 | { 668 | } 669 | 670 | /** {@inheritDoc} */ 671 | public void cancelRowUpdates() throws SQLException 672 | { 673 | } 674 | 675 | /** {@inheritDoc} */ 676 | public void moveToInsertRow() throws SQLException 677 | { 678 | } 679 | 680 | /** {@inheritDoc} */ 681 | public void moveToCurrentRow() throws SQLException 682 | { 683 | } 684 | 685 | /** {@inheritDoc} */ 686 | public Statement getStatement() throws SQLException 687 | { 688 | return null; 689 | } 690 | 691 | /** {@inheritDoc} */ 692 | public Object getObject(int columnIndex, Map> map) throws SQLException 693 | { 694 | return null; 695 | } 696 | 697 | /** {@inheritDoc} */ 698 | public Ref getRef(int columnIndex) throws SQLException 699 | { 700 | return null; 701 | } 702 | 703 | /** {@inheritDoc} */ 704 | public Blob getBlob(int columnIndex) throws SQLException 705 | { 706 | return null; 707 | } 708 | 709 | /** {@inheritDoc} */ 710 | public Clob getClob(int columnIndex) throws SQLException 711 | { 712 | return null; 713 | } 714 | 715 | /** {@inheritDoc} */ 716 | public Array getArray(int columnIndex) throws SQLException 717 | { 718 | return null; 719 | } 720 | 721 | /** {@inheritDoc} */ 722 | public Object getObject(String columnLabel, Map> map) throws SQLException 723 | { 724 | return null; 725 | } 726 | 727 | /** {@inheritDoc} */ 728 | public Ref getRef(String columnLabel) throws SQLException 729 | { 730 | return null; 731 | } 732 | 733 | /** {@inheritDoc} */ 734 | public Blob getBlob(String columnLabel) throws SQLException 735 | { 736 | return null; 737 | } 738 | 739 | /** {@inheritDoc} */ 740 | public Clob getClob(String columnLabel) throws SQLException 741 | { 742 | return null; 743 | } 744 | 745 | /** {@inheritDoc} */ 746 | public Array getArray(String columnLabel) throws SQLException 747 | { 748 | return null; 749 | } 750 | 751 | /** {@inheritDoc} */ 752 | public Date getDate(int columnIndex, Calendar cal) throws SQLException 753 | { 754 | return null; 755 | } 756 | 757 | /** {@inheritDoc} */ 758 | public Date getDate(String columnLabel, Calendar cal) throws SQLException 759 | { 760 | return null; 761 | } 762 | 763 | /** {@inheritDoc} */ 764 | public Time getTime(int columnIndex, Calendar cal) throws SQLException 765 | { 766 | return null; 767 | } 768 | 769 | /** {@inheritDoc} */ 770 | public Time getTime(String columnLabel, Calendar cal) throws SQLException 771 | { 772 | return null; 773 | } 774 | 775 | /** {@inheritDoc} */ 776 | public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException 777 | { 778 | return null; 779 | } 780 | 781 | /** {@inheritDoc} */ 782 | public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException 783 | { 784 | return null; 785 | } 786 | 787 | /** {@inheritDoc} */ 788 | public URL getURL(int columnIndex) throws SQLException 789 | { 790 | return null; 791 | } 792 | 793 | /** {@inheritDoc} */ 794 | public URL getURL(String columnLabel) throws SQLException 795 | { 796 | return null; 797 | } 798 | 799 | /** {@inheritDoc} */ 800 | public void updateRef(int columnIndex, Ref x) throws SQLException 801 | { 802 | } 803 | 804 | /** {@inheritDoc} */ 805 | public void updateRef(String columnLabel, Ref x) throws SQLException 806 | { 807 | } 808 | 809 | /** {@inheritDoc} */ 810 | public void updateBlob(int columnIndex, Blob x) throws SQLException 811 | { 812 | } 813 | 814 | /** {@inheritDoc} */ 815 | public void updateBlob(String columnLabel, Blob x) throws SQLException 816 | { 817 | } 818 | 819 | /** {@inheritDoc} */ 820 | public void updateClob(int columnIndex, Clob x) throws SQLException 821 | { 822 | } 823 | 824 | /** {@inheritDoc} */ 825 | public void updateClob(String columnLabel, Clob x) throws SQLException 826 | { 827 | } 828 | 829 | /** {@inheritDoc} */ 830 | public void updateArray(int columnIndex, Array x) throws SQLException 831 | { 832 | } 833 | 834 | /** {@inheritDoc} */ 835 | public void updateArray(String columnLabel, Array x) throws SQLException 836 | { 837 | } 838 | 839 | /** {@inheritDoc} */ 840 | public RowId getRowId(int columnIndex) throws SQLException 841 | { 842 | return null; 843 | } 844 | 845 | /** {@inheritDoc} */ 846 | public RowId getRowId(String columnLabel) throws SQLException 847 | { 848 | return null; 849 | } 850 | 851 | /** {@inheritDoc} */ 852 | public void updateRowId(int columnIndex, RowId x) throws SQLException 853 | { 854 | } 855 | 856 | /** {@inheritDoc} */ 857 | public void updateRowId(String columnLabel, RowId x) throws SQLException 858 | { 859 | } 860 | 861 | /** {@inheritDoc} */ 862 | public int getHoldability() throws SQLException 863 | { 864 | return 0; 865 | } 866 | 867 | /** {@inheritDoc} */ 868 | public boolean isClosed() throws SQLException 869 | { 870 | return closed; 871 | } 872 | 873 | /** {@inheritDoc} */ 874 | public void updateNString(int columnIndex, String nString) throws SQLException 875 | { 876 | } 877 | 878 | /** {@inheritDoc} */ 879 | public void updateNString(String columnLabel, String nString) throws SQLException 880 | { 881 | } 882 | 883 | /** {@inheritDoc} */ 884 | public void updateNClob(int columnIndex, NClob nClob) throws SQLException 885 | { 886 | } 887 | 888 | /** {@inheritDoc} */ 889 | public void updateNClob(String columnLabel, NClob nClob) throws SQLException 890 | { 891 | } 892 | 893 | /** {@inheritDoc} */ 894 | public NClob getNClob(int columnIndex) throws SQLException 895 | { 896 | return null; 897 | } 898 | 899 | /** {@inheritDoc} */ 900 | public NClob getNClob(String columnLabel) throws SQLException 901 | { 902 | return null; 903 | } 904 | 905 | /** {@inheritDoc} */ 906 | public SQLXML getSQLXML(int columnIndex) throws SQLException 907 | { 908 | return null; 909 | } 910 | 911 | /** {@inheritDoc} */ 912 | public SQLXML getSQLXML(String columnLabel) throws SQLException 913 | { 914 | return null; 915 | } 916 | 917 | /** {@inheritDoc} */ 918 | public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException 919 | { 920 | } 921 | 922 | /** {@inheritDoc} */ 923 | public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException 924 | { 925 | } 926 | 927 | /** {@inheritDoc} */ 928 | public String getNString(int columnIndex) throws SQLException 929 | { 930 | return null; 931 | } 932 | 933 | /** {@inheritDoc} */ 934 | public String getNString(String columnLabel) throws SQLException 935 | { 936 | return null; 937 | } 938 | 939 | /** {@inheritDoc} */ 940 | public Reader getNCharacterStream(int columnIndex) throws SQLException 941 | { 942 | return null; 943 | } 944 | 945 | /** {@inheritDoc} */ 946 | public Reader getNCharacterStream(String columnLabel) throws SQLException 947 | { 948 | return null; 949 | } 950 | 951 | /** {@inheritDoc} */ 952 | public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException 953 | { 954 | } 955 | 956 | /** {@inheritDoc} */ 957 | public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException 958 | { 959 | } 960 | 961 | /** {@inheritDoc} */ 962 | public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException 963 | { 964 | } 965 | 966 | /** {@inheritDoc} */ 967 | public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException 968 | { 969 | } 970 | 971 | /** {@inheritDoc} */ 972 | public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException 973 | { 974 | } 975 | 976 | /** {@inheritDoc} */ 977 | public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException 978 | { 979 | } 980 | 981 | /** {@inheritDoc} */ 982 | public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException 983 | { 984 | } 985 | 986 | /** {@inheritDoc} */ 987 | public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException 988 | { 989 | } 990 | 991 | /** {@inheritDoc} */ 992 | public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException 993 | { 994 | } 995 | 996 | /** {@inheritDoc} */ 997 | public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException 998 | { 999 | } 1000 | 1001 | /** {@inheritDoc} */ 1002 | public void updateClob(int columnIndex, Reader reader, long length) throws SQLException 1003 | { 1004 | } 1005 | 1006 | /** {@inheritDoc} */ 1007 | public void updateClob(String columnLabel, Reader reader, long length) throws SQLException 1008 | { 1009 | } 1010 | 1011 | /** {@inheritDoc} */ 1012 | public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException 1013 | { 1014 | } 1015 | 1016 | /** {@inheritDoc} */ 1017 | public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException 1018 | { 1019 | } 1020 | 1021 | /** {@inheritDoc} */ 1022 | public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException 1023 | { 1024 | } 1025 | 1026 | /** {@inheritDoc} */ 1027 | public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException 1028 | { 1029 | } 1030 | 1031 | /** {@inheritDoc} */ 1032 | public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException 1033 | { 1034 | } 1035 | 1036 | /** {@inheritDoc} */ 1037 | public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException 1038 | { 1039 | } 1040 | 1041 | /** {@inheritDoc} */ 1042 | public void updateCharacterStream(int columnIndex, Reader x) throws SQLException 1043 | { 1044 | } 1045 | 1046 | /** {@inheritDoc} */ 1047 | public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException 1048 | { 1049 | } 1050 | 1051 | /** {@inheritDoc} */ 1052 | public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException 1053 | { 1054 | } 1055 | 1056 | /** {@inheritDoc} */ 1057 | public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException 1058 | { 1059 | } 1060 | 1061 | /** {@inheritDoc} */ 1062 | public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException 1063 | { 1064 | } 1065 | 1066 | /** {@inheritDoc} */ 1067 | public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException 1068 | { 1069 | } 1070 | 1071 | /** {@inheritDoc} */ 1072 | public void updateClob(int columnIndex, Reader reader) throws SQLException 1073 | { 1074 | } 1075 | 1076 | /** {@inheritDoc} */ 1077 | public void updateClob(String columnLabel, Reader reader) throws SQLException 1078 | { 1079 | } 1080 | 1081 | /** {@inheritDoc} */ 1082 | public void updateNClob(int columnIndex, Reader reader) throws SQLException 1083 | { 1084 | } 1085 | 1086 | /** {@inheritDoc} */ 1087 | public void updateNClob(String columnLabel, Reader reader) throws SQLException 1088 | { 1089 | } 1090 | 1091 | /** {@inheritDoc} */ 1092 | public T getObject(int columnIndex, Class type) throws SQLException 1093 | { 1094 | return null; 1095 | } 1096 | 1097 | /** {@inheritDoc} */ 1098 | public T getObject(String columnLabel, Class type) throws SQLException 1099 | { 1100 | return null; 1101 | } 1102 | } 1103 | -------------------------------------------------------------------------------- /src/main/java/com/zaxxer/hikari/benchmark/stubs/StubStatement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Brett Wooldridge 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zaxxer.hikari.benchmark.stubs; 18 | 19 | import static java.lang.System.nanoTime; 20 | import static java.util.concurrent.TimeUnit.MILLISECONDS; 21 | 22 | import java.sql.Connection; 23 | import java.sql.ResultSet; 24 | import java.sql.SQLException; 25 | import java.sql.SQLWarning; 26 | import java.sql.Statement; 27 | 28 | import com.zaxxer.hikari.util.UtilityElf; 29 | 30 | /** 31 | * 32 | * @author Brett Wooldridge 33 | */ 34 | public class StubStatement implements Statement 35 | { 36 | protected int count; 37 | private boolean closed; 38 | private static long executeDelay; 39 | 40 | public static void setExecuteDelayMs(final long delay) 41 | { 42 | executeDelay = delay; 43 | } 44 | 45 | /** {@inheritDoc} */ 46 | @SuppressWarnings("unchecked") 47 | public T unwrap(Class iface) throws SQLException 48 | { 49 | if (iface.isInstance(this)) { 50 | return (T) this; 51 | } 52 | 53 | throw new SQLException("Wrapped connection is not an instance of " + iface); 54 | } 55 | 56 | /** {@inheritDoc} */ 57 | public boolean isWrapperFor(Class iface) throws SQLException 58 | { 59 | return false; 60 | } 61 | 62 | /** {@inheritDoc} */ 63 | public ResultSet executeQuery(String sql) throws SQLException 64 | { 65 | if (executeDelay > 0) { 66 | // final long start = nanoTime(); 67 | // do { 68 | // // spin 69 | // } while (nanoTime() - start < MILLISECONDS.toNanos(executeDelayMs)); 70 | UtilityElf.quietlySleep(executeDelay); 71 | } 72 | return new StubResultSet(); 73 | } 74 | 75 | /** {@inheritDoc} */ 76 | public int executeUpdate(String sql) throws SQLException 77 | { 78 | return 0; 79 | } 80 | 81 | /** {@inheritDoc} */ 82 | public void close() throws SQLException 83 | { 84 | closed = true; 85 | } 86 | 87 | /** {@inheritDoc} */ 88 | public int getMaxFieldSize() throws SQLException 89 | { 90 | return 0; 91 | } 92 | 93 | /** {@inheritDoc} */ 94 | public void setMaxFieldSize(int max) throws SQLException 95 | { 96 | } 97 | 98 | /** {@inheritDoc} */ 99 | public int getMaxRows() throws SQLException 100 | { 101 | return 0; 102 | } 103 | 104 | /** {@inheritDoc} */ 105 | public void setMaxRows(int max) throws SQLException 106 | { 107 | } 108 | 109 | /** {@inheritDoc} */ 110 | public void setEscapeProcessing(boolean enable) throws SQLException 111 | { 112 | } 113 | 114 | /** {@inheritDoc} */ 115 | public int getQueryTimeout() throws SQLException 116 | { 117 | return 0; 118 | } 119 | 120 | /** {@inheritDoc} */ 121 | public void setQueryTimeout(int seconds) throws SQLException 122 | { 123 | } 124 | 125 | /** {@inheritDoc} */ 126 | public void cancel() throws SQLException 127 | { 128 | } 129 | 130 | /** {@inheritDoc} */ 131 | public SQLWarning getWarnings() throws SQLException 132 | { 133 | return null; 134 | } 135 | 136 | /** {@inheritDoc} */ 137 | public void clearWarnings() throws SQLException 138 | { 139 | } 140 | 141 | /** {@inheritDoc} */ 142 | public void setCursorName(String name) throws SQLException 143 | { 144 | } 145 | 146 | /** {@inheritDoc} */ 147 | public boolean execute(String sql) throws SQLException 148 | { 149 | return sql.startsWith("I"); 150 | } 151 | 152 | /** {@inheritDoc} */ 153 | public ResultSet getResultSet() throws SQLException 154 | { 155 | return new StubResultSet(); 156 | } 157 | 158 | /** {@inheritDoc} */ 159 | public int getUpdateCount() throws SQLException 160 | { 161 | return 0; 162 | } 163 | 164 | /** {@inheritDoc} */ 165 | public boolean getMoreResults() throws SQLException 166 | { 167 | return false; 168 | } 169 | 170 | /** {@inheritDoc} */ 171 | public void setFetchDirection(int direction) throws SQLException 172 | { 173 | } 174 | 175 | /** {@inheritDoc} */ 176 | public int getFetchDirection() throws SQLException 177 | { 178 | return 0; 179 | } 180 | 181 | /** {@inheritDoc} */ 182 | public void setFetchSize(int rows) throws SQLException 183 | { 184 | } 185 | 186 | /** {@inheritDoc} */ 187 | public int getFetchSize() throws SQLException 188 | { 189 | return 0; 190 | } 191 | 192 | /** {@inheritDoc} */ 193 | public int getResultSetConcurrency() throws SQLException 194 | { 195 | return 0; 196 | } 197 | 198 | /** {@inheritDoc} */ 199 | public int getResultSetType() throws SQLException 200 | { 201 | return 0; 202 | } 203 | 204 | /** {@inheritDoc} */ 205 | public void addBatch(String sql) throws SQLException 206 | { 207 | } 208 | 209 | /** {@inheritDoc} */ 210 | public void clearBatch() throws SQLException 211 | { 212 | } 213 | 214 | /** {@inheritDoc} */ 215 | public int[] executeBatch() throws SQLException 216 | { 217 | return null; 218 | } 219 | 220 | /** {@inheritDoc} */ 221 | public Connection getConnection() throws SQLException 222 | { 223 | return null; 224 | } 225 | 226 | /** {@inheritDoc} */ 227 | public boolean getMoreResults(int current) throws SQLException 228 | { 229 | return false; 230 | } 231 | 232 | /** {@inheritDoc} */ 233 | public ResultSet getGeneratedKeys() throws SQLException 234 | { 235 | return new StubResultSet(); 236 | } 237 | 238 | /** {@inheritDoc} */ 239 | public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException 240 | { 241 | return 0; 242 | } 243 | 244 | /** {@inheritDoc} */ 245 | public int executeUpdate(String sql, int[] columnIndexes) throws SQLException 246 | { 247 | return 0; 248 | } 249 | 250 | /** {@inheritDoc} */ 251 | public int executeUpdate(String sql, String[] columnNames) throws SQLException 252 | { 253 | return 0; 254 | } 255 | 256 | /** {@inheritDoc} */ 257 | public boolean execute(String sql, int autoGeneratedKeys) throws SQLException 258 | { 259 | return false; 260 | } 261 | 262 | /** {@inheritDoc} */ 263 | public boolean execute(String sql, int[] columnIndexes) throws SQLException 264 | { 265 | return false; 266 | } 267 | 268 | /** {@inheritDoc} */ 269 | public boolean execute(String sql, String[] columnNames) throws SQLException 270 | { 271 | return false; 272 | } 273 | 274 | /** {@inheritDoc} */ 275 | public int getResultSetHoldability() throws SQLException 276 | { 277 | return 0; 278 | } 279 | 280 | /** {@inheritDoc} */ 281 | public boolean isClosed() throws SQLException 282 | { 283 | return closed; 284 | } 285 | 286 | /** {@inheritDoc} */ 287 | public void setPoolable(boolean poolable) throws SQLException 288 | { 289 | } 290 | 291 | /** {@inheritDoc} */ 292 | public boolean isPoolable() throws SQLException 293 | { 294 | return false; 295 | } 296 | 297 | /** {@inheritDoc} */ 298 | public void closeOnCompletion() throws SQLException 299 | { 300 | } 301 | 302 | /** {@inheritDoc} */ 303 | public boolean isCloseOnCompletion() throws SQLException 304 | { 305 | return false; 306 | } 307 | 308 | public int getCount() 309 | { 310 | return count; 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /src/main/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/test/java/com/zaxxer/hikari/benchmark/BandwidthTest.java: -------------------------------------------------------------------------------- 1 | package com.zaxxer.hikari.benchmark; 2 | 3 | import static com.zaxxer.hikari.util.ClockSource.currentTime; 4 | import static java.lang.System.out; 5 | import static java.sql.Connection.TRANSACTION_READ_COMMITTED; 6 | import static java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; 7 | import static java.util.concurrent.TimeUnit.MINUTES; 8 | import static java.util.concurrent.TimeUnit.SECONDS; 9 | 10 | import java.sql.Connection; 11 | import java.sql.ResultSet; 12 | import java.sql.SQLException; 13 | import java.sql.Statement; 14 | import java.util.Scanner; 15 | import java.util.concurrent.Executors; 16 | 17 | import javax.sql.DataSource; 18 | 19 | import org.apache.commons.dbcp2.BasicDataSource; 20 | import org.apache.commons.dbcp2.DbcpPoolAccessor; 21 | import org.apache.commons.dbcp2.TomcatPoolAccessor; 22 | import org.apache.tomcat.jdbc.pool.PoolProperties; 23 | import org.apache.tomcat.jdbc.pool.PooledConnection; 24 | import org.apache.tomcat.jdbc.pool.Validator; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | import org.vibur.dbcp.ViburDBCPDataSource; 28 | 29 | import com.zaxxer.hikari.HikariConfig; 30 | import com.zaxxer.hikari.HikariDataSource; 31 | import com.zaxxer.hikari.util.ClockSource; 32 | 33 | public class BandwidthTest 34 | { 35 | private static final Logger LOGGER = LoggerFactory.getLogger(BandwidthTest.class); 36 | 37 | private static final String jdbcUrl = "jdbc:postgresql://localhost/test"; 38 | 39 | private static final int MIN_POOL_SIZE = 1; 40 | private static final int MAX_POOL_SIZE = 1; 41 | 42 | private DataSource DS; 43 | private String pool; 44 | 45 | public static void main(String[] args) throws InterruptedException, SQLException 46 | { 47 | BandwidthTest test = new BandwidthTest(); 48 | 49 | test.setup(args); 50 | 51 | int blackhole = test.start(); 52 | LOGGER.debug("Blackhole value {}", blackhole); 53 | } 54 | 55 | private void setup(String[] args) throws SQLException 56 | { 57 | pool = args[0]; 58 | switch (pool) { 59 | case "hikari": 60 | setupHikari(); 61 | break; 62 | case "dbcp2": 63 | setupDbcp2(); 64 | break; 65 | case "tomcat": 66 | setupTomcat(); 67 | break; 68 | case "vibur": 69 | setupVibur(); 70 | break; 71 | default: 72 | throw new IllegalArgumentException("Unknown connection pool specified"); 73 | } 74 | 75 | try (Connection connection = DS.getConnection()) { 76 | connection.setAutoCommit(true); 77 | try (Statement stmt = connection.createStatement()) { 78 | stmt.execute("DROP TABLE IF EXISTS test; CREATE TABLE test (value VARCHAR(255));"); 79 | stmt.executeUpdate("INSERT INTO test (value) VALUES ('this is a test')"); 80 | connection.setAutoCommit(false); 81 | } 82 | } 83 | 84 | LOGGER.info("Primed connection: {}.", pool); 85 | } 86 | 87 | private int start() throws InterruptedException, SQLException 88 | { 89 | try (Scanner scanner = new Scanner(System.in)) { 90 | LOGGER.info("\n[Re]start iptop capture and press enter: sudo iftop -i lo0 -nf \"port 5432 and host localhost\""); 91 | scanner.nextLine(); 92 | 93 | int blackhole = 0; 94 | long start = currentTime(); 95 | 96 | for (int i = 0; i < 10_000; i++) { 97 | try (Connection connection = DS.getConnection()) { 98 | // connection.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED); 99 | // connection.setReadOnly(true); 100 | try (Statement stmt = connection.createStatement(); 101 | ResultSet rs = stmt.executeQuery("SELECT * FROM test")) { 102 | if (rs.next()) { 103 | blackhole += rs.getString(1).hashCode(); 104 | } 105 | } 106 | // connection.rollback(); 107 | } 108 | } 109 | 110 | LOGGER.info("Elapsed runtime {}" , ClockSource.elapsedDisplayString(start, currentTime())); 111 | return blackhole; 112 | } 113 | finally { 114 | shutdownPool(DS); 115 | } 116 | } 117 | 118 | private void shutdownPool(DataSource ds) 119 | { 120 | if (ds instanceof AutoCloseable) { 121 | try { 122 | ((AutoCloseable) ds).close(); 123 | } 124 | catch (Exception e) { 125 | } 126 | } 127 | } 128 | 129 | private void setupHikari() 130 | { 131 | HikariConfig config = new HikariConfig(); 132 | config.setJdbcUrl(jdbcUrl); 133 | config.setUsername("brettw"); 134 | config.setPassword(""); 135 | config.setMinimumIdle(MIN_POOL_SIZE); 136 | config.setMaximumPoolSize(MAX_POOL_SIZE); 137 | config.setConnectionTimeout(8000); 138 | config.setAutoCommit(false); 139 | config.setReadOnly(false); 140 | config.setTransactionIsolation("TRANSACTION_READ_COMMITTED"); 141 | 142 | DS = new HikariDataSource(config); 143 | } 144 | 145 | private void setupDbcp2() 146 | { 147 | BasicDataSource ds = new DbcpPoolAccessor(); 148 | ds.setUrl(jdbcUrl); 149 | ds.setUsername("brettw"); 150 | ds.setPassword(""); 151 | ds.setInitialSize(MIN_POOL_SIZE); 152 | ds.setMinIdle(MIN_POOL_SIZE); 153 | ds.setMaxIdle(MIN_POOL_SIZE); 154 | ds.setMaxTotal(MAX_POOL_SIZE); 155 | ds.setMaxWaitMillis(8000); 156 | 157 | ds.setSoftMinEvictableIdleTimeMillis(MINUTES.toMillis(10)); 158 | ds.setTimeBetweenEvictionRunsMillis(SECONDS.toMillis(30)); 159 | 160 | ds.setDefaultAutoCommit(false); 161 | ds.setDefaultTransactionIsolation(TRANSACTION_READ_COMMITTED); 162 | ds.setDefaultReadOnly(false); 163 | 164 | ds.setRollbackOnReturn(true); 165 | ds.setEnableAutoCommitOnReturn(false); 166 | ds.setTestOnBorrow(true); 167 | ds.setCacheState(true); 168 | ds.setFastFailValidation(true); 169 | 170 | DS = ds; 171 | } 172 | 173 | protected void setupTomcat() 174 | { 175 | PoolProperties props = new PoolProperties(); 176 | props.setUrl(jdbcUrl); 177 | props.setUsername("brettw"); 178 | props.setPassword(""); 179 | props.setInitialSize(MIN_POOL_SIZE); 180 | props.setMinIdle(MIN_POOL_SIZE); 181 | props.setMaxIdle(MAX_POOL_SIZE); 182 | props.setMaxActive(MAX_POOL_SIZE); 183 | props.setMaxWait(8000); 184 | 185 | props.setDefaultAutoCommit(false); 186 | props.setDefaultReadOnly(false); 187 | props.setDefaultTransactionIsolation(TRANSACTION_READ_COMMITTED); 188 | 189 | props.setRollbackOnReturn(true); 190 | props.setUseDisposableConnectionFacade(true); 191 | props.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"); 192 | props.setTestOnBorrow(true); 193 | props.setLogAbandoned(true); 194 | props.setSuspectTimeout(120); 195 | props.setValidationInterval(250); 196 | props.setValidator(new Validator() { 197 | @Override 198 | public boolean validate(Connection connection, int validateAction) 199 | { 200 | try { 201 | return (validateAction == PooledConnection.VALIDATE_BORROW ? connection.isValid(0) : true); 202 | } 203 | catch (SQLException e) 204 | { 205 | return false; 206 | } 207 | } 208 | }); 209 | 210 | DS = new TomcatPoolAccessor(props); 211 | } 212 | 213 | private void setupVibur() 214 | { 215 | ViburDBCPDataSource vibur = new ViburDBCPDataSource(); 216 | vibur.setJdbcUrl(jdbcUrl); 217 | vibur.setUsername("brettw"); 218 | vibur.setPassword(""); 219 | vibur.setPoolFair(false); 220 | vibur.setPoolInitialSize(MIN_POOL_SIZE); 221 | vibur.setPoolMaxSize(MAX_POOL_SIZE); 222 | vibur.setConnectionIdleLimitInSeconds(1); 223 | vibur.setUseNetworkTimeout(true); 224 | vibur.setNetworkTimeoutExecutor(Executors.newFixedThreadPool(1)); 225 | vibur.setClearSQLWarnings(true); 226 | 227 | vibur.setDefaultAutoCommit(false); 228 | vibur.setDefaultReadOnly(false); 229 | vibur.setDefaultTransactionIsolationIntValue(TRANSACTION_READ_COMMITTED); 230 | vibur.setResetDefaultsAfterUse(true); 231 | 232 | vibur.setReducerTimeIntervalInSeconds((int) MINUTES.toSeconds(10)); 233 | 234 | vibur.start(); 235 | 236 | DS = vibur; 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/test/java/com/zaxxer/hikari/benchmark/DbDownTest.java: -------------------------------------------------------------------------------- 1 | package com.zaxxer.hikari.benchmark; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | import java.util.Timer; 8 | import java.util.TimerTask; 9 | import java.util.concurrent.Executors; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | import javax.sql.DataSource; 13 | 14 | import org.apache.commons.dbcp2.BasicDataSource; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | import org.vibur.dbcp.ViburDBCPDataSource; 18 | 19 | import com.jolbox.bonecp.BoneCPConfig; 20 | import com.jolbox.bonecp.BoneCPDataSource; 21 | import com.mchange.v2.c3p0.ComboPooledDataSource; 22 | import com.zaxxer.hikari.HikariConfig; 23 | import com.zaxxer.hikari.HikariDataSource; 24 | 25 | public class DbDownTest 26 | { 27 | private static final String JDBC_URL = "jdbc:mysql://172.16.207.207/test"; 28 | 29 | private static final Logger LOGGER = LoggerFactory.getLogger(DbDownTest.class); 30 | 31 | private static final int MIN_POOL_SIZE = 5; 32 | private int maxPoolSize = MIN_POOL_SIZE; 33 | 34 | private DataSource hikariDS; 35 | private DataSource c3p0DS; 36 | private DataSource dbcp2DS; 37 | private DataSource viburDS; 38 | 39 | public static void main(String[] args) 40 | { 41 | DbDownTest dbDownTest = new DbDownTest(); 42 | dbDownTest.start(); 43 | } 44 | 45 | private DbDownTest() 46 | { 47 | hikariDS = setupHikari(); 48 | viburDS = setupVibur(); 49 | c3p0DS = setupC3P0(); 50 | dbcp2DS = setupDbcp2(); 51 | } 52 | 53 | private void start() 54 | { 55 | class MyTask extends TimerTask 56 | { 57 | private DataSource ds; 58 | public ResultSet resultSet; 59 | 60 | MyTask(DataSource ds) 61 | { 62 | this.ds = ds; 63 | } 64 | 65 | @Override 66 | public void run() 67 | { 68 | try (Connection c = ds.getConnection()) { 69 | LOGGER.info("{} got a connection.", ds.getClass().getSimpleName(), c); 70 | try (Statement stmt = c.createStatement()) { 71 | LOGGER.debug("{} Statement ({})", ds.getClass().getSimpleName(), System.identityHashCode(stmt)); 72 | stmt.setQueryTimeout(1); 73 | resultSet = stmt.executeQuery("SELECT id FROM test"); 74 | if (resultSet.next()) { 75 | LOGGER.debug("Ran query got {}", resultSet.getInt(1)); 76 | } 77 | else { 78 | LOGGER.warn("{} Query executed, got no results.", ds.getClass().getSimpleName()); 79 | } 80 | } 81 | catch (SQLException e) { 82 | LOGGER.error("{} Exception executing query, got a bad connection from the pool: {}", ds.getClass().getSimpleName(), e.getMessage()); 83 | } 84 | } 85 | catch (Throwable t) 86 | { 87 | LOGGER.error("{} Exception getting connection: {}", ds.getClass().getSimpleName(), t.getMessage()); 88 | } 89 | } 90 | } 91 | 92 | new Timer(true).schedule(new MyTask(hikariDS), 5000, 2000); 93 | new Timer(true).schedule(new MyTask(viburDS), 5000, 2000); 94 | new Timer(true).schedule(new MyTask(c3p0DS), 5000, 2000); 95 | new Timer(true).schedule(new MyTask(dbcp2DS), 5000, 2000); 96 | 97 | try 98 | { 99 | Thread.sleep(TimeUnit.SECONDS.toMillis(300)); 100 | } 101 | catch (InterruptedException e) 102 | { 103 | return; 104 | } 105 | } 106 | 107 | protected DataSource setupDbcp2() 108 | { 109 | BasicDataSource ds = new BasicDataSource(); 110 | ds.setUrl(JDBC_URL); 111 | ds.setUsername("root"); 112 | ds.setPassword(""); 113 | ds.setInitialSize(MIN_POOL_SIZE); 114 | ds.setMinIdle(MIN_POOL_SIZE); 115 | ds.setMaxIdle(maxPoolSize); 116 | ds.setMaxTotal(maxPoolSize); 117 | ds.setMaxWaitMillis(5000); 118 | 119 | ds.setDefaultAutoCommit(false); 120 | ds.setRollbackOnReturn(true); 121 | ds.setEnableAutoCommitOnReturn(false); 122 | ds.setTestOnBorrow(true); 123 | ds.setCacheState(true); 124 | ds.setFastFailValidation(true); 125 | 126 | return ds; 127 | } 128 | 129 | protected DataSource setupBone() 130 | { 131 | BoneCPConfig config = new BoneCPConfig(); 132 | config.setJdbcUrl(JDBC_URL); 133 | config.setUsername("root"); 134 | config.setPassword(""); 135 | config.setConnectionTimeoutInMs(5000); 136 | config.setAcquireIncrement(1); 137 | config.setAcquireRetryAttempts(3); 138 | config.setAcquireRetryDelayInMs(5000); 139 | config.setMinConnectionsPerPartition(MIN_POOL_SIZE); 140 | config.setMaxConnectionsPerPartition(maxPoolSize); 141 | config.setConnectionTestStatement("SELECT 1"); 142 | 143 | return new BoneCPDataSource(config); 144 | } 145 | 146 | protected DataSource setupHikari() 147 | { 148 | HikariConfig config = new HikariConfig(); 149 | config.setJdbcUrl(JDBC_URL); 150 | // config.setDriverClassName("com.mysql.jdbc.Driver"); 151 | config.setUsername("root"); 152 | config.setConnectionTimeout(5000); 153 | config.setMinimumIdle(MIN_POOL_SIZE); 154 | config.setMaximumPoolSize(maxPoolSize); 155 | config.setInitializationFailTimeout(0L); 156 | config.setConnectionTestQuery("SELECT 1"); 157 | 158 | return new HikariDataSource(config); 159 | } 160 | 161 | protected DataSource setupC3P0() 162 | { 163 | try 164 | { 165 | ComboPooledDataSource cpds = new ComboPooledDataSource(); 166 | cpds.setJdbcUrl( JDBC_URL ); 167 | cpds.setUser("root"); 168 | cpds.setCheckoutTimeout(5000); 169 | cpds.setTestConnectionOnCheckout(true); 170 | cpds.setAcquireIncrement(1); 171 | cpds.setAcquireRetryAttempts(3); 172 | cpds.setAcquireRetryDelay(5000); 173 | cpds.setInitialPoolSize(MIN_POOL_SIZE); 174 | cpds.setMinPoolSize(MIN_POOL_SIZE); 175 | cpds.setMaxPoolSize(maxPoolSize); 176 | cpds.setPreferredTestQuery("SELECT 1"); 177 | 178 | return cpds; 179 | } 180 | catch (Exception e) 181 | { 182 | throw new RuntimeException(e); 183 | } 184 | } 185 | 186 | private DataSource setupVibur() 187 | { 188 | ViburDBCPDataSource vibur = new ViburDBCPDataSource(); 189 | vibur.setJdbcUrl( JDBC_URL ); 190 | vibur.setUsername("root"); 191 | vibur.setPassword(""); 192 | vibur.setConnectionTimeoutInMs(5000); 193 | vibur.setValidateTimeoutInSeconds(3); 194 | vibur.setLoginTimeoutInSeconds(2); 195 | vibur.setPoolInitialSize(MIN_POOL_SIZE); 196 | vibur.setPoolMaxSize(maxPoolSize); 197 | vibur.setConnectionIdleLimitInSeconds(1); 198 | vibur.setAcquireRetryAttempts(0); 199 | vibur.setReducerTimeIntervalInSeconds(0); 200 | vibur.setUseNetworkTimeout(true); 201 | vibur.setNetworkTimeoutExecutor(Executors.newCachedThreadPool()); 202 | vibur.setClearSQLWarnings(true); 203 | vibur.setResetDefaultsAfterUse(true); 204 | vibur.setTestConnectionQuery("isValid"); // this is the default option, can be left commented out 205 | vibur.start(); 206 | return vibur; 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/test/java/com/zaxxer/hikari/benchmark/SpikeLoadTest.java: -------------------------------------------------------------------------------- 1 | package com.zaxxer.hikari.benchmark; 2 | 3 | import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_IN_USE; 4 | import static com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry.STATE_NOT_IN_USE; 5 | import static com.zaxxer.hikari.util.UtilityElf.quietlySleep; 6 | import static java.lang.Integer.parseInt; 7 | import static java.lang.System.nanoTime; 8 | import static java.lang.Thread.MAX_PRIORITY; 9 | import static java.lang.Thread.currentThread; 10 | import static java.util.concurrent.TimeUnit.MILLISECONDS; 11 | import static java.util.concurrent.TimeUnit.MINUTES; 12 | import static java.util.concurrent.TimeUnit.NANOSECONDS; 13 | import static java.util.concurrent.TimeUnit.SECONDS; 14 | 15 | import java.lang.reflect.Field; 16 | import java.sql.Connection; 17 | import java.sql.DriverManager; 18 | import java.sql.ResultSet; 19 | import java.sql.SQLException; 20 | import java.sql.Statement; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.Timer; 24 | import java.util.TimerTask; 25 | import java.util.concurrent.ExecutorService; 26 | import java.util.concurrent.Executors; 27 | import java.util.concurrent.atomic.AtomicInteger; 28 | import java.util.concurrent.atomic.LongAdder; 29 | import java.util.stream.IntStream; 30 | 31 | import javax.sql.DataSource; 32 | 33 | import com.alibaba.druid.pool.DruidDataSource; 34 | import org.apache.commons.dbcp2.BasicDataSource; 35 | import org.apache.commons.dbcp2.DbcpPoolAccessor; 36 | import org.apache.commons.dbcp2.TomcatPoolAccessor; 37 | import org.apache.tomcat.jdbc.pool.PoolProperties; 38 | import org.apache.tomcat.jdbc.pool.PooledConnection; 39 | import org.apache.tomcat.jdbc.pool.Validator; 40 | import org.slf4j.Logger; 41 | import org.slf4j.LoggerFactory; 42 | import org.vibur.dbcp.ViburDBCPDataSource; 43 | import org.vibur.dbcp.pool.Hook.CloseConnection; 44 | import org.vibur.dbcp.pool.Hook.GetConnection; 45 | import org.vibur.dbcp.pool.Hook.InitConnection; 46 | 47 | import com.mchange.v2.c3p0.ComboPooledDataSource; 48 | import com.zaxxer.hikari.HikariConfig; 49 | import com.zaxxer.hikari.HikariDataSource; 50 | import com.zaxxer.hikari.benchmark.stubs.StubDriver; 51 | import com.zaxxer.hikari.benchmark.stubs.StubStatement; 52 | import com.zaxxer.hikari.pool.HikariPool; 53 | import com.zaxxer.hikari.pool.HikariPoolAccessor; 54 | 55 | public class SpikeLoadTest 56 | { 57 | private static final Logger LOGGER = LoggerFactory.getLogger(SpikeLoadTest.class); 58 | 59 | public static final String jdbcUrl = "jdbc:stub"; 60 | 61 | private static final int MIN_POOL_SIZE = 5; 62 | private static final int MAX_POOL_SIZE = 50; 63 | 64 | private DataSource DS; 65 | 66 | private int requestCount; 67 | 68 | private String pool; 69 | 70 | private DbcpPoolAccessor dbcpPool; 71 | 72 | private ViburPoolHooks viburPool; 73 | 74 | private HikariPoolAccessor hikariPoolAccessor; 75 | 76 | private AtomicInteger threadsRemaining; 77 | 78 | private AtomicInteger threadsPending; 79 | 80 | private ComboPooledDataSource c3p0; 81 | 82 | private TomcatPoolAccessor tomcat; 83 | 84 | private DruidDataSource druid; 85 | 86 | public static void main(String[] args) throws InterruptedException 87 | { 88 | SpikeLoadTest test = new SpikeLoadTest(); 89 | 90 | test.setup(args); 91 | 92 | test.start(parseInt(args[0])); 93 | } 94 | 95 | private void setup(String[] args) 96 | { 97 | try { 98 | Class.forName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); 99 | StubDriver driver = (StubDriver) DriverManager.getDriver(jdbcUrl); 100 | LOGGER.info("Using driver ({}): {}", jdbcUrl, driver); 101 | } 102 | catch (Exception e) { 103 | throw new RuntimeException(e); 104 | } 105 | 106 | pool = args[1]; 107 | IntStream.of(0, 1).forEach( i -> { 108 | switch (pool) { 109 | case "hikari": 110 | setupHikari(); 111 | hikariPoolAccessor = new HikariPoolAccessor(getHikariPool(DS)); 112 | break; 113 | case "dbcp2": 114 | setupDbcp2(); 115 | dbcpPool = (DbcpPoolAccessor) DS; 116 | break; 117 | case "c3p0": 118 | setupC3P0(); 119 | c3p0 = (ComboPooledDataSource) DS; 120 | break; 121 | case "tomcat": 122 | setupTomcat(); 123 | tomcat = (TomcatPoolAccessor) DS; 124 | break; 125 | case "vibur": 126 | setupVibur(); 127 | break; 128 | case "druid": 129 | setupDruid(); 130 | break; 131 | default: 132 | throw new IllegalArgumentException("Unknown connection pool specified"); 133 | } 134 | 135 | if (i == 0) { 136 | try { 137 | LOGGER.info("Warming up pool..."); 138 | LOGGER.info("Warmup blackhole {}", warmupPool()); 139 | shutdownPool(DS); 140 | } 141 | catch (InterruptedException e) { 142 | } 143 | } 144 | }); 145 | 146 | quietlySleep(SECONDS.toMillis(2)); 147 | 148 | this.requestCount = parseInt(args[2]); 149 | } 150 | 151 | private void start(int connectDelay) throws InterruptedException 152 | { 153 | List list = new ArrayList<>(); 154 | for (int i = 0; i < requestCount; i++) { 155 | RequestThread rt = new RequestThread(); 156 | list.add(rt); 157 | } 158 | 159 | StubDriver.setConnectDelayMs(connectDelay); 160 | StubStatement.setExecuteDelayMs(2L); 161 | 162 | Timer timer = new Timer(true); 163 | ExecutorService executor = Executors.newFixedThreadPool(50); /*, new ThreadFactory() { 164 | @Override 165 | public Thread newThread(Runnable r) 166 | { 167 | Thread t = new Thread(r); 168 | t.setPriority(Thread.MIN_PRIORITY); 169 | return t; 170 | } 171 | }); */ 172 | 173 | quietlySleep(SECONDS.toMillis(3)); 174 | 175 | threadsRemaining = new AtomicInteger(requestCount); 176 | threadsPending = new AtomicInteger(0); 177 | 178 | LOGGER.info("SpikeLoadTest starting."); 179 | 180 | currentThread().setPriority(MAX_PRIORITY); 181 | 182 | timer.schedule(new TimerTask() { 183 | public void run() { 184 | for (int i = 0; i < requestCount; i++) { 185 | final Runnable runner = list.get(i); 186 | executor.execute(runner); 187 | } 188 | } 189 | }, 1); 190 | 191 | final long startTime = nanoTime(); 192 | 193 | List statsList = new ArrayList<>(); 194 | PoolStatistics poolStatistics; 195 | do { 196 | poolStatistics = getPoolStatistics(startTime, threadsPending.get()); 197 | statsList.add(poolStatistics); 198 | 199 | final long spinStart = nanoTime(); 200 | do { 201 | // spin 202 | } while (nanoTime() - spinStart < 250_000 /* 0.1ms */); 203 | } 204 | while (threadsRemaining.get() > 0 || poolStatistics.activeConnections > 0); 205 | 206 | long endTime = nanoTime(); 207 | 208 | executor.shutdown(); 209 | 210 | LOGGER.info("SpikeLoadTest completed in {}ms", MILLISECONDS.convert(endTime - startTime, NANOSECONDS)); 211 | 212 | dumpStats(statsList, list); 213 | } 214 | 215 | private void dumpStats(List statsList, List list) 216 | { 217 | System.out.println(String.join("\t", "Time", "Total", "Active", "Idle", "Wait")); 218 | for (PoolStatistics stats : statsList) { 219 | System.out.println(stats); 220 | } 221 | 222 | System.out.println("\n" + String.join("\t", "Total", "Conn", "Query", "Thread")); 223 | for (RequestThread req : list) { 224 | System.out.println(req); 225 | } 226 | } 227 | 228 | private class RequestThread extends TimerTask implements Runnable 229 | { 230 | @SuppressWarnings("unused") 231 | Exception exception; 232 | String name; 233 | long startTime; 234 | long endTime; 235 | long connectTime; 236 | long queryTime; 237 | 238 | @Override 239 | public void run() 240 | { 241 | name = currentThread().getName(); 242 | 243 | threadsPending.incrementAndGet(); 244 | startTime = nanoTime(); 245 | try (Connection connection = DS.getConnection()) { 246 | connectTime = nanoTime(); 247 | threadsPending.decrementAndGet(); 248 | try (Statement statement = connection.createStatement(); 249 | ResultSet resultSet = statement.executeQuery("SELECT x FROM faux")) { 250 | queryTime = nanoTime(); 251 | } 252 | } 253 | catch (SQLException e) { 254 | exception = e; 255 | } 256 | finally { 257 | endTime = nanoTime(); 258 | threadsRemaining.decrementAndGet(); 259 | } 260 | } 261 | 262 | @Override 263 | public String toString() 264 | { 265 | return String.format("%d\t%d\t%d\t%s", 266 | NANOSECONDS.toMicros(endTime - startTime), 267 | NANOSECONDS.toMicros(connectTime - startTime), 268 | NANOSECONDS.toMicros(queryTime - connectTime), 269 | name); 270 | } 271 | } 272 | 273 | private static class PoolStatistics 274 | { 275 | long timestamp = nanoTime(); 276 | int activeConnections; 277 | int idleConnections; 278 | int pendingThreads; 279 | int totalConnections; 280 | 281 | PoolStatistics(final long baseTime) { 282 | timestamp = nanoTime() - baseTime; 283 | } 284 | 285 | @Override 286 | public String toString() 287 | { 288 | return String.format("%d\t%d\t%d\t%d\t%d", NANOSECONDS.toMicros(timestamp), totalConnections, activeConnections, idleConnections, pendingThreads); 289 | } 290 | } 291 | 292 | private PoolStatistics getPoolStatistics(final long baseTime, int remaining) 293 | { 294 | PoolStatistics stats = new PoolStatistics(baseTime); 295 | 296 | switch (pool) { 297 | case "hikari": 298 | final int[] poolStateCounts = hikariPoolAccessor.getPoolStateCounts(); 299 | stats.activeConnections = poolStateCounts[STATE_IN_USE]; 300 | stats.idleConnections = poolStateCounts[STATE_NOT_IN_USE]; 301 | stats.totalConnections = poolStateCounts[4]; 302 | stats.pendingThreads = remaining; 303 | break; 304 | case "dbcp2": 305 | stats.activeConnections = dbcpPool.getNumActive(); 306 | stats.idleConnections = dbcpPool.getNumIdle(); 307 | stats.totalConnections = dbcpPool.getNumTotal(); 308 | stats.pendingThreads = remaining; 309 | break; 310 | case "tomcat": 311 | stats.activeConnections = tomcat.getNumActive(); 312 | stats.idleConnections = tomcat.getNumIdle(); 313 | stats.totalConnections = tomcat.getNumTotal(); 314 | stats.pendingThreads = remaining; 315 | break; 316 | case "c3p0": 317 | try { 318 | stats.activeConnections = c3p0.getNumBusyConnectionsDefaultUser(); 319 | stats.idleConnections = c3p0.getNumIdleConnectionsDefaultUser(); 320 | stats.totalConnections = c3p0.getNumConnectionsDefaultUser(); 321 | stats.pendingThreads = remaining; 322 | } 323 | catch (SQLException e) { 324 | throw new RuntimeException(e); 325 | } 326 | break; 327 | case "vibur": 328 | stats.activeConnections = viburPool.getActive(); 329 | stats.idleConnections = viburPool.getIdle(); 330 | stats.totalConnections = viburPool.getTotal(); 331 | stats.pendingThreads = remaining; 332 | break; 333 | case "druid": 334 | stats.activeConnections = druid.getActiveCount(); 335 | stats.idleConnections = druid.getMinIdle(); 336 | stats.totalConnections = (int) druid.getCreateCount(); 337 | stats.pendingThreads = remaining; 338 | break; 339 | } 340 | 341 | return stats; 342 | } 343 | 344 | private long warmupPool() throws InterruptedException 345 | { 346 | final LongAdder j = new LongAdder(); 347 | ExecutorService executor = Executors.newFixedThreadPool(10); 348 | for (int k = 0; k < 10; k++) { 349 | executor.execute(() -> { 350 | for (int i = 0; i < 100_000; i++) { 351 | try (Connection connection = DS.getConnection(); 352 | Statement statement = connection.createStatement(); 353 | ResultSet resultSet = statement.executeQuery("SELECT x FROM faux")) { 354 | j.add(resultSet.getInt(i)); 355 | } 356 | catch (SQLException e) { 357 | throw new RuntimeException(e); 358 | } 359 | } 360 | }); 361 | } 362 | 363 | executor.shutdown(); 364 | executor.awaitTermination(60, SECONDS); 365 | 366 | return j.sum(); 367 | } 368 | 369 | private void setupDbcp2() 370 | { 371 | BasicDataSource ds = new DbcpPoolAccessor(); 372 | ds.setUrl(jdbcUrl); 373 | ds.setUsername("brettw"); 374 | ds.setPassword(""); 375 | ds.setInitialSize(MIN_POOL_SIZE); 376 | ds.setMinIdle(MIN_POOL_SIZE); 377 | ds.setMaxIdle(MAX_POOL_SIZE); 378 | ds.setMaxTotal(MAX_POOL_SIZE); 379 | ds.setMaxWaitMillis(8000); 380 | 381 | ds.setSoftMinEvictableIdleTimeMillis(MINUTES.toMillis(10)); 382 | ds.setTimeBetweenEvictionRunsMillis(SECONDS.toMillis(30)); 383 | 384 | ds.setDefaultAutoCommit(false); 385 | ds.setRollbackOnReturn(true); 386 | ds.setEnableAutoCommitOnReturn(false); 387 | ds.setTestOnBorrow(true); 388 | ds.setCacheState(true); 389 | ds.setFastFailValidation(true); 390 | 391 | try { 392 | // forces internal pool creation 393 | ds.getLogWriter(); 394 | } 395 | catch (SQLException e) { 396 | throw new RuntimeException(e); 397 | } 398 | 399 | DS = ds; 400 | } 401 | 402 | private void setupHikari() 403 | { 404 | HikariConfig config = new HikariConfig(); 405 | config.setJdbcUrl(jdbcUrl); 406 | config.setUsername("brettw"); 407 | config.setPassword(""); 408 | config.setMinimumIdle(MIN_POOL_SIZE); 409 | config.setMaximumPoolSize(MAX_POOL_SIZE); 410 | config.setConnectionTimeout(8000); 411 | config.setAutoCommit(false); 412 | 413 | DS = new HikariDataSource(config); 414 | } 415 | 416 | protected void setupDruid() { 417 | DruidDataSource dataSource = new DruidDataSource(); 418 | 419 | dataSource.setInitialSize(MIN_POOL_SIZE); 420 | dataSource.setMaxActive(MAX_POOL_SIZE); 421 | dataSource.setMinIdle(MIN_POOL_SIZE); 422 | dataSource.setMaxIdle(MAX_POOL_SIZE); 423 | dataSource.setPoolPreparedStatements(true); 424 | dataSource.setDriverClassName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); 425 | dataSource.setUrl(jdbcUrl); 426 | dataSource.setUsername("brettw"); 427 | dataSource.setPassword(""); 428 | dataSource.setValidationQuery("SELECT 1"); 429 | dataSource.setTestOnBorrow(true); 430 | dataSource.setDefaultAutoCommit(false); 431 | dataSource.setMaxWait(8000); 432 | dataSource.setUseUnfairLock(true); 433 | 434 | druid = dataSource; 435 | 436 | DS = dataSource; 437 | } 438 | 439 | protected void setupTomcat() 440 | { 441 | PoolProperties props = new PoolProperties(); 442 | props.setUrl(jdbcUrl); 443 | props.setDriverClassName("com.zaxxer.hikari.benchmark.stubs.StubDriver"); 444 | props.setUsername("brettw"); 445 | props.setPassword(""); 446 | props.setInitialSize(MIN_POOL_SIZE); 447 | props.setMinIdle(MIN_POOL_SIZE); 448 | props.setMaxIdle(MAX_POOL_SIZE); 449 | props.setMaxActive(MAX_POOL_SIZE); 450 | props.setMaxWait(8000); 451 | 452 | props.setDefaultAutoCommit(false); 453 | 454 | props.setRollbackOnReturn(true); 455 | props.setUseDisposableConnectionFacade(true); 456 | props.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState"); //;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"); 457 | props.setTestOnBorrow(true); 458 | props.setValidationInterval(250); 459 | props.setValidator(new Validator() { 460 | @Override 461 | public boolean validate(Connection connection, int validateAction) 462 | { 463 | try { 464 | return (validateAction == PooledConnection.VALIDATE_BORROW ? connection.isValid(0) : true); 465 | } 466 | catch (SQLException e) 467 | { 468 | return false; 469 | } 470 | } 471 | }); 472 | 473 | DS = new TomcatPoolAccessor(props); 474 | } 475 | 476 | private void setupC3P0() 477 | { 478 | try { 479 | ComboPooledDataSource cpds = new ComboPooledDataSource(); 480 | cpds.setJdbcUrl(jdbcUrl); 481 | cpds.setUser("brettw"); 482 | cpds.setPassword(""); 483 | cpds.setAcquireIncrement(1); 484 | cpds.setInitialPoolSize(MIN_POOL_SIZE); 485 | cpds.setNumHelperThreads(2); 486 | cpds.setMinPoolSize(MIN_POOL_SIZE); 487 | cpds.setMaxPoolSize(MAX_POOL_SIZE); 488 | cpds.setCheckoutTimeout(8000); 489 | cpds.setLoginTimeout(8); 490 | cpds.setTestConnectionOnCheckout(true); 491 | 492 | try (Connection connection = cpds.getConnection()) { 493 | // acquire and close to poke the pool into action 494 | } 495 | 496 | DS = cpds; 497 | } 498 | catch (Exception e) { 499 | throw new RuntimeException(e); 500 | } 501 | } 502 | 503 | private void setupVibur() 504 | { 505 | ViburDBCPDataSource vibur = new ViburDBCPDataSource(); 506 | vibur.setJdbcUrl(jdbcUrl); 507 | vibur.setUsername("brettw"); 508 | vibur.setPassword(""); 509 | vibur.setPoolFair(false); 510 | vibur.setPoolInitialSize(MIN_POOL_SIZE); 511 | vibur.setPoolMaxSize(MAX_POOL_SIZE); 512 | vibur.setDefaultAutoCommit(false); 513 | vibur.setResetDefaultsAfterUse(true); 514 | vibur.setConnectionIdleLimitInSeconds(30); 515 | 516 | vibur.setReducerTimeIntervalInSeconds((int) MINUTES.toSeconds(10)); 517 | 518 | viburPool = new ViburPoolHooks(); 519 | 520 | vibur.getConnHooks().addOnInit(viburPool.getInitHook()); 521 | vibur.getConnHooks().addOnGet(viburPool.getGetHook()); 522 | vibur.getConnHooks().addOnClose(viburPool.getCloseHook()); 523 | 524 | vibur.start(); 525 | 526 | DS = vibur; 527 | } 528 | 529 | private void shutdownPool(DataSource ds) 530 | { 531 | if (ds instanceof AutoCloseable) { 532 | try { 533 | ((AutoCloseable) ds).close(); 534 | } 535 | catch (Exception e) { 536 | } 537 | } 538 | else if (ds instanceof ComboPooledDataSource) { 539 | ((ComboPooledDataSource) ds).close(); 540 | } 541 | } 542 | 543 | private static HikariPool getHikariPool(DataSource ds) 544 | { 545 | try { 546 | Field field = ds.getClass().getDeclaredField("pool"); 547 | field.setAccessible(true); 548 | return (HikariPool) field.get(ds); 549 | } 550 | catch (Exception e) { 551 | throw new RuntimeException(e); 552 | } 553 | } 554 | 555 | private static class ViburPoolHooks 556 | { 557 | private AtomicInteger created = new AtomicInteger(); 558 | private AtomicInteger active = new AtomicInteger(); 559 | 560 | int getTotal() 561 | { 562 | return created.get(); 563 | } 564 | 565 | int getActive() 566 | { 567 | return active.get(); 568 | } 569 | 570 | int getIdle() 571 | { 572 | return created.get() - active.get(); 573 | } 574 | 575 | InitHook getInitHook() 576 | { 577 | return new InitHook(); 578 | } 579 | 580 | GetHook getGetHook() 581 | { 582 | return new GetHook(); 583 | } 584 | 585 | CloseHook getCloseHook() 586 | { 587 | return new CloseHook(); 588 | } 589 | 590 | private class InitHook implements InitConnection 591 | { 592 | @Override 593 | public void on(Connection rawConnection, long takenNanos) throws SQLException 594 | { 595 | created.incrementAndGet(); 596 | } 597 | } 598 | 599 | private class GetHook implements GetConnection 600 | { 601 | @Override 602 | public void on(Connection rawConnection, long takenNanos) throws SQLException 603 | { 604 | active.incrementAndGet(); 605 | } 606 | } 607 | 608 | private class CloseHook implements CloseConnection 609 | { 610 | @Override 611 | public void on(Connection rawConnection, long takenNanos) throws SQLException 612 | { 613 | active.decrementAndGet(); 614 | } 615 | } 616 | } 617 | } 618 | -------------------------------------------------------------------------------- /src/test/java/com/zaxxer/hikari/pool/HikariPoolAccessor.java: -------------------------------------------------------------------------------- 1 | package com.zaxxer.hikari.pool; 2 | 3 | public class HikariPoolAccessor 4 | { 5 | private final HikariPool pool; 6 | 7 | public HikariPoolAccessor(HikariPool pool) 8 | { 9 | this.pool = pool; 10 | } 11 | 12 | public int[] getPoolStateCounts() 13 | { 14 | return pool.getPoolStateCounts(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/org/apache/commons/dbcp2/DbcpPoolAccessor.java: -------------------------------------------------------------------------------- 1 | package org.apache.commons.dbcp2; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | 6 | public final class DbcpPoolAccessor extends BasicDataSource 7 | { 8 | public DbcpPoolAccessor() 9 | { 10 | super(); 11 | } 12 | 13 | @Override 14 | public Connection getConnection() throws SQLException 15 | { 16 | return super.getConnection(); 17 | } 18 | 19 | public int getNumTotal() 20 | { 21 | return (int) getConnectionPool().getCreatedCount(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/org/apache/commons/dbcp2/TomcatPoolAccessor.java: -------------------------------------------------------------------------------- 1 | package org.apache.commons.dbcp2; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | 6 | import org.apache.tomcat.jdbc.pool.DataSource; 7 | import org.apache.tomcat.jdbc.pool.PoolProperties; 8 | 9 | public final class TomcatPoolAccessor extends DataSource 10 | { 11 | public TomcatPoolAccessor(PoolProperties props) 12 | { 13 | super(props); 14 | 15 | try { 16 | // forces internal pool creation 17 | super.createPool(); 18 | } 19 | catch (SQLException e) { 20 | e.printStackTrace(); 21 | } 22 | } 23 | 24 | @Override 25 | public Connection getConnection() throws SQLException 26 | { 27 | return super.getConnection(); 28 | } 29 | 30 | public int getNumTotal() 31 | { 32 | return pool.getActive() + pool.getIdle(); 33 | } 34 | } 35 | --------------------------------------------------------------------------------