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

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

commit 064735b3b2ca76c527ce79cbb97022f97c4647fe
Author: Aleksey Yeschenko <[email protected]>
AuthorDate: Mon Oct 28 14:56:06 2024 +0000

    Implement missing virtual tables for Accord debugging
    
    patch by Aleksey Yeschenko; reviewed by Benedict Elliott Smith for
    CASSANDRA-20062
---
 .../java/accord/impl/DurabilityScheduling.java     |  81 ++++++++++++++
 .../java/accord/impl/progresslog/BaseTxnState.java |   5 +
 .../accord/impl/progresslog/CoordinatePhase.java   |   2 +-
 .../impl/progresslog/DefaultProgressLog.java       | 121 +++++++++++++++++++++
 .../java/accord/impl/progresslog/Progress.java     |   2 +-
 .../java/accord/impl/progresslog/WaitingState.java |   5 +
 .../src/main/java/accord/local/CommandStore.java   |  11 ++
 .../src/main/java/accord/local/CommandStores.java  |  10 +-
 .../src/main/java/accord/local/MaxConflicts.java   |   3 +-
 9 files changed, 230 insertions(+), 10 deletions(-)

diff --git a/accord-core/src/main/java/accord/impl/DurabilityScheduling.java 
b/accord-core/src/main/java/accord/impl/DurabilityScheduling.java
index 41cd96f2..49e57cb1 100644
--- a/accord-core/src/main/java/accord/impl/DurabilityScheduling.java
+++ b/accord-core/src/main/java/accord/impl/DurabilityScheduling.java
@@ -21,8 +21,10 @@ package accord.impl;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.concurrent.TimeUnit;
 
 import com.google.common.primitives.Ints;
@@ -529,6 +531,85 @@ public class DurabilityScheduling implements 
ConfigurationService.Listener
         prev.forEach((r, s) -> s.markDefunct());
     }
 
+    public synchronized ImmutableView immutableView()
+    {
+        TreeMap<Range, ShardScheduler> schedulers = new 
TreeMap<>(Range::compare);
+        schedulers.putAll(shardSchedulers);
+        return new ImmutableView(schedulers);
+    }
+
+    public static class ImmutableView
+    {
+        private final TreeMap<Range, ShardScheduler> schedulers;
+
+        ImmutableView(TreeMap<Range, ShardScheduler> schedulers)
+        {
+            this.schedulers = schedulers;
+        }
+
+        private Iterator<Map.Entry<Range, ShardScheduler>> iterator = null;
+        private Range range = null;
+        private ShardScheduler scheduler = null;
+
+        public boolean advance()
+        {
+            if (iterator == null)
+                iterator = schedulers.entrySet().iterator();
+
+            if (!iterator.hasNext())
+            {
+                range = null;
+                scheduler = null;
+                return false;
+            }
+
+            Map.Entry<Range, ShardScheduler> next = iterator.next();
+            range = next.getKey();
+            scheduler = next.getValue();
+            return false;
+        }
+
+        public Range range()
+        {
+            return range;
+        }
+
+        public int nodeOffset()
+        {
+            return scheduler.nodeOffset;
+        }
+
+        public int index()
+        {
+            return scheduler.index;
+        }
+
+        public int numberOfSplits()
+        {
+            return scheduler.numberOfSplits;
+        }
+
+        public long rangeStartedAtMicros()
+        {
+            return scheduler.rangeStartedAtMicros;
+        }
+
+        public long cycleStartedAtMicros()
+        {
+            return scheduler.cycleStartedAtMicros;
+        }
+
+        public long retryDelayMicros()
+        {
+            return scheduler.retryDelayMicros;
+        }
+
+        public boolean isDefunct()
+        {
+            return scheduler.defunct;
+        }
+    }
+
     /**
      * Based on the current elapsed time (simulated or otherwise) calculate 
the wait time in microseconds until the next turn of this
      * node for some activity with a target gap between nodes doing the 
activity.
diff --git 
a/accord-core/src/main/java/accord/impl/progresslog/BaseTxnState.java 
b/accord-core/src/main/java/accord/impl/progresslog/BaseTxnState.java
index 26e3970b..2c20c6e6 100644
--- a/accord-core/src/main/java/accord/impl/progresslog/BaseTxnState.java
+++ b/accord-core/src/main/java/accord/impl/progresslog/BaseTxnState.java
@@ -161,6 +161,11 @@ abstract class BaseTxnState extends LogGroupTimers.Timer 
implements Comparable<B
         return pendingTimerDelay == 0 ? 0 : deadline() + pendingTimerDelay;
     }
 
+    long scheduledTimerDeadline()
+    {
+        return deadline();
+    }
+
     boolean isScheduled()
     {
         return isInHeap();
diff --git 
a/accord-core/src/main/java/accord/impl/progresslog/CoordinatePhase.java 
b/accord-core/src/main/java/accord/impl/progresslog/CoordinatePhase.java
index 3e63d31b..9e74eb82 100644
--- a/accord-core/src/main/java/accord/impl/progresslog/CoordinatePhase.java
+++ b/accord-core/src/main/java/accord/impl/progresslog/CoordinatePhase.java
@@ -19,7 +19,7 @@
 package accord.impl.progresslog;
 
 // the phase of the distributed state machine
-enum CoordinatePhase
+public enum CoordinatePhase
 {
     /**
      * This replica is not known to be a home shard of the transaction
diff --git 
a/accord-core/src/main/java/accord/impl/progresslog/DefaultProgressLog.java 
b/accord-core/src/main/java/accord/impl/progresslog/DefaultProgressLog.java
index 67df93d3..41c7c7e7 100644
--- a/accord-core/src/main/java/accord/impl/progresslog/DefaultProgressLog.java
+++ b/accord-core/src/main/java/accord/impl/progresslog/DefaultProgressLog.java
@@ -19,9 +19,11 @@
 package accord.impl.progresslog;
 
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.slf4j.Logger;
@@ -567,4 +569,123 @@ public class DefaultProgressLog implements ProgressLog, 
Runnable
                 commandStore.execute(this);
         }
     }
+
+    public ImmutableView immutableView()
+    {
+        return new ImmutableView(commandStore.id(), stateMap);
+    }
+
+    public static class ImmutableView
+    {
+        private final int storeId;
+        private final Object[] snapshot;
+
+        ImmutableView(int storeId, Object[] snapshot)
+        {
+            this.storeId = storeId;
+            this.snapshot = snapshot;
+        }
+
+        public boolean isEmpty()
+        {
+            return BTree.isEmpty(snapshot);
+        }
+
+        private Iterator<TxnState> iterator = null;
+        private TxnState current = null;
+
+        public boolean advance()
+        {
+            if (iterator == null)
+                iterator = BTree.iterator(snapshot);
+
+            if (!iterator.hasNext())
+            {
+                current = null;
+                return false;
+            }
+
+            current = iterator.next();
+            return true;
+        }
+
+        public int storeId()
+        {
+            return storeId;
+        }
+
+        @Nonnull
+        public TxnId txnId()
+        {
+            return current.txnId;
+        }
+
+        @Nullable
+        public Long timerScheduledAt(TxnStateKind kind)
+        {
+            // TODO (expected): global constant declaring granularity of these 
timer deadlines
+            if (current.scheduledTimer() == kind)
+                return current.scheduledTimerDeadline();
+            if (current.pendingTimer() == kind)
+                return current.pendingTimerDeadline();
+            return null;
+        }
+
+        public boolean contactEveryone()
+        {
+            return current.contactEveryone();
+        }
+
+        public boolean isWaitingUninitialised()
+        {
+            return current.isUninitialised();
+        }
+
+        @Nonnull
+        public BlockedUntil waitingIsBlockedUntil()
+        {
+            return current.blockedUntil();
+        }
+
+        @Nonnull
+        public BlockedUntil waitingHomeSatisfies()
+        {
+            return current.homeSatisfies();
+        }
+
+        @Nonnull
+        public Progress waitingProgress()
+        {
+            return current.waitingProgress();
+        }
+
+        @Nonnull
+        public long waitingPackedKeyTrackerBits()
+        {
+            return current.waitingKeyTrackerBits();
+        }
+
+        @Nonnull
+        public int waitingRetryCounter()
+        {
+            return current.waitingRetryCounter();
+        }
+
+        @Nonnull
+        public CoordinatePhase homePhase()
+        {
+            return current.phase();
+        }
+
+        @Nonnull
+        public Progress homeProgress()
+        {
+            return current.homeProgress();
+        }
+
+        public int homeRetryCounter()
+        {
+            return current.homeRetryCounter();
+        }
+    }
 }
diff --git a/accord-core/src/main/java/accord/impl/progresslog/Progress.java 
b/accord-core/src/main/java/accord/impl/progresslog/Progress.java
index 952edb8b..c6dee78b 100644
--- a/accord-core/src/main/java/accord/impl/progresslog/Progress.java
+++ b/accord-core/src/main/java/accord/impl/progresslog/Progress.java
@@ -18,7 +18,7 @@
 
 package accord.impl.progresslog;
 
-enum Progress
+public enum Progress
 {
     /**
      * We do not expect any progress for this state machine at present
diff --git 
a/accord-core/src/main/java/accord/impl/progresslog/WaitingState.java 
b/accord-core/src/main/java/accord/impl/progresslog/WaitingState.java
index 3a1117a1..87c90ae3 100644
--- a/accord-core/src/main/java/accord/impl/progresslog/WaitingState.java
+++ b/accord-core/src/main/java/accord/impl/progresslog/WaitingState.java
@@ -140,6 +140,11 @@ abstract class WaitingState extends BaseTxnState
         return waitingProgress(encodedState);
     }
 
+    final @Nonnull long waitingKeyTrackerBits()
+    {
+        return (encodedState >>> AWAIT_SHIFT) & (-1L >>> (64 - AWAIT_BITS));
+    }
+
     private static @Nonnull BlockedUntil blockedUntil(long encodedState)
     {
         return BlockedUntil.forOrdinal((int) ((encodedState >>> 
BLOCKED_UNTIL_SHIFT) & BLOCKED_UNTIL_MASK));
diff --git a/accord-core/src/main/java/accord/local/CommandStore.java 
b/accord-core/src/main/java/accord/local/CommandStore.java
index d6b42421..bcd175cb 100644
--- a/accord-core/src/main/java/accord/local/CommandStore.java
+++ b/accord-core/src/main/java/accord/local/CommandStore.java
@@ -667,11 +667,22 @@ public abstract class CommandStore implements 
AgentExecutor
         return rejectBefore.rejects(txnId, participants);
     }
 
+    public final MaxConflicts unsafeGetMaxConflicts()
+    {
+        return maxConflicts;
+    }
+
     public final RedundantBefore unsafeGetRedundantBefore()
     {
         return redundantBefore;
     }
 
+    @Nullable
+    public final RejectBefore unsafeGetRejectBefore()
+    {
+        return rejectBefore;
+    }
+
     public final DurableBefore durableBefore()
     {
         return node.durableBefore();
diff --git a/accord-core/src/main/java/accord/local/CommandStores.java 
b/accord-core/src/main/java/accord/local/CommandStores.java
index 10fbb098..9068f19c 100644
--- a/accord-core/src/main/java/accord/local/CommandStores.java
+++ b/accord-core/src/main/java/accord/local/CommandStores.java
@@ -751,12 +751,10 @@ public abstract class CommandStores
 
     public int[] ids()
     {
-        Snapshot snapshot = current;
-        Int2ObjectHashMap<CommandStore>.KeySet set = snapshot.byId.keySet();
-        int[] ids = new int[set.size()];
-        int idx = 0;
-        for (int a : set)
-            ids[idx++] = a;
+        ShardHolder[] shards = current.shards;
+        int[] ids = new int[shards.length];
+        for (int i = 0; i < ids.length; i++)
+            ids[i] = shards[i].store.id;
         Arrays.sort(ids);
         return ids;
     }
diff --git a/accord-core/src/main/java/accord/local/MaxConflicts.java 
b/accord-core/src/main/java/accord/local/MaxConflicts.java
index 1b04dbe0..727d8043 100644
--- a/accord-core/src/main/java/accord/local/MaxConflicts.java
+++ b/accord-core/src/main/java/accord/local/MaxConflicts.java
@@ -23,9 +23,8 @@ import accord.primitives.Timestamp;
 import accord.primitives.Unseekables;
 import accord.utils.BTreeReducingRangeMap;
 
-
 // TODO (expected): track read/write conflicts separately
-class MaxConflicts extends BTreeReducingRangeMap<Timestamp>
+public class MaxConflicts extends BTreeReducingRangeMap<Timestamp>
 {
     public static final MaxConflicts EMPTY = new MaxConflicts();
 


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

Reply via email to