Testing has revealed the datastore instantiates effectively a version
per tree node. This turns out to be not needed, as we really just need a
single version per commit -- which can be shared between nodes, as the
(node,version) tuple remains unique.
So let's just instantiate a single version when we start the
transaction, which we need to do anyway, and use it for all
nodes/subtrees added or modified. This places an upper bound on Version
objects retained to the number of transactions committed (not counting
no-ops).
Change-Id: I40d095ec230eee8b5af2409c1e8ee61a1860a9d3
Signed-off-by: Robert Varga <rovarga@cisco.com>
final class AlwaysFailOperation implements ModificationApplyOperation {
@Override
public Optional<TreeNode> apply(final ModifiedNode modification,
final class AlwaysFailOperation implements ModificationApplyOperation {
@Override
public Optional<TreeNode> apply(final ModifiedNode modification,
- final Optional<TreeNode> storeMeta, final Version subtreeVersion) {
+ final Optional<TreeNode> storeMeta, final Version version) {
throw new IllegalStateException("Schema Context is not available.");
}
throw new IllegalStateException("Schema Context is not available.");
}
* @param storeMeta
* Store Metadata Node on which NodeModification should be
* applied
* @param storeMeta
* Store Metadata Node on which NodeModification should be
* applied
- * @param subtreeVersion New subtree version of parent node
+ * @param version New subtree version of parent node
* @throws IllegalArgumentException
* If it is not possible to apply Operation on provided Metadata
* node
* @throws IllegalArgumentException
* If it is not possible to apply Operation on provided Metadata
* node
* node, {@link Optional#absent()} if {@link ModifiedNode}
* resulted in deletion of this node.
*/
* node, {@link Optional#absent()} if {@link ModifiedNode}
* resulted in deletion of this node.
*/
- Optional<TreeNode> apply(ModifiedNode modification, Optional<TreeNode> storeMeta, Version subtreeVersion);
+ Optional<TreeNode> apply(ModifiedNode modification, Optional<TreeNode> storeMeta, Version version);
@Override
protected TreeNode applyWrite(final ModifiedNode modification,
@Override
protected TreeNode applyWrite(final ModifiedNode modification,
- final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
- final Version nodeVersion;
- if (currentMeta.isPresent()) {
- nodeVersion = currentMeta.get().getVersion().next();
- } else {
- nodeVersion = subtreeVersion;
- }
-
+ final Optional<TreeNode> currentMeta, final Version version) {
final NormalizedNode<?, ?> newValue = modification.getWrittenValue();
final NormalizedNode<?, ?> newValue = modification.getWrittenValue();
- final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, nodeVersion);
+ final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, version);
if (Iterables.isEmpty(modification.getChildren())) {
return newValueMeta;
if (Iterables.isEmpty(modification.getChildren())) {
return newValueMeta;
* and run the common parts on it -- which end with the node being sealed.
*/
final MutableTreeNode mutable = newValueMeta.mutable();
* and run the common parts on it -- which end with the node being sealed.
*/
final MutableTreeNode mutable = newValueMeta.mutable();
- mutable.setSubtreeVersion(subtreeVersion);
+ mutable.setSubtreeVersion(version);
@SuppressWarnings("rawtypes")
final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue);
@SuppressWarnings("rawtypes")
final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue);
- return mutateChildren(mutable, dataBuilder, nodeVersion, modification.getChildren());
+ return mutateChildren(mutable, dataBuilder, version, modification.getChildren());
}
@SuppressWarnings({ "rawtypes", "unchecked" })
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
@Override
protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
- final Version subtreeVersion) {
+ final Version version) {
// For Node Containers - merge is same as subtree change - we only replace children.
// For Node Containers - merge is same as subtree change - we only replace children.
- return applySubtreeChange(modification, currentMeta, subtreeVersion);
+ return applySubtreeChange(modification, currentMeta, version);
}
@Override
public TreeNode applySubtreeChange(final ModifiedNode modification,
}
@Override
public TreeNode applySubtreeChange(final ModifiedNode modification,
- final TreeNode currentMeta, final Version subtreeVersion) {
- // Bump subtree version to its new target
- final Version updatedSubtreeVersion = currentMeta.getSubtreeVersion().next();
-
+ final TreeNode currentMeta, final Version version) {
final MutableTreeNode newMeta = currentMeta.mutable();
final MutableTreeNode newMeta = currentMeta.mutable();
- newMeta.setSubtreeVersion(updatedSubtreeVersion);
+ newMeta.setSubtreeVersion(version);
@SuppressWarnings("rawtypes")
NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData());
@SuppressWarnings("rawtypes")
NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData());
- return mutateChildren(newMeta, dataBuilder, updatedSubtreeVersion, modification.getChildren());
+ return mutateChildren(newMeta, dataBuilder, version, modification.getChildren());
- public Optional<TreeNode> apply(final Optional<TreeNode> data, final Version subtreeVersion) {
- return applyOperation.apply(modification, data, subtreeVersion);
+ public Optional<TreeNode> apply(final Optional<TreeNode> data, final Version version) {
+ return applyOperation.apply(modification, data, version);
}
public static OperationWithModification from(final ModificationApplyOperation operation,
}
public static OperationWithModification from(final ModificationApplyOperation operation,
@Override
public final Optional<TreeNode> apply(final ModifiedNode modification,
@Override
public final Optional<TreeNode> apply(final ModifiedNode modification,
- final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
+ final Optional<TreeNode> currentMeta, final Version version) {
switch (modification.getType()) {
case DELETE:
switch (modification.getType()) {
case DELETE:
Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification",
modification);
return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(),
Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification",
modification);
return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(),
case MERGE:
if(currentMeta.isPresent()) {
case MERGE:
if(currentMeta.isPresent()) {
- return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(),subtreeVersion)));
+ return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(), version)));
} // Fallback to write is intentional - if node is not preexisting merge is same as write
case WRITE:
} // Fallback to write is intentional - if node is not preexisting merge is same as write
case WRITE:
- return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion)));
+ return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, version)));
case UNMODIFIED:
return currentMeta;
default:
case UNMODIFIED:
return currentMeta;
default:
}
protected abstract TreeNode applyMerge(ModifiedNode modification,
}
protected abstract TreeNode applyMerge(ModifiedNode modification,
- TreeNode currentMeta, Version subtreeVersion);
+ TreeNode currentMeta, Version version);
protected abstract TreeNode applyWrite(ModifiedNode modification,
protected abstract TreeNode applyWrite(ModifiedNode modification,
- Optional<TreeNode> currentMeta, Version subtreeVersion);
+ Optional<TreeNode> currentMeta, Version version);
protected abstract TreeNode applySubtreeChange(ModifiedNode modification,
protected abstract TreeNode applySubtreeChange(ModifiedNode modification,
- TreeNode currentMeta, Version subtreeVersion);
+ TreeNode currentMeta, Version version);
protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification,
final Optional<TreeNode> current) throws DataPreconditionFailedException;
protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification,
final Optional<TreeNode> current) throws DataPreconditionFailedException;
@Override
protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
@Override
protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
- final Version subtreeVersion) {
- return applyWrite(modification, Optional.of(currentMeta), subtreeVersion);
+ final Version version) {
+ return applyWrite(modification, Optional.of(currentMeta), version);
}
@Override
protected TreeNode applySubtreeChange(final ModifiedNode modification,
}
@Override
protected TreeNode applySubtreeChange(final ModifiedNode modification,
- final TreeNode currentMeta, final Version subtreeVersion) {
+ final TreeNode currentMeta, final Version version) {
throw new UnsupportedOperationException("UnkeyedList does not support subtree change.");
}
@Override
protected TreeNode applyWrite(final ModifiedNode modification,
throw new UnsupportedOperationException("UnkeyedList does not support subtree change.");
}
@Override
protected TreeNode applyWrite(final ModifiedNode modification,
- final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
- return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion);
+ final Optional<TreeNode> currentMeta, final Version version) {
+ return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version);
@Override
protected TreeNode applySubtreeChange(final ModifiedNode modification,
@Override
protected TreeNode applySubtreeChange(final ModifiedNode modification,
- final TreeNode currentMeta, final Version subtreeVersion) {
+ final TreeNode currentMeta, final Version version) {
throw new UnsupportedOperationException("Node " + schema.getPath()
+ "is leaf type node. Subtree change is not allowed.");
}
@Override
protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
throw new UnsupportedOperationException("Node " + schema.getPath()
+ "is leaf type node. Subtree change is not allowed.");
}
@Override
protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
- final Version subtreeVersion) {
+ final Version version) {
// Just overwrite whatever was there
// Just overwrite whatever was there
- return applyWrite(modification, null, subtreeVersion);
+ return applyWrite(modification, null, version);
}
@Override
protected TreeNode applyWrite(final ModifiedNode modification,
}
@Override
protected TreeNode applyWrite(final ModifiedNode modification,
- final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
- return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion);
+ final Optional<TreeNode> currentMeta, final Version version) {
+ return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version);