From: Robert Varga Date: Wed, 22 Apr 2020 11:32:23 +0000 (+0200) Subject: Add NormalizedNodeContainer.size() X-Git-Tag: v3.0.11~3 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;a=commitdiff_plain;h=32100003da80d9afe1b73f3a6e701205b80298dc Add NormalizedNodeContainer.size() While the size of children is available through getValue(), it is not completely efficient, as it may be forcing instantiation of a Map.values() view. Add NormalizedNodeContainer.size() to provide a more efficient way of accessing this property. This has immediate benefits on both MinMaxElementsValidation as well as general InMemoryDataTree transaction performance. JIRA: YANGTOOLS-1101 Change-Id: I607c2872645850400e4f242152059958729666b2 Signed-off-by: Robert Varga (cherry picked from commit 9fc5fe4197ae53e7e07ca79421fb3dec72c6d0d9) --- diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/NormalizedNodeContainer.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/NormalizedNodeContainer.java index df81ece420..536b158830 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/NormalizedNodeContainer.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/NormalizedNodeContainer.java @@ -12,23 +12,19 @@ import java.util.Optional; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; /** - * Node which is not leaf, but has child {@link NormalizedNode}s as its valzue. + * Node which is not leaf, but has child {@link NormalizedNode}s as its value. * *

- * NormalizedNodeContainer does not have a value, but it has a child - * nodes. Definition of possible and valid child nodes is introduced - * in subclasses of this interface. + * NormalizedNodeContainer does not have a value, but it has a child nodes. Definition of possible and valid child nodes + * is introduced in subclasses of this interface. * *

- * This interface should not be used directly, but rather use of of derived subinterfaces - * such as {@link DataContainerNode}, {@link MapNode}, {@link LeafSetNode}. + * This interface should not be used directly, but rather use of of derived subclasses such as + * {@link DataContainerNode}, {@link MapNode}, {@link LeafSetNode}. * - * @param - * Node Identifier type - * @param - * Child Node Identifier type - * @param - * Child Node type + * @param Node Identifier type + * @param Child Node Identifier type + * @param Child Node type */ public interface NormalizedNodeContainer> extends NormalizedNode> { @@ -38,18 +34,29 @@ public interface NormalizedNodeContainer getValue(); + /** + * Return the logical size of this container, i.e. the number of children in contains. + * + *

+ * Default implementation defers to the collection returned by {@link #getValue()}. Implementations are strongly + * encouraged to provide a more efficient implementation of this method. + * + * @return Number of child nodes in this container. + */ + // FIXME: 6.0.0: consider making this method non-default + default int size() { + return getValue().size(); + } + /** * Returns child node identified by provided key. * - * @param child - * Path argument identifying child node - * @return Optional with child node if child exists. - * {@link Optional#empty()} if child does not exists. + * @param child Path argument identifying child node + * @return Optional with child node if child exists. {@link Optional#empty()} if child does not exist. */ Optional getChild(K child); } diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/spi/AbstractMutableContainerNode.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/spi/AbstractMutableContainerNode.java index 3106e369c8..22b2488c9f 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/spi/AbstractMutableContainerNode.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/spi/AbstractMutableContainerNode.java @@ -81,10 +81,11 @@ abstract class AbstractMutableContainerNode implements MutableTreeNode { */ if (!version.equals(subtreeVersion)) { final Map newChildren = MapAdaptor.getDefaultInstance().optimize(children); - final int dataSize = getData().getValue().size(); - if (dataSize != newChildren.size()) { - verify(dataSize > newChildren.size(), "Detected %s modified children, data has only %s", - newChildren.size(), dataSize); + final int dataSize = getData().size(); + final int childrenSize = newChildren.size(); + if (dataSize != childrenSize) { + verify(dataSize > childrenSize, "Detected %s modified children, data has only %s", + childrenSize, dataSize); ret = new LazyContainerNode(data, version, newChildren, subtreeVersion); } else { ret = new MaterializedContainerNode(data, version, newChildren, subtreeVersion); diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/spi/LazyContainerNode.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/spi/LazyContainerNode.java index c576df55ac..666b8d3372 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/spi/LazyContainerNode.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/spi/LazyContainerNode.java @@ -32,7 +32,7 @@ final class LazyContainerNode extends AbstractModifiedContainerNode { @Override public MutableTreeNode mutable() { final Map snapshot = snapshotChildren(); - if (snapshot.size() == castData().getValue().size()) { + if (snapshot.size() == castData().size()) { return new MaterializedMutableContainerNode(this, snapshot); } diff --git a/yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug890Test.java b/yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug890Test.java index 6afd5d6933..d97c185f7c 100644 --- a/yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug890Test.java +++ b/yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug890Test.java @@ -84,7 +84,7 @@ public class Bug890Test { assertTrue(outgoingLabelsList.orElse(null) instanceof MapNode); MapNode outgoingLabelsMap = (MapNode) outgoingLabelsList.get(); - assertEquals(2, outgoingLabelsMap.getValue().size()); + assertEquals(2, outgoingLabelsMap.size()); Collection labels = outgoingLabelsMap.getValue(); NodeIdentifierWithPredicates firstNodeId = NodeIdentifierWithPredicates.of(OUTGOING_LABELS_QNAME, INDEX_QNAME, 0); diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java index 46d8361897..0edc0b9f25 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java @@ -119,6 +119,11 @@ public class ImmutableLeafSetNodeBuilder implements ListNodeBuilder removeChild( final PathArgument key) { @@ -130,6 +129,11 @@ public class ImmutableMapNodeBuilder implements CollectionNodeBuilder return children.values(); } + @Override + public final int size() { + return children.size(); + } + @Override protected int valueHashCode() { return children.hashCode(); diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MinMaxElementsValidation.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MinMaxElementsValidation.java index 6c2ad21a71..d1a390b7c2 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MinMaxElementsValidation.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MinMaxElementsValidation.java @@ -150,7 +150,7 @@ final class MinMaxElementsValidation value) { if (value instanceof NormalizedNodeContainer) { - return ((NormalizedNodeContainer) value).getValue().size(); + return ((NormalizedNodeContainer) value).size(); } else if (value instanceof UnkeyedListNode) { return ((UnkeyedListNode) value).getSize(); } diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/BuilderTest.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/BuilderTest.java index 98e683aa50..f24a45c3f3 100644 --- a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/BuilderTest.java +++ b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/BuilderTest.java @@ -131,7 +131,7 @@ public class BuilderTest { assertEquals(orderedMapNodeCreateNode.getSize(), orderedMapNodeCreateNull.getSize() - 1); assertEquals(NODE_IDENTIFIER_LIST, orderedMapNodeCreateSize.getIdentifier()); assertEquals(LIST_MAIN_CHILD_1, orderedMapNodeCreateNull.getChild(0)); - assertEquals(SIZE, orderedMapNodeCreateNull.getValue().size()); + assertEquals(SIZE, orderedMapNodeCreateNull.size()); assertEquals(orderedMapNodeSchemaAware.getChild(0), orderedMapNodeSchemaAwareMapNodeConst.getChild(0)); } diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug2690Test.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug2690Test.java index d22a68fca5..579fa2ea18 100644 --- a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug2690Test.java +++ b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug2690Test.java @@ -65,7 +65,7 @@ public class Bug2690Test extends AbstractTestModelTest { final DataTreeModification modificationAfterTx = snapshotAfterTx.newModification(); final Optional> readNode = modificationAfterTx.readNode(TestModel.OUTER_LIST_PATH); assertTrue(readNode.isPresent()); - assertEquals(2, ((NormalizedNodeContainer)readNode.get()).getValue().size()); + assertEquals(2, ((NormalizedNodeContainer)readNode.get()).size()); } @Test diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug4454Test.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug4454Test.java index e33347e08c..9d05210203 100644 --- a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug4454Test.java +++ b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug4454Test.java @@ -230,7 +230,7 @@ public class Bug4454Test { DataTreeSnapshot test2 = inMemoryDataTree.takeSnapshot(); minMaxListRead = test2.readNode(MIN_MAX_LIST_PATH); assertTrue(minMaxListRead.isPresent()); - assertTrue(((NormalizedNodeContainer) minMaxListRead.get()).getValue().size() == 3); + assertEquals(3, ((NormalizedNodeContainer) minMaxListRead.get()).size()); DataTreeModification tempMod2 = test2.newModification(); tempMod2.write(MIN_MAX_LIST_PATH, mapNodeBaz); @@ -244,7 +244,7 @@ public class Bug4454Test { DataTreeSnapshot test3 = inMemoryDataTree.takeSnapshot(); minMaxListRead = test3.readNode(MIN_MAX_LIST_PATH); assertTrue(minMaxListRead.isPresent()); - assertTrue(((NormalizedNodeContainer) minMaxListRead.get()).getValue().size() == 1); + assertEquals(1, ((NormalizedNodeContainer) minMaxListRead.get()).size()); assertTrue(minMaxListRead.get().getValue().toString().contains("test2")); DataTreeModification tempMod3 = test3.newModification(); @@ -303,7 +303,7 @@ public class Bug4454Test { final Optional> leafList = ((NormalizedNodeContainer) masterContainer.get()) .getChild(new NodeIdentifier(MIN_MAX_LEAF_LIST_QNAME)); assertTrue(leafList.isPresent()); - assertTrue(leafList.get().getValue().size() == 3); + assertEquals(3, leafList.get().size()); } @Test @@ -346,7 +346,7 @@ public class Bug4454Test { final NormalizedNode data = inMemoryDataTree.takeSnapshot() .readNode(YangInstanceIdentifier.empty()).get(); assertTrue(data instanceof ContainerNode); - assertEquals(0, ((ContainerNode) data).getValue().size()); + assertEquals(0, ((ContainerNode) data).size()); } @Test @@ -434,7 +434,7 @@ public class Bug4454Test { private static void testLoop(final DataTreeSnapshot snapshot, final String first, final String second) { Optional> minMaxListRead = snapshot.readNode(MIN_MAX_LIST_PATH); assertTrue(minMaxListRead.isPresent()); - assertTrue(((NormalizedNodeContainer) minMaxListRead.get()).getValue().size() == 2); + assertEquals(2, ((NormalizedNodeContainer) minMaxListRead.get()).size()); UnmodifiableCollection collectionChildren = (UnmodifiableCollection) minMaxListRead.get().getValue(); for (Object collectionChild : collectionChildren) { diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ListConstraintsValidation.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ListConstraintsValidation.java index abe4acb82f..42fef9cb99 100644 --- a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ListConstraintsValidation.java +++ b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ListConstraintsValidation.java @@ -120,7 +120,7 @@ public class ListConstraintsValidation { final DataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot(); final Optional> minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_PATH); assertTrue(minMaxListRead.isPresent()); - assertTrue(((NormalizedNodeContainer) minMaxListRead.get()).getValue().size() == 2); + assertEquals(2, ((NormalizedNodeContainer) minMaxListRead.get()).size()); } @Test(expected = DataValidationFailedException.class) @@ -151,7 +151,7 @@ public class ListConstraintsValidation { DataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot(); Optional> minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_PATH); assertTrue(minMaxListRead.isPresent()); - assertTrue(((NormalizedNodeContainer) minMaxListRead.get()).getValue().size() == 2); + assertEquals(2, ((NormalizedNodeContainer) minMaxListRead.get()).size()); modificationTree = inMemoryDataTree.takeSnapshot().newModification(); modificationTree.write(gooPath, gooEntryNode); @@ -164,7 +164,7 @@ public class ListConstraintsValidation { snapshotAfterCommit = inMemoryDataTree.takeSnapshot(); minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_PATH); assertTrue(minMaxListRead.isPresent()); - assertTrue(((NormalizedNodeContainer) minMaxListRead.get()).getValue().size() == 3); + assertEquals(3, ((NormalizedNodeContainer) minMaxListRead.get()).size()); modificationTree = inMemoryDataTree.takeSnapshot().newModification(); @@ -209,7 +209,7 @@ public class ListConstraintsValidation { final Optional> leafList = ((NormalizedNodeContainer) masterContainer.get()) .getChild(new NodeIdentifier(MIN_MAX_LEAF_LIST_QNAME)); assertTrue(leafList.isPresent()); - assertTrue(leafList.get().getValue().size() == 2); + assertEquals(2, leafList.get().size()); } @Test