-- CreateTestFilePageMgrImpl.mesa
-- Last edited by
--    Kolling on November 14, 1983 2:23 pm

DIRECTORY

      AlpineEnvironment
        USING[FileID, nullFileID, PageCount, VolumeID],
      AlpineInternal
        USING[FileHandle],
      File
        USING[EraseVolume, FindVolumeFromName, GetVolumeID, Volume, VolumeID],
      FileMap
        USING[Handle, Initialize, Register],
      FilePageMgr
        USING[Create, Delete, ForceOutEverything, InitializeFilePageMgr, NoSuchFile,
           RestoreCacheToCleanState],
      FS
        USING[StreamOpen],
      IO
        USING[card, Close, GetCard, int, PutF, PutRope, rope, STREAM],
      MyPerfStats
         USING[CreateTimer, DestroyTimer, Initialize, InitializeTimer, Print,
            Start, Stop, Timer],
      RandomCard
        USING[Choose, Init],
      Rope
        USING[ROPE],
      SafeStorage
        USING[IsCollectorActive, WaitForCollectorDone],
      SystemVersion
        USING[machineType];


CreateTestFilePageMgrImpl: CEDAR PROGRAM
  IMPORTS File, FileMap, FPM: FilePageMgr, FS, IO, MyPerfStats, RandomCard, SafeStorage,
     SystemVersion =


BEGIN OPEN AI: AlpineInternal, AE: AlpineEnvironment;


GetParams: PROCEDURE =
   BEGIN
   paramStreamHandle: IO.STREAM ←
      FS.StreamOpen["AnomaliesCreateFile.Params", $read];
   IF (NFiles ← paramStreamHandle.GetCard[]) = 0 THEN ERROR;
   IF NFiles > 999 THEN ERROR;
   IF (NNormalChunksInCache ← paramStreamHandle.GetCard[]) = 0 THEN ERROR;
   IF (NLogChunksInCache ← paramStreamHandle.GetCard[]) = 0 THEN ERROR;
   IF (NLeaderChunksInCache ← paramStreamHandle.GetCard[]) = 0 THEN ERROR;
   paramStreamHandle.Close[];
   resultsStreamHandle.PutF["\nNFiles: %g\n\nNNormalChunksInCache: %g    NLogChunksInCache: %g    NLeaderChunksInCache: %g\n\n", IO.card[NFiles],
      IO.card[NNormalChunksInCache], IO.card[NLogChunksInCache],
      IO.card[NLeaderChunksInCache]];
   END;


SetUpFileData: PROCEDURE =
   BEGIN
   files ← NEW[Files[NFiles]];
   FOR index: CARDINAL IN [0..NFiles)
      DO files[index] ← [fileID: AE.nullFileID, inUse: FALSE, exists: FALSE, size: 0];
      ENDLOOP;
   END;
   

DeleteAllFiles: PROCEDURE =
   BEGIN
   FOR index: CARDINAL IN [0..NFiles)
      DO fileHandle: FileMap.Handle ← FileMap.Register[volumeID, files[index].fileID];
      FPM.Delete[fileHandle ! FPM.NoSuchFile => CONTINUE];
      fileHandle ← NIL;
      ENDLOOP;
   resultsStreamHandle.PutRope["
All files deleted.

"];
      END;


CleanCache: PROCEDURE =
   BEGIN
   FPM.ForceOutEverything[];
   FPM.RestoreCacheToCleanState[];
   resultsStreamHandle.PutRope["Cache cleaned.    "];
   END;
   
   
Shell: PROCEDURE[proc: PROCEDURE[fileIndex: CARDINAL, timer: MyPerfStats.Timer, fileInterval:
 FileInterval], timerName: Rope.ROPE, fileIndex: CARDINAL, fileInterval: FileInterval] =
   BEGIN
   timer: MyPerfStats.Timer ← MyPerfStats.CreateTimer[timerName];
   proc[fileIndex, timer, fileInterval];
   MyPerfStats.Print[ , resultsStreamHandle, FALSE];
   MyPerfStats.DestroyTimer[timer];
   END;
   


-- varies size of file.

CreateFile: PROCEDURE[fileIndex: CARDINAL, timer: MyPerfStats.Timer, fileInterval: FileInterval] =
   BEGIN
   FileIDProc: PROCEDURE[fileID: AE.FileID] =
    BEGIN files[fileIndex].fileID ← fileID;
    END;
   fileHandle: FileMap.Handle;
   active: BOOLEAN;
   prevCollectorIncarnation, endingPrevCollectorIncarnation: CARDINAL;
   attempts: CARDINAL ← 5;
   files[fileIndex].exists ← TRUE;
   files[fileIndex].size ← (WITH fileInt: fileInterval SELECT FROM
      allFixed => fileInt.nPagesEachTime,
      allRandom => RandomCard.Choose[min: 0, max: MaxFileSize],
   ENDCASE => ERROR);
   DO
   [active, prevCollectorIncarnation] ← SafeStorage.IsCollectorActive[];
   IF active
      THEN [prevCollectorIncarnation, , , ] ← SafeStorage.WaitForCollectorDone[];
   MyPerfStats.Start[timer];
   FPM.Create[volumeID, files[fileIndex].size, FileIDProc];
   MyPerfStats.Stop[timer];
   [active, endingPrevCollectorIncarnation] ← SafeStorage.IsCollectorActive[];
   IF ((active) OR (endingPrevCollectorIncarnation # prevCollectorIncarnation))
      THEN BEGIN
           resultsStreamHandle.PutRope[
              "CreateFile interrupted by garbage collection
              "];
           IF (attempts ← attempts - 1) > 0
             THEN BEGIN resultsStreamHandle.PutRope["retrying
             "];
                  fileHandle ← FileMap.Register[volumeID, files[fileIndex].fileID];
                  FPM.Delete[fileHandle];
                  fileHandle ← NIL;
                  CleanCache[];
                  MyPerfStats.InitializeTimer[timer];
                  [] ← SafeStorage.WaitForCollectorDone[];
                  LOOP;
                  END
             ELSE resultsStreamHandle.PutF["giving up\n"];
           EXIT;
           END;
   resultsStreamHandle.PutF["CreateFile  file: %g       size: %3g    ",
      IO.card[fileIndex], IO.int[files[fileIndex].size]];
   EXIT;
   ENDLOOP;
   END;
   

-- varies

AllSomeOrSomeRandom: TYPE = {allFixed, allRandom, someFixed, someRandom};

FileInterval: TYPE = RECORD[SELECT allOrSomeRandom: AllSomeOrSomeRandom FROM
   allFixed => [nPagesEachTime: CARDINAL],
   allRandom => NULL,
   someFixed => [firstPage, lastPage, nPagesEachTime: CARDINAL],
   someRandom => NULL,
   ENDCASE];


   
  
Main: PROCEDURE =
   BEGIN -- set up to call from CoPilot for debugging.
   foo: CARDINAL ← 0;
   increment: CARDINAL ← 150;
   fileSize: CARDINAL;
   BEGIN
   ENABLE ANY => foo ← foo + 1; -- protect us from the tempcedarexec.
   MyPerfStats.Initialize[];
   File.EraseVolume[volume];
   resultsStreamHandle ← FS.StreamOpen["AnomaliesCreateFile.Results", $append];
   resultsStreamHandle.PutRope["
Nucleus"];
   resultsStreamHandle.PutF["\nMachine type: %g\n\n", IO.rope[SELECT
      SystemVersion.machineType FROM dolphin => "Dolphin", dorado => "Dorado",
      dandelion => "Dandelion", dicentra => "Dicentra", ENDCASE => "unknown"]];
   [] ← RandomCard.Init[0];
   GetParams[];
   FileMap.Initialize[numHashSlotsDesired: 43, fQLength: 60];
   FPM.InitializeFilePageMgr[nNormalChunksInCache: NNormalChunksInCache,
      nLogChunksInCache: NLogChunksInCache, nLeaderChunksInCache:
      NLeaderChunksInCache];
   SetUpFileData[];
   THROUGH [0..5)
      DO
      fileSize ← 1;
      DeleteAllFiles[];
      FOR fileIndex: CARDINAL IN [0..NFiles)
         DO CleanCache[];
         Shell[proc: CreateFile, timerName: "CreateFile", fileIndex: fileIndex,
            fileInterval: [allFixed[fileSize]]];
         fileSize ← fileSize + increment;
         ENDLOOP;
      ENDLOOP;
   CleanCache[];
   THROUGH [0..5)
      DO
      fileSize ← ((NFiles-1)*increment) + 1;
      DeleteAllFiles[];
      FOR fileIndex: CARDINAL IN [0..NFiles)
         DO CleanCache[];
         Shell[proc: CreateFile, timerName: "CreateFile", fileIndex: fileIndex,
            fileInterval: [allFixed[fileSize]]];
         fileSize ← fileSize - increment;
         ENDLOOP;
      ENDLOOP;
   CleanCache[];
   DeleteAllFiles[];
   resultsStreamHandle.Close[];
   END;
   END;
   
   
   
   
-- main line code:

MaxFileSize: CARDINAL ← 150;

resultsStreamHandle: IO.STREAM;

NFiles: CARDINAL;
files: REF Files;
Files: TYPE = RECORD[SEQUENCE nFiles: [0..LAST[CARDINAL]] OF FileModel];
FileModel: TYPE = RECORD[fileID: AE.FileID, inUse: BOOLEAN, exists: BOOLEAN, size: CARDINAL];
NNormalChunksInCache: CARDINAL;
NLogChunksInCache: CARDINAL;
NLeaderChunksInCache: CARDINAL;
volume: File.Volume ← File.FindVolumeFromName["Gentian"];
volumeID: AE.VolumeID ← LOOPHOLE[File.GetVolumeID[volume]];



END.

                    Edit Log

Initial: Kolling: 19-Apr-82 12:22:00: test for FilePageManager.