@@ -340,15 +340,25 @@ private async Task CreateMinimumPooledSessions(IOBehavior ioBehavior, Cancellati
340
340
341
341
public static ConnectionPool GetPool ( string connectionString )
342
342
{
343
+ // check single-entry MRU cache for this exact connection string; most applications have just one
344
+ // connection string and will get a cache hit here
345
+ var cache = s_mruCache ;
346
+ if ( cache ? . ConnectionString == connectionString )
347
+ return cache . Pool ;
348
+
343
349
// check if pool has already been created for this exact connection string
344
350
if ( s_pools . TryGetValue ( connectionString , out var pool ) )
351
+ {
352
+ s_mruCache = new ConnectionStringPool ( connectionString , pool ) ;
345
353
return pool ;
354
+ }
346
355
347
356
// parse connection string and check for 'Pooling' setting; return 'null' if pooling is disabled
348
357
var connectionStringBuilder = new MySqlConnectionStringBuilder ( connectionString ) ;
349
358
if ( ! connectionStringBuilder . Pooling )
350
359
{
351
360
s_pools . GetOrAdd ( connectionString , default ( ConnectionPool ) ) ;
361
+ s_mruCache = new ConnectionStringPool ( connectionString , null ) ;
352
362
return null ;
353
363
}
354
364
@@ -359,6 +369,7 @@ public static ConnectionPool GetPool(string connectionString)
359
369
// try to set the pool for the connection string to the canonical pool; if someone else
360
370
// beats us to it, just use the existing value
361
371
pool = s_pools . GetOrAdd ( connectionString , pool ) ;
372
+ s_mruCache = new ConnectionStringPool ( connectionString , pool ) ;
362
373
return pool ;
363
374
}
364
375
@@ -369,9 +380,14 @@ public static ConnectionPool GetPool(string connectionString)
369
380
370
381
// if we won the race to create the new pool, also store it under the original connection string
371
382
if ( pool == newPool && connectionString != normalizedConnectionString )
383
+ {
372
384
s_pools . GetOrAdd ( connectionString , pool ) ;
385
+ s_mruCache = new ConnectionStringPool ( connectionString , pool ) ;
386
+ }
373
387
else if ( pool != newPool && Log . IsInfoEnabled ( ) )
388
+ {
374
389
Log . Info ( "{0} was created but will not be used (due to race)" , newPool . m_logArguments [ 0 ] ) ;
390
+ }
375
391
376
392
return pool ;
377
393
}
@@ -448,6 +464,18 @@ public IEnumerable<string> LoadBalance(IReadOnlyList<string> hosts)
448
464
readonly ConnectionPool m_pool ;
449
465
}
450
466
467
+ private sealed class ConnectionStringPool
468
+ {
469
+ public ConnectionStringPool ( string connectionString , ConnectionPool pool )
470
+ {
471
+ ConnectionString = connectionString ;
472
+ Pool = pool ;
473
+ }
474
+
475
+ public string ConnectionString { get ; }
476
+ public ConnectionPool Pool { get ; }
477
+ }
478
+
451
479
static readonly IMySqlConnectorLogger Log = MySqlConnectorLogManager . CreateLogger ( nameof ( ConnectionPool ) ) ;
452
480
static readonly ConcurrentDictionary < string , ConnectionPool > s_pools = new ConcurrentDictionary < string , ConnectionPool > ( ) ;
453
481
#if DEBUG
@@ -472,6 +500,7 @@ public IEnumerable<string> LoadBalance(IReadOnlyList<string> hosts)
472
500
} ) ;
473
501
474
502
static int s_poolId ;
503
+ static ConnectionStringPool s_mruCache ;
475
504
476
505
int m_generation ;
477
506
readonly SemaphoreSlim m_cleanSemaphore ;
0 commit comments