PrintLogImpl.mesa
Copyright Ó 1989 by Xerox Corporation. All rights reserved.
Bob Hagmann June 15, 1989 1:02:00 pm PDT
DIRECTORY
BasicTime,
Camelot,
Commander,
CommandTool,
Convert,
IO,
Rope,
YggDID,
YggDIDPrivate,
YggDIDMapPrivate,
YggdrasilInit,
YggLock,
YggLog,
YggLogBasic,
YggLogControl,
YggLogRep,
YggInternal,
YggEnvironment;
PrintLogImpl: CEDAR PROGRAM
IMPORTS Commander, IO, YggLogBasic, YggLog, YggLogControl
EXPORTS YggDID, YggInternal
= BEGIN
ROPE: TYPE = Rope.ROPE;
junk
DID: PUBLIC TYPE ~ REF DIDRep;
DIDRep: PUBLIC TYPE ~ YggDIDPrivate.DIDRep;
Document: TYPE = REF DocumentRep;
DocumentRep: PUBLIC TYPE = YggDIDMapPrivate.DocumentRep;
Global data
VolatilizeTest Command
RecoveryBlock: REF ARRAY [0..16384) OF CARD32;
PrintLogProc: Commander.CommandProc = {
[cmd: Handle] RETURNS [result: REFNIL, msg: ROPENIL]
CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...]
out: IO.STREAM;
noisy: BOOLFALSE;
offset: INT ← 0;
ok: BOOL;
checkpointWord: YggEnvironment.WordNumber;
checkpointRecord: YggLog.RecordID;
startAnalysisRecord: YggLog.RecordID;
currentRecord: YggLog.RecordID;
nextRecord: YggLog.RecordID;
out ← cmd.out;
[] ← YggLogBasic.EstablishLogFile[];
[ok, checkpointWord, checkpointRecord, startAnalysisRecord] ← YggLogControl.DiscoverWhereToStartAnalysisPass[FALSE];
IF ~ok THEN out.PutF["\nCheckpoint does not point at the start of a checkpoint record"];
out.PutF["\nCheckpoint at %g words and %g record ID, with start at %g words\n", IO.card[checkpointWord.low], IO.card[checkpointRecord.low], IO.card[startAnalysisRecord.low] ];
{
notStartOfRecord: BOOL;
[notStartOfRecord: notStartOfRecord, currentRecord: currentRecord] ←
YggLogBasic.OpenRecordStreamFromCheckpoint[checkpointWord: checkpointWord,
checkpointRecord: checkpointRecord, firstRecord: startAnalysisRecord];
IF notStartOfRecord THEN ERROR;
};
DO
status: YggLog.ReadProcStatus;
sizeOfRecordDataInWords: CARD;
recordHeader: LONG POINTER TO YggLogRep.TransactionHeader;
recordData: LONG POINTER;
currentRecordType: YggLog.RecordType;
recordTypeRope: ROPE;
currentRecordType ← YggLogControl.PeekCurrentType[currentRecord];
recordTypeRope ← SELECT currentRecordType FROM
noop => "noop",
checkpointBegin => "checkpointBegin",
checkpointComplete => "checkpointComplete",
startTrans => "startTrans",
commitTrans => "commitTrans",
abortTrans => "abortTrans",
writeBytes => "writeBytes"
ENDCASE => IO.PutFR["%g", IO.int[LOOPHOLE[currentRecordType, INTEGER]]];
IF currentRecordType = noop THEN {
out.PutF["noop \n"];
}
ELSE {
transHdr: YggLogRep.TransactionHeader;
IF YggLogBasic.CheckCurrentRecord[].truncated THEN EXIT;
transHdr ← YggLogControl.PeekCurrentTransactionHeader[currentRecord];
[status: status, wordsRead: sizeOfRecordDataInWords] ← YggLog.ReadForRecovery[thisRecord: currentRecord, wordsToSkip: 0, to: [base: LOOPHOLE[RecoveryBlock], length: 16384]];
IF status = destinationFull THEN ERROR;
recordHeader ← LOOPHOLE[RecoveryBlock];
recordData ← LOOPHOLE[RecoveryBlock, LONG POINTER];
Now we have:
sizeOfRecordDataInWords 32 bit words of data starting at recordData
it is for optr of recordHeader.optr
= [segmentId: segmentIdT, highOffset: CARD16, lowOffset: CARD32]
TRUSTED {
out.PutF["type: %g, seg: %g, offset: %b, size: %g(%b)\n", IO.rope[recordTypeRope], IO.card[transHdr.optr.segmentId.value], IO.card[transHdr.optr.lowOffset], IO.card[sizeOfRecordDataInWords], IO.card[sizeOfRecordDataInWords]];
};
};
{
endOfLog, truncatedRecord: BOOL;
[endOfLog: endOfLog, truncatedRecord: truncatedRecord, currentRecord: nextRecord] ← YggLogBasic.AdvanceRecordStream[];
IF endOfLog THEN {
out.PutF["end of log \n"];
EXIT;
};
};
currentRecord ← nextRecord;
ENDLOOP;
};
Initialization
Init: PROC = {
Commander.Register["PrintLog", PrintLogProc, "PrintLog "];
RecoveryBlock ← NEW[ARRAY [0..16384) OF CARD32];
};
Init[];
END.