Use a linear TypedefNamespace 51/98851/5
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 6 Dec 2021 07:17:42 +0000 (08:17 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 6 Dec 2021 10:42:42 +0000 (11:42 +0100)
We do not access TypedefNamespace in our code and it usually is empty,
implement it as a linear search map.

JIRA: YANGTOOLS-1375
Change-Id: I231dfc297bca6e85a2e998d3a2fe1b2bc83e7ad4
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/LinearTypedefNamespace.java [new file with mode: 0644]

index fa5d1db38b401814657251460e47f6e1c3978912..8847b96b7c1db3795c0186fbbb6305e12e309e83 100644 (file)
@@ -29,7 +29,6 @@ import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStat
 import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
 
 /**
@@ -272,17 +271,15 @@ public abstract class AbstractDeclaredEffectiveStatement<A, D extends DeclaredSt
             E extends DataTreeAwareEffectiveStatement<A, D>> extends WithDataTree<A, D, E> {
         public abstract static class WithTypedefNamespace<A, D extends DeclaredStatement<A>,
                 E extends DataTreeAwareEffectiveStatement<A, D>> extends DefaultWithDataTree<A, D, E> {
-            private final @NonNull ImmutableMap<QName, TypedefEffectiveStatement> typedefNamespace;
-
             protected WithTypedefNamespace(final D declared,
                 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
                 super(declared, substatements);
-                this.typedefNamespace = createTypedefNamespace(substatements);
+                // Consistency check only
+                createTypedefNamespace(substatements);
             }
 
             protected WithTypedefNamespace(final WithTypedefNamespace<A, D, E> original) {
                 super(original);
-                this.typedefNamespace = original.typedefNamespace;
             }
 
             @Override
@@ -290,7 +287,7 @@ public abstract class AbstractDeclaredEffectiveStatement<A, D extends DeclaredSt
             protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
                     final Class<N> namespace) {
                 if (TypedefNamespace.class.equals(namespace)) {
-                    return Optional.of((Map<K, V>) typedefNamespace);
+                    return Optional.of((Map<K, V>) new LinearTypedefNamespace(effectiveSubstatements()));
                 }
                 return super.getNamespaceContents(namespace);
             }
index 71a27a383a759890983af56c6abaef607d1d21c7..27ed8eaecf0546a28433b6ad9829484ca78c5234 100644 (file)
@@ -12,6 +12,7 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Optional;
@@ -118,14 +119,14 @@ abstract class AbstractEffectiveStatement<A, D extends DeclaredStatement<A>>
         return sameAsSchema ? (ImmutableMap) schemaTreeNamespace : ImmutableMap.copyOf(dataChildren);
     }
 
-    protected static @NonNull ImmutableMap<QName, TypedefEffectiveStatement> createTypedefNamespace(
+    protected static @NonNull HashMap<QName, TypedefEffectiveStatement> createTypedefNamespace(
             final Collection<? extends EffectiveStatement<?, ?>> substatements) {
-        final Map<QName, TypedefEffectiveStatement> typedefs = new LinkedHashMap<>();
+        final HashMap<QName, TypedefEffectiveStatement> typedefs = new HashMap<>();
 
         substatements.stream().filter(TypedefEffectiveStatement.class::isInstance)
             .forEach(child -> putChild(typedefs, (TypedefEffectiveStatement) child, "typedef"));
 
-        return ImmutableMap.copyOf(typedefs);
+        return typedefs;
     }
 
     private static boolean indexDataTree(final Map<QName, DataTreeEffectiveStatement<?>> map,
diff --git a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/LinearTypedefNamespace.java b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/LinearTypedefNamespace.java
new file mode 100644 (file)
index 0000000..3c12bb6
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. 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.yangtools.yang.model.spi.meta;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
+
+/**
+ * A filter-based implementation of a Map to serve with {@link TypedefNamespace}.
+ */
+final class LinearTypedefNamespace extends AbstractMap<QName, TypedefEffectiveStatement> implements Immutable {
+    private final Collection<TypedefEffectiveStatement> values;
+
+    @SuppressWarnings("unchecked")
+    LinearTypedefNamespace(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        values = (Collection<TypedefEffectiveStatement>)
+            Collections2.filter(substatements, TypedefEffectiveStatement.class::isInstance);
+    }
+
+    @Override
+    public int size() {
+        return values.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return values.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(final Object key) {
+        return get(key) != null;
+    }
+
+    @Override
+    public boolean containsValue(final Object value) {
+        return values.contains(requireNonNull(value));
+    }
+
+    @Override
+    public TypedefEffectiveStatement get(final Object key) {
+        final var nonnull = requireNonNull(key);
+        return values().stream().filter(stmt -> nonnull.equals(stmt.argument())).findFirst().orElse(null);
+    }
+
+    @Override
+    public TypedefEffectiveStatement remove(final Object key) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    @SuppressWarnings("checkstyle:parameterName")
+    public void putAll(final Map<? extends QName, ? extends TypedefEffectiveStatement> m) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<QName> keySet() {
+        return values.stream().map(TypedefEffectiveStatement::argument).collect(ImmutableSet.toImmutableSet());
+    }
+
+    @Override
+    public Collection<TypedefEffectiveStatement> values() {
+        return values;
+    }
+
+    @Override
+    public Set<Entry<QName, TypedefEffectiveStatement>> entrySet() {
+        return values.stream().map(stmt -> Map.entry(stmt.argument(), stmt)).collect(ImmutableSet.toImmutableSet());
+    }
+}