<> <> <> 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; <<>> <> <<>> <> <<>> RecoveryBlock: REF ARRAY [0..16384) OF CARD32; PrintLogProc: Commander.CommandProc = { <<[cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL]>> <> out: IO.STREAM; noisy: BOOL _ FALSE; 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]; <> <> <> <<= [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; }; <> Init: PROC = { Commander.Register["PrintLog", PrintLogProc, "PrintLog "]; RecoveryBlock _ NEW[ARRAY [0..16384) OF CARD32]; }; Init[]; END. <<>>