Do not implement concepts.Builder
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / FrontendClientMetadataBuilder.java
index 7e6eced779bdf4026dca36134b2b13e7509f1bbb..e43d736e7263e727594b031d235e144bd50e2f60 100644 (file)
@@ -14,10 +14,6 @@ import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableRangeSet;
-import com.google.common.collect.RangeSet;
-import com.google.common.primitives.UnsignedLong;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import org.eclipse.jdt.annotation.NonNull;
 import java.util.HashMap;
 import java.util.Map;
 import org.eclipse.jdt.annotation.NonNull;
@@ -26,8 +22,8 @@ import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifie
 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
 import org.opendaylight.controller.cluster.datastore.persisted.FrontendClientMetadata;
 import org.opendaylight.controller.cluster.datastore.persisted.FrontendHistoryMetadata;
 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
 import org.opendaylight.controller.cluster.datastore.persisted.FrontendClientMetadata;
 import org.opendaylight.controller.cluster.datastore.persisted.FrontendHistoryMetadata;
-import org.opendaylight.controller.cluster.datastore.utils.UnsignedLongRangeSet;
-import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.controller.cluster.datastore.utils.ImmutableUnsignedLongSet;
+import org.opendaylight.controller.cluster.datastore.utils.MutableUnsignedLongSet;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,16 +31,16 @@ import org.slf4j.LoggerFactory;
 /**
  * This class is NOT thread-safe.
  */
 /**
  * This class is NOT thread-safe.
  */
-abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMetadata>,
-        Identifiable<ClientIdentifier> {
+// FIXME: sealed when we have JDK17+
+abstract class FrontendClientMetadataBuilder implements Identifiable<ClientIdentifier> {
     static final class Disabled extends FrontendClientMetadataBuilder {
         Disabled(final String shardName, final ClientIdentifier identifier) {
             super(shardName, identifier);
         }
 
         @Override
     static final class Disabled extends FrontendClientMetadataBuilder {
         Disabled(final String shardName, final ClientIdentifier identifier) {
             super(shardName, identifier);
         }
 
         @Override
-        public FrontendClientMetadata build() {
-            return new FrontendClientMetadata(getIdentifier(), ImmutableRangeSet.of(), ImmutableList.of());
+        FrontendClientMetadata build() {
+            return new FrontendClientMetadata(getIdentifier(), ImmutableUnsignedLongSet.of(), ImmutableList.of());
         }
 
         @Override
         }
 
         @Override
@@ -77,6 +73,11 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
             // No-op
         }
 
             // No-op
         }
 
+        @Override
+        void onTransactionsSkipped(final LocalHistoryIdentifier historyId, final ImmutableUnsignedLongSet txIds) {
+            // No-op
+        }
+
         @Override
         LeaderFrontendState toLeaderState(final Shard shard) {
             return new LeaderFrontendState.Disabled(shard.persistenceId(), getIdentifier(), shard.getDataStore());
         @Override
         LeaderFrontendState toLeaderState(final Shard shard) {
             return new LeaderFrontendState.Disabled(shard.persistenceId(), getIdentifier(), shard.getDataStore());
@@ -84,15 +85,14 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
     }
 
     static final class Enabled extends FrontendClientMetadataBuilder {
     }
 
     static final class Enabled extends FrontendClientMetadataBuilder {
-
         private final Map<LocalHistoryIdentifier, FrontendHistoryMetadataBuilder> currentHistories = new HashMap<>();
         private final Map<LocalHistoryIdentifier, FrontendHistoryMetadataBuilder> currentHistories = new HashMap<>();
-        private final UnsignedLongRangeSet purgedHistories;
+        private final MutableUnsignedLongSet purgedHistories;
         private final LocalHistoryIdentifier standaloneId;
 
         Enabled(final String shardName, final ClientIdentifier identifier) {
             super(shardName, identifier);
 
         private final LocalHistoryIdentifier standaloneId;
 
         Enabled(final String shardName, final ClientIdentifier identifier) {
             super(shardName, identifier);
 
-            purgedHistories = UnsignedLongRangeSet.create();
+            purgedHistories = MutableUnsignedLongSet.of();
 
             // History for stand-alone transactions is always present
             standaloneId = standaloneHistoryId();
 
             // History for stand-alone transactions is always present
             standaloneId = standaloneHistoryId();
@@ -102,7 +102,7 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
         Enabled(final String shardName, final FrontendClientMetadata meta) {
             super(shardName, meta.getIdentifier());
 
         Enabled(final String shardName, final FrontendClientMetadata meta) {
             super(shardName, meta.getIdentifier());
 
-            purgedHistories = UnsignedLongRangeSet.create(meta.getPurgedHistories());
+            purgedHistories = meta.getPurgedHistories().mutableCopy();
             for (FrontendHistoryMetadata h : meta.getCurrentHistories()) {
                 final FrontendHistoryMetadataBuilder b = new FrontendHistoryMetadataBuilder(getIdentifier(), h);
                 currentHistories.put(b.getIdentifier(), b);
             for (FrontendHistoryMetadata h : meta.getCurrentHistories()) {
                 final FrontendHistoryMetadataBuilder b = new FrontendHistoryMetadataBuilder(getIdentifier(), h);
                 currentHistories.put(b.getIdentifier(), b);
@@ -118,8 +118,8 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
         }
 
         @Override
         }
 
         @Override
-        public FrontendClientMetadata build() {
-            return new FrontendClientMetadata(getIdentifier(), purgedHistories.toImmutable(),
+        FrontendClientMetadata build() {
+            return new FrontendClientMetadata(getIdentifier(), purgedHistories.immutableCopy(),
                 Collections2.transform(currentHistories.values(), FrontendHistoryMetadataBuilder::build));
         }
 
                 Collections2.transform(currentHistories.values(), FrontendHistoryMetadataBuilder::build));
         }
 
@@ -196,6 +196,17 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
             }
         }
 
             }
         }
 
+        @Override
+        void onTransactionsSkipped(final LocalHistoryIdentifier historyId, final ImmutableUnsignedLongSet txIds) {
+            final FrontendHistoryMetadataBuilder history = getHistory(historyId);
+            if (history != null) {
+                history.onTransactionsSkipped(txIds);
+                LOG.debug("{}: History {} skipped transactions {}", shardName(), historyId, txIds);
+            } else {
+                LOG.warn("{}: Unknown history {} for skipped transactions, ignoring", shardName(), historyId);
+            }
+        }
+
         @Override
         LeaderFrontendState toLeaderState(final Shard shard) {
             // Note: we have to make sure to *copy* all current state and not leak any views, otherwise leader/follower
         @Override
         LeaderFrontendState toLeaderState(final Shard shard) {
             // Note: we have to make sure to *copy* all current state and not leak any views, otherwise leader/follower
@@ -220,7 +231,7 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
             }
 
             return new LeaderFrontendState.Enabled(shard.persistenceId(), getIdentifier(), shard.getDataStore(),
             }
 
             return new LeaderFrontendState.Enabled(shard.persistenceId(), getIdentifier(), shard.getDataStore(),
-                purgedHistories.copy(), singleHistory, histories);
+                purgedHistories.mutableCopy(), singleHistory, histories);
         }
 
         @Override
         }
 
         @Override
@@ -229,15 +240,21 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
         }
 
         private FrontendHistoryMetadataBuilder getHistory(final TransactionIdentifier txId) {
         }
 
         private FrontendHistoryMetadataBuilder getHistory(final TransactionIdentifier txId) {
-            LocalHistoryIdentifier historyId = txId.getHistoryId();
+            return getHistory(txId.getHistoryId());
+        }
+
+        private FrontendHistoryMetadataBuilder getHistory(final LocalHistoryIdentifier historyId) {
+            final LocalHistoryIdentifier local;
             if (historyId.getHistoryId() == 0 && historyId.getCookie() != 0) {
                 // We are pre-creating the history for free-standing transactions with a zero cookie, hence our lookup
                 // needs to account for that.
                 LOG.debug("{}: looking up {} instead of {}", shardName(), standaloneId, historyId);
             if (historyId.getHistoryId() == 0 && historyId.getCookie() != 0) {
                 // We are pre-creating the history for free-standing transactions with a zero cookie, hence our lookup
                 // needs to account for that.
                 LOG.debug("{}: looking up {} instead of {}", shardName(), standaloneId, historyId);
-                historyId = standaloneId;
+                local = standaloneId;
+            } else {
+                local = historyId;
             }
 
             }
 
-            return currentHistories.get(historyId);
+            return currentHistories.get(local);
         }
 
         private LocalHistoryIdentifier standaloneHistoryId() {
         }
 
         private LocalHistoryIdentifier standaloneHistoryId() {
@@ -247,8 +264,8 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
 
     private static final Logger LOG = LoggerFactory.getLogger(FrontendClientMetadataBuilder.class);
 
 
     private static final Logger LOG = LoggerFactory.getLogger(FrontendClientMetadataBuilder.class);
 
-    private final ClientIdentifier identifier;
-    private final String shardName;
+    private final @NonNull ClientIdentifier identifier;
+    private final @NonNull String shardName;
 
     FrontendClientMetadataBuilder(final String shardName, final ClientIdentifier identifier) {
         this.shardName = requireNonNull(shardName);
 
     FrontendClientMetadataBuilder(final String shardName, final ClientIdentifier identifier) {
         this.shardName = requireNonNull(shardName);
@@ -256,13 +273,10 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
     }
 
     static FrontendClientMetadataBuilder of(final String shardName, final FrontendClientMetadata meta) {
     }
 
     static FrontendClientMetadataBuilder of(final String shardName, final FrontendClientMetadata meta) {
-        final Collection<FrontendHistoryMetadata> current = meta.getCurrentHistories();
-        final RangeSet<UnsignedLong> purged = meta.getPurgedHistories();
-
         // Completely empty histories imply disabled state, as otherwise we'd have a record of the single history --
         // either purged or active
         // Completely empty histories imply disabled state, as otherwise we'd have a record of the single history --
         // either purged or active
-        return current.isEmpty() && purged.isEmpty() ? new Disabled(shardName, meta.getIdentifier())
-                : new Enabled(shardName, meta);
+        return meta.getCurrentHistories().isEmpty() && meta.getPurgedHistories().isEmpty()
+            ? new Disabled(shardName, meta.getIdentifier()) : new Enabled(shardName, meta);
     }
 
     @Override
     }
 
     @Override
@@ -274,6 +288,8 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
         return shardName;
     }
 
         return shardName;
     }
 
+    abstract FrontendClientMetadata build();
+
     abstract void onHistoryCreated(LocalHistoryIdentifier historyId);
 
     abstract void onHistoryClosed(LocalHistoryIdentifier historyId);
     abstract void onHistoryCreated(LocalHistoryIdentifier historyId);
 
     abstract void onHistoryClosed(LocalHistoryIdentifier historyId);
@@ -286,6 +302,8 @@ abstract class FrontendClientMetadataBuilder implements Builder<FrontendClientMe
 
     abstract void onTransactionPurged(TransactionIdentifier txId);
 
 
     abstract void onTransactionPurged(TransactionIdentifier txId);
 
+    abstract void onTransactionsSkipped(LocalHistoryIdentifier historyId, ImmutableUnsignedLongSet txIds);
+
     /**
      * Transform frontend metadata for a particular client into its {@link LeaderFrontendState} counterpart.
      *
     /**
      * Transform frontend metadata for a particular client into its {@link LeaderFrontendState} counterpart.
      *