From 73262077092195b800edbeb89f0eeb80006d621b Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 20 May 2015 21:44:29 +0200 Subject: [PATCH] Speed up getModifiedChild() As it turns out, the original implementation transformed all children before performing a lookup. Methods involved in that conversion can be easily applied to transform a single child, so address the FIXME by first performing a lookup and then running transformation, if appropriate. Change-Id: I11a87a69ce3e8552926017c51db7d4899af74a2a Signed-off-by: Robert Varga --- .../tree/AbstractDataTreeCandidateNode.java | 39 +++++++++++++++++-- ...bstractModifiedNodeBasedCandidateNode.java | 27 ++++++++----- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractDataTreeCandidateNode.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractDataTreeCandidateNode.java index 64930c7e12..4d67080a98 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractDataTreeCandidateNode.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractDataTreeCandidateNode.java @@ -22,25 +22,56 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode; abstract class AbstractDataTreeCandidateNode implements DataTreeCandidateNode { - private static final Function, DataTreeCandidateNode> TO_DELETED_NODES = new Function, DataTreeCandidateNode>() { + private static final Function, DataTreeCandidateNode> TO_DELETED_NODE = new Function, DataTreeCandidateNode>() { @Override public DataTreeCandidateNode apply(final NormalizedNode input) { return AbstractRecursiveCandidateNode.deleteNode(input); } - }; private static final Function, DataTreeCandidateNode> TO_WRITTEN_NODES = new Function, DataTreeCandidateNode>() { + }; + private static final Function, DataTreeCandidateNode> TO_WRITTEN_NODE = new Function, DataTreeCandidateNode>() { @Override public DataTreeCandidateNode apply(final NormalizedNode input) { return AbstractRecursiveCandidateNode.writeNode(input); } }; + private static Optional> getChild(final NormalizedNodeContainer> container, final PathArgument identifier) { + if (container != null) { + return container.getChild(identifier); + } else { + return Optional.absent(); + } + } + + static DataTreeCandidateNode deltaChild( + final NormalizedNodeContainer> oldData, + final NormalizedNodeContainer> newData, final PathArgument identifier) { + + final Optional> maybeNewChild = getChild(newData, identifier); + final Optional> maybeOldChild = getChild(oldData, identifier); + if (maybeOldChild.isPresent()) { + final NormalizedNode oldChild = maybeOldChild.get(); + if (maybeNewChild.isPresent()) { + return AbstractRecursiveCandidateNode.replaceNode(oldChild, maybeNewChild.get()); + } else { + return TO_DELETED_NODE.apply(oldChild); + } + } else { + if (maybeNewChild.isPresent()) { + return TO_WRITTEN_NODE.apply(maybeNewChild.get()); + } else { + return null; + } + } + } + static Collection deltaChildren(@Nullable final NormalizedNodeContainer> oldData, @Nullable final NormalizedNodeContainer> newData) { if (newData == null) { - return Collections2.transform(oldData.getValue(), TO_DELETED_NODES); + return Collections2.transform(oldData.getValue(), TO_DELETED_NODE); } if (oldData == null) { - return Collections2.transform(newData.getValue(), TO_WRITTEN_NODES); + return Collections2.transform(newData.getValue(), TO_WRITTEN_NODE); } // Create index for fast cross-references diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java index 76b3131b6b..25fb2df240 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java @@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode; abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandidateNode { - private static final Function, DataTreeCandidateNode> TO_UNMODIFIED_NODES = new Function, DataTreeCandidateNode>() { + private static final Function, DataTreeCandidateNode> TO_UNMODIFIED_NODE = new Function, DataTreeCandidateNode>() { @Override public DataTreeCandidateNode apply(final NormalizedNode input) { return AbstractRecursiveCandidateNode.unmodifiedNode(input); @@ -95,7 +95,7 @@ abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandida // Unmodified node, but we still need to resolve potential children. canHaveChildren returns // false if both arguments are null. if (canHaveChildren(oldMeta, newMeta)) { - return Collections2.transform(getContainer(newMeta != null ? newMeta : oldMeta).getValue(), TO_UNMODIFIED_NODES); + return Collections2.transform(getContainer(newMeta != null ? newMeta : oldMeta).getValue(), TO_UNMODIFIED_NODE); } else { return Collections.emptyList(); } @@ -145,17 +145,24 @@ abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandida return childNode(childMod.get()); } return null; - case DELETE: case UNMODIFIED: - case WRITE: - // FIXME: this is a linear walk. We need a Map of these in order to - // do something like getChildMap().get(identifier); - for (DataTreeCandidateNode c : getChildNodes()) { - if (identifier.equals(c.getIdentifier())) { - return c; + if (canHaveChildren(oldMeta, newMeta)) { + final Optional> maybeChild = getContainer(newMeta != null ? newMeta : oldMeta).getChild(identifier); + if (maybeChild.isPresent()) { + return TO_UNMODIFIED_NODE.apply(maybeChild.get()); + } else { + return null; } + } else { + return null; + } + case DELETE: + case WRITE: + if (canHaveChildren(oldMeta, newMeta)) { + return AbstractDataTreeCandidateNode.deltaChild(getContainer(oldMeta), getContainer(newMeta), identifier); + } else { + return null; } - return null; default: throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType()); } -- 2.36.6