Always use lazy leaf nodes 02/92902/3
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 5 Oct 2020 12:39:00 +0000 (14:39 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 5 Oct 2020 14:42:50 +0000 (16:42 +0200)
Remove the global knob which controls eager/lazy leaf nodes, meaning
we will always treat them as transient.

Change-Id: I88d453821dd6ee1909b5e138ab16da560ebabe74
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableDataContainerNode.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/LazyLeafOperations.java
yang/yang-data-jaxen/src/test/java/org/opendaylight/yangtools/yang/data/jaxen/DerefXPathFunctionTest.java

index c81da66e2b7cb1aaf1c094b977ff192195ef2c05..6b5e0d7e5124eb8ee661fa9f8119a624252f7daf 100644 (file)
@@ -28,12 +28,12 @@ public abstract class AbstractImmutableDataContainerNode<K extends PathArgument>
 
     @Override
     public final Optional<DataContainerChild<? extends PathArgument, ?>> getChild(final PathArgument child) {
-        return LazyLeafOperations.findChild(children, child);
+        return Optional.ofNullable(LazyLeafOperations.getChild(children, child));
     }
 
     @Override
     public final Collection<DataContainerChild<? extends PathArgument, ?>> getValue() {
-        return LazyLeafOperations.getValue(children);
+        return new LazyValues(children);
     }
 
     @Override
index 087b87d2a6cbded3978cf34d88cf0b8f5ca71a9b..a8668def4e69129e58d7333b677769940fb20618 100644 (file)
@@ -11,77 +11,23 @@ import static com.google.common.base.Verify.verify;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
-import java.util.Collection;
 import java.util.Map;
-import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Support utilities for dealing with Maps which would normally hold {@link DataContainerChild} values, but are modified
  * to eliminate {@link LeafNode} instances.
- *
- * <p>
- * This class holds implementation logic which controls lifecycle of {@link LeafNode}s  by providing a central policy
- * point for how the implementation treats these nodes. There are two modes of operation:
- * <ul>
- *   <li>eager, which means leaf nodes are retained by their parent<li>
- *   <li>lazy, which means leaf nodes are created whenever they are queried and no attempt is made to retain them</li>
- * </ul>
- *
- * <p>
- * Selection of the mode in effect is available through {@value #EXPENDABLE_PROP_NAME} system property.
  */
 @Beta
 public final class LazyLeafOperations {
-    private static final Logger LOG = LoggerFactory.getLogger(LazyLeafOperations.class);
-
-    // FIXME: 6.0.0: remove this knob
-    private static final String EXPENDABLE_PROP_NAME =
-            "org.opendaylight.yangtools.yang.data.impl.schema.nodes.lazy-leaves";
-
-    /**
-     * Global enabled run-time constant. If set to true, this class will treat {@link LeafNode} and
-     * {@link LeafSetEntryNode} as an expendable object. This constant is controlled by {@value #EXPENDABLE_PROP_NAME}
-     * system property.
-     */
-    // FIXME: 6.0.0: remove this knob
-    private static final boolean EXPENDABLE;
-
-    static {
-        EXPENDABLE = Boolean.parseBoolean(System.getProperty(EXPENDABLE_PROP_NAME, "true"));
-        if (!EXPENDABLE) {
-            LOG.warn("Leaf nodes are treated as regular nodes. This option is deprecated and is schedule for removal.");
-        }
-    }
-
     private LazyLeafOperations() {
-
-    }
-
-    /**
-     * A boolean flag indicating whether leaf nodes are being treated as expendable.
-     *
-     * @return True if NormalizedNode implementations in this artifact are treating leaf nodes as transient, i.e. do
-     *              not retain them.
-     */
-    // FIXME: 6.0.0: remove this method
-    public static boolean isEnabled() {
-        return EXPENDABLE;
-    }
-
-    public static Optional<DataContainerChild<?, ?>> findChild(final Map<PathArgument, Object> map,
-            final PathArgument key) {
-        final Object value = map.get(key);
-        return value == null ? Optional.empty() : Optional.of(decodeChild(key, value));
+        // Hidden on purpose
     }
 
     public static @Nullable DataContainerChild<?, ?> getChild(final Map<PathArgument, Object> map,
@@ -92,14 +38,7 @@ public final class LazyLeafOperations {
 
     public static void putChild(final Map<PathArgument, Object> map, final DataContainerChild<?, ?> child) {
         final DataContainerChild<?, ?> node = requireNonNull(child);
-        map.put(node.getIdentifier(), EXPENDABLE ? encodeExpendableChild(node) : node);
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    public static @NonNull Collection<DataContainerChild<?, ?>> getValue(final Map<PathArgument, Object> map) {
-        return EXPENDABLE ? new LazyValues(map)
-                // This is an ugly cast, but it is accurate IFF all modifications are done through this class
-                : (Collection)map.values();
+        map.put(node.getIdentifier(), encodeExpendableChild(node));
     }
 
     static @NonNull LeafNode<?> coerceLeaf(final PathArgument key, final Object value) {
@@ -108,12 +47,12 @@ public final class LazyLeafOperations {
     }
 
     private static @Nullable DataContainerChild<?, ?> decodeChild(final PathArgument key, final @NonNull Object value) {
-        return EXPENDABLE ? decodeExpendableChild(key, value) : verifyCast(value);
+        return decodeExpendableChild(key, value);
     }
 
     private static @NonNull DataContainerChild<?, ?> decodeExpendableChild(final PathArgument key,
             @NonNull final Object value) {
-        return value instanceof DataContainerChild ? (DataContainerChild<?, ?>) value  : coerceLeaf(key, value);
+        return value instanceof DataContainerChild ? (DataContainerChild<?, ?>) value : coerceLeaf(key, value);
     }
 
     private static @NonNull Object encodeExpendableChild(final @NonNull DataContainerChild<?, ?> node) {
@@ -124,9 +63,4 @@ public final class LazyLeafOperations {
         verify(!(value instanceof DataContainerChild), "Unexpected leaf value %s", value);
         return value;
     }
-
-    private static @NonNull DataContainerChild<?, ?> verifyCast(final @NonNull Object value) {
-        verify(value instanceof DataContainerChild, "Unexpected child %s", value);
-        return (DataContainerChild<?, ?>)value;
-    }
 }
index 47bc7226c17b2ae2f75d2516d6933909495abd27..947cd0699b7609dae2389071a70f9cd6920d6009 100644 (file)
@@ -36,7 +36,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.nodes.LazyLeafOperations;
 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathDocument;
 import org.opendaylight.yangtools.yang.data.jaxen.api.XPathSchemaContext;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
@@ -89,7 +88,7 @@ public class DerefXPathFunctionTest {
         final Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
         assertNotNull(derefResult);
         assertTrue(derefResult instanceof LeafNode<?>);
-        assertLeafEquals(referencedLeafNode, (LeafNode<?>) derefResult);
+        assertEquals(referencedLeafNode, derefResult);
     }
 
     @Test
@@ -122,7 +121,7 @@ public class DerefXPathFunctionTest {
         Object derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
         assertNotNull(derefResult);
         assertTrue(derefResult instanceof LeafNode<?>);
-        assertLeafEquals(referencedLeafNode, (LeafNode<?>) derefResult);
+        assertEquals(referencedLeafNode, derefResult);
 
         final YangInstanceIdentifier relLeafrefPath = YangInstanceIdentifier.of(MY_INNER_CONTAINER)
                 .node(REL_LEAFREF_LEAF);
@@ -131,7 +130,7 @@ public class DerefXPathFunctionTest {
         derefResult = derefFunction.call(normalizedNodeContext, ImmutableList.of());
         assertNotNull(derefResult);
         assertTrue(derefResult instanceof LeafNode<?>);
-        assertLeafEquals(referencedLeafNode, (LeafNode<?>) derefResult);
+        assertEquals(referencedLeafNode, derefResult);
     }
 
     @Test
@@ -273,12 +272,4 @@ public class DerefXPathFunctionTest {
                 .withChild(myInnerContainerNode).build();
         return myContainerNode;
     }
-
-    private static void assertLeafEquals(final LeafNode<?> expected, final LeafNode<?> actual) {
-        if (LazyLeafOperations.isEnabled()) {
-            assertEquals(expected, actual);
-        } else {
-            assertSame(expected, actual);
-        }
-    }
 }