PROC [fileName: Rope.
{
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;
};