This is an automated email from the ASF dual-hosted git repository.

ifesdjeen pushed a commit to branch CASSANDRA-20112
in repository https://gitbox.apache.org/repos/asf/cassandra-accord.git

commit 155a67ec810060e48abfe2eefcc8785cd293763b
Author: Alex Petrov <[email protected]>
AuthorDate: Wed Nov 20 18:05:25 2024 +0100

    Nit: make checkstyle happy
    
    Add repro for the sorted array issue
    
    Randomize cache loading on per-item basis
    
    Add comment on fast path tracking
---
 .../java/accord/coordinate/ExecuteSyncPoint.java   |  3 +-
 .../main/java/accord/coordinate/PersistTxn.java    |  1 -
 .../java/accord/coordinate/RecoverWithRoute.java   |  7 +--
 .../coordinate/tracking/FastPathTracker.java       |  2 +-
 .../java/accord/impl/InMemoryCommandStore.java     |  2 +-
 .../main/java/accord/messages/BeginRecovery.java   | 11 ++--
 .../java/accord/primitives/AbstractRanges.java     | 14 ++---
 accord-core/src/test/java/accord/KeysTest.java     |  3 +-
 .../src/test/java/accord/impl/basic/Cluster.java   | 41 ++++++++++---
 .../accord/impl/basic/DelayedCommandStores.java    | 69 +++++++++++++++++++---
 .../src/test/java/accord/impl/basic/Journal.java   |  9 +--
 .../java/accord/topology/TopologyRandomizer.java   |  1 -
 .../test/java/accord/utils/SortedArraysTest.java   | 45 ++++++++------
 13 files changed, 142 insertions(+), 66 deletions(-)

diff --git a/accord-core/src/main/java/accord/coordinate/ExecuteSyncPoint.java 
b/accord-core/src/main/java/accord/coordinate/ExecuteSyncPoint.java
index 38cb8bd8..dc010351 100644
--- a/accord-core/src/main/java/accord/coordinate/ExecuteSyncPoint.java
+++ b/accord-core/src/main/java/accord/coordinate/ExecuteSyncPoint.java
@@ -18,16 +18,15 @@
 
 package accord.coordinate;
 
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.Function;
 
 import accord.api.Result;
 import accord.coordinate.CoordinationAdapter.Adapters;
-import accord.coordinate.tracking.SimpleTracker;
 import accord.coordinate.tracking.QuorumTracker;
 import accord.coordinate.tracking.RequestStatus;
+import accord.coordinate.tracking.SimpleTracker;
 import accord.local.Node;
 import accord.messages.ApplyThenWaitUntilApplied;
 import accord.messages.Callback;
diff --git a/accord-core/src/main/java/accord/coordinate/PersistTxn.java 
b/accord-core/src/main/java/accord/coordinate/PersistTxn.java
index c9139f01..797e8363 100644
--- a/accord-core/src/main/java/accord/coordinate/PersistTxn.java
+++ b/accord-core/src/main/java/accord/coordinate/PersistTxn.java
@@ -22,7 +22,6 @@ import accord.api.Result;
 import accord.local.Node;
 import accord.primitives.Deps;
 import accord.primitives.FullRoute;
-import accord.primitives.Participants;
 import accord.primitives.Route;
 import accord.primitives.Timestamp;
 import accord.primitives.Txn;
diff --git a/accord-core/src/main/java/accord/coordinate/RecoverWithRoute.java 
b/accord-core/src/main/java/accord/coordinate/RecoverWithRoute.java
index 25733111..f969a7e1 100644
--- a/accord-core/src/main/java/accord/coordinate/RecoverWithRoute.java
+++ b/accord-core/src/main/java/accord/coordinate/RecoverWithRoute.java
@@ -23,8 +23,6 @@ import javax.annotation.Nullable;
 
 import accord.local.Node;
 import accord.local.Node.Id;
-import accord.primitives.Status;
-import accord.primitives.Known;
 import accord.messages.CheckStatus;
 import accord.messages.CheckStatus.CheckStatusOk;
 import accord.messages.CheckStatus.CheckStatusOkFull;
@@ -33,16 +31,16 @@ import accord.messages.Propagate;
 import accord.primitives.Ballot;
 import accord.primitives.Deps;
 import accord.primitives.FullRoute;
-import accord.primitives.Participants;
+import accord.primitives.Known;
 import accord.primitives.Ranges;
 import accord.primitives.Route;
+import accord.primitives.Status;
 import accord.primitives.Txn;
 import accord.primitives.TxnId;
 import accord.topology.Topologies;
 import accord.utils.Invariants;
 
 import static 
accord.coordinate.CoordinationAdapter.Factory.Step.InitiateRecovery;
-import static accord.primitives.Status.Durability.Majority;
 import static accord.primitives.Known.KnownDeps.DepsKnown;
 import static accord.primitives.Known.KnownExecuteAt.ExecuteAtKnown;
 import static accord.primitives.Known.Outcome.Apply;
@@ -50,6 +48,7 @@ import static accord.primitives.ProgressToken.APPLIED;
 import static accord.primitives.ProgressToken.INVALIDATED;
 import static accord.primitives.ProgressToken.TRUNCATED_DURABLE_OR_INVALIDATED;
 import static accord.primitives.Route.castToFullRoute;
+import static accord.primitives.Status.Durability.Majority;
 import static accord.utils.Invariants.illegalState;
 
 public class RecoverWithRoute extends CheckShards<FullRoute<?>>
diff --git 
a/accord-core/src/main/java/accord/coordinate/tracking/FastPathTracker.java 
b/accord-core/src/main/java/accord/coordinate/tracking/FastPathTracker.java
index 81e9d118..271b1395 100644
--- a/accord-core/src/main/java/accord/coordinate/tracking/FastPathTracker.java
+++ b/accord-core/src/main/java/accord/coordinate/tracking/FastPathTracker.java
@@ -162,7 +162,7 @@ public class FastPathTracker extends 
PreAcceptTracker<FastPathTracker.FastPathSh
 
             ++successes;
             if (shard.fastPathElectorate.contains(node))
-                ++fastPathFailures;
+                ++fastPathFailures; // Quorum success can not count towards 
fast path success
 
             return quorumIfHasRejectedFastPath();
         }
diff --git a/accord-core/src/main/java/accord/impl/InMemoryCommandStore.java 
b/accord-core/src/main/java/accord/impl/InMemoryCommandStore.java
index 3ebe7e78..04ea28f4 100644
--- a/accord-core/src/main/java/accord/impl/InMemoryCommandStore.java
+++ b/accord-core/src/main/java/accord/impl/InMemoryCommandStore.java
@@ -666,7 +666,7 @@ public abstract class InMemoryCommandStore extends 
CommandStore
         }
     }
 
-    protected class InMemoryCommandStoreCaches extends 
AbstractSafeCommandStore.CommandStoreCaches<InMemorySafeCommand, 
InMemorySafeTimestampsForKey, InMemorySafeCommandsForKey>
+    public class InMemoryCommandStoreCaches extends 
AbstractSafeCommandStore.CommandStoreCaches<InMemorySafeCommand, 
InMemorySafeTimestampsForKey, InMemorySafeCommandsForKey>
     {
         @Override
         public void close() {}
diff --git a/accord-core/src/main/java/accord/messages/BeginRecovery.java 
b/accord-core/src/main/java/accord/messages/BeginRecovery.java
index 0ad80f66..4a925a83 100644
--- a/accord-core/src/main/java/accord/messages/BeginRecovery.java
+++ b/accord-core/src/main/java/accord/messages/BeginRecovery.java
@@ -41,19 +41,18 @@ import accord.topology.Topologies;
 import accord.utils.Invariants;
 import accord.utils.async.Cancellable;
 
-import static accord.local.SafeCommandStore.TestDep.WITH_OR_INVALIDATED;
 import static accord.local.SafeCommandStore.TestDep.WITHOUT;
+import static accord.local.SafeCommandStore.TestDep.WITH_OR_INVALIDATED;
 import static accord.local.SafeCommandStore.TestStartedAt.ANY;
-import static accord.local.SafeCommandStore.TestStatus.IS_STABLE;
-import static accord.local.SafeCommandStore.TestStatus.IS_PROPOSED;
 import static accord.local.SafeCommandStore.TestStartedAt.STARTED_AFTER;
 import static accord.local.SafeCommandStore.TestStartedAt.STARTED_BEFORE;
-import static 
accord.local.SafeCommandStore.TestStatus.IS_STABLE_OR_INVALIDATED;
+import static accord.local.SafeCommandStore.TestStatus.IS_PROPOSED;
+import static accord.local.SafeCommandStore.TestStatus.IS_STABLE;
+import static accord.messages.PreAccept.calculateDeps;
+import static accord.primitives.EpochSupplier.constant;
 import static accord.primitives.Status.Accepted;
 import static accord.primitives.Status.Phase;
 import static accord.primitives.Status.PreAccepted;
-import static accord.messages.PreAccept.calculateDeps;
-import static accord.primitives.EpochSupplier.constant;
 import static accord.utils.Invariants.illegalState;
 
 public class BeginRecovery extends 
TxnRequest.WithUnsynced<BeginRecovery.RecoverReply>
diff --git a/accord-core/src/main/java/accord/primitives/AbstractRanges.java 
b/accord-core/src/main/java/accord/primitives/AbstractRanges.java
index bb85b1d2..4812fed0 100644
--- a/accord-core/src/main/java/accord/primitives/AbstractRanges.java
+++ b/accord-core/src/main/java/accord/primitives/AbstractRanges.java
@@ -18,6 +18,13 @@
 
 package accord.primitives;
 
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.function.Function;
+import javax.annotation.Nonnull;
+
+import com.google.common.collect.Iterators;
+
 import accord.api.RoutingKey;
 import accord.utils.ArrayBuffers.ObjectBuffers;
 import accord.utils.IndexedFoldToLong;
@@ -26,14 +33,7 @@ import accord.utils.Invariants;
 import accord.utils.SortedArrays;
 import net.nicoulaj.compilecommand.annotations.Inline;
 
-import com.google.common.collect.Iterators;
-
-import javax.annotation.Nonnull;
-import java.util.*;
-import java.util.function.Function;
-
 import static accord.primitives.Ranges.EMPTY;
-import static accord.primitives.Ranges.ofSortedAndDeoverlappedUnchecked;
 import static accord.utils.ArrayBuffers.cachedRanges;
 import static accord.utils.Invariants.illegalArgument;
 import static accord.utils.SortedArrays.Search.CEIL;
diff --git a/accord-core/src/test/java/accord/KeysTest.java 
b/accord-core/src/test/java/accord/KeysTest.java
index 67a329e3..3538e21a 100644
--- a/accord-core/src/test/java/accord/KeysTest.java
+++ b/accord-core/src/test/java/accord/KeysTest.java
@@ -32,10 +32,9 @@ import accord.api.RoutingKey;
 import accord.impl.IntKey;
 import accord.impl.IntKey.Raw;
 import accord.primitives.AbstractKeys;
+import accord.primitives.Keys;
 import accord.primitives.Range;
 import accord.primitives.Ranges;
-import accord.primitives.Keys;
-
 import accord.primitives.RoutableKey;
 import accord.primitives.Routables;
 import accord.primitives.RoutingKeys;
diff --git a/accord-core/src/test/java/accord/impl/basic/Cluster.java 
b/accord-core/src/test/java/accord/impl/basic/Cluster.java
index dacab032..d712dce3 100644
--- a/accord-core/src/test/java/accord/impl/basic/Cluster.java
+++ b/accord-core/src/test/java/accord/impl/basic/Cluster.java
@@ -66,10 +66,10 @@ import accord.coordinate.Invalidated;
 import accord.coordinate.Preempted;
 import accord.coordinate.Timeout;
 import accord.coordinate.Truncated;
-import accord.impl.DurabilityScheduling;
 import accord.impl.DefaultLocalListeners;
 import accord.impl.DefaultRemoteListeners;
 import accord.impl.DefaultTimeouts;
+import accord.impl.DurabilityScheduling;
 import accord.impl.InMemoryCommandStore.GlobalCommand;
 import accord.impl.MessageListener;
 import accord.impl.PrefixedIntHashKey;
@@ -86,13 +86,9 @@ import accord.local.DurableBefore;
 import accord.local.Node;
 import accord.local.Node.Id;
 import accord.local.RedundantBefore;
+import accord.local.ShardDistributor;
 import accord.local.StoreParticipants;
 import accord.local.TimeService;
-import accord.primitives.RoutableKey;
-import accord.primitives.SaveStatus;
-import accord.local.ShardDistributor;
-import accord.primitives.Seekables;
-import accord.primitives.Status;
 import accord.local.cfk.CommandsForKey;
 import accord.messages.Message;
 import accord.messages.MessageType;
@@ -103,6 +99,10 @@ import accord.primitives.FullRoute;
 import accord.primitives.Keys;
 import accord.primitives.Range;
 import accord.primitives.Ranges;
+import accord.primitives.RoutableKey;
+import accord.primitives.SaveStatus;
+import accord.primitives.Seekables;
+import accord.primitives.Status;
 import accord.primitives.Timestamp;
 import accord.primitives.Txn;
 import accord.primitives.TxnId;
@@ -124,7 +124,6 @@ import static accord.utils.AccordGens.keysInsideRanges;
 import static accord.utils.AccordGens.rangeInsideRange;
 import static accord.utils.Gens.mixedDistribution;
 import static java.util.Collections.emptyMap;
-import static java.util.Collections.min;
 import static java.util.Collections.singletonMap;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
@@ -439,7 +438,6 @@ public class Cluster
                                                                 @Override
                                                                 public Packet 
get()
                                                                 {
-                                                                    // 
((Cluster) node.scheduler()).onDone(() -> checkOnResult(homeKey, txnId, 0, 
null));
                                                                     if 
(requestIterator == null)
                                                                     {
                                                                         
Map<Node.Id, Node> nodes = nodeMap.get();
@@ -528,7 +526,32 @@ public class Cluster
                 Journal journal = new Journal(id);
                 journalMap.put(id, journal);
                 BurnTestConfigurationService configService = new 
BurnTestConfigurationService(id, nodeExecutor, randomSupplier, topology, 
nodeMap::get, topologyUpdates);
-                BooleanSupplier isLoadedCheck = 
Gens.supplier(Gens.bools().mixedDistribution().next(random), random);
+                DelayedCommandStores.CacheLoadingChance isLoadedCheck = new 
DelayedCommandStores.CacheLoadingChance()
+                {
+                    private final BooleanSupplier cacheEmptyChance = 
Gens.supplier(Gens.bools().mixedDistribution().next(random), random);
+                    public boolean cacheEmpty()
+                    {
+                        return cacheEmptyChance.getAsBoolean();
+                    }
+
+                    private final BooleanSupplier commandLoadedChance = 
random.biasedUniformBools(0.1f);
+                    public boolean commandLoaded()
+                    {
+                        return commandLoadedChance.getAsBoolean();
+                    }
+
+                    private final BooleanSupplier cfkLoadedChance = 
random.biasedUniformBools(0.1f);
+                    public boolean cfkLoaded()
+                    {
+                        return cfkLoadedChance.getAsBoolean();
+                    }
+
+                    private final BooleanSupplier tfkLoadedChance = 
random.biasedUniformBools(0.1f);
+                    public boolean tfkLoaded()
+                    {
+                        return tfkLoadedChance.getAsBoolean();
+                    }
+                };
                 Node node = new Node(id, messageSink, configService, 
TimeService.ofNonMonotonic(nowSupplier, MILLISECONDS),
                                      () -> new ListStore(scheduler, random, 
id), new ShardDistributor.EvenSplit<>(8, ignore -> new 
PrefixedIntHashKey.Splitter()),
                                      nodeExecutor.agent(),
diff --git 
a/accord-core/src/test/java/accord/impl/basic/DelayedCommandStores.java 
b/accord-core/src/test/java/accord/impl/basic/DelayedCommandStores.java
index 04ac085d..7a41fe72 100644
--- a/accord-core/src/test/java/accord/impl/basic/DelayedCommandStores.java
+++ b/accord-core/src/test/java/accord/impl/basic/DelayedCommandStores.java
@@ -26,7 +26,6 @@ import java.util.Objects;
 import java.util.Queue;
 import java.util.concurrent.Callable;
 import java.util.function.BiConsumer;
-import java.util.function.BooleanSupplier;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
@@ -36,6 +35,7 @@ import accord.api.Agent;
 import accord.api.DataStore;
 import accord.api.LocalListeners;
 import accord.api.ProgressLog;
+import accord.api.RoutingKey;
 import accord.impl.InMemoryCommandStore;
 import accord.impl.InMemoryCommandStores;
 import accord.impl.InMemorySafeCommand;
@@ -70,12 +70,12 @@ import static 
accord.utils.Invariants.ParanoiaCostFactor.HIGH;
 
 public class DelayedCommandStores extends InMemoryCommandStores.SingleThread
 {
-    private DelayedCommandStores(NodeCommandStoreService time, Agent agent, 
DataStore store, RandomSource random, ShardDistributor shardDistributor, 
ProgressLog.Factory progressLogFactory, LocalListeners.Factory 
listenersFactory, SimulatedDelayedExecutorService executorService, 
BooleanSupplier isLoadedCheck, Journal journal)
+    private DelayedCommandStores(NodeCommandStoreService time, Agent agent, 
DataStore store, RandomSource random, ShardDistributor shardDistributor, 
ProgressLog.Factory progressLogFactory, LocalListeners.Factory 
listenersFactory, SimulatedDelayedExecutorService executorService, 
CacheLoadingChance isLoadedCheck, Journal journal)
     {
         super(time, agent, store, random, shardDistributor, 
progressLogFactory, listenersFactory, 
DelayedCommandStore.factory(executorService, isLoadedCheck, journal));
     }
 
-    public static CommandStores.Factory factory(PendingQueue pending, 
BooleanSupplier isLoadedCheck, Journal journal)
+    public static CommandStores.Factory factory(PendingQueue pending, 
CacheLoadingChance isLoadedCheck, Journal journal)
     {
         return (time, agent, store, random, shardDistributor, 
progressLogFactory, listenersFactory) ->
                new DelayedCommandStores(time, agent, store, random, 
shardDistributor, progressLogFactory, listenersFactory, new 
SimulatedDelayedExecutorService(pending, agent), isLoadedCheck, journal);
@@ -131,10 +131,10 @@ public class DelayedCommandStores extends 
InMemoryCommandStores.SingleThread
 
         private final SimulatedDelayedExecutorService executor;
         private final Queue<Task<?>> pending = new LinkedList<>();
-        private final BooleanSupplier isLoadedCheck;
+        private final CacheLoadingChance isLoadedCheck;
         private final Journal journal;
 
-        public DelayedCommandStore(int id, NodeCommandStoreService time, Agent 
agent, DataStore store, ProgressLog.Factory progressLogFactory, 
LocalListeners.Factory listenersFactory, EpochUpdateHolder epochUpdateHolder, 
SimulatedDelayedExecutorService executor, BooleanSupplier isLoadedCheck, 
Journal journal)
+        public DelayedCommandStore(int id, NodeCommandStoreService time, Agent 
agent, DataStore store, ProgressLog.Factory progressLogFactory, 
LocalListeners.Factory listenersFactory, EpochUpdateHolder epochUpdateHolder, 
SimulatedDelayedExecutorService executor, CacheLoadingChance isLoadedCheck, 
Journal journal)
         {
             super(id, time, agent, store, progressLogFactory, 
listenersFactory, epochUpdateHolder);
             this.executor = executor;
@@ -161,10 +161,10 @@ public class DelayedCommandStores extends 
InMemoryCommandStores.SingleThread
         @Override
         protected boolean canExposeUnloaded()
         {
-            return isLoadedCheck.getAsBoolean();
+            return !isLoadedCheck.cacheEmpty();
         }
 
-        private static CommandStore.Factory 
factory(SimulatedDelayedExecutorService executor, BooleanSupplier 
isLoadedCheck, Journal journal)
+        private static CommandStore.Factory 
factory(SimulatedDelayedExecutorService executor, CacheLoadingChance 
isLoadedCheck, Journal journal)
         {
             return (id, node, agent, store, progressLogFactory, 
listenersFactory, rangesForEpoch) -> new DelayedCommandStore(id, node, agent, 
store, progressLogFactory, listenersFactory, rangesForEpoch, executor, 
isLoadedCheck, journal);
         }
@@ -247,7 +247,7 @@ public class DelayedCommandStores extends 
InMemoryCommandStores.SingleThread
         @Override
         protected InMemorySafeStore createSafeStore(PreLoadContext context, 
RangesForEpoch ranges, Map<TxnId, InMemorySafeCommand> commands, 
Map<RoutableKey, InMemorySafeTimestampsForKey> timestampsForKey, 
Map<RoutableKey, InMemorySafeCommandsForKey> commandsForKeys)
         {
-            return new DelayedSafeStore(this, ranges, context, commands, 
timestampsForKey, commandsForKeys);
+            return new DelayedSafeStore(this, ranges, context, commands, 
timestampsForKey, commandsForKeys, isLoadedCheck);
         }
 
         @Override
@@ -260,10 +260,18 @@ public class DelayedCommandStores extends 
InMemoryCommandStores.SingleThread
     public static class DelayedSafeStore extends 
InMemoryCommandStore.InMemorySafeStore
     {
         private final DelayedCommandStore commandStore;
-        public DelayedSafeStore(DelayedCommandStore commandStore, 
RangesForEpoch ranges, PreLoadContext context, Map<TxnId, InMemorySafeCommand> 
commands, Map<RoutableKey, InMemorySafeTimestampsForKey> timestampsForKey, 
Map<RoutableKey, InMemorySafeCommandsForKey> commandsForKey)
+        private final CacheLoadingChance cacheLoadingChance;
+        public DelayedSafeStore(DelayedCommandStore commandStore,
+                                RangesForEpoch ranges,
+                                PreLoadContext context,
+                                Map<TxnId, InMemorySafeCommand> commands,
+                                Map<RoutableKey, InMemorySafeTimestampsForKey> 
timestampsForKey,
+                                Map<RoutableKey, InMemorySafeCommandsForKey> 
commandsForKey,
+                                CacheLoadingChance cacheLoadingChance)
         {
             super(commandStore, ranges, context, commands, timestampsForKey, 
commandsForKey);
             this.commandStore = commandStore;
+            this.cacheLoadingChance = cacheLoadingChance;
         }
 
         @Override
@@ -280,6 +288,41 @@ public class DelayedCommandStores extends 
InMemoryCommandStores.SingleThread
             });
             super.postExecute();
         }
+
+        @Override
+        protected InMemoryCommandStore.InMemoryCommandStoreCaches 
tryGetCaches()
+        {
+            if (commandStore.canExposeUnloaded())
+            {
+                return commandStore.new InMemoryCommandStoreCaches() {
+                    @Override
+                    public InMemorySafeCommand acquireIfLoaded(TxnId txnId)
+                    {
+                        if (cacheLoadingChance.commandLoaded())
+                            return super.acquireIfLoaded(txnId);
+                        return null;
+                    }
+
+                    @Override
+                    public InMemorySafeTimestampsForKey 
acquireTfkIfLoaded(RoutingKey key)
+                    {
+                        if (cacheLoadingChance.tfkLoaded())
+                            return super.acquireTfkIfLoaded(key);
+                        return null;
+                    }
+
+                    @Override
+                    public InMemorySafeCommandsForKey 
acquireIfLoaded(RoutingKey key)
+                    {
+                        if (cacheLoadingChance.cfkLoaded())
+                            return super.acquireIfLoaded(key);
+                        return null;
+                    }
+                };
+            }
+            return null;
+
+        }
     }
 
     public List<DelayedCommandStore> unsafeStores()
@@ -289,4 +332,12 @@ public class DelayedCommandStores extends 
InMemoryCommandStores.SingleThread
             stores.add((DelayedCommandStore) holder.store);
         return stores;
     }
+
+    public interface CacheLoadingChance
+    {
+        boolean cacheEmpty();
+        boolean commandLoaded();
+        boolean cfkLoaded();
+        boolean tfkLoaded();
+    }
 }
diff --git a/accord-core/src/test/java/accord/impl/basic/Journal.java 
b/accord-core/src/test/java/accord/impl/basic/Journal.java
index f26f1116..ac75af76 100644
--- a/accord-core/src/test/java/accord/impl/basic/Journal.java
+++ b/accord-core/src/test/java/accord/impl/basic/Journal.java
@@ -20,9 +20,7 @@ package accord.impl.basic;
 
 import java.util.AbstractList;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -42,20 +40,19 @@ import accord.local.CommandStore;
 import accord.local.Commands;
 import accord.local.CommonAttributes;
 import accord.local.Node;
-import accord.primitives.Known;
-import accord.primitives.SaveStatus;
-import accord.primitives.Status;
 import accord.local.StoreParticipants;
 import accord.primitives.Ballot;
+import accord.primitives.Known;
 import accord.primitives.PartialDeps;
 import accord.primitives.PartialTxn;
+import accord.primitives.SaveStatus;
+import accord.primitives.Status;
 import accord.primitives.Timestamp;
 import accord.primitives.TxnId;
 import accord.primitives.Writes;
 import accord.utils.Invariants;
 import org.agrona.collections.Long2ObjectHashMap;
 
-import static accord.primitives.SaveStatus.Erased;
 import static accord.primitives.SaveStatus.NotDefined;
 import static accord.primitives.SaveStatus.Stable;
 import static accord.primitives.Status.Invalidated;
diff --git a/accord-core/src/test/java/accord/topology/TopologyRandomizer.java 
b/accord-core/src/test/java/accord/topology/TopologyRandomizer.java
index 71a1dc40..ab24cf72 100644
--- a/accord-core/src/test/java/accord/topology/TopologyRandomizer.java
+++ b/accord-core/src/test/java/accord/topology/TopologyRandomizer.java
@@ -20,7 +20,6 @@ package accord.topology;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
diff --git a/accord-core/src/test/java/accord/utils/SortedArraysTest.java 
b/accord-core/src/test/java/accord/utils/SortedArraysTest.java
index 98ce2f59..07f14e6a 100644
--- a/accord-core/src/test/java/accord/utils/SortedArraysTest.java
+++ b/accord-core/src/test/java/accord/utils/SortedArraysTest.java
@@ -237,24 +237,35 @@ class SortedArraysTest
     @Test
     public void testLinearSubtract()
     {
-        Gen<Integer[]> gen = sortedUniqueIntegerArray(0);
-        qt().forAll(gen, gen).check((a, b) -> {
-            Set<Integer> left = new HashSet<>(Arrays.asList(a));
-            Set<Integer> right = new HashSet<>(Arrays.asList(b));
+        int[][] quants = {{0, 1000, 0, 1000},
+                          {0, 100, 0, 1000},
+                          {0, 100, 0, 10},
+                          {0, 10, 0, 10},
+                          {0, 5, 0, 5},
+                          {0, 5, 0, 5}};
+
+        for (int[] quant : quants)
+        {
+            Gen<Integer[]> gen1 = sortedUniqueIntegerArray(quant[1], quant[0]);
+            Gen<Integer[]> gen2 = sortedUniqueIntegerArray(quant[3], quant[2]);
+            qt().forAll(gen1, gen2).withExamples(1000).check((a, b) -> {
+                Set<Integer> left = new HashSet<>(Arrays.asList(a));
+                Set<Integer> right = new HashSet<>(Arrays.asList(b));
 
-            {
-                Set<Integer> difference = Sets.difference(left, right);
-                Integer[] expected = toArray(difference, Integer[]::new);
-                Arrays.sort(expected);
-                assertArrayEquals(expected, SortedArrays.linearSubtract(a, b, 
uncached(Integer[]::new)));
-            }
-            {
-                Set<Integer> difference = Sets.difference(right, left);
-                Integer[] expected = toArray(difference, Integer[]::new);
-                Arrays.sort(expected);
-                assertArrayEquals(expected, SortedArrays.linearSubtract(b, a, 
uncached(Integer[]::new)));
-            }
-        });
+                {
+                    Set<Integer> difference = Sets.difference(left, right);
+                    Integer[] expected = toArray(difference, Integer[]::new);
+                    Arrays.sort(expected);
+                    assertArrayEquals(expected, SortedArrays.linearSubtract(a, 
b, uncached(Integer[]::new)));
+                }
+                {
+                    Set<Integer> difference = Sets.difference(right, left);
+                    Integer[] expected = toArray(difference, Integer[]::new);
+                    Arrays.sort(expected);
+                    assertArrayEquals(expected, SortedArrays.linearSubtract(b, 
a, uncached(Integer[]::new)));
+                }
+            });
+        }
     }
 
     @Test


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to