-- CreateTestFilePageMgrImpl.mesa    Last edit: KK    November 9, 1983 12:18 pm

DIRECTORY

      AlpineEnvironment
        USING[FileID, PageCount, VolumeID],
      AlpineInternal
        USING[FileHandle],
      CedarVersion
        USING[machineType],
      File
        USING[Type],
      FileIO
        USING[Open],
      FileTypes
        USING[tUntypedFile],
      FileMap
        USING[Handle, Initialize, Register],
      FilePageMgr
        USING[CreateWithID, Delete, InitializeFilePageMgr, NoSuchFile,
           RestoreCacheToCleanState],
      IO
        USING[card, Close, GetCard, Handle, int, PutF, PutRope,
           rope],
      MyPerfStats
         USING[CreateTimer, DestroyTimer, Initialize, InitializeTimer, Print,
            Start, Stop, Timer],
      RandomCard
        USING[Choose, Init],
      Rope
        USING[ROPE],
      SafeStorage
        USING[IsCollectorActive, WaitForCollectorDone],
      System
        USING[VolumeID],
      SystemInternal
        USING[UniversalID],
      Volume
        USING[SystemID];


CreateTestFilePageMgrImpl: PROGRAM
  IMPORTS CedarVersion, FileIO, FileMap, FPM:
     FilePageMgr, IO, MyPerfStats, RandomCard, SafeStorage, Volume =


BEGIN OPEN AI: AlpineInternal, AE: AlpineEnvironment;


GetParams: PROCEDURE =
   BEGIN
   paramStreamHandle: IO.Handle ←
      FileIO.Open["AnomaliesCreateFile.Params", read, oldOnly];
   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
   myFilesIDsStreamHandle: IO.Handle ← FileIO.Open["noFilesFiles.IDs", read,
      oldOnly];
   IF myFilesIDsStreamHandle.GetCard[] < NFiles THEN ERROR;
   files ← NEW[Files[NFiles]];
   FOR index: CARDINAL IN [0..NFiles)
      DO files[index] ← [fileID: GetFileID[myFilesIDsStreamHandle], inUse: FALSE,
         exists: FALSE, size: 0];
      ENDLOOP;
   myFilesIDsStreamHandle.Close[];
   END;
   

GetFileID: PROCEDURE[stream: IO.Handle] RETURNS[fileID: AE.FileID] =
   BEGIN
   uid: SystemInternal.UniversalID;
   a: CARDINAL ← stream.GetCard[];
   b: CARDINAL ← stream.GetCard[];
   c: CARDINAL ← stream.GetCard[];
   uid ← [processor: [physical[a: a, b: b, c: c]], sequence: stream.GetCard[]];
   RETURN[LOOPHOLE[uid, AE.FileID]];
   END;
   

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

"];
      END;


CleanCache: PROCEDURE =
   BEGIN
   FPM.RestoreCacheToCleanState[];
   resultsStreamHandle.PutRope["Cache cleaned.    "];
   END;
   
   
Shell: PROCEDURE[proc: PROCEDURE[fileHandle: FileMap.Handle, fileIndex:
 CARDINAL, timer: MyPerfStats.Timer, fileInterval: FileInterval], timerName:
 Rope.ROPE, fileIndex: CARDINAL, fileInterval: FileInterval] =
   BEGIN
   fileID: AE.FileID ← files[fileIndex].fileID;
   fileHandle: FileMap.Handle ← FileMap.Register[volID, fileID];
   timer: MyPerfStats.Timer ← MyPerfStats.CreateTimer[timerName];
   proc[fileHandle, fileIndex, timer, fileInterval];
   MyPerfStats.Print[ , resultsStreamHandle, FALSE];
   MyPerfStats.DestroyTimer[timer];
   fileHandle ← NIL;
   END;
   


-- varies size of file.

CreateFile: PROCEDURE[fileHandle: FileMap.Handle, fileIndex: CARDINAL, timer:
 MyPerfStats.Timer, fileInterval: FileInterval] =
   BEGIN
   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.CreateWithID[fileHandle, files[fileIndex].size, FileTypes.tUntypedFile];
   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
             "];
                  FPM.Delete[fileHandle];
                  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[];
   resultsStreamHandle ← FileIO.Open["AnomaliesCreateFile.Results",
      append, none];
   resultsStreamHandle.PutRope["Pilot
   "];
   resultsStreamHandle.PutF["*nMachine type: %g*n*n", IO.rope[SELECT
      CedarVersion.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.Handle;

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;
volID: AE.VolumeID ← LOOPHOLE[Volume.SystemID[]];



END.

                    Edit Log

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