BELUGABEHR commented on a change in pull request #911: ZOOKEEPER-3365: Use 
Concurrent HashMap in NettyServerCnxnFactory
URL: https://github.com/apache/zookeeper/pull/911#discussion_r275160987
 
 

 ##########
 File path: 
zookeeper-server/src/main/java/org/apache/zookeeper/server/NettyServerCnxnFactory.java
 ##########
 @@ -512,44 +511,34 @@ public InetSocketAddress getLocalAddress() {
         return localAddress;
     }
 
-    private void addCnxn(NettyServerCnxn cnxn) {
+    private void addCnxn(final NettyServerCnxn cnxn) {
         cnxns.add(cnxn);
-        synchronized (ipMap){
-            InetAddress addr =
-                
((InetSocketAddress)cnxn.getChannel().remoteAddress()).getAddress();
-            Set<NettyServerCnxn> s = ipMap.get(addr);
-            if (s == null) {
-                s = new HashSet<>();
-                ipMap.put(addr, s);
+        InetAddress addr =
+            ((InetSocketAddress) 
cnxn.getChannel().remoteAddress()).getAddress();
+
+        ipMap.compute(addr, (a, cnxnSet) -> {
+            if (cnxnSet == null) {
+                cnxnSet = new HashSet<>();
             }
-            s.add(cnxn);
-        }
+            cnxnSet.add(cnxn);
 
 Review comment:
   @eolivelli 
   
   Take a look at the Map API for 
[computeIfAbsert](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-).
  They provide an example of how to use it:
   
   ```
   to implement a multi-value map, Map<K,Collection<V>>, supporting multiple 
values per key:
    
    map.computeIfAbsent(key, k -> new HashSet<V>()).add(v);
   ```
   
   The example is for a simple case where there is no multi-threading and the 
map accumulates records without removing empty records.  However, in this 
situation, there are a few issues with this approach:
   
   1. The underlying `HashSet` is not synchronized, so to threads from the same 
source could cause issue on insert
   2. There is a clean-up routine in `removeCnxnFromIpMap` where a key is 
removed if its associated `Set` has no entries.  Well, that could also conflict 
here since it could be the case that the `Set` returned by the 
`computeIfAbsent` is returned, the Thread pauses, and then another thread 
deletes the key in `removeCnxnFromIpMap` and therefore when the Thread resumes 
the `add` happens on a `Set` that was removed.  Better to do it all in a 
protected area.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to