/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2015 Cisco Systems, Inc. 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,
*/
package org.opendaylight.yangtools.yang.data.api.schema.tree.spi;
-import com.google.common.base.Optional;
-
-import java.util.HashMap;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.collect.Collections2;
import java.util.Map;
-
+import java.util.Optional;
+import org.opendaylight.yangtools.util.MapAdaptor;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-final class LazyContainerNode extends ContainerNode {
- protected LazyContainerNode(final NormalizedNode<?, ?> data, final Version version) {
- super(data, version, version);
+/**
+ * Lazily-materialized container node. Any new/modified children are tracked in a map. This map is consulted before
+ * instantiating a child node from data node. Resulting node is not cached.
+ */
+final class LazyContainerNode extends AbstractModifiedContainerNode {
+ LazyContainerNode(final NormalizedNode<?, ?> data, final Version version, final Version subtreeVersion) {
+ this(data, version, MapAdaptor.getDefaultInstance().initialSnapshot(1), subtreeVersion);
}
- @Override
- public Optional<TreeNode> getChild(final PathArgument key) {
- // We do not cache the instantiated node as it is dirt cheap
- final Optional<NormalizedNode<?, ?>> child = castData().getChild(key);
- if (child.isPresent()) {
- return Optional.of(TreeNodeFactory.createTreeNode(child.get(), getVersion()));
- }
-
- return Optional.absent();
+ LazyContainerNode(final NormalizedNode<?, ?> data, final Version version,
+ final Map<PathArgument, TreeNode> children, final Version subtreeVersion) {
+ super(data, version, children, subtreeVersion);
}
@Override
public MutableTreeNode mutable() {
- /*
- * We are creating a mutable view of the data, which means that the version
- * is going to probably change -- and we need to make sure any unmodified
- * children retain it.
- *
- * The simplest thing to do is to just flush the amortized work and be done
- * with it.
- */
- final Map<PathArgument, TreeNode> children = new HashMap<>();
- for (NormalizedNode<?, ?> child : castData().getValue()) {
- PathArgument id = child.getIdentifier();
- children.put(id, TreeNodeFactory.createTreeNode(child, getVersion()));
+ final Map<PathArgument, TreeNode> snapshot = snapshotChildren();
+ if (snapshot.size() == castData().size()) {
+ return new MaterializedMutableContainerNode(this, snapshot);
}
+ return new LazyMutableContainerNode(this, snapshot);
+ }
- return new Mutable(this, children);
+ @Override
+ public Optional<TreeNode> getChild(final PathArgument childId) {
+ final TreeNode modified;
+ return (modified = getModifiedChild(childId)) == null ? getChildFromData(childId) : Optional.of(modified);
}
- @SuppressWarnings("unchecked")
- private final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> castData() {
- return (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) getData();
+ @Override
+ protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+ // Modified children add added by superclass. Here we filter the other children.
+ return super.addToStringAttributes(helper).add("untouched", Collections2.filter(castData().getValue(),
+ input -> getModifiedChild(input.getIdentifier()) == null));
}
}