Remove Augmentation{Identifier,Node}
[yangtools.git] / data / yang-data-tree-ri / src / main / java / org / opendaylight / yangtools / yang / data / tree / impl / DataNodeContainerModificationStrategy.java
index e99e64af6d57ab2fbf39955d6c1c79cefd3c8602..ac653baf234db34ad7b93b502cdb05e80a5e648b 100644 (file)
@@ -10,19 +10,14 @@ package org.opendaylight.yangtools.yang.data.tree.impl;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import java.util.Optional;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
 import org.opendaylight.yangtools.yang.data.tree.impl.AbstractNodeContainerModificationStrategy.Visible;
-import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,13 +30,20 @@ import org.slf4j.LoggerFactory;
  */
 class DataNodeContainerModificationStrategy<T extends DataNodeContainer & WithStatus> extends Visible<T> {
     private static final Logger LOG = LoggerFactory.getLogger(DataNodeContainerModificationStrategy.class);
+    private static final VarHandle CHILDREN;
+
+    static {
+        try {
+            CHILDREN = MethodHandles.lookup().findVarHandle(
+                DataNodeContainerModificationStrategy.class, "children", ImmutableMap.class);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
 
     private final @NonNull DataTreeConfiguration treeConfig;
 
-    @SuppressWarnings("rawtypes")
-    private static final AtomicReferenceFieldUpdater<DataNodeContainerModificationStrategy, ImmutableMap> UPDATER =
-            AtomicReferenceFieldUpdater.newUpdater(DataNodeContainerModificationStrategy.class, ImmutableMap.class,
-                "children");
+    @SuppressWarnings("unused")
     private volatile ImmutableMap<PathArgument, ModificationApplyOperation> children = ImmutableMap.of();
 
     DataNodeContainerModificationStrategy(final NormalizedNodeContainerSupport<?, ?> support, final T schema,
@@ -52,33 +54,28 @@ class DataNodeContainerModificationStrategy<T extends DataNodeContainer & WithSt
 
     @Override
     public final ModificationApplyOperation childByArg(final PathArgument arg) {
-        final ImmutableMap<PathArgument, ModificationApplyOperation> local = children;
-        final ModificationApplyOperation existing = local.get(arg);
+        final var local = (ImmutableMap<PathArgument, ModificationApplyOperation>) CHILDREN.getAcquire(this);
+        final var existing = local.get(arg);
         if (existing != null) {
             return existing;
         }
 
-        final ModificationApplyOperation childOperation = resolveChild(arg);
+        final var childOperation = resolveChild(arg);
         return childOperation != null ? appendChild(local, arg, childOperation) : null;
     }
 
     private ModificationApplyOperation resolveChild(final PathArgument identifier) {
         final T schema = getSchema();
-        if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) {
-            return SchemaAwareApplyOperation.from(schema, (AugmentationTarget) schema,
-                (AugmentationIdentifier) identifier, treeConfig);
-        }
-
-        final QName qname = identifier.getNodeType();
-        final Optional<DataSchemaNode> child = schema.findDataChildByName(qname);
-        if (!child.isPresent()) {
+        final var qname = identifier.getNodeType();
+        final var child = schema.dataChildByName(qname);
+        if (child == null) {
             LOG.trace("Child {} not present in container schema {} children {}", identifier, this,
                 schema.getChildNodes());
             return null;
         }
 
         try {
-            return SchemaAwareApplyOperation.from(child.get(), treeConfig);
+            return SchemaAwareApplyOperation.from(child, treeConfig);
         } catch (ExcludedDataSchemaNodeException e) {
             LOG.trace("Failed to instantiate child {} in container schema {} children {}", identifier, this,
                 schema.getChildNodes(), e);
@@ -89,24 +86,25 @@ class DataNodeContainerModificationStrategy<T extends DataNodeContainer & WithSt
     private @Nullable ModificationApplyOperation appendChild(
             final ImmutableMap<PathArgument, ModificationApplyOperation> initial, final PathArgument identifier,
             final ModificationApplyOperation computed) {
-
-        ImmutableMap<PathArgument, ModificationApplyOperation> previous = initial;
+        var previous = initial;
         while (true) {
             // Build up a new map based on observed snapshot and computed child
-            final Builder<PathArgument, ModificationApplyOperation> builder = ImmutableMap.builderWithExpectedSize(
-                previous.size() + 1);
-            builder.putAll(previous);
-            builder.put(identifier, computed);
-            final ImmutableMap<PathArgument, ModificationApplyOperation> updated = builder.build();
+            final var updated = ImmutableMap
+                .<PathArgument, ModificationApplyOperation>builderWithExpectedSize(previous.size() + 1)
+                .putAll(previous)
+                .put(identifier, computed)
+                .build();
 
             // Attempt to install the updated map
-            if (UPDATER.compareAndSet(this, previous, updated)) {
+            final var witness = (ImmutableMap<PathArgument, ModificationApplyOperation>)
+                CHILDREN.compareAndExchangeRelease(this, previous, updated);
+            if (witness == previous) {
                 return computed;
             }
 
             // We have raced, acquire a new snapshot, recheck presence and retry if needed
-            previous = children;
-            final ModificationApplyOperation raced = previous.get(identifier);
+            previous = witness;
+            final var raced = previous.get(identifier);
             if (raced != null) {
                 return raced;
             }