Fix check path contention when create tree producers
[mdsal.git] / dom / mdsal-dom-broker / src / main / java / org / opendaylight / mdsal / dom / broker / ShardedDOMDataTree.java
index 92c2397a2f6ed831a7d224084a98825aaf94ff8f..7cbbf0be88314e3359a94d2e4e6f661b66e24015 100644 (file)
@@ -42,6 +42,7 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTreeShardingService {
     private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMDataTree.class);
 
@@ -49,6 +50,8 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
     private final DOMDataTreePrefixTable<DOMDataTreeShardRegistration<?>> shards = DOMDataTreePrefixTable.create();
     @GuardedBy("this")
     private final DOMDataTreePrefixTable<DOMDataTreeProducer> producers = DOMDataTreePrefixTable.create();
+    @GuardedBy("this")
+    private final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> producerMap = new HashMap<>();
 
     void removeShard(final DOMDataTreeShardRegistration<?> reg) {
         final DOMDataTreeIdentifier prefix = reg.getPrefix();
@@ -134,6 +137,7 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
     synchronized void destroyProducer(final ShardedDOMDataTreeProducer producer) {
         for (final DOMDataTreeIdentifier s : producer.getSubtrees()) {
             producers.remove(s);
+            producerMap.remove(s);
         }
     }
 
@@ -149,6 +153,7 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
         final DOMDataTreeProducer ret = ShardedDOMDataTreeProducer.create(this, subtrees, shardMap);
         for (final DOMDataTreeIdentifier subtree : subtrees) {
             producers.store(subtree, ret);
+            producerMap.put(subtree, ret);
         }
 
         return ret;
@@ -164,6 +169,12 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
             final DOMDataTreeProducer producer = findProducer(subtree);
             checkArgument(producer == null, "Subtree %s is attached to producer %s", subtree, producer);
 
+            for (Map.Entry<DOMDataTreeIdentifier, DOMDataTreeProducer> producerEntry : producerMap.entrySet()) {
+                checkArgument(!subtree.contains(producerEntry.getKey()),
+                    "Subtree %s contains subtree %s which is already attached to producer %s.",
+                    subtree, producerEntry.getKey(), producerEntry.getValue());
+            }
+
             final DOMDataTreePrefixTableEntry<DOMDataTreeShardRegistration<?>> possibleShardReg =
                     shards.lookup(subtree);
             if (possibleShardReg != null && possibleShardReg.getValue() != null) {