DIRECTORY BasicTime, Camelot, Commander, CommandTool, Convert, CountedVM, File, FileStream, FS, FSBackdoor, IO, Mach, PBasics, Process, Random, Rope, YggDID, YggDIDPrivate, YggDIDMap, YggDIDMapPrivate, YggLock, YggFixedNames, YggEnvironment, YggFile, YggFileStream, YggIndexMaint, YggInternal, YggMonitoringLog, YggRep, YggTransaction, YggVolatileObjectCache; VolatilizeTestImpl: CEDAR PROGRAM IMPORTS BasicTime, Commander, CommandTool, Convert, CountedVM, FileStream, FSBackdoor, IO, PBasics, Process, Random, Rope, YggDID, YggRep, YggVolatileObjectCache EXPORTS YggDID, YggDIDMap, YggFixedNames, YggMonitoringLog, YggLock, YggTransaction, YggIndexMaint, YggInternal, YggFile, YggFileStream = BEGIN ROPE: TYPE = Rope.ROPE; Contents: PUBLIC Rope.ROPE _ "$contents"; Inlinks: PUBLIC Rope.ROPE _ "$inlinks"; Outlinks: PUBLIC Rope.ROPE _ "$outlinks"; Parents: PUBLIC Rope.ROPE _ "$parents"; Children: PUBLIC Rope.ROPE _ "$children"; ParentContainers: PUBLIC Rope.ROPE _ "$parent-containers"; ChildContainers: PUBLIC Rope.ROPE _ "$child-containers"; AutoIndices: PUBLIC Rope.ROPE _ "$auto-indices"; IndexPrefix: PUBLIC Rope.ROPE _ "$index-"; IndexPrefixSize: PUBLIC INT _ Rope.Length[IndexPrefix]; notice: PUBLIC YggMonitoringLog.ProcsRecord _ []; BigRope: ROPE _ "Four score and seven years ago, our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great blah blah blah"; LittleRopes: ARRAY [0..3) OF ROPE _ ["foo", "bar", "bleah"]; attrNameArray: ARRAY [0..8] OF ROPE _ ["attr0", "thisisattribute1", "two", "attribute three is fairly long", "but then again, attribute four is longer than three", "and attribute five is longer than three and four together", "6", "sept", "eight"]; fieldNameArray: ARRAY [1..5] OF ROPE _ [NIL, "field2", "field3", "the name for field 4 is quite long", "field5"]; DID: PUBLIC TYPE ~ REF DIDRep; DIDRep: PUBLIC TYPE ~ YggDIDPrivate.DIDRep; Document: TYPE = REF DocumentRep; DocumentRep: PUBLIC TYPE = YggDIDMapPrivate.DocumentRep; FileHandle: TYPE = YggInternal.FileHandle; FileHandleRep: PUBLIC TYPE = RECORD [ did: YggDID.DID _ NIL, fileUse: ATOM _ NIL, -- use of the file (e. g., $contents) fileData: REF FileDataRep ]; Failed: PUBLIC ERROR [why: YggEnvironment.LockFailure] = CODE; Set: PUBLIC PROC [ trans: YggEnvironment.TransID, lock: YggLock.LockID, mode: YggLock.LockMode, wait: BOOL _ FALSE] RETURNS [granted: BOOL _ TRUE] ~ {}; MakeLockID: PUBLIC PROC [did: DID] RETURNS [lock: YggLock.LockID] ~ { segmentId: Camelot.segmentIdT; offset: Mach.vmOffsetT; segmentId _ [did.didHigh]; offset _ did.didLow; RETURN[[did: did, subEntity: [segmentId, offset]]]; }; TransID: TYPE = YggEnvironment.TransID; -- really a Camelot.tidT EqualTrans: PUBLIC PROC [transID1: TransID, transID2: TransID] RETURNS [equal: BOOL] ~ { IF transID1.top = transID2.top AND transID1.bottom = transID2.bottom THEN RETURN [TRUE] ELSE RETURN [FALSE]; }; IsNullTrans: PUBLIC PROC [ transID: YggTransaction.TransID] RETURNS [null: BOOL] ~ { RETURN [transID = YggEnvironment.nullTransID]; }; IsTopLevel: PUBLIC PROC [transID: TransID] RETURNS [topLevel: BOOL _ TRUE] ~ { }; UpdateDocList: LIST OF DocUpdate _ NIL; DocUpdate: TYPE = RECORD [ transID: TransID, inUse: BOOL, vDocs: LIST OF YggRep.VDoc ]; NotePossibleDocumentUpdate: PUBLIC PROC [transID: TransID, vDoc: YggRep.VDoc] ~ { unusedDocUpdate: LIST OF DocUpdate _ NIL; FOR udl: LIST OF DocUpdate _ UpdateDocList, udl.rest UNTIL udl = NIL DO IF EqualTrans[transID, udl.first.transID] THEN { FOR lovd: LIST OF YggRep.VDoc _ udl.first.vDocs, lovd.rest UNTIL lovd = NIL DO IF EqualDIDs[vDoc.did, lovd.first.did] THEN EXIT; REPEAT FINISHED => { udl.first.vDocs _ CONS[vDoc, udl.first.vDocs]; }; ENDLOOP; EXIT; }; IF unusedDocUpdate = NIL AND ~udl.first.inUse THEN unusedDocUpdate _ udl; REPEAT FINISHED => { IF unusedDocUpdate # NIL THEN { unusedDocUpdate.first.transID _ transID; unusedDocUpdate.first.inUse _ TRUE; unusedDocUpdate.first.vDocs _ LIST[vDoc]; } ELSE UpdateDocList _ CONS[[transID, TRUE, LIST[vDoc]], UpdateDocList]; }; ENDLOOP; }; GetPossibleDocumentUpdates: PUBLIC PROC [transID: TransID] RETURNS [ vDocs: LIST OF YggRep.VDoc _ NIL] ~ { FOR udl: LIST OF DocUpdate _ UpdateDocList, udl.rest UNTIL udl = NIL DO IF EqualTrans[transID, udl.first.transID] THEN { RETURN[udl.first.vDocs]; }; ENDLOOP; }; GetParent: PUBLIC PROC [ transID: YggTransaction.TransID] RETURNS [transFound: BOOL _ TRUE, parentTransID: YggTransaction.TransID _ YggEnvironment.nullTransID] ~ { }; NewValueForAttribute: PUBLIC PROC [did: YggDID.DID, tid: Camelot.tidT, attributeName: Rope.ROPE, oldValues: LIST OF LIST OF YggRep.AttributeValue, newValues: LIST OF LIST OF YggRep.AttributeValue] ~ { }; NewValueForMetaAttribute: PUBLIC PROC [did: YggDID.DID, tid: Camelot.tidT, metaAttributesChanged: LIST OF YggRep.metaAttributeMod] ~ { }; NewValueForAttributeCommitStatus: PUBLIC PROC [did: YggDID.DID, tid: Camelot.tidT, commited: BOOL] ~ { }; EqualDIDs: PUBLIC PROC [did1: DID, did2: DID] RETURNS [equal: BOOL] = { IF did1.didHigh = did2.didHigh AND did1.didLow = did2.didLow THEN RETURN [TRUE] ELSE RETURN [FALSE] }; SwapLinkInfo: PUBLIC PROC [doc: YggInternal.Document, newFromDID, newToDID: YggDID.DID, newLinkType: Rope.ROPE] RETURNS [oldFromDID, oldToDID: YggDID.DID, oldLinkType: Rope.ROPE] ~ { }; OpenDocumentFromDID: PUBLIC PROC [did: YggDID.DID, tid: Camelot.tidT] RETURNS [doc: YggInternal.Document _ NIL] = { FOR lokd: LIST OF DIDStuff _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO IF EqualDIDs[lokd.first.did, did] THEN {doc _ lokd.first.doc; EXIT}; ENDLOOP; }; GetComponentFiles: PUBLIC PROC [doc: Document] RETURNS [componentFiles: LIST OF YggInternal.FileHandle] ~ { RETURN[componentFiles _ doc.componentFiles]; }; AddComponentFile: PUBLIC PROC [doc: Document, componentFile: YggInternal.FileHandle, tid: Camelot.tidT] ~ { lastCF: LIST OF YggInternal.FileHandle _ NIL; FOR files: LIST OF YggInternal.FileHandle _ doc.componentFiles, files.rest UNTIL files = NIL DO lastCF _ files; ENDLOOP; IF lastCF = NIL THEN doc.componentFiles _ CONS[componentFile, NIL] ELSE lastCF.rest _ CONS[componentFile, NIL]; }; FileFromComponentFiles: PUBLIC PROC [componentFiles: LIST OF YggInternal.FileHandle, fileUse: ATOM] RETURNS [file: FileHandle _ NIL] ~ { FOR cf: LIST OF FileHandle _ componentFiles, cf.rest UNTIL cf = NIL DO IF cf.first.fileUse = fileUse THEN { RETURN[cf.first]; }; ENDLOOP; }; StreamFromComponentFilesAndTid: PUBLIC PROC [componentFiles: LIST OF YggInternal.FileHandle, fileUse: ATOM, tid: Camelot.tidT] RETURNS [stream: IO.STREAM _ NIL] = { FOR cf: LIST OF YggInternal.FileHandle _ componentFiles, cf.rest UNTIL cf = NIL DO IF cf.first.fileUse = fileUse THEN { stream _ StreamFromOpenFileAndTid[cf.first, tid]; RETURN; }; ENDLOOP; }; fileLengthZero: SIGNAL = CODE; StreamFromOpenFileAndTid: PUBLIC PROC [file: FileHandle, tid: Camelot.tidT] RETURNS [stream: IO.STREAM _ NIL] = { fsOpenFile: FS.OpenFile; fsOpenFile _ FSBackdoor.CreateProcsOpenFile[clientFile: file.fileData, fileProcs: FileProcs]; stream _ FileStream.StreamFromOpenFile[fsOpenFile, write, start, [FALSE, FALSE, TRUE], [1,1]]; IF file.fileData.bytes # IO.GetLength[stream] THEN ERROR; IF file.fileData.bytes # IO.GetLength[stream] THEN ERROR; }; PagesForBytes: PUBLIC PROC [bytes: CARD] RETURNS [pages: YggFile.PageCount] ~ { IF bytes = 0 THEN RETURN [0] ELSE RETURN[PBasics.ShiftRight[[int[(bytes-1)]], YggFile.logBytesPerPage].int + 1]; }; FileProcs: REF FSBackdoor.FileProcs _ FSBackdoor.CreateFileProcs[GetClass, SameFile, GetName, GetInfo, SetPageCount, SetByteCountAndCreatedTime, Read, Write, Close]; FileDataRep: TYPE = RECORD [ pages: INT, bytes: INT, pageStorage: LIST OF pageStorageRep, tid: Camelot.tidT ]; pageStorageRep: TYPE = RECORD [ pageNo: INT, pageAddress: CountedVM.Handle ]; Create: PUBLIC PROC [size: YggFile.PageCount, did: YggDID.DID, fileUse: ATOM, nearToDid: YggDID.DID, tid: Camelot.tidT] RETURNS [file: FileHandle _ NIL] ~ { file _ NEW[FileHandleRep _ [did: did, fileUse: fileUse, fileData: NEW[FileDataRep _ [pages: size, bytes: 0, pageStorage: NIL, tid: tid]]]]; FOR nowPage: INT IN [0..size) DO file.fileData.pageStorage _ CONS[[nowPage, CountedVM.Allocate[File.wordsPerPage]], file.fileData.pageStorage]; ENDLOOP; }; GetClass: PROC [clientFile: REF] RETURNS [ATOM] = { RETURN [$YggdrasilTest]; }; SameFile: PROC [clientFile1, clientFile2: REF] RETURNS [BOOL] = { ERROR; }; GetName: PROC [clientFile: REF] RETURNS [fullFName, attachedTo: Rope.ROPE] = { WITH clientFile SELECT FROM fileData: REF FileDataRep => { RETURN [NIL, NIL]; }; ENDCASE => ERROR; }; GetInfo: PROC [clientFile: REF] RETURNS [keep: CARDINAL _ 1, pages, bytes: INT, created: BasicTime.GMT _ BasicTime.Now[], lock: FS.Lock _ write, fileType: FS.FileType] = { WITH clientFile SELECT FROM fileData: REF FileDataRep => { pages _ fileData.pages; bytes _ fileData.bytes; }; ENDCASE => ERROR; }; SetPageCount: PROC [clientFile: REF, pages: INT] = { WITH clientFile SELECT FROM fileData: REF FileDataRep => { maxPage: INT _ -1; fileData.pages _ pages; FOR lops: LIST OF pageStorageRep _ fileData.pageStorage, lops.rest UNTIL lops = NIL DO IF lops.first.pageNo > maxPage THEN maxPage _ lops.first.pageNo; ENDLOOP; FOR nowPage: INT IN (maxPage..pages) DO fileData.pageStorage _ CONS[[nowPage, CountedVM.Allocate[File.wordsPerPage]], fileData.pageStorage]; ENDLOOP; }; ENDCASE => ERROR; }; SetByteCountAndCreatedTime: PROC [clientFile: REF, bytes: INT, created: BasicTime.GMT] = { WITH clientFile SELECT FROM fileData: REF FileDataRep => { fileData.bytes _ bytes; IF bytes # fileData.bytes THEN ERROR; }; ENDCASE => ERROR; }; notFirst: INT _ 0; Read: UNSAFE PROC [clientFile: REF, from, nPages: INT, to: LONG POINTER] = { WITH clientFile SELECT FROM fileData: REF FileDataRep => { toPtr: LONG POINTER _ to; nPagesLeft: INT _ nPages; FOR nowPage: INT IN [from .. from + nPages) DO IF nowPage # from THEN notFirst _ notFirst + 1; FOR lops: LIST OF pageStorageRep _ fileData.pageStorage, lops.rest UNTIL lops = NIL DO IF lops.first.pageNo = nowPage THEN { TRUSTED {PBasics.Move[dst: toPtr, src: lops.first.pageAddress.pointer, nWords: File.wordsPerPage/2]; }; toPtr _ toPtr + File.wordsPerPage*UNITS[WORD]; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; ENDLOOP; }; ENDCASE => ERROR; }; Write: PROC [clientFile: REF, to: INT, nPages: INT, from: LONG POINTER] = { WITH clientFile SELECT FROM fileData: REF FileDataRep => { fromPtr: LONG POINTER _ from; nPagesLeft: INT _ nPages; FOR nowPage: INT IN [to .. to + nPages) DO FOR lops: LIST OF pageStorageRep _ fileData.pageStorage, lops.rest UNTIL lops = NIL DO IF lops.first.pageNo = nowPage THEN { TRUSTED {PBasics.Move[dst: lops.first.pageAddress.pointer, src: fromPtr, nWords: File.wordsPerPage/2]; }; fromPtr _ fromPtr + File.wordsPerPage*UNITS[WORD]; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; ENDLOOP; }; ENDCASE => ERROR; }; Close: PROC [clientFile: REF] = { }; NextDID: DIDRep _ [33, 400]; KnownDIDs: LIST OF DIDStuff _ NIL; NumberOfKnownDIDs: INT _ 0; DIDStuff: TYPE = RECORD [ did: DID, doc: Document, contents: YggRep.TypedPrimitiveElement, attributes: LIST OF YggRep.Attribute _ NIL ]; NextTransCount: CARD _ 10001; GetNextTrans: PROC RETURNS [transID: YggTransaction.TransID] ~ { NextTransCount _ NextTransCount + 1; transID _ [top: [lowTicker: NextTransCount], bottom: []]; }; GetNextDID: PROC RETURNS [did: YggDID.DID] ~ { did _ NEW[YggDIDPrivate.DIDRep _ [NextDID.didHigh, NextDID.didLow]]; NextDID.didLow _ NextDID.didLow + 1; }; GetNextDIDWithEmptyDoc: PROC RETURNS [did: YggDID.DID, doc: Document, didStuff: LIST OF DIDStuff] ~ { did _ GetNextDID[]; doc _ NEW[DocumentRep _ [did: did, name: NIL, componentFiles: NIL]]; didStuff _ KnownDIDs _ CONS[[did: did, doc: doc], KnownDIDs]; NumberOfKnownDIDs _ NumberOfKnownDIDs + 1; }; DoCommit: PROC [transID: YggTransaction.TransID] ~ { YggRep.PreCommit[transID]; YggRep.Commit[transID]; FOR udl: LIST OF DocUpdate _ UpdateDocList, udl.rest UNTIL udl = NIL DO IF EqualTrans[transID, udl.first.transID] THEN { udl.first.inUse _ FALSE; EXIT; }; ENDLOOP; }; VolatilizeTestProc: Commander.CommandProc = { MakeUpTPE: PROC RETURNS [tpe: YggRep.TypedPrimitiveElement] ~ { tpe.docType _ Random.ChooseInt[randomStream, 1, 8]; SELECT tpe.docType FROM YggRep.int => { tpe.bits _ NEW[INT _ Random.ChooseInt[randomStream, 1, 1066]]; }; YggRep.rope => { tpe.bits _ BigRope; }; YggRep.shortRope => { randr: INT = Random.ChooseInt[randomStream, 0, 2]; tpe.bits _ LittleRopes[randr]; }; YggRep.float => { rr: REAL32; ii: INT ; ii _ Random.ChooseInt[randomStream, 1, 1492]; rr _ ii; tpe.bits _ NEW[REAL32 _ rr]; }; YggRep.date => { newData: YggRep.AccurateGMT; newData _ NEW[YggRep.AccurateGMTRep _ [BasicTime.Now[], Random.ChooseInt[randomStream, 1, 1789]]]; tpe.bits _ newData; }; YggRep.did => { newDID: DID; newDID _ GetNextDID[]; tpe.bits _ newDID; }; YggRep.uninterpretedBytes => { noBytes: INT _ Random.ChooseInt[randomStream, 1, 1920]; theBytes: REF YggRep.BitsRep; theBytes _ NEW[YggRep.BitsRep[noBytes]]; theBytes.validBytes _ Random.ChooseInt[randomStream, 1, noBytes]; FOR byteNo: CARD IN [0..theBytes.validBytes) DO theBytes.b[byteNo] _ Random.ChooseInt[randomStream, 1, 255]; ENDLOOP; tpe.bits _ theBytes; }; 8 => { noBytes: INT _ Random.ChooseInt[randomStream, 1, 1920]; theBytes: REF YggRep.BitsRep; tpe.docType _ Random.ChooseInt[randomStream, YggRep.lastReservedDocType+1, YggRep.lastReservedDocType+1334]; theBytes _ NEW[YggRep.BitsRep[noBytes]]; theBytes.validBytes _ Random.ChooseInt[randomStream, 1, noBytes]; FOR byteNo: CARD IN [0..theBytes.validBytes) DO theBytes.b[byteNo] _ Random.ChooseInt[randomStream, 1, 255]; ENDLOOP; tpe.bits _ theBytes; }; ENDCASE => ERROR; }; CompareTPE: PROC [tpe1: YggRep.TypedPrimitiveElement, tpe2: YggRep.TypedPrimitiveElement] ~ { IF tpe1.docType # tpe2.docType THEN ERROR; SELECT tpe1.docType FROM YggRep.int => { vInt: REF INT; mInt: REF INT; vInt _ NARROW[tpe1.bits]; mInt _ NARROW[tpe2.bits]; IF vInt^ # mInt^ THEN ERROR; }; YggRep.rope => { biggaRope: ROPE; biggaRope _ NARROW[tpe1.bits]; IF ~Rope.Equal[biggaRope, BigRope] THEN ERROR; }; YggRep.shortRope => { smallaRope: ROPE; listRope: ROPE; smallaRope _ NARROW[tpe1.bits]; listRope _ NARROW[tpe2.bits]; IF ~Rope.Equal[smallaRope, listRope] THEN ERROR; }; YggRep.float => { vReal: REF REAL32; mReal: REF REAL32; vReal _ NARROW[tpe1.bits]; mReal _ NARROW[tpe2.bits]; IF vReal^ # mReal^ THEN ERROR; }; YggRep.date => { vDate: YggRep.AccurateGMT; mDate: YggRep.AccurateGMT; vDate _ NARROW[tpe1.bits]; mDate _ NARROW[tpe2.bits]; IF BasicTime.Period[vDate.gmt, mDate.gmt] # 0 THEN ERROR; IF vDate.usecs # mDate.usecs THEN ERROR; }; YggRep.did => { vDID: DID; mDID: DID; vDID _ NARROW[tpe1.bits]; mDID _ NARROW[tpe2.bits]; IF ~YggDID.EqualDIDs[vDID, mDID] THEN ERROR; }; YggRep.uninterpretedBytes => { vUnintBytes: REF YggRep.BitsRep; mUnintBytes: REF YggRep.BitsRep; vUnintBytes _ NARROW[tpe1.bits]; mUnintBytes _ NARROW[tpe2.bits]; IF vUnintBytes.validBytes # mUnintBytes.validBytes THEN ERROR; FOR byteNo: CARD IN [0..vUnintBytes.validBytes) DO IF vUnintBytes.b[byteNo] # mUnintBytes.b[byteNo] THEN ERROR; ENDLOOP; }; IN [YggRep.lastReservedDocType+1 .. YggRep.lastReservedDocType+1334] => { vUnintBytes: REF YggRep.BitsRep; mUnintBytes: REF YggRep.BitsRep; vUnintBytes _ NARROW[tpe1.bits]; mUnintBytes _ NARROW[tpe2.bits]; IF vUnintBytes.validBytes # mUnintBytes.validBytes THEN ERROR; FOR byteNo: CARD IN [0..vUnintBytes.validBytes) DO IF vUnintBytes.b[byteNo] # mUnintBytes.b[byteNo] THEN ERROR; ENDLOOP; }; ENDCASE => ERROR; }; CheckADID: PROC [lokd: LIST OF DIDStuff] ~ { vDoc: YggRep.VDoc _ NIL; trans: YggTransaction.TransID; vDocAttCount: INT _ 0; savedAttCount: INT _ 0; YggVolatileObjectCache.InvalidateDID[did: lokd.first.did, transID: YggEnvironment.nullTransID]; IF YggVolatileObjectCache.LookupDIDInCache[did: lokd.first.did, transID: YggEnvironment.nullTransID, mode: read] # NIL THEN ERROR; trans _ GetNextTrans[] ; vDoc _ YggRep.VolatizeFromDID[transID: trans, did: lokd.first.did, access: readOnly, lock: [read, wait], metaAttributesOnly: FALSE]; IF ~EqualDIDs[vDoc.did, lokd.first.did] THEN ERROR; CompareTPE[vDoc.contents, lokd.first.contents]; FOR aL: LIST OF YggRep.Attribute _ lokd.first.attributes, aL.rest UNTIL aL = NIL DO FOR aLVDoc: LIST OF YggRep.Attribute _ vDoc.attributes, aLVDoc.rest UNTIL aLVDoc = NIL DO IF Rope.Equal[aL.first.attributeName, aLVDoc.first.attributeName] THEN { savedValue: LIST OF YggRep.AttributeValue _ aL.first.value; vDocValue: LIST OF YggRep.AttributeValue _ aLVDoc.first.value; FOR loav: LIST OF YggRep.AttributeValue _ vDocValue, loav.rest UNTIL loav = NIL DO savedValueSet: LIST OF YggRep.TypedPrimitiveElement; IF savedValue = NIL THEN ERROR; savedValueSet _ savedValue.first.valueSet; IF ~Rope.Equal[savedValue.first.fieldName, loav.first.fieldName] THEN ERROR; FOR vtpeList: LIST OF YggRep.TypedPrimitiveElement _ loav.first.valueSet, vtpeList.rest UNTIL vtpeList = NIL DO IF savedValueSet = NIL THEN ERROR; CompareTPE[vtpeList.first, savedValueSet.first]; savedValueSet _ savedValueSet.rest; ENDLOOP; IF savedValueSet # NIL THEN ERROR; savedValue _ savedValue.rest; ENDLOOP; IF savedValue # NIL THEN ERROR; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; savedAttCount _ savedAttCount + 1; ENDLOOP; FOR aL: LIST OF YggRep.Attribute _ vDoc.attributes, aL.rest UNTIL aL = NIL DO vDocAttCount _ vDocAttCount + 1; ENDLOOP; IF vDocAttCount # savedAttCount THEN ERROR; DoCommit[trans]; }; argv: CommandTool.ArgumentVector; out: IO.STREAM; randomStream: Random.RandomStream; noisy: BOOL _ FALSE; offset: INT _ 0; noTests: INT; out _ cmd.out; argv _ CommandTool.Parse[cmd: cmd ! CommandTool.Failed => {msg _ errorMsg; GO TO failed}]; IF argv.argc < 2 THEN GOTO failed; IF Rope.InlineFetch[argv[1], 0] = '- THEN { c: CHAR; IF argv[1].Length[] # 2 THEN GOTO failed; c _ argv[1].InlineFetch[1] ; SELECT c FROM 'n => noisy _ TRUE; ENDCASE; offset _ 1; }; noTests _ Convert.IntFromRope[argv[1+offset] ! Convert.Error => GOTO failed]; KnownDIDs _ NIL; NumberOfKnownDIDs _ 0; UpdateDocList _ NIL; NextDID.didHigh _ LOOPHOLE[BasicTime.Now[], PBasics.LongNumber].lo; [] _ GetNextDID[]; IF noTests <= 0 THEN RETURN; randomStream _ Random.Create[range: 16384, seed: -1] ; FOR loopCount: INT IN (0..noTests] DO rand: INT _ Random.ChooseInt[randomStream, 0, 24]; Process.CheckForAbort[]; IF loopCount = noTests THEN rand _ 0; SELECT rand FROM IN [0..3) => { -- volatalize and look up old did lokd: LIST OF DIDStuff; IF NumberOfKnownDIDs <= 0 THEN LOOP; FOR lokd _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO CheckADID[lokd]; ENDLOOP; IF noisy THEN out.PutF["\nLook Up All Old Dids\n\n"]; }; IN [3..13) => { -- make new doc with a contents newDID: DID; doc: Document; didStuff: LIST OF DIDStuff; contents: YggRep.TypedPrimitiveElement; vDoc: YggRep.VDoc; trans: YggTransaction.TransID; trans _ GetNextTrans[] ; [newDID, doc, didStuff] _ GetNextDIDWithEmptyDoc[]; vDoc _ YggRep.VolatizeFromDID[trans, newDID, readWrite, [write, wait]]; contents _ MakeUpTPE[]; didStuff.first.contents _ contents; vDoc.contents _ contents; vDoc.contentsChanged _ TRUE; DoCommit[trans]; IF noisy THEN out.PutF["Make new doc: did= %g\n", IO.card[newDID.didLow] ]; }; IN [8..16) => { -- volatalize and look up old did rand: INT; lokd: LIST OF DIDStuff; IF NumberOfKnownDIDs <= 0 THEN LOOP; rand _ Random.ChooseInt[randomStream, 0, MIN[16384, NumberOfKnownDIDs]]; FOR lokd _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO rand _ rand - 1; IF rand <= 0 THEN EXIT; ENDLOOP; IF lokd = NIL THEN LOOP; CheckADID[lokd]; IF noisy THEN out.PutF["look up old did: did= %g\n", IO.card[lokd.first.did.didLow] ]; }; IN [16..24) => { -- add attribute to did rand: INT; trans: YggTransaction.TransID; lokd: LIST OF DIDStuff; attrName: ROPE; noAttrVals: INT ; property: YggRep.Attribute; fieldTaken: ARRAY [1..5] OF BOOL _ ALL[FALSE]; vDoc: YggRep.VDoc _ NIL; IF NumberOfKnownDIDs <= 0 THEN LOOP; rand _ Random.ChooseInt[randomStream, 0, MIN[16384, NumberOfKnownDIDs]]; FOR lokd _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO rand _ rand - 1; IF rand <= 0 THEN EXIT; ENDLOOP; IF lokd = NIL THEN LOOP; trans _ GetNextTrans[] ; vDoc _ YggRep.VolatizeFromDID[transID: trans, did: lokd.first.did, access: readWrite, lock: [write, wait], metaAttributesOnly: FALSE]; IF ~EqualDIDs[vDoc.did, lokd.first.did] THEN ERROR; IF vDoc.contents.docType # lokd.first.contents.docType THEN ERROR; FOR tryNo: INT IN [0..7] DO propExists: BOOL _ FALSE; rand _ Random.ChooseInt[randomStream, 0, 8]; attrName _ attrNameArray[rand]; FOR aL: LIST OF YggRep.Attribute _ vDoc.attributes, aL.rest UNTIL aL = NIL DO IF Rope.Equal[aL.first.attributeName, attrName] THEN { propExists _ TRUE; EXIT; }; ENDLOOP; IF ~propExists THEN EXIT; attrName _ NIL; ENDLOOP; IF attrName = NIL THEN {DoCommit[trans]; LOOP;}; noAttrVals _ Random.ChooseInt[randomStream, 1, 5]; property.value _ NIL; FOR attrValNo: INT IN [0..noAttrVals) DO attrVal: YggRep.AttributeValue; fni: INT; fni _ noAttrVals _ Random.ChooseInt[randomStream, 1, 5]; IF fieldTaken[fni] THEN LOOP; fieldTaken[fni] _ TRUE; attrVal.fieldName _ fieldNameArray[fni]; attrVal.valueSet _ NIL; FOR tpeNo: INT IN [1..fni] DO attrVal.valueSet _ CONS[MakeUpTPE[], attrVal.valueSet]; ENDLOOP; property.value _ CONS[attrVal, property.value]; ENDLOOP; property.attributeName _ attrName; vDoc.attributes _ CONS[property, vDoc.attributes]; lokd.first.attributes _ CONS[property, lokd.first.attributes]; vDoc.namesOfAttributesChanged _ LIST[attrName]; DoCommit[trans]; IF noisy THEN out.PutF["add attribute to old did: did= %g\n", IO.card[lokd.first.did.didLow]]; }; ENDCASE; ENDLOOP; EXITS failed => {result _ $Failure}; }; Init: PROC = { Commander.Register["VolatilizeTest", VolatilizeTestProc, "VolatilizeTest noTests"]; }; Init[]; END. ¬VolatilizeTestImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Bob Hagmann October 27, 1988 1:22:03 pm PDT Exported junk Construct the lock identifier for the did Note that this did/attributeName has a new value. Note that this did/metaattribute has a new value. Called during Pre-Commit. Note state of previous NewValueForAttribute or NewValueForMetaAttribute call(s). Called during Commit or Abort. Compare the dids. Exported good stuff My files Global data Local procs VolatilizeTest Command [cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL] CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...] Initialization Κa˜šœ™Icodešœ<™K˜—Jš žœ œVœœ œ˜˜J˜š ž œœœœœ˜EJ™)Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ-˜3J˜—K˜Kšœ œŸ˜Aunitš ž œœœ(œ œ˜XKšœœ#œœœœœœ˜lK˜—š ž œœœ$œœ˜TKšœ(˜.K˜—š ž œœœœ  œ˜NK˜—M˜'˜Kšœ˜K˜ Kšœ˜K˜—šžœœœ*˜QKšœœœ˜)š œœœ%œœ˜Gšœ(œ˜0šœN˜NKšœ1˜1˜Kšœ.˜.K˜—K˜—Kšœ˜K˜—Kšœœœœ˜I˜šœ˜Kšœ(˜(Kšœ#˜#Kšœ)˜)K˜—KšœG˜GK˜—Kšœ˜—K˜—šžœœœœ œœœ˜jš œœœ%œœ˜Gšœ(œ˜0Kšœ˜K˜—Kšœ˜—K˜K˜K˜—š ž œœœ$œœœI˜£M˜—šžœœœœ$ œ œœœœ#œœœœ˜ΘKšœ1™1K˜K˜—š žœ œœ,œœ˜†KšœL™LK˜—šž œ œœœ˜fKšœp™pK˜—š ž œ œœœœ œ˜GKšœ Οoœ™Kšœœœœœœœœ˜cK˜K™—šž œ œ:œœœœœ˜ΆK˜K™——™K˜š žœœœœœœ˜sš œœœ!œœ˜EKšœ œ˜DKšœ˜—K˜—š žœ œœœœ˜lKšœ,˜,K˜—šžœ œN˜kKšœœœ˜-šœ œœM˜_Kšœ˜K˜—Kš œ œœœœ˜BKšœœœœ˜-K˜K˜—šžœœœœœ"œœœ˜ˆš œœœ&œœœ˜Gšœœ˜$Kšœ ˜K˜—Kšœ˜—K˜K˜—šžœœœœœ"œœ œœœ˜€š œœœ2œœœ˜Sšœœ˜$Kšœ1˜1Kšœ˜K˜—Kšœ˜—K˜K˜—M˜šžœœœ'œ œœœ˜qKšœ œ ˜Kšœ]˜]Kšœ^˜^Kšœœœœ˜9Kšœœœœ˜9K˜—šž œ œ œœ˜OKš œ œœœœH˜pK˜K˜—K™—™ K˜Kšž œœ—˜₯code2šœ œœ˜Nšœœ˜ Nšœœ˜ N˜$Nšœ˜Nšœ˜—šœœœ˜Nšœœ˜ Nšœ˜N˜—K˜K˜šžœœœ'œ œœœœ˜œKšœiœ!˜‹šœ œœ ˜ NšœœN˜nNšœ˜—K˜K™—š žœœœœœ˜3Nšœ˜K˜K˜—š žœœœœœ˜AKšœ˜K˜K˜—š žœœœœœ˜Nšœ œ˜šœ œ˜Nšœœœ˜Nšœ˜—Nšœœ˜—K˜K˜—Kš žœœœœ œœ˜Oš œœ œœœ˜^šœ œ˜šœ œ˜Kšœ˜Kšœ˜Nšœ˜—Nšœœ˜—K˜K˜—šž œœœ œ˜4šœ œ˜šœ œ˜K˜Kšœ˜š œœœ2œœ˜VJšœ@˜@Nšœ˜—šœ œœ˜'NšœœI˜dNšœ˜—Nšœ˜—Nšœœ˜—K˜K˜—š žœœœ œœ˜]šœ œ˜šœ œ˜Kšœ˜Kšœ%˜%Nšœ˜—Nšœœ˜—K˜K˜—Kšœ˜K˜šžœœœœœœœ˜Lšœ œ˜šœ œ˜Nšœœœ˜Nšœ œ ˜šœ œœ˜.Nšœ/˜/š œœœ2œœ˜Všœœ˜%Nšœ`˜gNšœ"œœ˜.Nšœ˜N˜—Nšœœœ˜Nšœ˜—Nšœ˜—Nšœ˜—Nšœœ˜—K˜K˜—šžœœœœ œœœ˜Kšœ œ˜šœ œ˜Nšœ œœ˜Nšœ œ ˜šœ œœ˜*š œœœ2œœ˜Všœœ˜%Nšœb˜iNšœ&œœ˜2Nšœ˜N˜—Nšœœœ˜Nšœ˜—Nšœ˜—Nšœ˜—Nšœœ˜—K˜K˜—šžœœœ˜!K˜—K™—™ K˜Kšœ˜K˜Kšœ œœ œ˜"Kšœ˜˜K˜ K˜Kšœ'˜'Kšœ œœ˜*K˜—Kšœ˜K™—™ K˜šž œœœ&˜@Kšœ$˜$Kšœ9˜9K˜—šž œœœœ˜.Kšœœ;˜DKšœ$˜$K˜—š žœœœœœœ˜eKšœ˜Kšœ!œœœ˜DKšœœ"˜=Kšœ*˜*K˜—šžœœ&˜4Kšœ˜Kšœ˜š œœœ%œœ˜Gšœ(œ˜0Kšœ˜Kšœ˜K˜—Kšœ˜—K˜K˜—K™—šœ™K™šžœ˜-š œœ œœœœ™:Kšœœœ™Gšž œœœ(˜?Jšœ3˜3šœ œ˜šœ˜Jšœ œœ,˜>J˜—šœ˜Jšœ˜J˜—šœ˜Icode1šœœ(˜2Jšœ˜J˜—šœ˜Jšœœ˜ Jšœœ˜ Jšœ-˜-J˜Jšœ œœ˜J˜—šœ˜Jšœ˜Jšœ œU˜bJšœ˜J˜—šœ˜Jšœœ˜ Jšœ˜Jšœ˜J˜—šœ˜Jšœ œ+˜7Jšœ œ˜Jšœ œ˜(JšœA˜Ašœ œœ˜/Jšœ<˜šœ œœ˜2Jšœ/œœ˜šœ œœ˜2Jšœ/œœ˜š œœœ.œœ˜ROšœœœ˜4Ošœœœœ˜Ošœ*˜*Ošœ?œœ˜LšœœœZ˜oOšœ"˜"Ošœ0˜0Ošœ#˜#O˜—Ošœ"˜"Ošœ˜Ošœ˜—Ošœ˜O˜O˜—O˜Ošœ˜—Ošœ"˜"Ošœ˜—š œœœ-œœ˜MOšœ ˜ Ošœ˜—Ošœœœ˜+Ošœ˜K˜—Kšœ!˜!Kšœœœ˜Ošœ"˜"Ošœœœ˜Ošœœ˜Kšœ œ˜ K˜KšœKœœ ˜ZKšœœœ˜"šœ#œ˜+Jšœœ˜Jšœœœ˜)Jšœ˜šœ˜ Jšœœ˜Jšœ˜—J˜ J˜—Kšœ@œ ˜MOšœ œ˜Ošœ˜O˜Ošœœ)˜COšœ˜Ošœœœ˜Ošœ6˜6šœ œœ˜%Ošœœ)˜2Ošœ˜Ošœ%˜%šœ˜šœ Ÿ!˜0Ošœœœ ˜Ošœœœ˜$šœœœ˜3Ošœ˜Ošœ˜—Ošœœ(˜5O˜—šœŸ˜/Ošœœ˜ Kšœ˜Kšœ œœ ˜Kšœ'˜'Kšœ˜Ošœ˜Ošœ˜Ošœ3˜3KšœG˜GJšœ˜Jšœ#˜#Jšœ˜Kšœœ˜Ošœ˜Ošœœ%œ˜KO˜—šœŸ!˜1Ošœœ˜ Ošœœœ ˜Ošœœœ˜$Ošœ)œ˜Hšœœœ˜3Ošœ˜Ošœ œœ˜Ošœ˜—Ošœœœœ˜Ošœ˜Ošœœ(œ˜VO˜—šœŸ˜(Ošœœ˜ Ošœ˜Ošœœœ ˜Ošœ˜O˜Ošœ˜Ošœ.˜.Ošœœ˜Ošœ$˜$OšœH˜Hšœ3˜3Ošœ˜Ošœ˜O˜—Ošœ˜Ošœ˜Ošœ€œ˜‡Ošœ3˜3OšœB˜B˜O˜Ošœ,˜,Ošœ˜š œœœ-œœ˜Mšœ0œ˜6O˜O˜O˜—Ošœ˜—O˜Ošœ˜Ošœ˜—Ošœ œœœ˜0Ošœ2˜2Ošœ˜šœ(˜(Ošœ œ˜Ošœ ˜ Ošœ8˜8Ošœ˜Ošœ˜Ošœ(˜(Ošœ˜šœ˜Ošœ7˜7O˜—Ošœ/˜/O˜—Ošœ"˜"Ošœ2˜2Ošœ>˜>Ošœ/˜/Ošœ˜Ošœœ1œ˜^O˜—Ošœ˜—Ošœ˜—š˜Kšœ˜—O˜J˜O˜——K˜K˜—™K˜šžœœ˜šœS˜SK˜—K˜K˜K˜—K˜—K˜Kšœ˜K™J˜—…—ULsY