GossipLinkStore: switch inner Map to non-Concurrent

Change-Id: I7489cef4cb40c2201a5be3435b63fc5ccd87e033
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/link/impl/GossipLinkStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/link/impl/GossipLinkStore.java
index 043917e..a6c1660 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/link/impl/GossipLinkStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/link/impl/GossipLinkStore.java
@@ -9,7 +9,6 @@
 import com.google.common.collect.SetMultimap;
 
 import org.apache.commons.lang3.RandomUtils;
-import org.apache.commons.lang3.concurrent.ConcurrentUtils;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -46,7 +45,6 @@
 import org.onlab.onos.store.serializers.DistributedStoreSerializers;
 import org.onlab.onos.store.serializers.KryoSerializer;
 import org.onlab.util.KryoPool;
-import org.onlab.util.NewConcurrentHashMap;
 import org.slf4j.Logger;
 
 import java.io.IOException;
@@ -87,7 +85,7 @@
     private final Logger log = getLogger(getClass());
 
     // Link inventory
-    private final ConcurrentMap<LinkKey, ConcurrentMap<ProviderId, Timestamped<LinkDescription>>> linkDescs =
+    private final ConcurrentMap<LinkKey, Map<ProviderId, Timestamped<LinkDescription>>> linkDescs =
         new ConcurrentHashMap<>();
 
     // Link instance cache
@@ -267,7 +265,7 @@
 
         LinkKey key = linkKey(linkDescription.value().src(),
                               linkDescription.value().dst());
-        ConcurrentMap<ProviderId, Timestamped<LinkDescription>> descs = getLinkDescriptions(key);
+        Map<ProviderId, Timestamped<LinkDescription>> descs = getLinkDescriptions(key);
 
         synchronized (descs) {
             // if the link was previously removed, we should proceed if and
@@ -294,12 +292,12 @@
 
     // Guarded by linkDescs value (=locking each Link)
     private Timestamped<LinkDescription> createOrUpdateLinkDescription(
-            ConcurrentMap<ProviderId, Timestamped<LinkDescription>> existingLinkDescriptions,
+            Map<ProviderId, Timestamped<LinkDescription>> descs,
             ProviderId providerId,
             Timestamped<LinkDescription> linkDescription) {
 
         // merge existing attributes and merge
-        Timestamped<LinkDescription> existingLinkDescription = existingLinkDescriptions.get(providerId);
+        Timestamped<LinkDescription> existingLinkDescription = descs.get(providerId);
         if (existingLinkDescription != null && existingLinkDescription.isNewer(linkDescription)) {
             return null;
         }
@@ -314,7 +312,7 @@
                         linkDescription.value().type(), merged),
                     linkDescription.timestamp());
         }
-        return existingLinkDescriptions.put(providerId, newLinkDescription);
+        return descs.put(providerId, newLinkDescription);
     }
 
     // Creates and stores the link and returns the appropriate event.
@@ -380,7 +378,7 @@
     }
 
     private LinkEvent removeLinkInternal(LinkKey key, Timestamp timestamp) {
-        ConcurrentMap<ProviderId, Timestamped<LinkDescription>> linkDescriptions =
+        Map<ProviderId, Timestamped<LinkDescription>> linkDescriptions =
                 getLinkDescriptions(key);
         synchronized (linkDescriptions) {
             // accept removal request if given timestamp is newer than
@@ -409,10 +407,10 @@
      * @return primary ProviderID, or randomly chosen one if none exists
      */
     private ProviderId pickPrimaryProviderId(
-            ConcurrentMap<ProviderId, Timestamped<LinkDescription>> providerDescs) {
+            Map<ProviderId, Timestamped<LinkDescription>> linkDescriptions) {
 
         ProviderId fallBackPrimary = null;
-        for (Entry<ProviderId, Timestamped<LinkDescription>> e : providerDescs.entrySet()) {
+        for (Entry<ProviderId, Timestamped<LinkDescription>> e : linkDescriptions.entrySet()) {
             if (!e.getKey().isAncillary()) {
                 return e.getKey();
             } else if (fallBackPrimary == null) {
@@ -423,9 +421,9 @@
         return fallBackPrimary;
     }
 
-    private Link composeLink(ConcurrentMap<ProviderId, Timestamped<LinkDescription>> linkDescriptions) {
-        ProviderId primaryProviderId = pickPrimaryProviderId(linkDescriptions);
-        Timestamped<LinkDescription> base = linkDescriptions.get(primaryProviderId);
+    private Link composeLink(Map<ProviderId, Timestamped<LinkDescription>> descs) {
+        ProviderId primaryProviderId = pickPrimaryProviderId(descs);
+        Timestamped<LinkDescription> base = descs.get(primaryProviderId);
 
         ConnectPoint src = base.value().src();
         ConnectPoint dst = base.value().dst();
@@ -433,7 +431,7 @@
         DefaultAnnotations annotations = DefaultAnnotations.builder().build();
         annotations = merge(annotations, base.value().annotations());
 
-        for (Entry<ProviderId, Timestamped<LinkDescription>> e : linkDescriptions.entrySet()) {
+        for (Entry<ProviderId, Timestamped<LinkDescription>> e : descs.entrySet()) {
             if (primaryProviderId.equals(e.getKey())) {
                 continue;
             }
@@ -450,9 +448,20 @@
         return new DefaultLink(primaryProviderId , src, dst, type, annotations);
     }
 
-    private ConcurrentMap<ProviderId, Timestamped<LinkDescription>> getLinkDescriptions(LinkKey key) {
-        return ConcurrentUtils.createIfAbsentUnchecked(linkDescs, key,
-                NewConcurrentHashMap.<ProviderId, Timestamped<LinkDescription>>ifNeeded());
+    private Map<ProviderId, Timestamped<LinkDescription>> getLinkDescriptions(LinkKey key) {
+        Map<ProviderId, Timestamped<LinkDescription>> r;
+        r = linkDescs.get(key);
+        if (r != null) {
+            return r;
+        }
+        r = new HashMap<>();
+        final Map<ProviderId, Timestamped<LinkDescription>> concurrentlyAdded;
+        concurrentlyAdded = linkDescs.putIfAbsent(key, r);
+        if (concurrentlyAdded != null) {
+            return concurrentlyAdded;
+        } else {
+            return r;
+        }
     }
 
     private Timestamped<LinkDescription> getLinkDescription(LinkKey key, ProviderId providerId) {
@@ -471,13 +480,13 @@
         }
     }
 
-    private static final Predicate<Provided> IS_PRIMARY = new IsPrimary();
-    private static final Predicate<Provided> isPrimary() {
-        return IS_PRIMARY;
-    }
-
     private static final class IsPrimary implements Predicate<Provided> {
 
+        private static final Predicate<Provided> IS_PRIMARY = new IsPrimary();
+        public static final Predicate<Provided> isPrimary() {
+            return IS_PRIMARY;
+        }
+
         @Override
         public boolean apply(Provided input) {
             return !input.providerId().isAncillary();
@@ -582,11 +591,11 @@
         Map<LinkFragmentId, Timestamp> linkTimestamps = new HashMap<>(linkDescs.size());
         Map<LinkKey, Timestamp> linkTombstones = new HashMap<>(removedLinks.size());
 
-        for (Entry<LinkKey, ConcurrentMap<ProviderId, Timestamped<LinkDescription>>>
+        for (Entry<LinkKey, Map<ProviderId, Timestamped<LinkDescription>>>
             provs : linkDescs.entrySet()) {
 
             final LinkKey linkKey = provs.getKey();
-            final ConcurrentMap<ProviderId, Timestamped<LinkDescription>> linkDesc = provs.getValue();
+            final Map<ProviderId, Timestamped<LinkDescription>> linkDesc = provs.getValue();
             synchronized (linkDesc) {
                 for (Map.Entry<ProviderId, Timestamped<LinkDescription>> e : linkDesc.entrySet()) {
                     linkTimestamps.put(new LinkFragmentId(linkKey, e.getKey()), e.getValue().timestamp());