Refactor global NamespaceStorage access 82/105282/5
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 6 Apr 2023 20:43:45 +0000 (22:43 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 6 Apr 2023 21:25:55 +0000 (23:25 +0200)
There is only one way we are passing BuildGlobalContext, hence there is
no reason to indirect access through GlobalStorageAccess, as there is
only one implementation of it -- which always has the result handy.

Remove GlobalStorageAccess and introduce GlobalStorage as a
specialization of NamespaceStorage -- and pass that to
NamespaceBehaviour. This also improves coupling a bit, as there is only
a single implementation (as opposed to NamespaceStorage, which has
multiple implementations).

JIRA: YANGTOOLS-1497
Change-Id: Ica03ac855b62541ec5c52ce24044387199c75e9c
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractNamespaceStorage.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BehaviourNamespaceAccess.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/SchemaTreeNamespaceBehaviour.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceStorage.java

index a6cf680e4a095c2ff034e9a71ef711d1320731e8..04a97921947c0e20ba8addd0fed3b5ca84c0be7a 100644 (file)
@@ -12,7 +12,6 @@ import static com.google.common.base.Verify.verifyNotNull;
 import com.google.common.collect.ImmutableMap;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Map.Entry;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
@@ -26,17 +25,6 @@ abstract class AbstractNamespaceStorage implements NamespaceStorage {
 
     private Map<ParserNamespace<?, ?>, Map<?, ?>> namespaces = ImmutableMap.of();
 
-    /**
-     * {@inheritDoc}
-     *
-     * <p>
-     * This method override provides bimorphic invocation on this method invocation between
-     * {@link SourceSpecificContext} and the more general {@link AbstractNamespaceStorage}. We typically do not expect
-     * the two accesses to overlap.
-     */
-    @Override
-    public abstract NamespaceStorage getParentStorage();
-
     /**
      * Get access to a {@link ParserNamespace}.
      *
@@ -140,8 +128,8 @@ abstract class AbstractNamespaceStorage implements NamespaceStorage {
                     break;
                 case 1:
                     // Alright, time to grow to a full HashMap
-                    final Map<ParserNamespace<?, ?>, Map<?,?>> newNamespaces = new HashMap<>(4);
-                    final Entry<ParserNamespace<?, ?>, Map<?, ?>> entry = namespaces.entrySet().iterator().next();
+                    final var newNamespaces = new HashMap<ParserNamespace<?, ?>, Map<?, ?>>(4);
+                    final var entry = namespaces.entrySet().iterator().next();
                     newNamespaces.put(entry.getKey(), entry.getValue());
                     namespaces = newNamespaces;
                     // fall through
index 367bd367b581727feb9a204e31a08b73540c2fe9..5028df6c70cd4234140fb5438c5783bc047bf88b 100644 (file)
@@ -16,39 +16,34 @@ import java.util.Map;
 import java.util.Map.Entry;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.GlobalStorageAccess;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.GlobalStorage;
 
 /**
  * A {@link NamespaceAccess} backed by a {@link NamespaceBehaviour}. Also holds reference to {@link BuildGlobalContext}.
  */
-final class BehaviourNamespaceAccess<K, V> extends NamespaceAccess<K, V> implements GlobalStorageAccess {
-    private final @NonNull AbstractNamespaceStorage globalContext;
+final class BehaviourNamespaceAccess<K, V> extends NamespaceAccess<K, V> {
     private final @NonNull NamespaceBehaviour<K, V> behaviour;
+    private final @NonNull GlobalStorage globalStorage;
 
     // FIXME: Change this to Multimap, once issue with modules is resolved.
     private List<KeyedValueAddedListener<K>> listeners;
     private List<PredicateValueAddedListener<K, V>> predicateListeners;
 
-    BehaviourNamespaceAccess(final AbstractNamespaceStorage globalContext, final NamespaceBehaviour<K, V> behaviour) {
-        this.globalContext = requireNonNull(globalContext);
+    BehaviourNamespaceAccess(final GlobalStorage globalStorage, final NamespaceBehaviour<K, V> behaviour) {
+        this.globalStorage = requireNonNull(globalStorage);
         this.behaviour = requireNonNull(behaviour);
     }
 
-    @Override
-    public AbstractNamespaceStorage getGlobalStorage() {
-        return globalContext;
-    }
-
     @Override
     V valueFrom(final NamespaceStorage storage, final K key) {
-        return behaviour.getFrom(this, storage, key);
+        return behaviour.getFrom(globalStorage, storage, key);
     }
 
     @Override
     void valueTo(final NamespaceStorage storage, final K key, final V value) {
-        behaviour.addTo(this, storage, key, value);
+        behaviour.addTo(globalStorage, storage, key, value);
 
         if (listeners != null) {
             final var toNotify = new ArrayList<KeyedValueAddedListener<K>>();
@@ -84,12 +79,12 @@ final class BehaviourNamespaceAccess<K, V> extends NamespaceAccess<K, V> impleme
 
     @Override
     Map<K, V> allFrom(final NamespaceStorage storage) {
-        return behaviour.getAllFrom(this, storage);
+        return behaviour.getAllFrom(globalStorage, storage);
     }
 
     @Override
     Entry<K, V> entryFrom(final NamespaceStorage storage, final NamespaceKeyCriterion<K> criterion) {
-        return behaviour.getFrom(this, storage, criterion);
+        return behaviour.getFrom(globalStorage, storage, criterion);
     }
 
     @Override
index 11f246f998d06a44997ea07be65e4caf1bb08c4c..02d55eb5cc7b9ccd4d76e6da0b007de34e73da4f 100644 (file)
@@ -44,7 +44,7 @@ import org.opendaylight.yangtools.yang.parser.spi.ParserNamespaces;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.GlobalStorage;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
@@ -57,7 +57,7 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.SourceSpecificContext
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class BuildGlobalContext extends AbstractNamespaceStorage {
+final class BuildGlobalContext extends AbstractNamespaceStorage implements GlobalStorage {
     private static final Logger LOG = LoggerFactory.getLogger(BuildGlobalContext.class);
 
     private static final ModelProcessingPhase[] PHASE_EXECUTION_ORDER = {
@@ -120,16 +120,6 @@ final class BuildGlobalContext extends AbstractNamespaceStorage {
             ImmutableSetMultimap.copyOf(modulesDeviatedByModules));
     }
 
-    @Override
-    public StorageType getStorageType() {
-        return StorageType.GLOBAL;
-    }
-
-    @Override
-    public NamespaceStorage getParentStorage() {
-        return null;
-    }
-
     @Override
     <K, V> BehaviourNamespaceAccess<K, V> accessNamespace(final ParserNamespace<K, V> namespace) {
         @SuppressWarnings("unchecked")
index b1871e25a76f9b50f48b28dc105d71060e93b838..e11a54addf3b1b08f0627620613cebbe70e31846 100644 (file)
@@ -324,7 +324,7 @@ final class SourceSpecificContext implements NamespaceStorage, Mutable {
     }
 
     @Override
-    public BuildGlobalContext getParentStorage() {
+    public GlobalStorage getParentStorage() {
         return globalContext;
     }
 
index 8cca66f30ac222d7e1431665b8491bffcb1aec6c..6e276b26fd66947832dfe9c3014cf68d4229f5e4 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveSt
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.GlobalStorage;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.StorageType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.OnDemandSchemaTreeStorage;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
@@ -40,7 +41,7 @@ final class SchemaTreeNamespaceBehaviour<D extends DeclaredStatement<QName>, E e
      * This method is analogous to {@link SchemaTreeAwareEffectiveStatement#findSchemaTreeNode(QName)}.
      */
     @Override
-    public StmtContext<QName, D, E> getFrom(final GlobalStorageAccess globalAccess, final NamespaceStorage storage,
+    public StmtContext<QName, D, E> getFrom(final GlobalStorage global, final NamespaceStorage storage,
             final QName key) {
         // Get the backing storage node for the requested storage
         final NamespaceStorage storageNode = globalOrStatementSpecific(storage);
@@ -52,14 +53,13 @@ final class SchemaTreeNamespaceBehaviour<D extends DeclaredStatement<QName>, E e
     }
 
     @Override
-    public Map<QName, StmtContext<QName, D, E>> getAllFrom(final GlobalStorageAccess globalAccess,
-            final NamespaceStorage storage) {
+    public Map<QName, StmtContext<QName, D, E>> getAllFrom(final GlobalStorage global, final NamespaceStorage storage) {
         // FIXME: 7.0.0: this method needs to be well-defined
         return null;
     }
 
     @Override
-    public void addTo(final GlobalStorageAccess globalAccess, final NamespaceStorage storage, final QName key,
+    public void addTo(final GlobalStorage global, final NamespaceStorage storage, final QName key,
             final StmtContext<QName, D, E> value) {
         final var prev = globalOrStatementSpecific(storage).putToLocalStorageIfAbsent(namespace(), key, value);
         if (prev != null) {
index d555e7deecd31cfd8c2efbdbeb5e7466a4911c79..c7cf9542a8ffa15ccb278f07191b7ba6a9c08d83 100644 (file)
@@ -16,6 +16,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.GlobalStorage;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.StorageType;
 
 /**
@@ -30,18 +31,6 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.StorageT
  * @param <V> Value type
  */
 public abstract class NamespaceBehaviour<K, V> {
-    /**
-     * Interface allowing quick access to {@link StorageType#GLOBAL} {@link NamespaceStorage}.
-     */
-    public interface GlobalStorageAccess {
-        /**
-         * Return the {@link StorageType#GLOBAL} {@link NamespaceStorage}.
-         *
-         * @return Global namespace storage
-         */
-        @NonNull NamespaceStorage getGlobalStorage();
-    }
-
     private final @NonNull ParserNamespace<K, V> namespace;
 
     protected NamespaceBehaviour(final ParserNamespace<K, V> namespace) {
@@ -113,24 +102,24 @@ public abstract class NamespaceBehaviour<K, V> {
     /**
      * Returns a value from model namespace storage according to key param class.
      *
-     * @param globalAccess A {@link GlobalStorageAccess}
+     * @param global global namespace storage
      * @param storage namespace storage
      * @param key type parameter
      * @return value from model namespace storage according to key param class
      */
-    public abstract V getFrom(GlobalStorageAccess globalAccess, NamespaceStorage storage, K key);
+    public abstract V getFrom(GlobalStorage global, NamespaceStorage storage, K key);
 
     /**
      * Returns the key/value mapping best matching specified criterion.
      *
-     * @param globalAccess A {@link GlobalStorageAccess}
+     * @param global global namespace storage
      * @param storage namespace storage
      * @param criterion selection criterion
      * @return Selected mapping, if available.
      */
-    public final @Nullable Entry<K, V> getFrom(final GlobalStorageAccess globalAccess, final NamespaceStorage storage,
+    public final @Nullable Entry<K, V> getFrom(final GlobalStorage global, final NamespaceStorage storage,
             final NamespaceKeyCriterion<K> criterion) {
-        final var mappings = getAllFrom(globalAccess, storage);
+        final var mappings = getAllFrom(global, storage);
         if (mappings == null) {
             return null;
         }
@@ -159,21 +148,21 @@ public abstract class NamespaceBehaviour<K, V> {
     /**
      * Returns all values of a keys of param class from model namespace storage.
      *
-     * @param globalAccess A {@link GlobalStorageAccess}
+     * @param global global namespace storage
      * @param storage namespace storage
      * @return all values of keys of param class from model namespace storage
      */
-    public abstract Map<K, V> getAllFrom(GlobalStorageAccess globalAccess, NamespaceStorage storage);
+    public abstract Map<K, V> getAllFrom(GlobalStorage global, NamespaceStorage storage);
 
     /**
      * Adds a key/value to corresponding namespace storage according to param class.
      *
-     * @param globalAccess A {@link GlobalStorageAccess}
+     * @param global global namespace storage
      * @param storage namespace storage
      * @param key type parameter
      * @param value type parameter
      */
-    public abstract void addTo(GlobalStorageAccess globalAccess, NamespaceStorage storage, K key, V value);
+    public abstract void addTo(GlobalStorage global, NamespaceStorage storage, K key, V value);
 
     protected final V getFromLocalStorage(final NamespaceStorage storage, final K key) {
         return storage.getFromLocalStorage(namespace, key);
@@ -202,22 +191,22 @@ public abstract class NamespaceBehaviour<K, V> {
         }
 
         @Override
-        public final V getFrom(final GlobalStorageAccess globalAccess, final NamespaceStorage storage, final K key) {
-            return getFromLocalStorage(findStorage(globalAccess, storage), key);
+        public final V getFrom(final GlobalStorage global, final NamespaceStorage storage, final K key) {
+            return getFromLocalStorage(findStorage(global, storage), key);
         }
 
         @Override
-        public final Map<K, V> getAllFrom(final GlobalStorageAccess globalAccess, final NamespaceStorage storage) {
-            return getAllFromLocalStorage(findStorage(globalAccess, storage));
+        public final Map<K, V> getAllFrom(final GlobalStorage global, final NamespaceStorage storage) {
+            return getAllFromLocalStorage(findStorage(global, storage));
         }
 
         @Override
-        public final void addTo(final GlobalStorageAccess globalAccess, final NamespaceStorage storage, final K key,
+        public final void addTo(final GlobalStorage global, final NamespaceStorage storage, final K key,
                 final V value) {
-            addToStorage(findStorage(globalAccess, storage), key, value);
+            addToStorage(findStorage(global, storage), key, value);
         }
 
-        abstract NamespaceStorage findStorage(GlobalStorageAccess globalAccess, NamespaceStorage storage);
+        abstract NamespaceStorage findStorage(GlobalStorage global, NamespaceStorage storage);
     }
 
     private static final class StatementLocal<K, V> extends AbstractSpecific<K, V> {
@@ -226,7 +215,7 @@ public abstract class NamespaceBehaviour<K, V> {
         }
 
         @Override
-        NamespaceStorage findStorage(final GlobalStorageAccess globalAccess, final NamespaceStorage storage) {
+        NamespaceStorage findStorage(final GlobalStorage global, final NamespaceStorage storage) {
             return storage;
         }
     }
@@ -237,8 +226,8 @@ public abstract class NamespaceBehaviour<K, V> {
         }
 
         @Override
-        NamespaceStorage findStorage(final GlobalStorageAccess globalAccess, final NamespaceStorage storage) {
-            return globalAccess.getGlobalStorage();
+        GlobalStorage findStorage(final GlobalStorage global, final NamespaceStorage storage) {
+            return global;
         }
     }
 
@@ -251,7 +240,7 @@ public abstract class NamespaceBehaviour<K, V> {
         }
 
         @Override
-        NamespaceStorage findStorage(final GlobalStorageAccess globalAccess, final NamespaceStorage storage) {
+        NamespaceStorage findStorage(final GlobalStorage global, final NamespaceStorage storage) {
             var current = storage;
             while (current != null && current.getStorageType() != type) {
                 current = current.getParentStorage();
@@ -271,8 +260,8 @@ public abstract class NamespaceBehaviour<K, V> {
         }
 
         @Override
-        public V getFrom(final GlobalStorageAccess globalAccess, final NamespaceStorage storage, final K key) {
-            NamespaceStorage current = storage;
+        public V getFrom(final GlobalStorage global, final NamespaceStorage storage, final K key) {
+            var current = storage;
             while (current != null) {
                 final V val = getFromLocalStorage(current, key);
                 if (val != null) {
@@ -284,7 +273,7 @@ public abstract class NamespaceBehaviour<K, V> {
         }
 
         @Override
-        public Map<K, V> getAllFrom(final GlobalStorageAccess globalAccess, final NamespaceStorage storage) {
+        public Map<K, V> getAllFrom(final GlobalStorage global, final NamespaceStorage storage) {
             var current = storage;
             while (current != null) {
                 final Map<K, V> val = getAllFromLocalStorage(current);
@@ -297,8 +286,7 @@ public abstract class NamespaceBehaviour<K, V> {
         }
 
         @Override
-        public void addTo(final GlobalStorageAccess globalAccess, final NamespaceStorage storage, final K key,
-                final V value) {
+        public void addTo(final GlobalStorage global, final NamespaceStorage storage, final K key, final V value) {
             addToStorage(storage, key, value);
         }
     }
index bc1492b69992f080c1459a81f149984b1fb5637b..1f9647ce5522d2ad62c1dc756b030cbe3ef2091b 100644 (file)
@@ -40,6 +40,22 @@ public interface NamespaceStorage {
         ROOT_STATEMENT_LOCAL
     }
 
+    /**
+     * {@link NamespaceStorage} for {@link StorageType#GLOBAL}. This is sufficiently special to warrant a dedicated
+     * interface, as there is only one instance of this storage in every parser build.
+     */
+    interface GlobalStorage extends NamespaceStorage {
+        @Override
+        default StorageType getStorageType() {
+            return StorageType.GLOBAL;
+        }
+
+        @Override
+        default NamespaceStorage getParentStorage() {
+            return null;
+        }
+    }
+
     /**
      * Return the type of this storage.
      *