WalnutRoot.Mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Willie-Sue, March 27, 1986 11:26:40 am PST
Donahue, August 5, 1985 2:16:01 pm PDT
Contents: types and procedures which take the root file as implicit parameter
Parses the root file and sets up the Log objects; dispenses the various streams and values parsed from the rootFile
DIRECTORY
BasicTime USING [GMT],
IO USING [STREAM],
Rope USING [ROPE],
WalnutKernelDefs USING [Segment, WhichTempLog];
WalnutRoot: CEDAR DEFINITIONS =
BEGIN
Types
GMT: TYPE = BasicTime.GMT;
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
WhichTempLog: TYPE = WalnutKernelDefs.WhichTempLog;
Root file Information
Open: PROC[rootName: ROPE, readOnly: BOOLFALSE, newSegmentOk: BOOLFALSE]
RETURNS [
key, mailFor: ROPE,
rootFileCreateDate: GMT,
segment: WalnutKernelDefs.Segment,
isReadOnly: BOOL];
opens rootName as the current root file; finds out the name of the various logs, and who may retrieve mail into this database (one user only). Also returns the segment name, which is used by the WalnutDB operations to identify the database.
Shutdown: PROC;
Shutdown the connection to the root. Must do an Open after this.
KeyIs: PROC RETURNS[ROPE];
Mailfor: PROC RETURNS[ROPE];
DBName: PROC RETURNS[ROPE];
GetRootFileStamp: PROC RETURNS[rootFileStamp: GMT];
gets the create date of the rootFile
GetExpungeID: PROC RETURNS[expungeFileID: INT];
Transaction Management
WalnutRoot does all of the transaction management in Walnut. It will set up the necessary coordinator and worker transactions to handle logs and databases stored on different machines (although currently this is not the generally accepted method of usage!).
StartTransaction: PROC[openDB: BOOLTRUE] RETURNS[schemaInvalid: BOOL];
Start a transaction to handle the logs and the database -- this may be either the coordinator transaction, if everything is on the same machine, or a new worker transaction if not. In the case of doing an EraseDB, we must not start a transaction on the database at this time
CloseTransaction: PROC;
To allow closing of the currentLog streams and database file when there is no activity
CommitAndContinue: PROC;
Commits and continues the current transaction
AbortTransaction: PROC;
Aborts the DBCache and aborts the transaction
FlushAndContinue: PROC[strm: STREAM];
WalnutRoot handles all the transactions for the streams it gives out
EraseDB: PROC;
Erases the database segment
Managing the CurrentLog
AcquireWriteLock: PROC;
upgrades the lock on the currentLog to write
GetCurrentLogStreams: PROC RETURNS[readStream, writeStream: STREAM];
ReleaseWriteLock: PROC RETURNS[readStream, writeStream: STREAM];
Closes the log streams and re-opens, to release the write lock; is careful to use the same transaction as before, so the database is not affected
ReturnCurrentLogStreams: PROC;
closes any open currentLog or expungeLog streams; does a commitAndContinue of the transaction; may raise WalnutDefs.Error
Managing the ExpungeLog
GetStreamsForExpunge: PROC RETURNS[
currentStream, expungeStream: STREAM, keyIs: ROPE, expungeFileID, logSeqNo: INT];
SwapLogs: PROC[expungeFileID: INT, newRootStamp: GMT] RETURNS[newLogLen: INT];
Rewrites the rootFile entries, so that the currentlog and expungeLog are swapped; expungeFileID is the internalFileID of the log that was just written;
converts any error into a WalnutDefs.Error with code = $RootTransAbort; No streams are open at the end of this operation.
ReturnExpungeStreams: PROC;
Used if there was an error during RestartExpunge; closes the expunge stream
Managing the TempLogs
PrepareToCopyTempLog: PROC[which: WhichTempLog, pagesAlreadyCopied: INT, reportProc: PROC[msg1, msg2, msg3: ROPENIL]] RETURNS[currentStream, tempStream: STREAM];
makes sure there is enough space to copy the WhichTempLog onto the currentLog; returns NIL for the streams if there is not enough space; currentStream & tempStream are opened under the same transaction
GetStreamsForCopy: PROC[which: WhichTempLog]
RETURNS[currentStream, tempStream: STREAM];
used during restart, when a copy was in progress; the same trans is used for both the currentStream and the tempStream
FinishCopy: PROC[which: WhichTempLog];
sets the length of the tempLog to something reasonable and closes the tempStream
AbortTempCopy: PROC[which: WhichTempLog, strm: STREAM];
returns tempLog if the copy of a temp log was not successful
Access to streams for the various logs
GetNewMailStream: PROC[lengthRequired: INT, pagesWanted: INT ← 100]
RETURNS[strm: STREAM, actualLen: INT];
the newMailStream must be at least lenExpected bytes long (it is truncated to that length if longer); if the number of pages in the file not equal to sizeWanted, then page count is changed; is sizeWanted = -1, the pageCount is not changed
ReturnNewMailStream: PROC[mStream: STREAM];
called when finished getting newMail from grapevine
GetReadArchiveStream: PROC[pagesWanted: INT ← -1] RETURNS[STREAM];
If pagesWanted is -1 then don't change the length
ReturnReadArchiveStream: PROC[aStream: STREAM];
StreamToWhich: PROC[stream: STREAM] RETURNS[ROPE];
Utilities
RegisterStatsProc: PROC[proc: PROC[ROPE]];
UnregisterStatsProc: PROC[proc: PROC[ROPE]];
StatsReport: PROC[ROPE];
END.