This is an automated email from the ASF dual-hosted git repository.
aleksey pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-accord.git
The following commit(s) were added to refs/heads/trunk by this push:
new 289d5ea5 Implement missing virtual tables for Accord debugging
289d5ea5 is described below
commit 289d5ea544f29842122b06eea93ad41c51cc642c
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]