internal static ConnectorPool GetOrAdd(string key, ConnectorPool pool) { lock (_lock) { if (TryGetValue(key, out var result)) { return(result); } // May need to grow the array. if (_nextSlot == _pools.Length) { var newPools = new (string, ConnectorPool)[_pools.Length * 2];
internal static bool TryGetValue(string key, out ConnectorPool pool) { // Note that pools never get removed. _pools is strictly append-only. var nextSlot = _nextSlot; var pools = _pools; var sw = new SpinWait(); // First scan the pools and do reference equality on the connection strings for (var i = 0; i < nextSlot; i++) { var cp = pools[i]; if (ReferenceEquals(cp.Key, key)) { // It's possible that this pool entry is currently being written: the connection string // component has already been writte, but the pool component is just about to be. So we // loop on the pool until it's non-null while (Volatile.Read(ref cp.Pool) == null) { sw.SpinOnce(); } pool = cp.Pool; return(true); } } // Next try value comparison on the strings for (var i = 0; i < nextSlot; i++) { var cp = pools[i]; if (cp.Key == key) { // See comment above while (Volatile.Read(ref cp.Pool) == null) { sw.SpinOnce(); } pool = cp.Pool; return(true); } } pool = null; return(false); }
public MultiHostConnectorPool(NpgsqlConnectionStringBuilder settings, string connString) : base(settings, connString) { var hosts = settings.Host !.Split(','); _pools = new ConnectorPool[hosts.Length]; for (var i = 0; i < hosts.Length; i++) { var host = hosts[i].Trim(); var port = settings.Port; var portSeparator = host.IndexOf(':'); if (portSeparator != -1) { port = int.Parse(host.Substring(portSeparator + 1)); host = host.Substring(0, portSeparator); } var poolSettings = settings.Clone(); poolSettings.Host = host; poolSettings.Port = port; _pools[i] = new ConnectorPool(poolSettings, poolSettings.ConnectionString, this); } }