YggOpenDocImpl.mesa
Copyright Ó 1985, 1988 by Xerox Corporation. All rights reserved.
Last edited by
Kolling on November 2, 1983 4:09 pm
Bob Hagmann May 4, 1988 9:28:32 pm PDT
Derived from Alpine's FileInstanceImpl.mesa.
This implementation manages OpenDoc objects. These are documents that are open for a particular transaction.
DIRECTORY
YggEnvironment USING[DID, LockMode, PageCount],
YggInternal USING[Document, TransHandle],
YggOpenDoc,
YggOpenDocPrivate,
YggDID USING[DID, EqualDIDs],
YggDIDMap USING[GetDID, Register],
YggTransactionMap USING[GetOpenDocList, SetOpenDocList];
YggOpenDocImpl: CEDAR MONITOR
IMPORTS YggDID, YggDIDMap, YggTransactionMap
EXPORTS YggInternal =
BEGIN
OpenDoc: TYPE = REF OpenDocRep;
OpenDocRep: PUBLIC TYPE = YggOpenDocPrivate.OpenDocRep;
errors:
InUse: --CALLING-- ERROR = CODE;
OldHandleNotFound: --CALLING-- ERROR = CODE;
UseCountAlreadyZero: --CALLING-- ERROR = CODE;
Finds or creates a Handle for the supplied transand did, and increments use count on the returned handle. If the handle is created, it is also entered in the YggOpenDoc list for its transaction and YggDIDMap.Register is called.
Register: PUBLIC ENTRY PROCEDURE [trans: YggInternal.TransHandle, did: YggDID.DID] RETURNS [openDoc: OpenDoc] =
BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
firstOpenDoc: OpenDoc;
TRUSTED BEGIN firstOpenDoc ← YggTransactionMap.GetOpenDocList[trans]; END;
FOR openDoc ← firstOpenDoc, openDoc.nextForTrans UNTIL openDoc = NIL DO
IF YggDID.EqualDIDs[did, GetDID[openDoc]] THEN GOTO found;
REPEAT
found => openDoc.useCount ← openDoc.useCount + 1;
FINISHED => BEGIN openDoc ← NEW[OpenDocRep ← [trans:
trans, docHandle: YggDIDMap.Register[did], useCount: 1,
deltaVersion: 0, highWaterMark: LAST[YggEnvironment.PageCount], lockMode: none,
nextForTrans: firstOpenDoc]];
YggTransactionMap.SetOpenDocList[trans, openDoc];
END;
ENDLOOP;
END;
Decrements use count on handle. If the use count becomes zero and delta version is 0 (i.e., if the file has not been updated), deletes it from the YggOpenDoc list for its transaction. (Updated files are taken care of by FlushTransState.)
Unregister: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc] =
BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
IF openDoc.useCount = 0 THEN RETURN WITH ERROR UseCountAlreadyZero;
IF (((openDoc.useCount ← openDoc.useCount - 1) = 0) AND (openDoc.deltaVersion = 0))
THEN TRUSTED BEGIN
prevOpenDoc: OpenDoc ← FindOpenDoc[openDoc.docHandle,
YggTransactionMap.GetOpenDocList[openDoc.trans]];
IF prevOpenDoc = NIL
THEN YggTransactionMap.SetOpenDocList[openDoc.trans, openDoc.nextForTrans]
ELSE prevOpenDoc.nextForTrans ← openDoc.nextForTrans;
END;
END;
When this is called, it is a error if any handle in this transaction's YggOpenDoc list has useCount # 0 or delta version = 0.
FlushTransState: PUBLIC ENTRY PROCEDURE [trans: YggInternal.TransHandle] =
TRUSTED BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
FOR openDoc: OpenDoc ← YggTransactionMap.GetOpenDocList[trans], openDoc.nextForTrans UNTIL openDoc = NIL DO
IF ((openDoc.useCount # 0) OR (openDoc.deltaVersion = 0))
THEN RETURN WITH ERROR InUse;
ENDLOOP;
YggTransactionMap.SetOpenDocList[trans, NIL];
END;
Access to immutable attributes.
GetDocHandle: PUBLIC PROCEDURE [openDoc: OpenDoc] RETURNS [doc: YggInternal.Document] =
BEGIN -- errors defined in YggOpenDoc: none.
RETURN[openDoc.docHandle];
END;
GetTransHandle: PUBLIC PROCEDURE [openDoc: OpenDoc] RETURNS [trans: YggInternal.TransHandle] =
BEGIN -- errors defined in YggOpenDoc: none.
RETURN[openDoc.trans];
END;
GetDID: PUBLIC PROCEDURE [openDoc: OpenDoc] RETURNS [did: YggEnvironment.DID] =
BEGIN -- errors defined in YggOpenDoc: none.
RETURN[YggDIDMap.GetDID[openDoc.docHandle]];
END;
Access to read/write attributes.
GetDeltaVersion: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc] RETURNS [delta: LONG
INTEGER] =
BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
RETURN[openDoc.deltaVersion];
END;
Sets the delta version to the MAX of increment and its existing value.
SetMaxDeltaVersion: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc, increment: LONG
INTEGER] =
BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
openDoc.deltaVersion ← MAX[openDoc.deltaVersion, increment];
END;
Returns the uncommitted highWaterMark, for this transaction. Initialize value is LAST[PageCount].
GetHighWaterMark: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc] RETURNS
[highWaterMark: YggEnvironment.PageCount] =
BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
RETURN[openDoc.highWaterMark];
END;
GetLockMode: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc] RETURNS [lock: YggEnvironment.LockMode] =
BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
RETURN[openDoc.lockMode];
END;
SetLockMode: PUBLIC ENTRY PROCEDURE [openDoc: OpenDoc, lock: YggEnvironment.LockMode] =
BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
openDoc.lockMode ← lock;
END;
Enumeration.
handle = NIL starts a new enumeration, and nextHandle = NIL is returned when the
enumeration is exhausted. The YggOpenDoc list is assumed to not be being modified during
this enumeration. When handle is non-NIL, not finding it is a fatal error.
GetNextHandleForTrans: PUBLIC ENTRY PROCEDURE [trans: YggInternal.TransHandle, lastOpenDoc: OpenDoc ← NIL] RETURNS [nextOpenDoc: OpenDoc] =
BEGIN -- errors defined in YggOpenDoc: none.
ENABLE UNWIND => NULL;
firstOpenDoc: OpenDoc;
TRUSTED BEGIN firstOpenDoc ← YggTransactionMap.GetOpenDocList[trans]; END;
IF lastOpenDoc = NIL THEN RETURN[firstOpenDoc];
[] ← FindOpenDoc[lastOpenDoc.docHandle, firstOpenDoc];
RETURN[lastOpenDoc.nextForTrans];
END;
FindOpenDoc: INTERNAL PROCEDURE [doc: YggInternal.Document, firstDoc: OpenDoc]
RETURNS [foundDoc: OpenDoc] = {
errors defined in YggOpenDoc: none.
did: YggDID.DID;
did ← YggDIDMap.GetDID[doc];
FOR foundDoc ← firstDoc, foundDoc.nextForTrans UNTIL foundDoc = NIL DO
IF YggDID.EqualDIDs[did, GetDID[foundDoc]] THEN RETURN;
REPEAT FINISHED => ERROR OldHandleNotFound;
ENDLOOP;
};
main line code.
END.
Edit Log
Initial: Kolling: October 21, 1982 2:22 pm: an impl module for YggOpenDoc.
Hauser, March 7, 1985 2:53:07 pm PST
Nodified, added copyright.