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.
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.