-- ParseObjectDirs.mesa -- M. D. Schroeder, February 8, 1983 8:42 am DIRECTORY CIFS USING [Error, Reset], FileIO USING [Open, OpenFailed], IO USING [Close, EndOf, Error, GetRope, int, PutF, PutRope, real, STREAM, UnsafeBlock, UnsafeGetBlock], ObjectDirDefs USING [ObjectType], ObjectDirXDefs, Process USING [Detach], Rope USING [Cat, Equal, ROPE], ViewerIO USING [CreateViewerStreams], VMDefs USING [PageIndex, PageNumber, pageSize, pageByteSize]; ParseObjectDirs: PROGRAM IMPORTS CIFS, FileIO, IO, Process, Rope, ViewerIO = BEGIN ObjectCount: TYPE = CARDINAL; ObjDirPageSpace: TYPE = [0..255]; DirData: TYPE = RECORD[ SELECT freedom: * --w0,b15-- FROM free => [ next: VMDefs.PageIndex,--w0,b[7..0]-- dopc: ObjectDirXDefs.DOPC --w[1..2]-- ], used => [ type: ObjectDirDefs.ObjectType,--w0,b[14..11]-- word: VMDefs.PageIndex,--w0,b[7..0]-- page: VMDefs.PageNumber,--w1-- count: ObjectCount --w2-- ], ENDCASE]; DirPageHeader: TYPE = RECORD[ nextFreePage: ObjDirPageSpace, nextFreeIndex: VMDefs.PageIndex ]; entriesPerPage: CARDINAL = (VMDefs.pageSize-SIZE[DirPageHeader])/SIZE[DirData]; DirIndex: TYPE = [ 0 .. entriesPerPage ); -- NOTE: DirIndex values must fit in the "index" field of an object number -- DirPage: TYPE = RECORD[ header: DirPageHeader, data: ARRAY DirIndex OF DirData ]; CountsIndex: TYPE = [0 .. 999); Counts: TYPE = ARRAY CountsIndex OF INT _ ALL[0]; DoIt: PROCEDURE = BEGIN in, out: IO.STREAM; server, total: REF Counts; dirPage: DirPage; dirPagePtr: LONG POINTER = @dirPage; serverName: Rope.ROPE; grandNum, grandProd: INT _ 0; total _ NEW [Counts]; [in, out] _ ViewerIO.CreateViewerStreams[name: "ParseObjectDirs"]; DO server _ NEW [Counts]; out.PutF["\n\nServer name: "]; serverName _ in.GetRope[ ! IO.Error => EXIT ]; IF Rope.Equal[serverName, "*"] THEN BEGIN out.PutRope["\n\n\n\nTotals for all servers\n\n"]; FOR i: CountsIndex IN CountsIndex DO IF total[i] # 0 THEN out.PutF["%g %g\n", IO.int[i], IO.int[total[i]]]; ENDLOOP; IF grandNum#0 THEN out.PutF["\nmessage bodies: %g, ave. references: %3.2f", IO.int[grandNum], IO.real[REAL[grandProd]/REAL[grandNum]]]; END ELSE BEGIN num, prod: INT _ 0; objectDirName: Rope.ROPE = Rope.Cat["/", serverName, "/Heap.ObjectDir"]; file: IO.STREAM; --Parse the file-- CIFS.Reset[objectDirName ! CIFS.Error => CHECKED {CONTINUE}]; file _ FileIO.Open[objectDirName ! FileIO.OpenFailed, CIFS.Error => CHECKED {out.PutRope["\nOpen failed"]; LOOP}]; UNTIL file.EndOf[] DO IF file.UnsafeGetBlock[ block: IO.UnsafeBlock[dirPagePtr, 0, VMDefs.pageByteSize]] # VMDefs.pageByteSize THEN ERROR; FOR i: DirIndex IN DirIndex DO WITH entry: dirPage.data[i] SELECT FROM free => NULL; used => IF entry.type = body THEN BEGIN server[entry.count] _ server[entry.count] + 1; total[entry.count] _ total[entry.count] + 1; END; ENDCASE => ERROR; ENDLOOP; ENDLOOP; out.PutF["\n\n"]; FOR i: CountsIndex IN CountsIndex DO IF server[i]#0 THEN BEGIN out.PutF["%g %g\n", IO.int[i], IO.int[server[i]]]; IF i#0 THEN {num _ num + server[i]; prod _ prod + server[i]*i}; END; ENDLOOP; IF num#0 THEN out.PutF["\nmessage bodies: %g, ave. references: %3.2f", IO.int[num], IO.real[REAL[prod]/REAL[num]]]; grandNum _ grandNum + num; grandProd _ grandProd + prod; file.Close[]; END ENDLOOP; END; Process.Detach[FORK DoIt]; END. Ęk˜Jš|Īcœ-œĪk œžœžœžœžœžœ:žœ1žœ)žœžœžœ žœ žœDžœžœžœ žœžœžœžœžœžœžœžœ  œžœ)œ'žœ œ4œ)œ*œ$œ žœžœžœsžœ'žœžœžœMœžœžœ>žœ žœžœžœžœ žœžœžœ%Īnœž œžœ žœžœžœ)žœžœžœ˜Ü JšĨœžœžœPžœ žœIžœ žœžœ žœžœ<žœžœ žœžœžœžœ žœžœžœ žœEžœžœžœ žœžœžœžœžœžœ;žœžœœžœžœ žœžœIžœ'žœ žœžœžœžœ%žœNžœžœžœ žœ žœžœžœžœžœžœžœžœužœ žœžœžœžœžœžœ žœžœ žœžœžœ žœžœžœ;žœžœžœžœEžœ žœžœžœ`žœžœžœžœ žœ˜į—…—Æ7