impossibl/pgjdbc-ng — pull request #64 by brettwooldridge (2014-01-24 09:22:59+00:00)
Title: Implement prepared statement caching.

This is a pull request that implements #58 (Implement driver-side prepared statement cache).

The largest block of code below is the class ``LruStatementCache``. This class is a modified version of a prepared statement cache that I wrote for the [Bitronix JTA Transaction Manager](https://github.com/bitronix/btm). The BTM original class is [here](https://github.com/bitronix/btm/blob/master/btm/src/main/java/bitronix/tm/resource/jdbc/LruStatementCache.java) and has been in use for several years, so it's pretty solid (no reported bugs). It is Apache Licensed, and I wrote it, so there should be no issue using it.

The performance numbers for this change are as follows for 100,000 prepare statements:
```
Original : 27945ms
Original+parsed SQL cache (PSC) : 11721ms
Original+PSC+statement cache : 56ms
```
1 The [parsed SQL cache](https://github.com/impossibl/pgjdbc-ng/pull/62) was recently pulled.

The prepared statement cache is per-connection. PGPreparedStatements are "single-use", by which I mean ... when a statement is prepared, if it exists in the cache it is removed from the cache and re-used, during which time if the client re-prepares the same statement it is *not* found in the cache and a new PGPreparedStatement will be created. When a PGPreparedStatement is closed, it is returned to the cache. The cache is this case is acting more like a "pool" (a "pool" is technically still a "cache").

The next biggest change after the inclusion of ``LruStatementCache`` are the changes to ``PGConnectionImpl``. The ``PGConnectionImpl.java`` diffs below are a little difficult to read as rendered, but in fact are rather simple in nature. I suggest opening ``PGConnectionImpl.java`` in a separate browser window and following the diffs along in the full source for readability.

All tests are passing with both the cache turned on and with the cache turned off. There are two changes to unit tests included here which were leaking statements and causing noise in the test output, so I added close() calls to those tests' statements.