--- /dev/null
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema.tree;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Iterator;
+
+abstract class AbstractReadyIterator {
+ final Iterator<ModifiedNode> children;
+ final ModifiedNode node;
+
+ private AbstractReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children) {
+ this.children = Preconditions.checkNotNull(children);
+ this.node = Preconditions.checkNotNull(node);
+ }
+
+ static AbstractReadyIterator create(final ModifiedNode root) {
+ return new RootReadyIterator(root, root.getChildren().iterator());
+ }
+
+ final AbstractReadyIterator process() {
+ // Walk all child nodes and remove any children which have not
+ // been modified. If a child
+ while (children.hasNext()) {
+ final ModifiedNode child = children.next();
+ final Collection<ModifiedNode> grandChildren = child.getChildren();
+ if (grandChildren.isEmpty()) {
+ child.seal();
+ if (child.getOperation() == LogicalOperation.NONE) {
+ children.remove();
+ }
+ } else {
+ return new NestedReadyIterator(this, child, grandChildren.iterator());
+ }
+ }
+
+ node.seal();
+
+ // Remove from parent if we have one and this is a no-op
+ if (node.getOperation() == LogicalOperation.NONE) {
+ removeFromParent();
+ }
+ return getParent();
+ }
+
+ abstract AbstractReadyIterator getParent();
+ abstract void removeFromParent();
+
+ private static final class NestedReadyIterator extends AbstractReadyIterator {
+ private final AbstractReadyIterator parent;
+
+ private NestedReadyIterator(final AbstractReadyIterator parent, final ModifiedNode node, final Iterator<ModifiedNode> children) {
+ super(node, children);
+ this.parent = Preconditions.checkNotNull(parent);
+ }
+
+ @Override
+ AbstractReadyIterator getParent() {
+ return parent;
+ }
+
+ @Override
+ void removeFromParent() {
+ parent.children.remove();
+ }
+ }
+
+ private static final class RootReadyIterator extends AbstractReadyIterator {
+ private RootReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children) {
+ super(node, children);
+ }
+
+ @Override
+ AbstractReadyIterator getParent() {
+ return null;
+ }
+
+ @Override
+ void removeFromParent() {
+ // No-op, since root node cannot be removed
+ }
+ }
+
+}
\ No newline at end of file
ModifiedNode modification = rootNode;
int i = 1;
- for(PathArgument pathArg : path.getPathArguments()) {
+ for (PathArgument pathArg : path.getPathArguments()) {
Optional<ModificationApplyOperation> potential = operation.getChild(pathArg);
if (!potential.isPresent()) {
throw new IllegalArgumentException(String.format("Child %s is not present in schema tree.",
return OperationWithModification.from(operation, modification);
}
- @Override
- public void ready() {
- final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
- Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
-
- rootNode.seal();
- }
-
private void checkSealed() {
Preconditions.checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
}
applyNode(cursor, child);
}
}
+
+ @Override
+ public void ready() {
+ final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
+ Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
+
+ AbstractReadyIterator current = AbstractReadyIterator.create(rootNode);
+ do {
+ current = current.process();
+ } while (current != null);
+ }
+
}
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.annotation.Nonnull;
}
/**
- * Seal the modification node and prune any children which has not been
- * modified.
+ * Seal the modification node.
*/
void seal() {
clearSnapshot();
- // Walk all child nodes and remove any children which have not
- // been modified.
- final Iterator<ModifiedNode> it = children.values().iterator();
- while (it.hasNext()) {
- final ModifiedNode child = it.next();
- child.seal();
-
- if (child.operation == LogicalOperation.NONE) {
- it.remove();
- }
- }
-
// A TOUCH node without any children is a no-op
if (operation == LogicalOperation.TOUCH && children.isEmpty()) {
updateOperationType(LogicalOperation.NONE);