DIRECTORY Basics USING [UnsafeBlock], PBasics USING [charsPerWord, RawBytes], Camelot USING [tidT], IO USING [Close, PutChar, PutRope, STREAM, UnsafePutBlock], Process USING [MsecToTicks, Pause], Rope USING [Equal, Length, ROPE], YggDID USING [DID, EqualDIDs], YggDIDPrivate USING [DIDRep], YggDIDMap USING [AddComponentFile, GetComponentFiles, OpenDocumentFromDID, SwapLinkInfo], YggFile USING [Create, FileFromComponentFiles, FileHandle, PagesForBytes, StreamFromOpenFileAndTid], YggFixedNames USING [Inlinks, Outlinks], YggIndexMaint USING [NewValueForAttribute, NewValueForAttributeCommitStatus, NewValueForMetaAttribute], YggInternal USING [Document, FileHandle], YggRep USING [AccurateGMT, AccurateGMTRep, AccurateGMTRepByteSize, Attribute, AttributePreamble, AttributeValue, BitsRep, date, did, DocType, float, int, lastReservedDocType, LatchVDoc, linkMod, metaAttributeMod, rope, shortRope, SizeOfBits, TypedPrimitiveElement, unknown, uninterpretedBytes, UnlatchVDoc, VDoc], YggEnvironment USING [nullDID, nullTransID, TransID], YggTransaction USING [GetPossibleDocumentUpdates, IsTopLevel], YggVolatileObjectCache USING [InvalidateDID, PromoteToParent, ReserveDIDInCache, UnreserveDIDInCache]; YggStabilizeImpl: CEDAR PROGRAM IMPORTS IO, Process, Rope, YggDID, YggDIDMap, YggFile, YggFixedNames, YggIndexMaint, YggRep, YggTransaction, YggVolatileObjectCache EXPORTS YggDID, YggRep ~ BEGIN ROPE: TYPE ~ Rope.ROPE; DID: PUBLIC TYPE ~ REF DIDRep; DIDRep: PUBLIC TYPE ~ YggDIDPrivate.DIDRep; AllNulls: REF PACKED ARRAY [0..PBasics.charsPerWord) OF CHAR _ NEW[ PACKED ARRAY [0..PBasics.charsPerWord) OF CHAR _ ALL[0C]]; PreCommit: PUBLIC PROC[tid: Camelot.tidT] ~ { vDocs: LIST OF YggRep.VDoc; IF YggTransaction.IsTopLevel[tid] THEN { -- top level xact trying to commit tryingToLatch: BOOL _ TRUE; vDocs _ YggTransaction.GetPossibleDocumentUpdates[tid]; -- get documents (really VDoc's) that were write locked during the xact WHILE tryingToLatch DO latchFailed: LIST OF YggRep.VDoc _ NIL; FOR vD: LIST OF YggRep.VDoc _ vDocs, vD.rest UNTIL vD = NIL DO IF ~YggRep.LatchVDoc[vD.first, FALSE] THEN { latchFailed _ vD; EXIT; }; ENDLOOP; IF latchFailed # NIL THEN { FOR vD: LIST OF YggRep.VDoc _ vDocs, vD.rest UNTIL vD = NIL DO IF vD = latchFailed THEN EXIT; IF ~YggRep.UnlatchVDoc[vD.first] THEN ERROR; ENDLOOP; Process.Pause[Process.MsecToTicks[13]]; LOOP; }; tryingToLatch _ FALSE; FOR vD: LIST OF YggRep.VDoc _ vDocs, vD.rest UNTIL vD = NIL DO doc: YggInternal.Document _ NIL; meta: YggInternal.FileHandle _ NIL; metaAttributesInAttributesFileChanged: BOOL _ FALSE; contentsInAttributesFileChanged: BOOL _ FALSE; setContentsAsAttribute: BOOL _ FALSE; componentFiles: LIST OF YggInternal.FileHandle _ NIL; attributesStream: IO.STREAM _ NIL; doc _ YggDIDMap.OpenDocumentFromDID[vD.first.did, tid]; [vD.first.fromDID, vD.first.toDID, vD.first.linkType] _ YggDIDMap.SwapLinkInfo[doc, vD.first.fromDID, vD.first.toDID, vD.first.linkType]; componentFiles _ YggDIDMap.GetComponentFiles[doc]; meta _ YggFile.FileFromComponentFiles[componentFiles: componentFiles, fileUse: $meta]; IF meta = NIL AND (vD.first.outlinksChanged # NIL OR vD.first.inlinksChanged # NIL OR vD.first.metaAttributesChanged # NIL) THEN metaAttributesInAttributesFileChanged _ TRUE; IF vD.first.contentsChanged OR vD.first.namesOfAttributesChanged # NIL OR metaAttributesInAttributesFileChanged THEN { -- if a change really occured contents, attributes, links: YggInternal.FileHandle _ NIL; componentFiles: LIST OF YggInternal.FileHandle; componentFiles _ YggDIDMap.GetComponentFiles[doc]; IF vD.first.contentsChanged THEN { contents _ YggFile.FileFromComponentFiles[componentFiles: componentFiles, fileUse: $contents]; IF contents = NIL THEN { contentsInAttributesFileChanged _ TRUE; setContentsAsAttribute _ TRUE; IF vD.first.contents.docType = YggRep.uninterpretedBytes OR vD.first.contents.docType >= YggRep.lastReservedDocType THEN { byteSize: INT; IF (byteSize _ YggRep.SizeOfBits[vD.first.contents.bits]) > 200 THEN { contents _ YggFile.Create[size: YggFile.PagesForBytes[byteSize], did: vD.first.did, fileUse: $contents, nearToDid: YggEnvironment.nullDID, tid: tid]; YggDIDMap.AddComponentFile[doc: doc, componentFile: contents, tid: tid]; contentsInAttributesFileChanged _ FALSE; setContentsAsAttribute _ FALSE; }; }; }; } ELSE { IF YggFile.FileFromComponentFiles[componentFiles: componentFiles, fileUse: $contents] = NIL THEN setContentsAsAttribute _ TRUE; }; IF vD.first.namesOfAttributesChanged # NIL OR metaAttributesInAttributesFileChanged OR contentsInAttributesFileChanged OR contents # NIL THEN { attributes _ YggFile.FileFromComponentFiles[componentFiles: componentFiles, fileUse: $attributes]; IF attributes = NIL THEN { attributes _ YggFile.Create[size: 1, did: vD.first.did, fileUse: $attributes, nearToDid: YggEnvironment.nullDID, tid: tid]; YggDIDMap.AddComponentFile[doc: doc, componentFile: attributes, tid: tid]; }; }; attributesStream _ StabilizeToFiles[tid, vD.first.did, vD.first, metaAttributesInAttributesFileChanged, contents, attributes, links, setContentsAsAttribute]; }; IF vD.first.namesOfAttributesChanged # NIL THEN { -- if an attribute really occured FOR loa: LIST OF YggRep.Attribute _ vD.first.attributes, loa.rest UNTIL loa = NIL DO FOR aC: LIST OF ROPE _ vD.first.namesOfAttributesChanged, aC.rest UNTIL aC = NIL DO IF Rope.Equal[aC.first, loa.first.attributeName] THEN { vD.first.attributesChanged _ CONS[loa.first, vD.first.attributesChanged]; EXIT; }; ENDLOOP; ENDLOOP; }; IF vD.first.metaAttributesChanged # NIL THEN { -- if a meta attribute change occured componentFiles: LIST OF YggInternal.FileHandle; componentFiles _ YggDIDMap.GetComponentFiles[doc]; meta _ YggFile.FileFromComponentFiles[componentFiles: componentFiles, fileUse: $meta]; StabilizeMetaAttributes[tid, vD.first.did, vD.first, meta, attributesStream]; -- apply changes and write it out IF meta# NIL AND attributesStream # NIL THEN IO.Close[attributesStream]; YggIndexMaint.NewValueForMetaAttribute[vD.first.did, tid, vD.first.metaAttributesChanged]; } ELSE IF attributesStream # NIL THEN IO.Close[attributesStream]; IF vD.first.namesOfAttributesChanged # NIL THEN { -- if a change really occured vDoc: YggRep.VDoc; newValues: LIST OF LIST OF YggRep.AttributeValue _ NIL; oldValues: LIST OF LIST OF YggRep.AttributeValue _ NIL; vDoc _ vD.first; FOR aC: LIST OF ROPE _ vDoc.namesOfAttributesChanged, aC.rest UNTIL aC = NIL DO FOR loa: LIST OF YggRep.Attribute _ vDoc.attributes, loa.rest UNTIL loa = NIL DO IF Rope.Equal[aC.first, loa.first.attributeName] THEN newValues _ CONS[loa.first.value, newValues]; ENDLOOP; FOR loa: LIST OF YggRep.Attribute _ vDoc.attributesChanged, loa.rest UNTIL loa = NIL DO IF Rope.Equal[aC.first, loa.first.attributeName] THEN oldValues _ CONS[loa.first.value, oldValues]; ENDLOOP; YggIndexMaint.NewValueForAttribute[vDoc.did, tid, aC.first, oldValues, newValues]; ENDLOOP; }; ENDLOOP; FOR vD: LIST OF YggRep.VDoc _ vDocs, vD.rest UNTIL vD = NIL DO IF ~YggRep.UnlatchVDoc[vD.first] THEN ERROR; ENDLOOP; ENDLOOP; }; }; Commit: PUBLIC PROC[tid: Camelot.tidT] ~ { vDocs: LIST OF YggRep.VDoc; vDocs _ YggTransaction.GetPossibleDocumentUpdates[tid]; FOR vD: LIST OF YggRep.VDoc _ vDocs, vD.rest UNTIL vD = NIL DO IF YggTransaction.IsTopLevel[tid] THEN { IF vD.first.namesOfAttributesChanged # NIL OR vD.first.metaAttributesChanged # NIL THEN { -- if a change really occured YggIndexMaint.NewValueForAttributeCommitStatus[vD.first.did, tid, TRUE]; vD.first.namesOfAttributesChanged _ NIL; vD.first.attributesChanged _ NIL; vD.first.metaAttributesChanged _ NIL; vD.first.outlinksChanged _ NIL; vD.first.inlinksChanged _ NIL; vD.first.contentsChanged _ FALSE; vD.first.linkChanged _ FALSE; }; }; YggVolatileObjectCache.PromoteToParent[vD.first.did, tid]; ENDLOOP; }; Abort: PUBLIC PROC[tid: Camelot.tidT] ~ { vDocs: LIST OF YggRep.VDoc; vDocs _ YggTransaction.GetPossibleDocumentUpdates[tid]; IF YggTransaction.IsTopLevel[tid] THEN { -- must back out of applied intentions FOR vD: LIST OF YggRep.VDoc _ vDocs, vD.rest UNTIL vD = NIL DO doc: YggInternal.Document _ NIL; doc _ YggDIDMap.OpenDocumentFromDID[vD.first.did, tid]; [] _ YggDIDMap.SwapLinkInfo[doc, vD.first.fromDID, vD.first.toDID, vD.first.linkType]; YggVolatileObjectCache.InvalidateDID[vD.first.did, YggEnvironment.nullTransID]; IF vD.first.namesOfAttributesChanged # NIL OR vD.first.metaAttributesChanged # NIL THEN { -- if a change really occured YggIndexMaint.NewValueForAttributeCommitStatus[vD.first.did, tid, FALSE]; }; vD.first.namesOfAttributesChanged _ NIL; vD.first.attributesChanged _ NIL; vD.first.metaAttributesChanged _ NIL; vD.first.outlinksChanged _ NIL; vD.first.inlinksChanged _ NIL; vD.first.contentsChanged _ FALSE; vD.first.linkChanged _ FALSE; ENDLOOP; } ELSE { -- smash object cache for xact that aborted FOR vD: LIST OF YggRep.VDoc _ vDocs, vD.rest UNTIL vD = NIL DO YggVolatileObjectCache.InvalidateDID[vD.first.did, tid]; ENDLOOP; }; }; StabilizeMetaAttributes: PUBLIC PROC [transID: YggEnvironment.TransID, did: DID, vDoc: YggRep.VDoc, meta: YggFile.FileHandle, attributesStream: IO.STREAM] ~ { applyLinkMods: PROC [links: LIST OF YggRep.AttributeValue, linksChanged: LIST OF YggRep.linkMod] RETURNS [newLinks: LIST OF YggRep.AttributeValue] ~ { newLinks _ links; FOR lolm: LIST OF YggRep.linkMod _ linksChanged, lolm.rest UNTIL lolm = NIL DO FOR loav: LIST OF YggRep.AttributeValue _ newLinks, loav.rest UNTIL loav = NIL DO IF Rope.Equal[lolm.first.linkName, loav.first.fieldName] THEN { IF lolm.first.add THEN { -- add the link in loav.first.valueSet _ CONS[[YggRep.did, lolm.first.linkValue], loav.first.valueSet]; EXIT; } ELSE { -- remove the link gotOne: BOOL _ FALSE; prevTPE: LIST OF YggRep.TypedPrimitiveElement _ NIL; FOR lotpe: LIST OF YggRep.TypedPrimitiveElement _ loav.first.valueSet, lotpe.rest UNTIL lotpe = NIL DO linkDID: DID; IF lotpe.first.docType # YggRep.did THEN ERROR; linkDID _ NARROW[lotpe.first.bits]; IF YggDID.EqualDIDs[linkDID, lolm.first.linkValue] THEN { gotOne _ TRUE; IF prevTPE = NIL THEN loav.first.valueSet _ lotpe.rest ELSE prevTPE.rest _ lotpe.rest; LOOP; }; prevTPE _ lotpe; ENDLOOP; IF ~gotOne THEN ERROR; }; }; REPEAT FINISHED => IF lolm.first.add THEN { newLinks _ CONS[[lolm.first.linkName, LIST[[YggRep.did, lolm.first.linkValue]]], newLinks]; }; ENDLOOP; ENDLOOP; }; IF attributesStream = NIL THEN attributesStream _ YggFile.StreamFromOpenFileAndTid[meta, transID]; FOR macl: LIST OF YggRep.metaAttributeMod _ vDoc.metaAttributesChanged, macl.rest UNTIL macl = NIL DO FOR loa: LIST OF YggRep.Attribute _ vDoc.metaAttributes, loa.rest UNTIL loa = NIL DO IF Rope.Equal[loa.first.attributeName, macl.first.attributeName] THEN { prev: LIST OF YggRep.AttributeValue _ NIL; FOR listoav: LIST OF YggRep.AttributeValue _ loa.first.value, listoav.rest UNTIL listoav = NIL DO tpe: YggRep.TypedPrimitiveElement _ listoav.first.valueSet.first; didOnList: DID; IF tpe.docType # YggRep.did THEN ERROR; didOnList _ NARROW[tpe.bits]; IF YggDID.EqualDIDs[didOnList, macl.first.didValue] THEN { IF macl.first.add THEN EXIT; -- already on list prev.rest _ listoav; EXIT; }; prev _ listoav; REPEAT FINISHED => IF macl.first.add THEN { addItem: LIST OF YggRep.AttributeValue; addItem _ LIST[[NIL, LIST[[YggRep.did, macl.first.didValue]]]]; IF prev = NIL THEN vDoc.metaAttributes _ LIST[[macl.first.attributeName, FALSE, addItem]] ELSE prev.rest _ addItem }; ENDLOOP; LOOP; }; REPEAT FINISHED => IF macl.first.add THEN { addItem: YggRep.Attribute; addItem _ [macl.first.attributeName, FALSE, LIST[[NIL, LIST[[YggRep.did, macl.first.didValue]]]]]; vDoc.metaAttributes _ CONS[addItem, vDoc.metaAttributes]; }; ENDLOOP; ENDLOOP; FOR restOfAttributes: LIST OF YggRep.Attribute _ vDoc.metaAttributes, restOfAttributes.rest UNTIL restOfAttributes = NIL DO writeAttribute[restOfAttributes.first, attributesStream]; ENDLOOP; vDoc.outlinks _ applyLinkMods[vDoc.outlinks, vDoc.outlinksChanged]; vDoc.inlinks _ applyLinkMods[vDoc.inlinks, vDoc.inlinksChanged]; IF vDoc.outlinks # NIL THEN writeAttribute[[YggFixedNames.Outlinks, FALSE, vDoc.outlinks], attributesStream]; IF vDoc.inlinks # NIL THEN writeAttribute[[YggFixedNames.Inlinks, FALSE, vDoc.inlinks], attributesStream]; IO.Close[attributesStream]; }; StabilizeToFiles: PROC [transID: YggEnvironment.TransID, did: DID, vDoc: YggRep.VDoc, metaAttributesInAttributesFile: BOOL, contents, attributes, links: YggFile.FileHandle, setContentsAsAttribute: BOOL] RETURNS [attributesStream: IO.STREAM _ NIL]~ { YggVolatileObjectCache.ReserveDIDInCache[did, transID]; IF contents # NIL THEN { SELECT vDoc.contents.docType FROM YggRep.unknown => ERROR; YggRep.int, YggRep.shortRope, YggRep.float, YggRep.date => {}; YggRep.rope => { contentsStream: IO.STREAM _ NIL; rRope: ROPE; rRope _ NARROW[vDoc.contents.bits]; contentsStream _ YggFile.StreamFromOpenFileAndTid[contents, transID]; IO.PutRope[contentsStream, rRope]; setContentsAsAttribute _ FALSE; IO.Close[contentsStream]; }; ENDCASE => { contentsStream: IO.STREAM _ NIL; rBits: REF YggRep.BitsRep; rBits _ NARROW[vDoc.contents.bits]; contentsStream _ YggFile.StreamFromOpenFileAndTid[contents, transID]; TRUSTED { ptBits: LONG POINTER TO YggRep.BitsRep; unsafeBlock: Basics.UnsafeBlock; ptBits _ LOOPHOLE[rBits]; unsafeBlock _ [LOOPHOLE[ptBits, LONG POINTER TO PBasics.RawBytes] + SIZE[YggRep.BitsRep[0]], 0, rBits.validBytes]; IO.UnsafePutBlock [self: contentsStream, block: unsafeBlock]; }; setContentsAsAttribute _ FALSE; IO.Close[contentsStream]; }; }; IF attributes # NIL THEN { attributesStream _ YggFile.StreamFromOpenFileAndTid[attributes, transID]; writeInt[attributesStream, vDoc.contents.docType]; FOR restOfAttributes: LIST OF YggRep.Attribute _ vDoc.attributes, restOfAttributes.rest UNTIL restOfAttributes = NIL DO writeAttribute[restOfAttributes.first, attributesStream]; ENDLOOP; IF setContentsAsAttribute THEN writeAttribute[["$contents", FALSE, LIST[[NIL, LIST[vDoc.contents]]]], attributesStream]; }; YggVolatileObjectCache.UnreserveDIDInCache[did, transID]; }; writeInt: PROC [attributesStream: IO.STREAM, int: INT] = { xyzInt: REF INT _ NEW[INT _ int]; TRUSTED {IO.UnsafePutBlock[attributesStream, [LOOPHOLE[xyzInt], 0, BYTES[INT]]];}; }; writeAttribute: PROC [attribute: YggRep.Attribute, attributesStream: IO.STREAM] = { writeBits: PROC [tpe: YggRep.TypedPrimitiveElement] = { SELECT tpe.docType FROM YggRep.unknown => ERROR; YggRep.int => { ri: REF INT32; ri _ NARROW[tpe.bits]; writeInt[attributesStream, ri^]; }; YggRep.shortRope => { rRope: ROPE; rRope _ NARROW[tpe.bits]; writeString[rRope, 0]; }; YggRep.rope => { len: INT; rRope: ROPE; rRope _ NARROW[tpe.bits]; len _ Rope.Length[rRope]; writeInt[attributesStream, len]; writeString[rRope, 0]; }; YggRep.float => { rReal: REF REAL32; rReal _ NARROW[tpe.bits]; TRUSTED { ptReal: LONG POINTER TO REAL32; ptReal _ LOOPHOLE[rReal]; IO.UnsafePutBlock[attributesStream, [LOOPHOLE[ptReal], 0, BYTES[REAL32]]]; }; }; YggRep.date => { rAccurateGMT: YggRep.AccurateGMT; rAccurateGMT _ NARROW[tpe.bits]; TRUSTED { ptAGMT: LONG POINTER TO YggRep.AccurateGMTRep; ptAGMT _ LOOPHOLE[rAccurateGMT]; IO.UnsafePutBlock[attributesStream, [LOOPHOLE[ptAGMT], 0, YggRep.AccurateGMTRepByteSize]]; }; }; YggRep.did => { rDID: DID; rDID _ NARROW[tpe.bits]; TRUSTED { ptDID: LONG POINTER TO DIDRep; ptDID _ LOOPHOLE[rDID]; IO.UnsafePutBlock[attributesStream, [LOOPHOLE[ptDID], 0, BYTES[DIDRep]]]; }; }; ENDCASE => { nullsToWrite: INT; rBits: REF YggRep.BitsRep; rBits _ NARROW[tpe.bits]; writeInt[attributesStream, rBits.validBytes]; TRUSTED { ptBits: LONG POINTER TO YggRep.BitsRep; ptBits _ LOOPHOLE[rBits]; IO.UnsafePutBlock[attributesStream, [LOOPHOLE[ptBits, LONG POINTER TO PBasics.RawBytes] + SIZE[YggRep.BitsRep[0]], 0, rBits.validBytes]]; }; nullsToWrite _ PBasics.charsPerWord - 1 - ((rBits.validBytes + PBasics.charsPerWord - 1) MOD PBasics.charsPerWord); IF nullsToWrite > 0 THEN TRUSTED {IO.UnsafePutBlock[attributesStream, [LOOPHOLE[AllNulls], 0 , nullsToWrite]];}; }; }; writeString: PROC [string: ROPE, extraChars: INT] = { len: INT; nullsToWrite: INT; len _ Rope.Length[string]; IF len > 0 THEN IO.PutRope[attributesStream, string]; nullsToWrite _ PBasics.charsPerWord - 1 - ((len + extraChars+ PBasics.charsPerWord - 1)) MOD PBasics.charsPerWord; nullsToWrite _ PBasics.charsPerWord - (len+extraChars) MOD PBasics.charsPerWord; TRUSTED {IO.UnsafePutBlock[attributesStream, [LOOPHOLE[AllNulls], 0 , nullsToWrite]];}; }; nullFieldNames: BOOL _ TRUE; singletonFieldValues: BOOL _ TRUE; numberOfAttributeValues: INT _ 0; primitiveType: YggRep.DocType _ YggRep.unknown; preample: YggRep.AttributePreamble; FOR rv: LIST OF YggRep.AttributeValue _ attribute.value, rv.rest UNTIL rv = NIL DO numberOfAttributeValues _ numberOfAttributeValues + 1; IF rv.first.fieldName # NIL THEN nullFieldNames _ FALSE; IF rv.first.valueSet.rest # NIL THEN singletonFieldValues _ FALSE; FOR avl: LIST OF YggRep.TypedPrimitiveElement _ rv.first.valueSet, avl.rest UNTIL avl = NIL DO tpe: YggRep.TypedPrimitiveElement = avl.first; IF tpe.docType < YggRep.date AND (primitiveType = YggRep.unknown OR primitiveType = tpe.docType) THEN primitiveType _ tpe.docType ELSE primitiveType _ 10000; ENDLOOP; ENDLOOP; preample[0].ordered _ attribute.ordered; preample[0].noFieldNames _ nullFieldNames; preample[0].singletonAttribute _ (numberOfAttributeValues = 1); preample[0].singletonField _ singletonFieldValues; preample[0].typeCode _ SELECT primitiveType FROM YggRep.int => integer, YggRep.rope => ropeLarge, YggRep.shortRope => ropeShort, YggRep.float => float, YggRep.date => date, YggRep.did => did, YggRep.uninterpretedBytes => uninterpretedBytes, ENDCASE => separate; IF numberOfAttributeValues <= 0 THEN RETURN; TRUSTED {IO.PutChar[attributesStream, LOOPHOLE[preample[0]]];}; -- @preample points to preample[0] writeString[attribute.attributeName, 1]; -- write attribute name IF numberOfAttributeValues # 1 THEN writeInt[attributesStream, numberOfAttributeValues]; -- write number of attribute values; FOR rv: LIST OF YggRep.AttributeValue _ attribute.value, rv.rest UNTIL rv = NIL DO IF ~nullFieldNames THEN writeString[rv.first.fieldName, 0]; -- write field name FOR avl: LIST OF YggRep.TypedPrimitiveElement _ rv.first.valueSet, avl.rest UNTIL avl = NIL DO tpe: YggRep.TypedPrimitiveElement = avl.first; IF preample[0].typeCode = separate THEN writeInt[attributesStream, tpe.docType]; writeBits[tpe]; ENDLOOP; IF ~preample[0].singletonField THEN writeInt[attributesStream, YggRep.unknown]; ENDLOOP; }; END. YggStabilizeImpl.mesa Copyright ำ 1988 by Xerox Corporation. All rights reserved. Bob Hagmann October 27, 1988 3:33:13 pm PDT Take a volatile form of a document, and write it onto some files. Exported procedures for transactions A transaction is trying to commit. Apply intentions. Take the volatile form of documents, and write them out fetch all the new values for the attribute Commit actually occured. Transaction has aborted. This transaction may or may not have gone through PreCommit. Smash object cache for the null transaction => this makes the system rebuild the cache from stable values the next time. That's semantically OK, but not fast. If there are lots of aborts (which is not the expected case), then this could be a performance loose. Exported conversion procedures apply link mods Given a document, write it out to the files. Given an attribute, write it out to the stream. See YggRep.mesa for a description of what the format is. Write the contents of a TypedPrimitiveElement. The type has already been writen. สฅ˜code•Mark outsideHeaderšœ™Kšœ<™KšœœJ˜f—K˜Kšัblnœœ˜Kšœœy˜ƒKšœ˜šœ˜K˜Kšœœœ˜K˜Kšœœœœ˜Kšœœœ˜+K˜Kšœ  œœœœ œœœ œ˜~—headšœ$™$šฯn œœœ˜-K™5K™7Kšœœœ ˜šœ œฯc"˜LKšœœœ˜Kšœ9 G˜€šœ˜Kšœ œœœ˜'š œœœœœ˜>šœœœ˜,Kšœ˜Kšœ˜K˜—Kšœ˜šœœœ˜š œœœœœ˜>Kšœœœ˜Kšœœœ˜,Kšœ˜—Kšœ'˜'Kšœ˜K˜——Kšœœ˜š œœœœœ˜>Kšœœ˜ Kšœœ˜#Kšœ'œœ˜4Kšœ!œœ˜.Kšœœœ˜%Kšœœœœ˜5Kšœœœœ˜"Kšœ7˜7Kšœ‰˜‰Kšœ2˜2KšœV˜VKšœœœœœœœ"œœ)œ˜ฎš œœ%œœ'œ ˜•Kšœ6œ˜:Kšœœœ˜/Kšœ2˜2šœœ˜"Kšœ^˜^šœ œœ˜K˜'Kšœ˜šœ7œ9œ˜zKšœ œ˜šœ>œ˜FKšœ•˜•KšœH˜HK˜(Kšœ˜K˜—K˜—K˜—K˜—˜Kšœ˜K˜—š œ%œœ'œ3œ˜Kšœb˜bšœœœ˜Kšœ{˜{KšœJ˜JK˜—K˜—Kšœ˜Kšœ˜—šœ%œœ !˜Sš œœœ2œœ˜Tš œœœœ.œœ˜Sšœ/œ˜7Kšœœ(˜JKšœ˜K˜—Kšœ˜—Kšœ˜—Kšœ˜—šœ"œœ %˜UKšœœœ˜/Kšœ2˜2KšœV˜VKšœO !˜pKš œœœœœœ˜HKšœZ˜ZKšœ˜—Kš œœœœœœ˜@šœ%œœ ˜PK˜Kšœ œœœ˜7Kšœ œœœ˜7Kšœ˜š œœœœ*œœ˜OK™*š œœœ.œœ˜PKšœ/œ œ˜cKšœ˜—š œœœ5œœ˜WKšœ/œ œ˜cKšœ˜—KšœR˜RKšœ˜—K˜—Kšœ˜—š œœœœœ˜>Kšœœœ˜,Kšœ˜—Kšœ˜—K˜—K˜—K˜šŸœœœ˜*K™Kšœœœ ˜Kšœ7˜7š œœœœœ˜>šœ œ˜(š œ%œœ$œ ˜xKšœBœ˜HKšœ(˜(Kšœ!˜!Kšœ%˜%Kšœ˜Kšœ˜Kšœœ˜!Kšœœ˜K˜—K˜—Kšœ:˜:Kšœ˜—K˜—K˜šŸœœœ˜)Kšœ+ฯrœกœ™VKšœœœ ˜Kšœ7˜7šœ œ &˜Pš œœœœœ˜>Kšœœ˜ Kšœ7˜7KšœV˜VšœO˜OKšœ†™†—š œ%œœ$œ ˜xKšœBœ˜IK˜—Kšœ(˜(Kšœ!˜!Kšœ%˜%Kšœ˜Kšœ˜Kšœœ˜!Kšœœ˜Kšœ˜—K˜—šœœ +˜4š œœœœœ˜>Kšœ8˜8Kšœ˜—K˜—K˜—K˜—šœ™š Ÿœœœ(œAœœ˜žšฯbœœ œœ&œœœ œœ˜–Kšœ˜š œœœ*œœ˜Nš œœœ-œœ˜Qšœ7œ˜?šœœ ˜+Kšœœ:˜TKšœ˜K˜—šœœ ˜Kšœœœ˜Kšœ œœ$˜4š œœœ@œ œ˜fKšœ œ˜ Kšœ"œœ˜/Kšœ œ˜#šœ1œ˜9Kšœ œ˜Kšœ œœ!˜6Kšœœ˜ Kšœ˜K˜—Kšœ˜Kšœ˜—Kšœ œœ˜K˜—K˜—šœœœœ˜+Kšœ œœ1˜[K˜—Kšœ˜—Kšœ˜—K˜—KšœœœD˜bš œœœAœœ˜eš œœœ2œœ˜Tšœ?œ˜GKšœœœœ˜*š œ œœ7œ œœ˜bJšœB˜BKšœ œ˜Jšœœœ˜(Jšœ œ ˜šœ2œ˜:Jšœœœ ˜0Jšœ˜Jšœ˜J˜—Jšœ˜šœœœ˜+Jšœ œœ˜'Jšœ œœœ&˜?Jšœœœ7œ ˜YJšœœ˜J˜—Jšœ˜—Kšœ˜K˜—šœœœœ˜+Jšœ˜Jš œ%œœœœ'˜bJšœ9˜9K˜—Kšœ˜—Kšœ˜—š œœœ?œœ˜{Kšœ9˜9Kšœ˜K™—KšœC˜CKšœ@˜@Kšœœœ)œ$˜mKšœœœ(œ#˜jKšœ˜K˜K˜—šŸœœ(œ5œKœœœœœ˜๙Kšœ,™,K˜K˜Kšœ7˜7K˜šœ œœ˜šœ˜!Kšœœ˜Kšœ>˜>šœ˜Kšœœœœ˜ Kšœœ˜ Kšœœ˜#KšœE˜EKšœ ˜"Kšœœ˜Kšœ˜K˜—šœ˜ Kšœœœœ˜ Kšœœ˜Kšœœ˜#KšœE˜Ešœ˜ Kšœ œœ˜'Kšœ ˜ Kšœ œ˜Kš œœ  œœœ*˜rKšœ;˜=K˜—Kšœœ˜Kšœ˜K˜——Kšœ˜K˜—šœœœ˜KšœI˜IKšœ2˜2š œœœ;œœ˜wKšœ9˜9Kšœ˜—Kš œœœœœœ&˜xK˜—K˜Kšœ9˜9K˜K˜K™—š ขœœœœœ˜:Kš œœœœœ˜!Kš œœ#œ œœ˜RKšœ˜—K˜šขœœ1œœ˜SKšœi™išข œœ(˜7KšœQ™Qšœ ˜Kšœœ˜šœ˜Kšœœœ˜Kšœœ ˜Kšœ ˜ K˜—šœ˜Kšœœ˜ Kšœœ ˜Kšœ˜K˜—šœ˜Kšœœ˜ Kšœœ˜ Kšœœ ˜Kšœ˜Kšœ ˜ Kšœ˜K˜—šœ˜Kšœœœ˜Kšœœ ˜šœ˜ Kšœ œœœ˜Kšœ œ˜Kšœ#œœ˜JKšœ˜—Kšœ˜—šœ˜Kšœ!˜!Kšœœ ˜ šœ˜ Kšœ œœ˜.Kšœ œ˜ Kšœ#œ-˜ZKšœ˜—Kšœ˜—šœ˜Kšœœ˜ Kšœœ ˜šœ˜ Kšœ œœ˜Kšœœ˜Kšœ#œ œ ˜IKšœ˜—Kšœ˜—šœ˜ Kšœœ˜Kšœœ˜Kšœœ ˜Kšœ-˜-šœ˜ Kšœ œœ˜'Kšœ œ˜Kš œ#œ  œœœ+˜‰Kšœ˜—KšœYœ˜sKš œœœœ#œ!˜pK˜——Kšœ˜—šข œœ œœ˜5Kšœœ˜ Kšœœ˜Kšœ˜Kšœ œœ#˜5KšœYœ˜rKšœ7œ˜PKšœœ#œ!˜WKšœ˜—Kšœœœ˜Kšœœœ˜"Kšœœ˜!Kšœ/˜/Kšœ#˜#š œœœ2œœ˜RKšœ6˜6Kšœœœœ˜8Kšœœœœ˜Bš œœœ<œœ˜^Kšœ.˜.Kš œœ!œœœ˜Kšœ˜—Kšœ˜—Kšœ(˜(Kšœ*˜*Kšœ?˜?Kšœ2˜2šœœ˜0Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ0˜0Kšœ ˜—Kšœœœ˜,Kšœœœ "˜cKšœ* ˜BKšœœ7 %˜š œœœ2œœ˜RKšœœ& ˜Qš œœœ<œœ˜^Kšœ.˜.Kšœ!œ)˜PKšœ˜Kšœ˜—Kšœœ,˜OKšœ˜—K˜K˜—™K™——K˜Kšœ˜—…—HPa