<> <> <> DIRECTORY Disk, File, FileBackdoor, FileInternal, FS, FSBackdoor, Random, Rope, VM; FileSpliceTester: CEDAR PROGRAM IMPORTS FileBackdoor, FileInternal, FS, FSBackdoor, Random, VM = BEGIN DoTest: PROC [fileName: Rope.ROPE, size: INT, numberOfSplices: INT ] = { vmBuffer: VM.Interval _ VM.nullInterval; { ENABLE UNWIND => IF vmBuffer # VM.nullInterval THEN TRUSTED { VM.Free[vmBuffer ! VM.AddressFault => CONTINUE;]; }; file: FS.OpenFile; fileFile: File.Handle; offset: INT _ 0; dummy1, dummy2: INT _ 0; bufferPointer: LONG POINTER; randomStream: Random.RandomStream; MarkTypeArray: TYPE = RECORD [ pages: SEQUENCE count: CARDINAL OF RECORD [ mark: INT _ 0, page: Disk.PageNumber _ [0] ]]; wordZero: REF MarkTypeArray _ NEW[MarkTypeArray[size]]; file _ FS.Create[name: fileName, setPages: TRUE, pages: size, setKeep: TRUE, keep: 100]; fileFile _ FSBackdoor.GetFileHandle[file]; randomStream _ Random.Create[range: 10000, seed: -1] ; offset _ Random.ChooseInt[randomStream, 1, 10000]; vmBuffer _ VM.Allocate[count: 1]; TRUSTED { bufferPointer _ VM.AddressForPageNumber[vmBuffer.page]; }; FOR page: INT IN [0..size) DO runPage: Disk.PageNumber; intBuffer: LONG POINTER TO ARRAY [0..8) OF INT = LOOPHOLE[bufferPointer]; TRUSTED { wordZero.pages[page].mark _ intBuffer[0] _ offset+page;}; TRUSTED{ [diskPage: runPage] _ FileInternal.FindRun[start: [page], nPages: 1, runTable: LOOPHOLE[fileFile, FileInternal.Handle].runTable] }; wordZero.pages[page].page _ runPage; file.Write[to: page, nPages: 1, from: bufferPointer]; ENDLOOP; FOR spliceNo: INT IN [0..numberOfSplices) DO page: INT _ Random.ChooseInt[randomStream, 0, size-1]; intBuffer: LONG POINTER TO ARRAY [0..8) OF INT = LOOPHOLE[bufferPointer]; runPage, oldRunPage, oldPage: Disk.PageNumber; oldChannel: Disk.Channel; TRUSTED{ [diskPage: oldRunPage] _ FileInternal.FindRun[start: [page], nPages: 1, runTable: LOOPHOLE[fileFile, FileInternal.Handle].runTable] }; [oldPage, oldChannel] _ FileBackdoor.SpliceOutDataPage[file: fileFile, filePage: page]; TRUSTED { wordZero.pages[page].mark _ intBuffer[0] _ 100000+offset+page;}; TRUSTED{ [diskPage: runPage] _ FileInternal.FindRun[start: [page], nPages: 1, runTable: LOOPHOLE[fileFile, FileInternal.Handle].runTable] }; IF oldPage # oldRunPage OR oldPage = runPage THEN ERROR; wordZero.pages[page].page _ runPage; file.Write[to: page, nPages: 1, from: bufferPointer]; ENDLOOP; TRUSTED { FOR page: INT IN [0..size) DO intBuffer: LONG POINTER TO ARRAY [0..8) OF INT = bufferPointer; runPage: Disk.PageNumber; intBuffer[0] _ -1; file.Read[from: page, nPages: 1, to: bufferPointer]; TRUSTED{ [diskPage: runPage] _ FileInternal.FindRun[start: [page], nPages: 1, runTable: LOOPHOLE[fileFile, FileInternal.Handle].runTable] }; IF intBuffer[0] # wordZero.pages[page].mark THEN ERROR; IF runPage # wordZero.pages[page].page THEN ERROR; ENDLOOP; }; file.Close[]; dummy1 _ size; dummy2 _ size; }; }; <> END. <<>>