WalnutLogExpunge.Mesa
Copyright Ó 1985, 1988, 1992 by Xerox Corporation. All rights reserved.
Willie-Sue, May 20, 1988 7:18:04 pm PDT
Contents: procedures for doing an expunge
DIRECTORY
IO USING [STREAM],
Rope USING [ROPE],
WalnutDefs USING [WalnutOpsHandle],
WalnutRoot USING [InternalLogInfo];
WalnutLogExpunge: CEDAR DEFINITIONS = BEGIN
STREAM: TYPE = IO.STREAM;
ROPE: TYPE = Rope.ROPE;
WalnutOpsHandle: TYPE = WalnutDefs.WalnutOpsHandle;
InternalLogInfo: TYPE = WalnutRoot.InternalLogInfo;
ExpungeHandle: TYPE = REF ExpungeHandleRec;
ExpungeHandleRec: PUBLIC TYPE = RECORD[
thisLog: InternalLogInfo,
eStrm: STREAM, -- expungeStream for writing
rStrm: STREAM, -- stream for reading
thisLogPos: INT ¬ -1,
expungeLogLength: INT ¬ -1,
entryLengthHint: INT ¬ -1,
entryPos: INT ¬ -1
];
Managing the ExpungeLog
StartExpunge: PROC[opsH: WalnutOpsHandle, pagesNeeded: INT]
RETURNS[expungeFileID: INT];
Writes the first log record on the expunge log, from information from the root; returns the internalFileID of the expunge log being written on
RestartExpunge: PROC[opsH: WalnutOpsHandle, currentLogPos, expungeLogLength: INT] RETURNS[ok: BOOL];
Set the length of the expunge log and the read position of the current log to be the given values. If it returns NOT ok, then you must StartExpunge -- StartExpunge is always guaranteed to succeed (if space exists!)
CopyBytesToExpungeLog: PROC[opsH: WalnutOpsHandle, bytesToCopy: INT];
Copies bytesToCopy from wH.expungeLog.readStream at its current position onto the end of the wH.expungeLog.writeStream; does not flush the expungeLog (must use GetExpungeProgress);
caller guarantees that this does not cross a log boundary on the read side
GetExpungeProgress: PROC[opsH: WalnutOpsHandle]
RETURNS[currentLogPos, expungeLogLength: INT];
Get the read position of wH.expungeLog.readStream and the length of wH.expungeLog.writeStream (this information can later be used to restart an expunge that was in progress); forces a flush (commit) of the writeStream - raises WalnutDefs.Error if the flush fails
EndExpunge: PROC[opsH: WalnutOpsHandle];
closes the expunge log being written - NILs out opsH.expungeHandle
Parsing a log for Expunging
SetPosition: PROC[opsH: WalnutOpsHandle, startPos: INT] RETURNS[charsSkipped: INT];
Set the position of the log to begin at the first log entry at or beyond startPos.. This procedure will skip ahead to the beginning of a log entry if startPos is not one -- the number of characters skipped is returned in charsSkipped.
SetIndex: PROC[opsH: WalnutOpsHandle, pos: INT];
sets the current log to the indicated position; used during expunge. This differs from SetPosition in that this asserts that the position is at the beginning of a log entry.
PeekEntry: PROC[opsH: WalnutOpsHandle] RETURNS[ident: ATOM, msgID: ROPE, at: INT];
returns at = -1 if there is not a valid entry at the current position. The entry is not "consumed" so that performing a NextEntry or a CopyEntry after reading the ident & msg ID information will copy or retrieve the entry returned. Performing successive PeekEntry's will NOT advance the log position; use SkipEntry to advance the log
Does not check if ident is for a legal log entry type.
SkipEntry: PROC[opsH: WalnutOpsHandle] RETURNS[ok: BOOL];
returns NOT ok if there is not a valid entry at the current position, and does not advance the log position. If there is a valid entry, it is "consumed", and the log is advanced.
CopyEntry: PROC[opsH: WalnutOpsHandle] RETURNS[newPosition, bytesCopied: INT];
Copies the next entry from the current log to the expunge log; it returns the new position that the entry now has in the expunge log; does NOT flush (commit) the expungeLog, raises WalnutDefs.Error with code = $ExpungeTransAbort if the expunge transaction aborts
EndCopyEntry: PROC[opsH: WalnutOpsHandle] RETURNS[startCopyPos: INT];
the only two entries that logExpunge needs to be able to parse - raises WalnutDefs.Error if the current entry is not an EndCopyXXInfo entry; does not advance the current position
ExpLogLength: PROC[opsH: WalnutOpsHandle] RETURNS[length: INT];
returns the length of the current log file to be expunged
the following are used by the WalnutRescue code
EntryStatus: TYPE = { validEntry, noValidEntry, EndOfStream };
GetIndex: PROC[opsH: WalnutOpsHandle] RETURNS[curPos: INT];
returns the index of the current log file (the log being read/expunged)
CopyBytes: PROC[opsH: WalnutOpsHandle, strm: STREAM, num: INT];
copies num bytes from the current position of the current log to the end of strm
ExamineThisEntry: PROC[opsH: WalnutOpsHandle] RETURNS[status: EntryStatus];
returns noValidEntry if there is not a valid entry at the current position, and does not advance the log position. If there is a valid entry, it is "consumed", and the log is advanced.
IF IO.EndOfStream is raised, EndOfStream is returned and log is not advanced.
END.