Skip to content

Commit 3ad1846

Browse files
committed
Optimized find strategy
1 parent b04d1d7 commit 3ad1846

4 files changed

Lines changed: 28 additions & 19 deletions

File tree

ebean-datasource/src/main/java/io/ebean/datasource/pool/ConnectionBuffer.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@
119119
final class ConnectionBuffer {
120120

121121
// special key to return the oldest connection from freeList.
122-
static final Object GET_OLDEST = new Object();
122+
static final Object GET_LAST = new Object();
123+
static final Object GET_FIRST = new Object();
123124

124125
private final ConnectionList[] affinityLists;
125126
private final ConnectionList freeList = new ConnectionList();
@@ -218,17 +219,23 @@ boolean removeBusy(PooledConnection c) {
218219
*/
219220
PooledConnection removeFree(Object affinityId) {
220221
PooledConnection pc;
221-
if (affinityId == GET_OLDEST) {
222-
pc = freeList.peekLast();
223-
} else if (affinityLists == null) {
222+
if (affinityLists == null) {
223+
// affinity disabled. Always use first in list
224224
pc = freeList.peekFirst();
225225
} else if (affinityId == null) {
226+
// null affinity passed
226227
pc = affinityLists[hashSize].peekFirst();
227-
} else { // we have an affinity id.
228+
} else if (affinityId == GET_FIRST) {
229+
// explicitly first one was requested (for heartbeat)
230+
pc = freeList.peekFirst();
231+
} else if (affinityId == GET_LAST) {
232+
// explicitly last one was requested (for changing affinityId)
233+
pc = freeList.peekLast();
234+
} else {
235+
// we have an affinity id request
228236
pc = affinityLists[affinityId.hashCode() % hashSize].find(affinityId);
229237
if (pc == null) {
230-
// no pc with this affinity-id in the pool.
231-
// query "null"-affinityList
238+
// no pc with this affinity-id in the pool. Query "null"-affinityList
232239
pc = affinityLists[hashSize].peekFirst();
233240
}
234241
}

ebean-datasource/src/main/java/io/ebean/datasource/pool/ConnectionPool.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ private void testConnection() {
382382
PooledConnection conn = null;
383383
try {
384384
// Get a connection from the pool and test it
385-
conn = getPooledConnection(affinityProvider.get());
385+
conn = getPooledConnection(ConnectionBuffer.GET_FIRST);
386386
heartbeatPoolExhaustedCount = 0;
387387
if (testConnection(conn)) {
388388
notifyDataSourceIsUp();
@@ -648,7 +648,6 @@ public DataSourceConnection getConnection(Object affinityId) throws SQLException
648648
*/
649649
private PooledConnection getPooledConnection(Object affinitiyId) throws SQLException {
650650
PooledConnection c = queue.obtainConnection(affinitiyId);
651-
c.setAffinityId(affinitiyId);
652651
if (captureStackTrace) {
653652
c.setStackTrace(Thread.currentThread().getStackTrace());
654653
}

ebean-datasource/src/main/java/io/ebean/datasource/pool/PooledConnectionQueue.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ PooledConnection obtainConnection(Object affinitiyId) throws SQLException {
190190
try {
191191
PooledConnection pc = _obtainConnection(affinitiyId);
192192
pc.resetForUse();
193+
if (affinitiyId != ConnectionBuffer.GET_FIRST && affinitiyId != ConnectionBuffer.GET_LAST) {
194+
pc.setAffinityId(affinitiyId);
195+
}
193196
return pc;
194197

195198
} catch (InterruptedException e) {
@@ -227,11 +230,6 @@ private PooledConnection _obtainConnection(Object affinitiyId) throws Interrupte
227230
return connection;
228231
}
229232
connection = createConnection();
230-
if (connection == null && buffer.isAffinitySupported()) {
231-
// we could not find connection with required affinity and
232-
// buffer is full. So try to get oldest connection from buffer
233-
connection = extractFromFreeList(ConnectionBuffer.GET_OLDEST);
234-
}
235233
if (connection != null) {
236234
return connection;
237235
}
@@ -254,7 +252,7 @@ private PooledConnection _obtainConnection(Object affinitiyId) throws Interrupte
254252
}
255253

256254
private PooledConnection createConnection() throws SQLException {
257-
if (buffer.busySize() < maxSize) {
255+
if (totalConnections() < maxSize) {
258256
// grow the connection pool
259257
PooledConnection c = pool.createConnectionForQueue(connectionId++);
260258
int busySize = registerBusyConnection(c);
@@ -279,6 +277,13 @@ private PooledConnection _obtainConnectionWaitLoop(Object affinitiyId) throws SQ
279277
if (conn != null) {
280278
return conn;
281279
}
280+
// we could not create new connection, so we take the last one and change the affinity id
281+
if (buffer.isAffinitySupported()) {
282+
conn = extractFromFreeList(ConnectionBuffer.GET_LAST);
283+
}
284+
if (conn != null) {
285+
return conn;
286+
}
282287
String msg = "Unsuccessfully waited [" + waitTimeoutMillis + "] millis for a connection to be returned."
283288
+ " No connections are free. You need to Increase the max connections of [" + maxSize + "]"
284289
+ " or look for a connection pool leak using datasource.xxx.capturestacktrace=true";
@@ -292,9 +297,7 @@ private PooledConnection _obtainConnectionWaitLoop(Object affinitiyId) throws SQ
292297
try {
293298
nanos = notEmpty.awaitNanos(nanos);
294299
PooledConnection c = extractFromFreeList(affinitiyId);
295-
if (c == null && buffer.isAffinitySupported()) {
296-
c = extractFromFreeList(ConnectionBuffer.GET_OLDEST);
297-
}
300+
298301
if (c != null) {
299302
// successfully waited
300303
return c;

ebean-datasource/src/test/java/io/ebean/datasource/pool/ConnectionBufferTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ public void test_Affinity() {
187187
private static PooledConnection getConnection(ConnectionBuffer b, Object affinity) {
188188
PooledConnection c1 = b.removeFree(affinity);
189189
if (c1 == null) {
190-
c1 = b.removeFree(ConnectionBuffer.GET_OLDEST);
190+
c1 = b.removeFree(ConnectionBuffer.GET_LAST);
191191
}
192192
c1.setAffinityId(affinity);
193193
b.addBusy(c1);

0 commit comments

Comments
 (0)