Generalized ShardingTableEntry into generic 43/26243/5
authorTony Tkacik <ttkacik@cisco.com>
Mon, 31 Aug 2015 15:57:11 +0000 (17:57 +0200)
committerRobert Varga <nite@hq.sk>
Tue, 15 Sep 2015 13:31:01 +0000 (13:31 +0000)
ShardingTableEntry was generalized into generic structure
which is indexed by YangInstanceIdentifier and may
store any arbitrary structure.

This allows for tree-base index not only of shards,
but also producers and listeners, which may be useful
during resharding operations.

Change-Id: Idde0cca1b0f4292bab0c06a0fede67fb25992e83
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTree.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardingTable.java [new file with mode: 0644]
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardingTableEntry.java

index 06e7e849722f658e8a445b9e566dccb0d99da01a..9544cbd114d1f8f8e9622a51a5ea7ee00e3051e5 100644 (file)
@@ -9,14 +9,12 @@ package org.opendaylight.mdsal.dom.broker;
 
 import com.google.common.base.Preconditions;
 import java.util.Collection;
-import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
 import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeLoopException;
@@ -33,44 +31,20 @@ import org.slf4j.LoggerFactory;
 
 public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTreeShardingService {
     private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMDataTree.class);
-    private final Map<LogicalDatastoreType, ShardingTableEntry> shardingTables = new EnumMap<>(LogicalDatastoreType.class);
-    @GuardedBy("this")
-    private final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> idToProducer = new TreeMap<>();
 
     @GuardedBy("this")
-    private ShardingTableEntry lookupShard(final DOMDataTreeIdentifier prefix) {
-        final ShardingTableEntry t = shardingTables.get(prefix.getDatastoreType());
-        if (t == null) {
-            return null;
-        }
-
-        return t.lookup(prefix.getRootIdentifier());
-    }
-
+    private final ShardingTable<ShardRegistration<?>> shards = ShardingTable.create();
     @GuardedBy("this")
-    private void storeShard(final DOMDataTreeIdentifier prefix, final ShardRegistration<?> reg) {
-        ShardingTableEntry t = shardingTables.get(prefix.getDatastoreType());
-        if (t == null) {
-            t = new ShardingTableEntry();
-            shardingTables.put(prefix.getDatastoreType(), t);
-        }
+    private final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> idToProducer = new TreeMap<>();
 
-        t.store(prefix.getRootIdentifier(), reg);
-    }
 
     void removeShard(final ShardRegistration<?> reg) {
         final DOMDataTreeIdentifier prefix = reg.getPrefix();
         final ShardRegistration<?> parentReg;
 
         synchronized (this) {
-            final ShardingTableEntry t = shardingTables.get(prefix.getDatastoreType());
-            if (t == null) {
-                LOG.warn("Shard registration {} points to non-existent table", reg);
-                return;
-            }
-
-            t.remove(prefix.getRootIdentifier());
-            parentReg = lookupShard(prefix).getRegistration();
+            shards.remove(prefix);
+            parentReg = shards.lookup(prefix).getValue();
 
             /*
              * FIXME: adjust all producers and listeners. This is tricky, as we need different
@@ -95,9 +69,9 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
              * and if it exists, check if its registration prefix does not collide with
              * this registration.
              */
-            final ShardingTableEntry parent = lookupShard(prefix);
+            final ShardingTableEntry<ShardRegistration<?>> parent = shards.lookup(prefix);
             if (parent != null) {
-                parentReg = parent.getRegistration();
+                parentReg = parent.getValue();
                 if (parentReg != null && prefix.equals(parentReg.getPrefix())) {
                     throw new DOMDataTreeShardingConflictException(String.format(
                             "Prefix %s is already occupied by shard %s", prefix, parentReg.getInstance()));
@@ -110,7 +84,7 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
 
             reg = new ShardRegistration<T>(this, prefix, shard);
 
-            storeShard(prefix, reg);
+            shards.store(prefix, reg);
 
             // FIXME: update any producers/registrations
         }
@@ -164,7 +138,7 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
             final DOMDataTreeProducer producer = findProducer(s);
             Preconditions.checkArgument(producer == null, "Subtree %s is attached to producer %s", s, producer);
 
-            shardMap.put(s, lookupShard(s).getRegistration().getInstance());
+            shardMap.put(s, shards.lookup(s).getValue().getInstance());
         }
 
         return createProducer(shardMap);
@@ -175,7 +149,7 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
 
         final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap = new HashMap<>();
         for (final DOMDataTreeIdentifier s : subtrees) {
-            shardMap.put(s, lookupShard(s).getRegistration().getInstance());
+            shardMap.put(s, shards.lookup(s).getValue().getInstance());
         }
 
         return createProducer(shardMap);
@@ -200,7 +174,7 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree
             }
 
             for (DOMDataTreeIdentifier subtree : subtrees) {
-                DOMDataTreeShard shard = lookupShard(subtree).getRegistration().getInstance();
+                DOMDataTreeShard shard = shards.lookup(subtree).getValue().getInstance();
                 // FIXME: What should we do if listener is wildcard? And shards are on per
                 // node basis?
                 Preconditions.checkArgument(shard instanceof DOMStoreTreeChangePublisher,
diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardingTable.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardingTable.java
new file mode 100644 (file)
index 0000000..44fb028
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.broker;
+
+import java.util.EnumMap;
+import java.util.Map;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class ShardingTable<V> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ShardingTable.class);
+    private final Map<LogicalDatastoreType, ShardingTableEntry<V>> roots = new EnumMap<>(LogicalDatastoreType.class);
+
+    private ShardingTable() {
+
+    }
+
+    static <V> ShardingTable<V> create() {
+        return new ShardingTable<>();
+    }
+
+    ShardingTableEntry<V> lookup(final DOMDataTreeIdentifier prefix) {
+        final ShardingTableEntry<V> t = roots.get(prefix.getDatastoreType());
+        if (t == null) {
+            return null;
+        }
+
+        return t.lookup(prefix.getRootIdentifier());
+    }
+
+    void store(final DOMDataTreeIdentifier prefix, final V reg) {
+        ShardingTableEntry<V> t = roots.get(prefix.getDatastoreType());
+        if (t == null) {
+            t = new ShardingTableEntry<V>();
+            roots.put(prefix.getDatastoreType(), t);
+        }
+
+        t.store(prefix.getRootIdentifier(), reg);
+    }
+
+    void remove(final DOMDataTreeIdentifier prefix) {
+        final ShardingTableEntry<V> t = roots.get(prefix.getDatastoreType());
+        if (t == null) {
+            LOG.warn("Shard registration {} points to non-existent table", t);
+            return;
+        }
+
+        t.remove(prefix.getRootIdentifier());
+    }
+
+}
index 82966e9147771d3e210bf2e4f04ae7006d435b53..e122e6ca0a454a8cfc1ebc9adf1d99a4772eb2ac 100644 (file)
@@ -17,12 +17,12 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgum
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class ShardingTableEntry implements Identifiable<PathArgument> {
+final class ShardingTableEntry<V> implements Identifiable<PathArgument> {
     private static final Logger LOG = LoggerFactory.getLogger(ShardingTableEntry.class);
     // FIXME: We do probably want to adapt map
-    private final Map<PathArgument, ShardingTableEntry> children = new HashMap<>();
+    private final Map<PathArgument, ShardingTableEntry<V>> children = new HashMap<>();
     private final PathArgument identifier;
-    private ShardRegistration<?> registration;
+    private V value;
 
     ShardingTableEntry() {
         identifier = null;
@@ -37,17 +37,17 @@ final class ShardingTableEntry implements Identifiable<PathArgument> {
         return identifier;
     }
 
-    public ShardRegistration<?> getRegistration() {
-        return registration;
+    public V getValue() {
+        return value;
     }
 
-    ShardingTableEntry lookup(final YangInstanceIdentifier id) {
+    ShardingTableEntry<V> lookup(final YangInstanceIdentifier id) {
         final Iterator<PathArgument> it = id.getPathArguments().iterator();
-        ShardingTableEntry entry = this;
+        ShardingTableEntry<V> entry = this;
 
         while (it.hasNext()) {
             final PathArgument a = it.next();
-            final ShardingTableEntry child = entry.children.get(a);
+            final ShardingTableEntry<V> child = entry.children.get(a);
             if (child == null) {
                 LOG.debug("Lookup of {} stopped at {}", id, a);
                 break;
@@ -59,29 +59,29 @@ final class ShardingTableEntry implements Identifiable<PathArgument> {
         return entry;
     }
 
-    void store(final YangInstanceIdentifier id, final ShardRegistration<?> reg) {
+    void store(final YangInstanceIdentifier id, final V reg) {
         final Iterator<PathArgument> it = id.getPathArguments().iterator();
-        ShardingTableEntry entry = this;
+        ShardingTableEntry<V> entry = this;
 
         while (it.hasNext()) {
             final PathArgument a = it.next();
-            ShardingTableEntry child = entry.children.get(a);
+            ShardingTableEntry<V> child = entry.children.get(a);
             if (child == null) {
-                child = new ShardingTableEntry(a);
+                child = new ShardingTableEntry<>(a);
                 entry.children.put(a, child);
             }
             // TODO: Is this correct? We want to enter child
             entry = child;
         }
 
-        Preconditions.checkState(entry.registration == null);
-        entry.registration = reg;
+        Preconditions.checkState(entry.value == null);
+        entry.value = reg;
     }
 
     private boolean remove(final Iterator<PathArgument> it) {
         if (it.hasNext()) {
             final PathArgument arg = it.next();
-            final ShardingTableEntry child = children.get(arg);
+            final ShardingTableEntry<V> child = children.get(arg);
             if (child != null) {
                 if (child.remove(it)) {
                     children.remove(arg);
@@ -91,13 +91,12 @@ final class ShardingTableEntry implements Identifiable<PathArgument> {
             }
         } else {
             /*
-             * Iterator is empty, this effectivelly means is table entry to remove registration.
-             * FIXME: We probably want to compare registration object to make sure we are removing
-             * correct shard.
+             * Iterator is empty, this effectively means is table entry to remove registration.
+             * FIXME: We probably want to compare value to make sure we are removing correct value.
              */
-            registration = null;
+            value = null;
         }
-        return registration == null && children.isEmpty();
+        return value == null && children.isEmpty();
     }
 
     void remove(final YangInstanceIdentifier id) {