Skip to content

Commit 064735b

Browse files
iamalekseybelliottsmith
authored andcommitted
Implement missing virtual tables for Accord debugging
patch by Aleksey Yeschenko; reviewed by Benedict Elliott Smith for CASSANDRA-20062
1 parent 8bd9d69 commit 064735b

File tree

9 files changed

+230
-10
lines changed

9 files changed

+230
-10
lines changed

accord-core/src/main/java/accord/impl/DurabilityScheduling.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
import java.util.ArrayList;
2222
import java.util.Collections;
2323
import java.util.HashMap;
24+
import java.util.Iterator;
2425
import java.util.List;
2526
import java.util.Map;
27+
import java.util.TreeMap;
2628
import java.util.concurrent.TimeUnit;
2729

2830
import com.google.common.primitives.Ints;
@@ -529,6 +531,85 @@ private synchronized void updateTopology(Topology latestGlobal)
529531
prev.forEach((r, s) -> s.markDefunct());
530532
}
531533

534+
public synchronized ImmutableView immutableView()
535+
{
536+
TreeMap<Range, ShardScheduler> schedulers = new TreeMap<>(Range::compare);
537+
schedulers.putAll(shardSchedulers);
538+
return new ImmutableView(schedulers);
539+
}
540+
541+
public static class ImmutableView
542+
{
543+
private final TreeMap<Range, ShardScheduler> schedulers;
544+
545+
ImmutableView(TreeMap<Range, ShardScheduler> schedulers)
546+
{
547+
this.schedulers = schedulers;
548+
}
549+
550+
private Iterator<Map.Entry<Range, ShardScheduler>> iterator = null;
551+
private Range range = null;
552+
private ShardScheduler scheduler = null;
553+
554+
public boolean advance()
555+
{
556+
if (iterator == null)
557+
iterator = schedulers.entrySet().iterator();
558+
559+
if (!iterator.hasNext())
560+
{
561+
range = null;
562+
scheduler = null;
563+
return false;
564+
}
565+
566+
Map.Entry<Range, ShardScheduler> next = iterator.next();
567+
range = next.getKey();
568+
scheduler = next.getValue();
569+
return false;
570+
}
571+
572+
public Range range()
573+
{
574+
return range;
575+
}
576+
577+
public int nodeOffset()
578+
{
579+
return scheduler.nodeOffset;
580+
}
581+
582+
public int index()
583+
{
584+
return scheduler.index;
585+
}
586+
587+
public int numberOfSplits()
588+
{
589+
return scheduler.numberOfSplits;
590+
}
591+
592+
public long rangeStartedAtMicros()
593+
{
594+
return scheduler.rangeStartedAtMicros;
595+
}
596+
597+
public long cycleStartedAtMicros()
598+
{
599+
return scheduler.cycleStartedAtMicros;
600+
}
601+
602+
public long retryDelayMicros()
603+
{
604+
return scheduler.retryDelayMicros;
605+
}
606+
607+
public boolean isDefunct()
608+
{
609+
return scheduler.defunct;
610+
}
611+
}
612+
532613
/**
533614
* Based on the current elapsed time (simulated or otherwise) calculate the wait time in microseconds until the next turn of this
534615
* node for some activity with a target gap between nodes doing the activity.

accord-core/src/main/java/accord/impl/progresslog/BaseTxnState.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ long pendingTimerDeadline()
161161
return pendingTimerDelay == 0 ? 0 : deadline() + pendingTimerDelay;
162162
}
163163

164+
long scheduledTimerDeadline()
165+
{
166+
return deadline();
167+
}
168+
164169
boolean isScheduled()
165170
{
166171
return isInHeap();

accord-core/src/main/java/accord/impl/progresslog/CoordinatePhase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
package accord.impl.progresslog;
2020

2121
// the phase of the distributed state machine
22-
enum CoordinatePhase
22+
public enum CoordinatePhase
2323
{
2424
/**
2525
* This replica is not known to be a home shard of the transaction

accord-core/src/main/java/accord/impl/progresslog/DefaultProgressLog.java

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
package accord.impl.progresslog;
2020

2121
import java.util.Arrays;
22+
import java.util.Iterator;
2223
import java.util.Map;
2324
import java.util.concurrent.TimeUnit;
2425
import java.util.function.Consumer;
26+
import javax.annotation.Nonnull;
2527
import javax.annotation.Nullable;
2628

2729
import org.slf4j.Logger;
@@ -567,4 +569,123 @@ public void maybeNotify()
567569
commandStore.execute(this);
568570
}
569571
}
572+
573+
public ImmutableView immutableView()
574+
{
575+
return new ImmutableView(commandStore.id(), stateMap);
576+
}
577+
578+
public static class ImmutableView
579+
{
580+
private final int storeId;
581+
private final Object[] snapshot;
582+
583+
ImmutableView(int storeId, Object[] snapshot)
584+
{
585+
this.storeId = storeId;
586+
this.snapshot = snapshot;
587+
}
588+
589+
public boolean isEmpty()
590+
{
591+
return BTree.isEmpty(snapshot);
592+
}
593+
594+
private Iterator<TxnState> iterator = null;
595+
private TxnState current = null;
596+
597+
public boolean advance()
598+
{
599+
if (iterator == null)
600+
iterator = BTree.iterator(snapshot);
601+
602+
if (!iterator.hasNext())
603+
{
604+
current = null;
605+
return false;
606+
}
607+
608+
current = iterator.next();
609+
return true;
610+
}
611+
612+
public int storeId()
613+
{
614+
return storeId;
615+
}
616+
617+
@Nonnull
618+
public TxnId txnId()
619+
{
620+
return current.txnId;
621+
}
622+
623+
@Nullable
624+
public Long timerScheduledAt(TxnStateKind kind)
625+
{
626+
// TODO (expected): global constant declaring granularity of these timer deadlines
627+
if (current.scheduledTimer() == kind)
628+
return current.scheduledTimerDeadline();
629+
if (current.pendingTimer() == kind)
630+
return current.pendingTimerDeadline();
631+
return null;
632+
}
633+
634+
public boolean contactEveryone()
635+
{
636+
return current.contactEveryone();
637+
}
638+
639+
public boolean isWaitingUninitialised()
640+
{
641+
return current.isUninitialised();
642+
}
643+
644+
@Nonnull
645+
public BlockedUntil waitingIsBlockedUntil()
646+
{
647+
return current.blockedUntil();
648+
}
649+
650+
@Nonnull
651+
public BlockedUntil waitingHomeSatisfies()
652+
{
653+
return current.homeSatisfies();
654+
}
655+
656+
@Nonnull
657+
public Progress waitingProgress()
658+
{
659+
return current.waitingProgress();
660+
}
661+
662+
@Nonnull
663+
public long waitingPackedKeyTrackerBits()
664+
{
665+
return current.waitingKeyTrackerBits();
666+
}
667+
668+
@Nonnull
669+
public int waitingRetryCounter()
670+
{
671+
return current.waitingRetryCounter();
672+
}
673+
674+
@Nonnull
675+
public CoordinatePhase homePhase()
676+
{
677+
return current.phase();
678+
}
679+
680+
@Nonnull
681+
public Progress homeProgress()
682+
{
683+
return current.homeProgress();
684+
}
685+
686+
public int homeRetryCounter()
687+
{
688+
return current.homeRetryCounter();
689+
}
690+
}
570691
}

accord-core/src/main/java/accord/impl/progresslog/Progress.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
package accord.impl.progresslog;
2020

21-
enum Progress
21+
public enum Progress
2222
{
2323
/**
2424
* We do not expect any progress for this state machine at present

accord-core/src/main/java/accord/impl/progresslog/WaitingState.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ boolean isUninitialised()
140140
return waitingProgress(encodedState);
141141
}
142142

143+
final @Nonnull long waitingKeyTrackerBits()
144+
{
145+
return (encodedState >>> AWAIT_SHIFT) & (-1L >>> (64 - AWAIT_BITS));
146+
}
147+
143148
private static @Nonnull BlockedUntil blockedUntil(long encodedState)
144149
{
145150
return BlockedUntil.forOrdinal((int) ((encodedState >>> BLOCKED_UNTIL_SHIFT) & BLOCKED_UNTIL_MASK));

accord-core/src/main/java/accord/local/CommandStore.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,22 @@ public final boolean isRejectedIfNotPreAccepted(TxnId txnId, Unseekables<?> part
667667
return rejectBefore.rejects(txnId, participants);
668668
}
669669

670+
public final MaxConflicts unsafeGetMaxConflicts()
671+
{
672+
return maxConflicts;
673+
}
674+
670675
public final RedundantBefore unsafeGetRedundantBefore()
671676
{
672677
return redundantBefore;
673678
}
674679

680+
@Nullable
681+
public final RejectBefore unsafeGetRejectBefore()
682+
{
683+
return rejectBefore;
684+
}
685+
675686
public final DurableBefore durableBefore()
676687
{
677688
return node.durableBefore();

accord-core/src/main/java/accord/local/CommandStores.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -751,12 +751,10 @@ public CommandStore forId(int id)
751751

752752
public int[] ids()
753753
{
754-
Snapshot snapshot = current;
755-
Int2ObjectHashMap<CommandStore>.KeySet set = snapshot.byId.keySet();
756-
int[] ids = new int[set.size()];
757-
int idx = 0;
758-
for (int a : set)
759-
ids[idx++] = a;
754+
ShardHolder[] shards = current.shards;
755+
int[] ids = new int[shards.length];
756+
for (int i = 0; i < ids.length; i++)
757+
ids[i] = shards[i].store.id;
760758
Arrays.sort(ids);
761759
return ids;
762760
}

accord-core/src/main/java/accord/local/MaxConflicts.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@
2323
import accord.primitives.Unseekables;
2424
import accord.utils.BTreeReducingRangeMap;
2525

26-
2726
// TODO (expected): track read/write conflicts separately
28-
class MaxConflicts extends BTreeReducingRangeMap<Timestamp>
27+
public class MaxConflicts extends BTreeReducingRangeMap<Timestamp>
2928
{
3029
public static final MaxConflicts EMPTY = new MaxConflicts();
3130

0 commit comments

Comments
 (0)