Perform partial substatement initialization
[yangtools.git] / yang / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / NamespaceStorageSupport.java
index 7f15c0615504292b8e546a2047096e1b5050704a..ddf97aa68da1a64183e01668a7f4819584425445 100644 (file)
@@ -13,6 +13,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
@@ -25,6 +26,14 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode {
 
     private Map<Class<?>, Map<?,?>> namespaces = ImmutableMap.of();
 
+    /**
+     * {@inheritDoc}
+     *
+     * <p>
+     * This method override provides bimorphic invocation on this method invocation between
+     * {@link SourceSpecificContext} and the more general {@link NamespaceStorageSupport}. We typically do not expect
+     * the two accesses to overlap.
+     */
     @Override
     public abstract NamespaceStorageNode getParentNamespaceStorage();
 
@@ -49,54 +58,31 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode {
         // NOOP
     }
 
-    /**
-     * Return a value associated with specified key within a namespace.
-     *
-     * @param type Namespace type
-     * @param key Key
-     * @param <K> namespace key type
-     * @param <V> namespace value type
-     * @param <N> namespace type
-     * @param <T> key type
-     * @return Value, or null if there is no element
-     * @throws NamespaceNotAvailableException when the namespace is not available.
-     */
-    public final <K, V, T extends K, N extends IdentifierNamespace<K, V>> V getFromNamespace(final Class<N> type,
-            final T key) {
-        return getBehaviourRegistry().getNamespaceBehaviour(type).getFrom(this, key);
-    }
-
     public final <K, V, N extends IdentifierNamespace<K, V>> Optional<Entry<K, V>> getFromNamespace(
             final Class<N> type, final NamespaceKeyCriterion<K> criterion) {
         return getBehaviourRegistry().getNamespaceBehaviour(type).getFrom(this, criterion);
     }
 
-    public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromNamespace(final Class<N> type) {
+    public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getNamespace(final Class<N> type) {
         return getBehaviourRegistry().getNamespaceBehaviour(type).getAllFrom(this);
     }
 
     @SuppressWarnings("unchecked")
-    public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromCurrentStmtCtxNamespace(
-            final Class<N> type) {
+    final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getLocalNamespace(final Class<N> type) {
         return (Map<K, V>) namespaces.get(type);
     }
 
-    /**
-     * Associate a value with a key within a namespace.
-     *
-     * @param type Namespace type
-     * @param key Key
-     * @param value value
-     * @param <K> namespace key type
-     * @param <V> namespace value type
-     * @param <N> namespace type
-     * @param <T> key type
-     * @param <U> value type
-     * @throws NamespaceNotAvailableException when the namespace is not available.
-     */
-    public final <K, V, T extends K, U extends V, N extends IdentifierNamespace<K, V>> void addToNs(
+    final <K, V, T extends K, U extends V, N extends IdentifierNamespace<K, V>> void addToNamespace(
             final Class<N> type, final T key, final U value) {
-        getBehaviourRegistry().getNamespaceBehaviour(type).addTo(this,key,value);
+        getBehaviourRegistry().getNamespaceBehaviour(type).addTo(this, key, value);
+    }
+
+    final <K, V, T extends K, U extends V, N extends IdentifierNamespace<K, V>> void addToNamespace(
+            final Class<N> type, final Map<T, U> map) {
+        final NamespaceBehaviour<K, V, N> behavior = getBehaviourRegistry().getNamespaceBehaviour(type);
+        for (final Entry<T, U> validationBundle : map.entrySet()) {
+            behavior.addTo(this, validationBundle.getKey(), validationBundle.getValue());
+        }
     }
 
     /**
@@ -136,10 +122,22 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode {
             checkLocalNamespaceAllowed(type);
             ret = new HashMap<>(1);
 
-            if (namespaces.isEmpty()) {
-                namespaces = new HashMap<>(1);
+            switch (namespaces.size()) {
+                case 0:
+                    // We typically have small population of namespaces, use a singleton map
+                    namespaces = ImmutableMap.of(type, ret);
+                    break;
+                case 1:
+                    // Alright, time to grow to a full HashMap
+                    final Map<Class<?>, Map<?,?>> newNamespaces = new HashMap<>(4);
+                    final Entry<Class<?>, Map<?, ?>> entry = namespaces.entrySet().iterator().next();
+                    newNamespaces.put(entry.getKey(), entry.getValue());
+                    namespaces = newNamespaces;
+                    // fall through
+                default:
+                    // Already expanded, just put the new namespace
+                    namespaces.put(type, ret);
             }
-            namespaces.put(type, ret);
         }
 
         return ret;