Correct annotations
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / databroker / actors / dds / AbstractClientHandle.java
index 80fbf037647d7a3065765079cd31abc16063c4c4..90971b31cece3b7718e830b6a59014405d0d8a7b 100644 (file)
@@ -7,14 +7,15 @@
  */
 package org.opendaylight.controller.cluster.databroker.actors.dds;
 
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
 import java.util.Collection;
-import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import java.util.function.Function;
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
 import org.opendaylight.yangtools.concepts.Identifiable;
@@ -42,15 +43,15 @@ public abstract class AbstractClientHandle<T extends AbstractProxyTransaction> e
     private static final AtomicReferenceFieldUpdater<AbstractClientHandle, State> STATE_UPDATER =
             AtomicReferenceFieldUpdater.newUpdater(AbstractClientHandle.class, State.class, "state");
 
-    private final TransactionIdentifier transactionId;
-    private final AbstractClientHistory parent;
+    private final @NonNull TransactionIdentifier transactionId;
+    private final @NonNull AbstractClientHistory parent;
 
     private volatile State<T> state = new State<>();
 
     // Hidden to prevent outside instantiation
     AbstractClientHandle(final AbstractClientHistory parent, final TransactionIdentifier transactionId) {
-        this.transactionId = Preconditions.checkNotNull(transactionId);
-        this.parent = Preconditions.checkNotNull(parent);
+        this.transactionId = requireNonNull(transactionId);
+        this.parent = requireNonNull(parent);
     }
 
     @Override
@@ -96,25 +97,28 @@ public abstract class AbstractClientHandle<T extends AbstractProxyTransaction> e
      *         closed, too.
      */
     final @Nullable Collection<T> ensureClosed() {
-        @SuppressWarnings("unchecked")
-        final State<T> local = STATE_UPDATER.getAndSet(this, null);
-        return local == null ? null : local.values();
+        // volatile read and a conditional CAS. This ends up being better in the typical case when we are invoked more
+        // than once (see ClientBackedTransaction) than performing a STATE_UPDATER.getAndSet().
+        final State<T> local = state;
+        return local != null && STATE_UPDATER.compareAndSet(this, local, null) ? local.values() : null;
     }
 
-    final T ensureProxy(final YangInstanceIdentifier path, final Function<Long, T> createProxy) {
-        final Map<Long, T> local = getState();
+    final T ensureProxy(final YangInstanceIdentifier path) {
+        final State<T> local = getState();
         final Long shard = parent.resolveShardForPath(path);
 
-        return local.computeIfAbsent(shard, createProxy);
+        return local.computeIfAbsent(shard, this::createProxy);
     }
 
     final AbstractClientHistory parent() {
         return parent;
     }
 
+    abstract @NonNull T createProxy(@NonNull Long shard);
+
     private State<T> getState() {
         final State<T> local = state;
-        Preconditions.checkState(local != null, "Transaction %s is closed", transactionId);
+        checkState(local != null, "Transaction %s is closed", transactionId);
         return local;
     }