Index: src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java (revision 1488896) +++ src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java (working copy) @@ -371,8 +371,8 @@ return false; } } - - return this.base.compareAgainstBaseState(base, new NodeStateDiff() { + + NodeStateDiff d = new NodeStateDiff() { @Override public boolean propertyAdded(PropertyState after) { return properties.containsKey(after.getName()) @@ -404,7 +404,62 @@ return nodes.containsKey(name) || diff.childNodeDeleted(name, before); } - }); + }; + + if (base instanceof ModifiedNodeState && + !(this.base instanceof ModifiedNodeState)) { + return base.compareAgainstBaseState(this.base, new ReverseNodeStateDiff(d)); + } + + return this.base.compareAgainstBaseState(base, d); } + + /** + * A node state diff that reverses the result. It allows to write + * {@code a.compareAgainstBaseState(b, diff)} + * as + * {@code b.compareAgainstBaseState(a, new ReverseNodeStateDiff(diff))} + * , which might be more efficient depending on the implementation. + */ + static class ReverseNodeStateDiff implements NodeStateDiff { + + private final NodeStateDiff base; + + ReverseNodeStateDiff(NodeStateDiff base) { + this.base = base; + } + + @Override + public boolean propertyAdded(PropertyState after) { + return base.propertyDeleted(after); + } + + @Override + public boolean propertyChanged(PropertyState before, PropertyState after) { + return base.propertyChanged(after, before); + } + + @Override + public boolean propertyDeleted(PropertyState before) { + return base.propertyAdded(before); + } + + @Override + public boolean childNodeAdded(String name, NodeState after) { + return base.childNodeDeleted(name, after); + } + + @Override + public boolean childNodeChanged(String name, NodeState before, + NodeState after) { + return base.childNodeChanged(name, after, before); + } + + @Override + public boolean childNodeDeleted(String name, NodeState before) { + return base.childNodeAdded(name, before); + } + + } }