|
| 1 | +---- MODULE MCStorage2Verso ---- |
| 2 | +EXTENDS Storage2, Functions, TLCExt |
| 3 | + |
| 4 | +VARIABLE mtxnSnapshots1 |
| 5 | +\* mtxnSnapshots1 == [n \in Node |-> |
| 6 | +\* [tid \in MTxId |-> |
| 7 | +\* IF tid \in DOMAIN mtxnSnapshots[n] |
| 8 | +\* THEN mtxnSnapshots[n][tid] |
| 9 | +\* ELSE [active |-> FALSE, committed |-> FALSE, aborted |-> FALSE] |
| 10 | +\* ] |
| 11 | +\* ] |
| 12 | + |
| 13 | +txnStatus1 == [n \in Node |-> |
| 14 | + [tid \in MTxId |-> |
| 15 | + IF tid \in DOMAIN txnStatus[n] |
| 16 | + THEN txnStatus[n][tid] |
| 17 | + ELSE STATUS_OK |
| 18 | + ] |
| 19 | +] |
| 20 | + |
| 21 | +Storage == INSTANCE Storage WITH |
| 22 | + mtxnSnapshots <- mtxnSnapshots1, |
| 23 | + txnStatus <- txnStatus1 |
| 24 | + |
| 25 | +Storage2RefinesStorage == |
| 26 | + Storage!Init /\ [][Storage!Next]_(Storage!vars) |
| 27 | + |
| 28 | +StateConstraint == |
| 29 | + /\ Len(mlog["n"]) <= 3 |
| 30 | + |
| 31 | +DontUnabort == |
| 32 | + \A n \in Node, tid \in MTxId : |
| 33 | + mtxnSnapshots1[n][tid].aborted => mtxnSnapshots1'[n][tid].aborted |
| 34 | +DontUncommit == |
| 35 | + \A n \in Node, tid \in MTxId : |
| 36 | + mtxnSnapshots1[n][tid].committed => mtxnSnapshots1'[n][tid].committed |
| 37 | + |
| 38 | +SnapshotsMatch == |
| 39 | + \A n \in Node : \A tid \in DOMAIN mtxnSnapshots[n] : |
| 40 | + mtxnSnapshots1[n][tid] = mtxnSnapshots[n][tid] |
| 41 | + |
| 42 | +MCStorage2VersoInit == |
| 43 | + /\ Init |
| 44 | + /\ mtxnSnapshots1 = [n \in Node |-> [t \in MTxId |-> [active |-> FALSE, committed |-> FALSE, aborted |-> FALSE]]] |
| 45 | + |
| 46 | +MCStorage2VersoNext == |
| 47 | + /\ Next |
| 48 | + /\ mtxnSnapshots1' = [n \in Node |-> |
| 49 | + [tid \in DOMAIN mtxnSnapshots1[n] |-> |
| 50 | + IF /\ tid \in DOMAIN mtxnSnapshots[n] |
| 51 | + /\ tid \notin DOMAIN mtxnSnapshots'[n] |
| 52 | + THEN CASE /\ mtxnSnapshots[n][tid].active |
| 53 | + /\ mlog'[n] # <<>> |
| 54 | + /\ Last(mlog'[n]).tid = tid |
| 55 | + /\ "data" \in DOMAIN Last(mlog'[n]) -> |
| 56 | + [mtxnSnapshots1[n][tid] EXCEPT |
| 57 | + !.committed = TRUE, |
| 58 | + !.active = FALSE |
| 59 | + ] |
| 60 | + [] mtxnSnapshots[n][tid].active -> |
| 61 | + [mtxnSnapshots1[n][tid] EXCEPT |
| 62 | + !.aborted = TRUE, |
| 63 | + !.active = FALSE |
| 64 | + ] |
| 65 | + [] OTHER -> |
| 66 | + mtxnSnapshots[n][tid] |
| 67 | + ELSE IF tid \in DOMAIN mtxnSnapshots'[n] |
| 68 | + THEN mtxnSnapshots'[n][tid] |
| 69 | + ELSE mtxnSnapshots1[n][tid] |
| 70 | + ] |
| 71 | + ] |
| 72 | + \* Disallow rerunning an old transaction. |
| 73 | + \* It's possible because our model is "forgetful", |
| 74 | + \* but otherwise benign. Our runner should not be |
| 75 | + \* doing this. |
| 76 | + /\ DontUnabort |
| 77 | + /\ DontUncommit |
| 78 | + |
| 79 | +DebugAlias == [ |
| 80 | + mlog |-> mlog, |
| 81 | + mtxnSnapshots |-> mtxnSnapshots, |
| 82 | + txnStatus |-> txnStatus, |
| 83 | + stableTs |-> stableTs, |
| 84 | + oldestTs |-> oldestTs, |
| 85 | + allDurableTs |-> allDurableTs, |
| 86 | + |
| 87 | + mtxnSnapshots1 |-> mtxnSnapshots1, |
| 88 | + txnStatus1 |-> txnStatus1, |
| 89 | + |
| 90 | + ActiveTransactions |-> [n \in Node |-> ActiveTransactions(n)], |
| 91 | + PreparedTransactions |-> [n \in Node |-> PreparedTransactions(n)], |
| 92 | + AllDurableTs |-> [n \in Node |-> AllDurableTs(n)], |
| 93 | + |
| 94 | + ActiveTransactions1 |-> [n \in Node |-> Storage!ActiveTransactions(n)], |
| 95 | + PreparedTransactions1 |-> [n \in Node |-> Storage!PreparedTransactions(n)], |
| 96 | + AllDurableTs1 |-> [n \in Node |-> Storage!AllDurableTs(n)] |
| 97 | +] |
| 98 | + |
| 99 | +==== |
0 commit comments