DIRECTORY YggEnvironment USING[PageCount, PageNumber, PageRun], YggInternal USING[Document, LogRecordID, TransHandle], Basics USING[CompareInt], YggDIDMap USING[ClearLogMapHandle, Document, VerifyLogMapHandle], YggLogMap USING[CheckOutOption, CallingErrorType, FileDescription, Location, MappedPageRun], YggLogMapPrivate USING[IntentionObject, Intention], RedBlackTree USING[Compare, Create, Delete, GetKey, Insert, Lookup, LookupLargest, LookupNextLarger, LookupNextSmaller, LookupSmallest, Node, Table], YggTransactionMap USING[IsCommitted]; YggLogMapImpl: CEDAR MONITOR LOCKS logMapHandle USING logMapHandle: LogMap IMPORTS Basics, YggDIDMap, RedBlackTree, YggTransactionMap EXPORTS YggInternal, YggLogMap = BEGIN LogMap: TYPE = REF LogMapRep; LogMapRep: PUBLIC TYPE = MONITORED RECORD[ createTrans: YggInternal.TransHandle, deleteTrans: YggInternal.TransHandle, sizeUncommitted: YggEnvironment.PageCount, sizeUncommittedTrans: YggInternal.TransHandle, sizeCommitted: YggEnvironment.PageCount, highWaterMarkCommitted: YggEnvironment.PageCount, intentionsTable: RedBlackTree.Table, rbKeyRef: REF YggEnvironment.PageNumber ]; Error: PUBLIC --CALLING-- ERROR [error: YggLogMap.CallingErrorType] = CODE; ProbableLockingFailure: --CALLING-- ERROR = CODE; Horrible: --CALLING-- ERROR = CODE; DescribeFile: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle] RETURNS [fileDesc: YggLogMap.FileDescription] = BEGIN -- non-fatal errors: none. MonitoredDescribeFile: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. fileDesc.registered _ TRUE; fileDesc.created _ trans = logMapHandle.createTrans; fileDesc.deleted _ trans = logMapHandle.deleteTrans; TRUSTED BEGIN fileDesc.exists _ ( ((fileDesc.created) OR (logMapHandle.createTrans = NIL) OR (YggTransactionMap.IsCommitted[logMapHandle.createTrans])) AND NOT ((fileDesc.deleted) OR ((logMapHandle.deleteTrans # NIL) AND (YggTransactionMap.IsCommitted[logMapHandle.deleteTrans])))); END; fileDesc.sizeChanged _ trans = logMapHandle.sizeUncommittedTrans; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, FALSE]; IF logMapHandle # NIL THEN MonitoredDescribeFile[logMapHandle] ELSE fileDesc.registered _ FALSE; END; RegisterCreate: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle] = BEGIN -- non-fatal errors: none. MonitoredRegisterCreate: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. IF logMapHandle.createTrans # NIL THEN RETURN WITH ERROR ProbableLockingFailure; logMapHandle.createTrans _ trans; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, TRUE]; MonitoredRegisterCreate[logMapHandle]; END; RegisterDelete: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle] = BEGIN -- non-fatal errors: none. MonitoredRegisterDelete: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. IF logMapHandle.deleteTrans # NIL THEN RETURN WITH ERROR ProbableLockingFailure; logMapHandle.deleteTrans _ trans; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, TRUE]; MonitoredRegisterDelete[logMapHandle]; END; SetUncommittedSize: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle, size: YggEnvironment.PageCount] = BEGIN -- non-fatal errors: none. MonitoredSetUncommittedSize: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. IF ((logMapHandle.sizeUncommittedTrans = NIL) OR (trans = NIL) OR (trans = logMapHandle.sizeUncommittedTrans)) THEN BEGIN logMapHandle.sizeUncommittedTrans _ trans; logMapHandle.sizeUncommitted _ size; END ELSE RETURN WITH ERROR ProbableLockingFailure; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, TRUE]; MonitoredSetUncommittedSize[logMapHandle]; END; GetUncommittedSize: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle] RETURNS[size: YggEnvironment.PageCount] = BEGIN -- non-fatal errors: none. MonitoredGetUncommittedSize: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. IF ((trans # logMapHandle.sizeUncommittedTrans) AND (logMapHandle.sizeUncommittedTrans # NIL)) THEN TRUSTED BEGIN IF YggTransactionMap.IsCommitted[logMapHandle.sizeUncommittedTrans] THEN RETURN WITH ERROR ProbableLockingFailure ELSE size _ LAST[YggEnvironment.PageCount]; END ELSE size _ logMapHandle.sizeUncommitted; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, FALSE]; IF logMapHandle = NIL THEN RETURN[LAST[YggEnvironment.PageCount]]; MonitoredGetUncommittedSize[logMapHandle]; END; SetCommittedSize: PUBLIC PROCEDURE[file: YggInternal.Document, size: YggEnvironment.PageCount] = BEGIN -- non-fatal errors: none. MonitoredSetCommittedSize: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. logMapHandle.sizeCommitted _ size; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, TRUE]; MonitoredSetCommittedSize[logMapHandle]; END; GetCommittedSize: PUBLIC PROCEDURE[file: YggInternal.Document] RETURNS[size: YggEnvironment.PageCount] = BEGIN -- non-fatal errors: none. MonitoredGetCommittedSize: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. size _ logMapHandle.sizeCommitted; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, FALSE]; IF logMapHandle = NIL THEN RETURN[LAST[YggEnvironment.PageCount]]; MonitoredGetCommittedSize[logMapHandle]; END; SetCommittedHighWaterMark: PUBLIC PROCEDURE[file: YggInternal.Document, highWaterMark: YggEnvironment.PageCount] = BEGIN -- non-fatal errors: none. MonitoredSetCommittedHighWaterMark: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. logMapHandle.highWaterMarkCommitted _ highWaterMark; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, TRUE]; MonitoredSetCommittedHighWaterMark[logMapHandle]; END; GetCommittedHighWaterMark: PUBLIC PROCEDURE[file: YggInternal.Document] RETURNS [highWaterMark: YggEnvironment.PageCount] = BEGIN -- non-fatal errors: none. MonitoredGetCommittedHighWaterMark: ENTRY PROCEDURE[logMapHandle: LogMap] = INLINE BEGIN -- non-fatal errors: none. highWaterMark _ logMapHandle.highWaterMarkCommitted; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, FALSE]; IF logMapHandle = NIL THEN RETURN[LAST[YggEnvironment.PageCount]]; MonitoredGetCommittedHighWaterMark[logMapHandle]; END; RegisterPages: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle, pageRun: YggEnvironment.PageRun, logRecordID: YggInternal.LogRecordID] = BEGIN -- non-fatal errors: none. MonitoredRegisterPages: ENTRY PROCEDURE[logMapHandle: LogMap] = BEGIN -- non-fatal errors: none. currentFirstPage: YggEnvironment.PageNumber _ pageRun.firstPage; currentCount: INT _ pageRun.count; int: YggLogMapPrivate.Intention _ RBTLookupNextSmaller[logMapHandle, currentFirstPage]; IF ((int # NIL) AND (int.pageRun.firstPage + int.pageRun.count > currentFirstPage)) THEN -- fission off the higher part. BEGIN higherPartInt: YggLogMapPrivate.Intention _ NEW[YggLogMapPrivate.IntentionObject _ [int.trans, [currentFirstPage, int.pageRun.count - (currentFirstPage - int.pageRun.firstPage)], int.logRecordID, FALSE, , , ]]; RBTInsert[logMapHandle, higherPartInt, higherPartInt.pageRun.firstPage]; int.pageRun.count _ int.pageRun.count - higherPartInt.pageRun.count; int _ higherPartInt; END ELSE int _ RBTLookup[logMapHandle, currentFirstPage]; DO -- on entry int starts at currentFirstPage or is NIL if nothing starts there. IF int = NIL THEN BEGIN overlap: BOOLEAN; newInt: YggLogMapPrivate.Intention; int _ RBTLookupNextLarger[logMapHandle, currentFirstPage]; overlap _ ((int # NIL) AND (int.pageRun.firstPage < currentFirstPage + currentCount)); newInt _ NEW[YggLogMapPrivate.IntentionObject _ [trans, [currentFirstPage, (IF overlap THEN int.pageRun.firstPage - currentFirstPage ELSE currentCount)], logRecordID, FALSE, , , ]]; -- newInt starts at currentFirstPage. RBTInsert[logMapHandle, newInt, newInt.pageRun.firstPage]; IF NOT overlap THEN EXIT; currentCount _ currentCount - newInt.pageRun.count; currentFirstPage _ int.pageRun.firstPage; END; IF ((int.trans # trans) OR (int.checkedOut)) THEN RETURN WITH ERROR ProbableLockingFailure; IF int.pageRun.count > currentCount THEN BEGIN -- fission off the higher part. higherPartInt: YggLogMapPrivate.Intention _ NEW[YggLogMapPrivate.IntentionObject _ [trans, [currentFirstPage + currentCount, int.pageRun.count - currentCount], int.logRecordID, FALSE, , , ]]; RBTInsert[logMapHandle, higherPartInt, higherPartInt.pageRun.firstPage]; int.pageRun.count _ currentCount; END; int.logRecordID _ logRecordID; IF (currentCount _ currentCount - int.pageRun.count) = 0 THEN EXIT; currentFirstPage _ currentFirstPage + int.pageRun.count; int _ RBTLookup[logMapHandle, currentFirstPage]; ENDLOOP; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, TRUE]; TRUSTED BEGIN IF YggTransactionMap.IsCommitted[trans] THEN ERROR Horrible; END; MonitoredRegisterPages[logMapHandle]; END; UnregisterPages: PUBLIC PROCEDURE[file: YggInternal.Document, pageRun: YggEnvironment.PageRun] = BEGIN -- non-fatal errors: none. MonitoredUnregisterPages: ENTRY PROCEDURE[logMapHandle: LogMap] = BEGIN -- non-fatal errors: none. intention: YggLogMapPrivate.Intention _ RBTLookup[logMapHandle, pageRun.firstPage]; IF ((intention = NIL) OR (NOT intention.checkedOut) OR (intention.pageRun.count # pageRun.count)) THEN RETURN WITH ERROR Horrible; [] _ RBTDelete[logMapHandle, pageRun.firstPage]; BROADCAST IntentionFreed; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, FALSE]; IF logMapHandle = NIL THEN ERROR Horrible; MonitoredUnregisterPages[logMapHandle]; END; IntentionFreed: CONDITION; LocatePages: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle, pageRun: YggEnvironment.PageRun, checkOut: YggLogMap.CheckOutOption] RETURNS[mappedPageRun: YggLogMap.MappedPageRun] = BEGIN -- non-fatal errors: Error[exceedsFileSize]. MonitoredLocatePages: ENTRY PROCEDURE[logMapHandle: LogMap] RETURNS[mappedPageRun: YggLogMap.MappedPageRun] = BEGIN -- non-fatal errors: Error[exceedsFileSize]. int: YggLogMapPrivate.Intention; currentCount: INT; DO IF pageRun.firstPage + pageRun.count > (IF logMapHandle.sizeUncommittedTrans = trans THEN logMapHandle.sizeUncommitted ELSE logMapHandle.sizeCommitted) THEN RETURN WITH ERROR Error[exceedsFileSize]; int _ RBTLookup[logMapHandle, pageRun.firstPage]; IF (int # NIL) THEN currentCount _ MIN[pageRun.count, int.pageRun.count] ELSE BEGIN int _ RBTLookupNextSmaller[logMapHandle, pageRun.firstPage]; IF ((int # NIL) AND (int.pageRun.firstPage + int.pageRun.count > pageRun.firstPage)) THEN currentCount _ MIN[int.pageRun.firstPage + int.pageRun.count, pageRun.firstPage + pageRun.count] - pageRun.firstPage ELSE BEGIN int _ RBTLookupNextLarger[logMapHandle, pageRun.firstPage]; IF int # NIL THEN BEGIN currentCount _ IF int.pageRun.firstPage < pageRun.firstPage + pageRun.count THEN int.pageRun.firstPage - pageRun.firstPage ELSE pageRun.count; int _ NIL; END ELSE currentCount _ pageRun.count; END; END; TRUSTED BEGIN IF ((int = NIL) OR ((int.trans # trans) AND (NOT YggTransactionMap.IsCommitted[int.trans]))) THEN RETURN[[[pageRun.firstPage, currentCount], base[]]]; END; IF int.trans = trans THEN RETURN[[[pageRun.firstPage, currentCount], log[int.logRecordID, int.pageRun, FALSE]]]; IF checkOut = checkOut THEN BEGIN IF int.checkedOut THEN BEGIN WAIT IntentionFreed; LOOP; END ELSE int.checkedOut _ TRUE; END; RETURN[[[pageRun.firstPage, currentCount], log[int.logRecordID, int.pageRun, (checkOut = checkOut)]]]; ENDLOOP; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, FALSE]; IF logMapHandle = NIL THEN RETURN[[pageRun, base[]]]; RETURN[MonitoredLocatePages[logMapHandle]]; END; LocateAnyPagesForTrans: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle] RETURNS[found: BOOLEAN, logRecordID: YggInternal.LogRecordID, logMapPageRun: YggEnvironment.PageRun] = BEGIN -- non-fatal errors: none. MonitoredLocateAnyPagesForTrans: ENTRY PROCEDURE[logMapHandle: LogMap] = BEGIN -- non-fatal errors: none. FOR intention: YggLogMapPrivate.Intention _ RBTLookupSmallest[logMapHandle], RBTLookupNextLarger[logMapHandle, intention.pageRun.firstPage] UNTIL intention = NIL DO IF ((intention.trans = trans) AND (NOT intention.checkedOut)) THEN BEGIN found _ TRUE; intention.checkedOut _ TRUE; logRecordID _ intention.logRecordID; logMapPageRun _ intention.pageRun; RETURN; END; ENDLOOP; DO FOR intention: YggLogMapPrivate.Intention _ RBTLookupSmallest[logMapHandle], RBTLookupNextLarger[logMapHandle, intention.pageRun.firstPage] UNTIL intention = NIL DO IF intention.trans = trans THEN BEGIN IF (NOT intention.checkedOut) THEN RETURN WITH ERROR Horrible; WAIT IntentionFreed; EXIT; END; REPEAT FINISHED => GOTO allDone; ENDLOOP; REPEAT allDone => NULL; ENDLOOP; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, FALSE]; found _ FALSE; IF logMapHandle # NIL THEN MonitoredLocateAnyPagesForTrans[logMapHandle]; END; UnregisterTrans: PUBLIC PROCEDURE[file: YggInternal.Document, trans: YggInternal.TransHandle] = BEGIN -- non-fatal errors: none. MonitoredUnregisterTrans: ENTRY PROCEDURE[logMapHandle: LogMap] = BEGIN -- non-fatal errors: none. ClearTransFromLogMapHandle: INTERNAL PROCEDURE RETURNS[LogMap] = BEGIN -- non system fatal errors: none. FOR intention: YggLogMapPrivate.Intention _ RBTLookupSmallest[logMapHandle], RBTLookupNextLarger[logMapHandle, intention.pageRun.firstPage] UNTIL intention = NIL DO IF intention.trans = trans THEN BEGIN IF intention.checkedOut THEN RETURN WITH ERROR Horrible; [] _ RBTDelete[logMapHandle, intention.pageRun.firstPage]; END; ENDLOOP; IF logMapHandle.createTrans = trans THEN logMapHandle.createTrans _ NIL; IF logMapHandle.deleteTrans = trans THEN logMapHandle.deleteTrans _ NIL; IF logMapHandle.sizeUncommittedTrans = trans THEN BEGIN logMapHandle.sizeUncommittedTrans _ NIL; logMapHandle.sizeUncommitted _ LAST[YggEnvironment.PageCount]; END; IF ((RBTLookupSmallest[logMapHandle] = NIL) AND (logMapHandle.createTrans = NIL) AND (logMapHandle.deleteTrans = NIL) AND (logMapHandle.sizeUncommittedTrans = NIL) ) THEN RETURN[NIL] ELSE RETURN[logMapHandle]; END; YggDIDMap.ClearLogMapHandle[file, ClearTransFromLogMapHandle]; END; logMapHandle: LogMap _ GetOrReportOnLogMapHandle[file, FALSE]; IF logMapHandle # NIL THEN MonitoredUnregisterTrans[logMapHandle]; END; GetKeyProc: RedBlackTree.GetKey -- PROC [data: UserData] RETURNS [Key] = { RETURN[ data ]; }; CompareProc: RedBlackTree.Compare -- PROC [k: Key, data: UserData] RETURNS [Basics.Comparison] = { dataIntention: YggLogMapPrivate.Intention = NARROW[ data ]; WITH k SELECT FROM pnRef: REF YggEnvironment.PageNumber => RETURN[Basics.CompareInt[pnRef^, dataIntention.pageRun.firstPage]]; keyIntention: YggLogMapPrivate.Intention => RETURN[Basics.CompareInt[keyIntention.pageRun.firstPage, dataIntention.pageRun.firstPage]]; ENDCASE => ERROR; }; GetOrReportOnLogMapHandle: PROCEDURE[fileHandle: YggDIDMap.Document, create: BOOLEAN] RETURNS[logMapHandle: LogMap] = BEGIN -- non system fatal errors: none. CreateLogMapHandle: PROCEDURE RETURNS[logMapHandle: LogMap] = BEGIN -- non system fatal errors: none. logMapHandle _ IF create THEN NEW[LogMapRep _ [ createTrans: NIL, deleteTrans: NIL, sizeUncommitted: LAST[YggEnvironment.PageCount], sizeUncommittedTrans: NIL, sizeCommitted: LAST[YggEnvironment.PageCount], highWaterMarkCommitted: LAST[YggEnvironment.PageCount], intentionsTable: RedBlackTree.Create[getKey: GetKeyProc, compare: CompareProc], rbKeyRef: NEW[YggEnvironment.PageNumber _ 0]] ] ELSE NIL; END; logMapHandle _ YggDIDMap.VerifyLogMapHandle[fileHandle, CreateLogMapHandle]; END; RBTLookupProc: TYPE = PROCEDURE[ logMapHandle: LogMap, key: YggEnvironment.PageNumber ] RETURNS [YggLogMapPrivate.Intention]; RBTLookup: INTERNAL RBTLookupProc = { logMapHandle.rbKeyRef^ _ key; RETURN[ NARROW[RedBlackTree.Lookup[ logMapHandle.intentionsTable, logMapHandle.rbKeyRef]] ]; }; RBTLookupNextLarger: INTERNAL RBTLookupProc = { logMapHandle.rbKeyRef^ _ key; RETURN[ NARROW[RedBlackTree.LookupNextLarger[ logMapHandle.intentionsTable, logMapHandle.rbKeyRef]] ]; }; RBTLookupNextSmaller: INTERNAL RBTLookupProc = { logMapHandle.rbKeyRef^ _ key; RETURN[ NARROW[RedBlackTree.LookupNextSmaller[ logMapHandle.intentionsTable, logMapHandle.rbKeyRef]] ]; }; RBTLookupLargest: INTERNAL PROCEDURE[ logMapHandle: LogMap ] RETURNS [YggLogMapPrivate.Intention] = { RETURN[ NARROW[RedBlackTree.LookupLargest[ logMapHandle.intentionsTable]] ]; }; RBTLookupSmallest: INTERNAL PROCEDURE[ logMapHandle: LogMap ] RETURNS [YggLogMapPrivate.Intention] = { RETURN[ NARROW[RedBlackTree.LookupSmallest[ logMapHandle.intentionsTable ]] ]; }; RBTDelete: INTERNAL PROCEDURE[ logMapHandle: LogMap, key: YggEnvironment.PageNumber ] RETURNS [YggLogMapPrivate.Intention] = { n: RedBlackTree.Node; logMapHandle.rbKeyRef^ _ key; n _ RedBlackTree.Delete[ logMapHandle.intentionsTable, logMapHandle.rbKeyRef]; RETURN[ IF n=NIL THEN NIL ELSE NARROW[n.data] ]; }; RBTInsert: INTERNAL PROCEDURE[ logMapHandle: LogMap, refChunk: YggLogMapPrivate.Intention, key: YggEnvironment.PageNumber ] = { logMapHandle.rbKeyRef^ _ key; RedBlackTree.Insert[ logMapHandle.intentionsTable, refChunk, logMapHandle.rbKeyRef ]; }; END. ~YggLogMapImpl.mesa Copyright Ó 1985, 1988 by Xerox Corporation. All rights reserved. Last edited by Taft on November 19, 1982 5:59 pm Kolling on January 30, 1984 3:13 pm MBrown on January 30, 1984 9:20:26 pm PST Hauser, March 27, 1985 10:49:29 am PST Carl Hauser, February 24, 1987 4:55:01 pm PST Bob Hagmann May 9, 1988 1:38:31 pm PDT rbKeyRef should be initialized at creation to refer to an YggEnvironment.PageNumber object. It is used thereafter for the key parameter to RedBlackTree routines, called from YggFilePageMgrMainImpl. This avoids allocating an object to get a reference each time such a call is made. fatal errors: A fatal error is raised if the LogMapRep createTrans field is not NIL. A fatal error is raised if the LogMapRep deleteTrans field is not NIL. Remembers the uncommitted size of the file and which trans is setting it. If trans # NIL and the previous trans that set the uncommitted size # NIL and these transactions do not match, a fatal error is raised. Returns the uncommitted size (LAST[PageCount] if it has never been set). If the previous trans that set the uncommitted size # NIL and if trans does not match the previous trans, then if the previous trans is committed a fatal error is raised else LAST[PageCount] is returned. Remembers the committed size of the file. Returns the committed size of the file (LAST[PageCount] if it has never been set). Remembers the committed high water mark for the file. Returns the committed high water mark for the file (LAST[PageCount] if it has never been set). For file pages, the LogMap remembers only the LogRecordID for the data written, rather than the actual data; it is the client's responsibility to subsequently read the log, if necessary. Registers a logged write of the pages identified by for transaction trans, identified in the log by logRecordID. The log record contains exactly this pageRun. If writes are already registered for any of those pages by the same transaction, the old writes are forgotten. If writes are already registered for a different transaction, a fatal error is raised. here int starts at (possibly changed) currentFirstPage. Forgets registered writes for the specified pageRun. If the does not exactly match a checked out entry in the LogMap, a fatal error is raised. A caller who checks out an entry is required to carry out the operation described by that entry and then Unregister the entry from the YggLogMap before proceeding further. Checking out an entry prevents other clients from checking out the same entry. If the entry is already checked out, the checkOut option waits until that entry has been unregistered (or, more likely, on something less specific) and then tries again. Returns a MappedPageRun describing the initial interval of pageRun. If the YggLogMap knows the size of the file as seen by this transaction (precisely, if SetUncommittedSize has been done by this trans or, failing that, if SetCommittedSize has been done), exceedsFileSize is errored if any part of the pageRun is past the eof. No checking is done to see if the file exists. If the initial interval of pageRun is not represented in the YggLogMap or if it is represented but for an uncommitted different transaction, returns location = base. Otherwise, handles the CheckOutOption, and if it doesn't have to wait and retry, returns location = log and a MappedPageRun log field containing the data which describes the initial interval. The pageRun describes the initial interval available. Looks for registered writes for this trans in file. If there is an unchecked out one, checks it out, and returns it. Otherwise, if the only ones it can find are ones which have already been checked out, it waits until they all go away. When unable to find any, returns found = FALSE. Removes from the YggLogMap all information that was set by transaction trans for this file. If fields that were associated with this trans will persist, they are set to their default initial values. If the intentionsTable becomes empty and no trans fields in the LogMapRep contain references to other transactions, the LogMapRep is thrown away. utility routines: If create is FALSE and the logMapHandle doesn't exist, will return NIL. A thin interface over RedBlackTree handling the coercions. main line code: Hauser: March 1, 1985: Nodified. Removed check for AlreadySet leader page handle. Hauser, March 8, 1985 10:54:42 am PST Added copyright Ê‹˜šœ™IcodešœB™B—šœ™Jšœ!™!Jšœ#™#Jšœ&Ïk™)Kšœ#™&Kšœ*™-Kšœ&™&—J˜Jš ˜ ˜˜Jšœ!˜&—˜ Jšœ%˜*—˜Jšœ ˜—˜ Jšœ2˜7—˜ JšœM˜R—˜Jšœ˜"—˜ šœR˜WJ˜0——šœ˜Jšœ˜J˜J˜——š Ïn œœœœœ˜JJšœ3˜:Jšœ˜ J˜—Jš˜J˜J˜Jšœœœ ˜J˜š œ œœ œœ˜*Jšœ%˜%Jšœ%˜%Jšœ*˜*Jšœ.˜.Jšœ(˜(Jšœ1˜1Jšœ$˜$Jšœš™šJšœ œ˜'J˜J˜—J˜J˜Jš žœœÏc œœ'œ˜KJ˜J˜Jšœ ™ J˜JšžœŸ œœœ˜1JšžœŸ œœœ˜#J˜J˜šž œœ œ=˜bJšœ'˜'šœŸ˜!šžœœ œ˜EšœŸ˜"Jšœœ˜J˜4J˜4šœœ˜!šœœœ˜:Jšœ:˜:—š œœœœ˜DJšœ>œ˜B——J˜A—Jšœ˜—Jšœ7œ˜>šœ˜Jšœ$˜(Jšœœ˜!——šœ˜J˜J˜J˜——JšœBœ™FJ˜šžœœ œ>˜^šœŸ˜!šžœœ œ˜GšœŸ˜"Jš œœœœœœ˜PJ˜!—Jšœ˜—Jšœ7œ˜=J˜&—Jšœ˜J˜J˜J˜—JšœBœ™FJ˜šžœœ œ>˜^šœŸ˜!šžœœ œ˜GšœŸ˜"Jš œœœœœœ˜PJ˜!—Jšœ˜—Jšœ7œ˜=J˜&—Jšœ˜J˜J˜˜J˜J˜——JšœVœ8œ>™ÒJ˜šžœœ œB˜fJšœ˜šœŸ˜!šžœœ œ˜KšœŸ˜"šœ'œ˜0Jšœ œ˜˜,šœœ+˜5J˜$Jš˜—Jšœœœœ˜.———Jšœ˜—Jšœ7œ˜=J˜*—šœ˜J˜J˜——Jšœœ^œvœ™•J˜šžœœ œ<˜`Jšœ"˜)šœŸ˜!šžœœ œ˜KšœŸ˜"šœ.œ˜4šœ%œ˜*šœœ˜šœA˜CJšœœœœ˜-Jšœœ˜+—Jš˜—Jšœ%˜)———Jšœ˜—Jšœ7œ˜>Jš œœœœœ˜BJ˜*—šœ˜J˜J˜——Jšœ)™)J˜šžœœ œ>˜`šœŸ˜!šžœœ œ˜IšœŸ˜"J˜"—Jšœ˜—Jšœ7œ˜=J˜(—Jšœ˜J˜J˜—Jšœ(œ&™RJ˜šžœœ œœ"˜hšœŸ˜!šžœœ œ˜IšœŸ˜"J˜"—Jšœ˜—Jšœ7œ˜>Jš œœœœœ˜BJ˜(—Jšœ˜J˜J˜J˜—Jšœ5™5J˜šžœœ œ+˜VJšœ˜šœŸ˜!šž"œœ œ˜RšœŸ˜"J˜4—Jšœ˜—Jšœ7œ˜=J˜1—šœ˜J˜J˜——Jšœ4œ&™^J˜šžœœ œ˜OJšœ+˜+šœŸ˜!šž"œœ œ˜RšœŸ˜"J˜4—Jšœ˜—Jšœ7œ˜>Jš œœœœœ˜BJ˜1—šœ˜J˜J˜J˜——Jšœ¼™¼J˜Jšœ÷™÷J˜šž œœ œE˜dJšœ?˜?šœŸ˜!šžœœ œ˜?šœŸ˜"Jšœ@˜@Jšœœ˜"šœD˜DJ˜—šœ œ˜˜?šœŸ˜%Jš˜šœ,œ#˜RJ˜FJšœ*œ ˜8—šœ&˜&J˜!—J˜DJ˜Jš˜—Jšœ1˜5——šœŸM˜Pšœ˜ šœ˜ Jšœ œ˜Jšœ#˜#Jšœ:˜:šœœœ,˜FJ˜—šœ œ>˜JJšœœ œ*˜>Jšœœ Ÿ%˜R—Jšœ:˜:Jšœœ œœ˜J˜3J˜)Jšœ˜——Jšœ7™7šœœ˜,Jšœœœœ˜.—šœ!˜#šœœŸ˜+Jšœ,œ#˜R˜LJšœœ ˜—šœ&˜&J˜!—J˜!Jšœ˜——J˜Jšœ7œœ˜CJ˜8Jšœ0˜0—Jšœ˜—Jšœ˜—Jšœ7œ˜=Jš œœœ&œœ œ˜OJ˜%—šœ˜J˜J˜J˜J˜——JšœŸ™ŸJ˜šžœœ œ?˜`šœŸ˜!šžœœ œ˜AšœŸ˜"JšœS˜Sš œœœœœ+˜aJšœœœœ ˜ —Jšœ0˜0Jš œ˜—Jšœ˜—Jšœ7œ˜>Jšœœœœ ˜*J˜'—Jšœ˜J˜—Jšžœ œ˜J˜˜Jšœ¦™¦J˜—Jšœ–™–J˜šž œœ œE˜bJšœ<œ˜RJšœ˜JšœŸ-˜4šžœœ œ˜;Jšœ*˜1šœŸ-˜4Jšœ ˜ Jšœœ˜š˜šœ&œ*˜Tšœœ˜BJšœœœœ˜.——Jšœ1˜1šœœ˜Jšœœ"˜9šœ˜ Jšœ<˜<šœ œœ-˜@˜šœœ+˜BJ˜6—šœ˜ šœ'˜'˜Jšœ˜ —šœ˜ Jšœœ,˜=˜ Jšœ*˜.Jšœ˜—šœœ˜ Jš˜—Jšœ˜"Jšœ˜—————Jšœ˜——š œœœ œ˜ šœœœ,˜IJšœœ/œ˜>——šœ˜šœœF˜QJšœ ˜——šœ˜šœ˜ šœ˜Jš œœœœ˜)Jšœœ˜—Jšœ˜——šœ˜J˜J——Jšœ˜—Jšœ˜—Jšœ7œ˜>Jšœœœœ˜5Jšœ%˜+šœ˜J˜J˜——Jšœ˜œ™žJ˜šžœœ œ<˜dJšœœP˜fšœŸ˜!šžœœ œ˜HšœŸ˜"šœI˜LJšœ>˜>—šœ ˜š˜šœœœ˜=šœ˜ Jšœœ˜ Jšœœ˜J˜$J˜"Jšœ˜Jšœ˜———Jšœ˜—š˜šœI˜LJšœ>˜>—šœ ˜š˜šœ˜šœ˜ Jš œœœœœœ ˜>Jšœ˜Jšœ˜Jšœ˜——Jšœœœ ˜ —Jšœ˜—Jšœ œ˜—Jšœ˜—Jšœ˜—Jšœ7œ˜>Jšœœ˜Jšœœœ/˜I—šœ˜J˜J˜J˜J˜J˜——JšœÚ™ÚJ˜šžœœ œ>˜_šœŸ˜!šžœœ œ˜AšœŸ˜"šžœœ œœ ˜@šœŸ!˜'šœ(˜+šœ ˜ Jšœ!˜!J˜——šœ ˜Jš˜šœ˜šœ˜ Jš œœœœœ ˜8šœ˜J˜—Jšœ˜——Jšœ˜—Jšœ"œœ˜HJšœ"œœ˜Hšœ*˜,šœœ%œ˜3Jšœœ˜>Jšœ˜——šœ%œ˜/Jšœœ˜$Jšœœ˜$šœ%œ˜+Jšœœœ˜Jšœœ˜———Jšœ˜—J˜>—Jšœ˜—Jšœ7œ˜>Jšœœœ(˜B—šœ˜J˜J˜——Jšœ™Jšž œŸ&˜Fšœ˜Jšœ ˜J˜J˜—J•StartOfExpansion[]šž œŸ<˜^šœ˜Jšœ,œ ˜;šœœ˜Jšœœœ=˜kJšœ,œU˜‡Jšœœ˜—J˜—J˜Jšœ œ1œ™GJ˜šžœ œ)œ˜UJšœ˜ šœŸ!˜'šžœ œœ˜=šœŸ!˜'šœœ˜šœœ˜Jšœ œ˜Jšœ œ˜Jšœœ˜0Jšœœ˜Jšœœ˜.Jšœœ˜7JšœO˜OJšœ œ ˜-J˜—Jšœœ˜ —Jšœ˜——J˜L—šœ˜J˜——J™:JšÏb œœ œ:œ˜~šÐbn œœ˜%Jšœ˜JšœœN˜\J˜J˜—š¡œœ˜/Jšœ˜JšœœX˜fJ˜J˜—š¡œœ˜0Jšœ˜JšœœY˜gJ˜—J˜š¡œœ œœ!˜eJšœœ>˜LJ˜—J˜š¡œœ œœ!˜fJšœœ@˜NJ˜—J˜š¡ œœ œ:œ!˜J˜Jšœ˜JšœN˜NJšœœœœœœœ ˜0J˜—J˜š¡ œœ œc˜€Jšœ˜JšœU˜UJ˜—J˜˜J˜—Jšœ™J˜J˜J˜J˜Jšœ˜J˜JšžœL™Ršœ"™%J™—K™—…—D"j+