This is an automated email from the ASF dual-hosted git repository.

florianhockmann pushed a commit to branch TINKERPOP-2135
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit eb137abced0103ed966e073da9da6f9223956c61
Author: Florian Hockmann <[email protected]>
AuthorDate: Sun Mar 3 12:33:22 2019 +0100

    TINKERPOP-2135 Wrap ConcurrentDictionary
    
    A dedicated ConcurrentConnectionCollection is used to wrap
    ConcurrentDictionary as we don't really need a dictionary in
    ConnectionPool. Using the dictionary there directly leads to strange
    looking API calls that could be distracting. Our own collection class
    provides exactly the API we need.
---
 .../Driver/ConcurrentConnectionCollection.cs       | 51 ++++++++++++++++++++++
 .../src/Gremlin.Net/Driver/ConnectionPool.cs       | 13 +++---
 2 files changed, 57 insertions(+), 7 deletions(-)

diff --git 
a/gremlin-dotnet/src/Gremlin.Net/Driver/ConcurrentConnectionCollection.cs 
b/gremlin-dotnet/src/Gremlin.Net/Driver/ConcurrentConnectionCollection.cs
new file mode 100644
index 0000000..c68e0e9
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConcurrentConnectionCollection.cs
@@ -0,0 +1,51 @@
+#region License
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#endregion
+
+using System.Collections;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+
+namespace Gremlin.Net.Driver
+{
+    internal class ConcurrentConnectionCollection : IEnumerable<Connection>
+    {
+        private const int DefaultValue = 0;
+        
+        // We use a ConcurrentDictionary because we need a concurrent 
collection with a TryRemove() method.
+        // Only the keys are used here, the values just contain a dummy 
DefaultValue.
+        private readonly ConcurrentDictionary<Connection, int> _connections =
+            new ConcurrentDictionary<Connection, int>();
+
+        public int Count => _connections.Count;
+
+        public bool IsEmpty => _connections.IsEmpty;
+
+        public void Add(Connection connection) => 
_connections.TryAdd(connection, DefaultValue);
+
+        public bool TryRemove(Connection connection) => 
_connections.TryRemove(connection, out _);
+
+        public IEnumerator<Connection> GetEnumerator() => 
_connections.Keys.GetEnumerator();
+
+        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+    }
+}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs 
b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
index 40aa99b..130d6fd 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ConnectionPool.cs
@@ -34,8 +34,7 @@ namespace Gremlin.Net.Driver
     internal class ConnectionPool : IDisposable
     {
         private readonly ConnectionFactory _connectionFactory;
-        private readonly ConcurrentDictionary<Connection, object> _connections 
=
-            new ConcurrentDictionary<Connection, object>();
+        private readonly ConcurrentConnectionCollection _connections = new 
ConcurrentConnectionCollection();
         private readonly int _poolSize;
         private readonly int _maxInProcessPerConnection;
         private int _poolState;
@@ -90,7 +89,7 @@ namespace Gremlin.Net.Driver
             var createdConnections = await 
Task.WhenAll(connectionCreationTasks).ConfigureAwait(false);
             foreach (var c in createdConnections)
             {
-                _connections.TryAdd(c, null);
+                _connections.Add(c);
             }
         }
         
@@ -120,7 +119,7 @@ namespace Gremlin.Net.Driver
             var nrMinInFlightConnections = int.MaxValue;
             Connection leastBusy = null;
             
-            foreach (var connection in _connections.Keys)
+            foreach (var connection in _connections)
             {
                 var nrInFlight = connection.NrRequestsInFlight;
                 if (nrInFlight >= nrMinInFlightConnections) continue;
@@ -138,7 +137,7 @@ namespace Gremlin.Net.Driver
         
         private void RemoveConnectionFromPool(Connection connection)
         {
-            if (_connections.TryRemove(connection, out _))
+            if (_connections.TryRemove(connection))
                 DefinitelyDestroyConnection(connection);
         }
         
@@ -160,9 +159,9 @@ namespace Gremlin.Net.Driver
 
         private async Task CloseAndRemoveAllConnectionsAsync()
         {
-            foreach (var connection in _connections.Keys)
+            foreach (var connection in _connections)
             {
-                _connections.TryRemove(connection, out _);
+                _connections.TryRemove(connection);
                 await connection.CloseAsync().ConfigureAwait(false);
                 DefinitelyDestroyConnection(connection);
             }

Reply via email to