DIRECTORY Commander, Convert, FS, IO, IOClasses, Menus, PLAOps, Process, REFBit, Rope, TypeScript, ViewerClasses, ViewerOps, ViewerIO; PLAOpsImplE: CEDAR MONITOR IMPORTS Commander, Convert, FS, IO, IOClasses, Menus, PLAOps, Process, REFBit, Rope, TypeScript, ViewerIO, ViewerOps = BEGIN OPEN PLAOps; UseFlag: CONDITION; InUse: BOOL _ FALSE; AcquireUseFlag: ENTRY PROC[] = {WHILE InUse DO WAIT UseFlag ENDLOOP; InUse_TRUE}; ReleaseUseFlag: ENTRY PROC = {InUse _ FALSE; NOTIFY UseFlag}; PLACompress: Commander.CommandProc = { log, traceV: IO.STREAM; DO ENABLE { UNWIND => {FinishUp[log, traceV]; }; FS.Error => IF error.group = user THEN { cmd.err.PutRope[error.explanation]; EXIT }}; source, dest: IO.ROPE; first, last, time: CARDINAL; comSum, mult: BOOL; [source, first, last, time, comSum, mult] _ GetCommandLineParams[cmd]; IF source=NIL OR source.Length[]=0 THEN {cmd.err.PutF["\n%g\n", IO.rope[plaOpsDoc]]; RETURN}; source _ source.Substr[len: source.Index[s2: ".ttt"]]; source _ FS.ExpandName[source].fullFName; IF InUse THEN cmd.err.PutRope[" . . . waiting for PLA Compressor . . . \n"]; AcquireUseFlag[]; [traceV, log] _ OpenTraceAndLogStreams[source, IF mult THEN "field" ELSE "composite"]; dest _ source.Cat[IF mult THEN ".fld.ttt" ELSE ".com.ttt"]; source _ source.Cat[".ttt"]; IF mult THEN CompressPLAFields [source, dest, first, last, comSum, time, log, traceV] ELSE CompressPLA [source, dest, first, last, comSum, time, log, traceV]; cmd.out.PutF["%g _ %g\n", IO.rope[dest], IO.rope[source]]; EXIT ENDLOOP}; OpenTraceAndLogStreams: PROC[source, msg: IO.ROPE] RETURNS [traceV, log: IO.STREAM] = { logF, logV: IO.STREAM; name: IO.ROPE _ IO.PutFR["Trace of %g.pla %g compression", IO.rope[source], IO.rope[msg]]; traceV_ BuildControlPanel[name]; logF _ FS.StreamOpen[fileName: source.Cat[".log"], accessOptions: $append, keep: 2]; logV _ ViewerIO.CreateViewerStreams[name: source.Cat[".log"]].out; log _ IOClasses.CreateDribbleOutputStream[ output1: logV, output2: logF]; TypeScript.ChangeLooks[ViewerIO.GetViewerFromStream[logV], 'f]; TypeScript.ChangeLooks[ViewerIO.GetViewerFromStream[logV], 's]}; FinishUp: PROC[log, traceV: IO.STREAM] = { logViewer: ViewerClasses.Viewer _ ViewerIO.GetViewerFromStream[log]; traceViewer: ViewerClasses.Viewer _ ViewerIO.GetViewerFromStream[traceV]; log.Close; traceV.Close; ViewerOps.CloseViewer [traceViewer]; ViewerOps.DestroyViewer [logViewer]; ReleaseUseFlag[]}; BuildControlPanel: PROC[name: IO.ROPE] RETURNS [out: IO.STREAM] = { viewer: ViewerClasses.Viewer; out _ ViewerIO.CreateViewerStreams[name].out; viewer _ ViewerIO.GetViewerFromStream[out]; TypeScript.ChangeLooks[viewer, 'f]; TypeScript.ChangeLooks[viewer, 's]; Menus.AppendMenuEntry[ menu: viewer.menu, entry: Menus.CreateEntry[name: "Trace", clientData: out, proc: TraceProc]]; Menus.AppendMenuEntry[ menu: viewer.menu, entry: Menus.CreateEntry[name: "FinishCS", clientData: out, proc: FinishCSProc]]; Menus.AppendMenuEntry[ menu: viewer.menu, entry: Menus.CreateEntry[name: "FinishMin", clientData: out, proc: FinishMinProc]]; Menus.AppendMenuEntry[ menu: viewer.menu, entry: Menus.CreateEntry[name: "Abort", clientData: out, proc: AbortProc]] }; FinishCSProc: Menus.ClickProc = { out: IO.STREAM _ NARROW[clientData]; FinishCS _ TRUE; out.PutRope["\nTruncate complete sum"]}; FinishMinProc: Menus.ClickProc = { out: IO.STREAM _ NARROW[clientData]; FinishMin _ TRUE; out.PutRope["\nTruncate minimum sum search"]}; AbortProc: Menus.ClickProc = { out: IO.STREAM _ NARROW[clientData]; FinishCS_FinishMin_Abort _ TRUE; out.PutRope["\nAbort"]}; TraceProc: Menus.ClickProc = { out: IO.STREAM _ NARROW[clientData]; Trace _ NOT Trace; out.PutF["\nTrace %g", IO.rope[(IF Trace THEN "ON" ELSE "OFF")]]}; GetCommandLineParams: PROC[cmd: Commander.Handle] RETURNS [source: IO.ROPE, begin, end, time: CARDINAL, comSum, mult: BOOL] = { cls: IO.STREAM _ IO.RIS[cmd.commandLine]; token: IO.ROPE; source _ NIL; time _ 177777B; -- delay in minutes ~ 45 days begin _ end _ 177777B; comSum _ mult _ FALSE; token _ IO.GetTokenRope[cls ! IO.EndOfStream => {token _ NIL; CONTINUE}].token; IF token # NIL THEN DO ENABLE IO.EndOfStream => EXIT; Next: PROC = {token_IO.GetTokenRope[cls].token}; SELECT token.Fetch[0] FROM '/, IN ['a..'z], IN ['A..'Z ] => {source _ source.Cat[token]; Next[]; LOOP}; '- => { Next[]; SELECT token.Fetch[0] FROM 'm, 'M => {mult_TRUE; --Multiple plas-- Next[]; LOOP}; 'c, 'C => {comSum_TRUE; --complete sum-- Next[]; LOOP}; 't, 'T => {time_Convert.CardFromRope[token.Substr[1]]; Next[]; LOOP}; 'f, 'F => { -- field or field range IF token.Length[] > 1 -- field THEN { token _ token.Substr[1]; begin _ end _ Convert.CardFromRope[token]; Next[]; LOOP}; Next[]; -- field range SELECT token.Fetch[0] FROM '[ => {begin _ 0}; '( => {begin _ 1}; ENDCASE => LOOP; Next[]; begin _ Convert.CardFromRope[token.Substr[len: token.Index[s2:".."]]] + begin; token _ token.Substr[token.Index[s2:".."]+2]; end _ Convert.CardFromRope[token]; Next[]; SELECT token.Fetch[0] FROM '] => {}; ') => {end _ end-1}; ENDCASE => {cmd.err.PutF["\n**I don't understand '%g'. I was expecting an end of range\n", IO.rope[token]]; RETURN}; Next[]; LOOP}; ENDCASE => {cmd.err.PutF["\n**Unknown switch: %g\n", IO.rope[token]]; RETURN} }; ENDCASE => {cmd.err.PutF["\n**I don't understand '%g'. I was expecting a switch or filename\n", IO.rope[token]]; RETURN}; ENDLOOP; cls.Close[]}; TOD: PROC RETURNS[IO.Value] = { time: IO.ROPE _ IO.PutFR["%g", IO.time[]]; time _ time.Substr[time.Index[s2:"198"]+5]; time _ time.Substr[len: time.Index[s2:" "]]; IF time.Length[] = 7 THEN time _ Rope.Cat[" ", time]; RETURN[IO.rope[time]]}; CompressPLA: PROC[ source, dest: IO.ROPE, first: CARDINAL, last: CARDINAL, comSum: BOOL, time: CARDINAL, log, traceV: IO.STREAM _ IO.noWhereStream] = { refPLA: PLA; newPLA: PLA; dfList: TermList; iForm: Format; oForm: Format; index: CARDINAL _ 0; dfLength: CARDINAL _ 0; csLength: CARDINAL _ 0; initEssential: CARDINAL _ 0; initDelete: CARDINAL _ 0; cover: CARDINAL _ 0; insTot, outsTot: CARDINAL _ 0; finishCS, finishMin: BOOL _ FALSE; Process.SetPriority[Process.priorityBackground]; log.PutF["\n\n%g _ %g - %g", IO.rope[dest], IO.rope[source], IO.time[]]; refPLA _ ReadPLAFile[source]; log.PutF["\n%g\n", IO.rope[PLAHeader[refPLA]]]; log.Flush[]; newPLA _ NewPLA[refPLA.data, refPLA.out, refPLA.name]; iForm _ REFBit.Desc[refPLA.data].fieldForm; oForm _ REFBit.Desc[refPLA.out].fieldForm; IF first=177777B THEN {first _ 0; last _ oForm.size-1}; Trace _ FinishCS _ FinishMin _ Abort _ FALSE; dfList _ CopyTermListForField[ list: refPLA.termList, -- Size Effect is removing null terms firstBit: oForm[first].firstBit, bitSize: oForm[last].firstBit + oForm[last].bitSize - oForm[first].firstBit ]; DO ENABLE { UNWIND => GOTO AbortExit; ABORTED => GOTO AbortExit }; log.PutRope["\n"]; IF Abort THEN {log.PutRope["\n<<<>>>\n"]; log.Flush[]; EXIT}; dfLength _ dfList.length; log.PutF["\nConsolidated DEF Terms: %3g %g", IO.card[dfLength], TOD[] ]; IF dfLength=0 THEN {log.Flush[]; LOOP}; IF Abort THEN GOTO AbortExit; finishCS _ ConvertTermListToCompleteSum [list: dfList, addMerges: comSum, addConsensus: comSum, log: traceV]; csLength _ dfList.length; log.PutF["\nConsolidated SUM Terms: %3g %g", IO.card[csLength], TOD[] ]; IF finishCS THEN log.PutRope[" ~finished"]; IF Abort THEN GOTO AbortExit; [initEssential, initDelete, cover, finishMin] _ FindAMinimalCover[list: dfList, time: time, log: traceV]; log.PutF["\nConsolidated MIN Terms: %3g %g", IO.card[cover], TOD[] ]; IF finishMin THEN log.PutRope[" ~finished"]; newPLA.termList _ dfList; log.PutF["\n\nConsolidated RES Def:%3g %g:%3g", IO.card[dfLength], IO.rope[(IF comSum THEN "CS" ELSE "Sum")], IO.card[csLength] ]; log.PutF[" Ess:%3g Del:%3g Cov:%3g", IO.card[initEssential ], IO.card[initDelete ], IO.card[cover ] ]; log.PutF[" %g", TOD[]]; IF finishCS OR finishMin THEN { IF finishCS THEN log.PutRope[" CS"]; IF finishMin THEN log.PutRope[" Min"]; log.PutRope[" ~finished"]}; log.Flush[]; EXIT REPEAT AbortExit => {log.PutRope["\n<<<>>>\n"]; log.Flush[] } ENDLOOP; FOR index IN [0..iForm.size) DO insTot _ insTot + iForm[index].bitSize ENDLOOP; FOR index IN [0..oForm.size) DO outsTot _ outsTot + oForm[index].bitSize ENDLOOP; IF ~Abort THEN { log.PutF["\n\nSummary:"]; log.PutF["\n Inputs Bits:%4g", IO.card[insTot]]; log.PutF["\n Total Outputs Bits:%4g", IO.card[outsTot]]; log.PutF["\n Definition Terms:%4g", IO.card[dfLength]]; log.PutF["\n Complete Sum Terms:%4g", IO.card[csLength]]; log.PutF["\n Essential Terms:%4g", IO.card[initEssential]]; log.PutF["\n Init Deletes Terms:%4g", IO.card[initDelete]]; log.PutF["\n Cover Terms:%4g", IO.card[cover]]; IF finishCS THEN log.PutRope["\n CS Unfinished"]; IF finishMin THEN log.PutRope["\n Min Unfinished"]; log.PutF["\n\n"]; WritePLAFile[newPLA, dest, log] }; log.PutChar[IO.FF]; Trace _ FinishCS _ FinishMin _ Abort _ FALSE; FinishUp[log, traceV]}; CompressPLAFields: PROC[ source, dest: IO.ROPE, first: CARDINAL, last: CARDINAL, comSum: BOOL, time: CARDINAL, log, traceV: IO.STREAM _ IO.noWhereStream] = { iForm: Format; oForm: Format; refPLA: PLA; newPLA: PLA; dfList: TermList; index: CARDINAL _ 0; dfLength, dfSeqTot: CARDINAL _ 0; csLength, csSeqTot: CARDINAL _ 0; initEssential, initEssentialTot: CARDINAL _ 0; initDelete, initDeleteTot: CARDINAL _ 0; cover, coverTot: CARDINAL _ 0; finishCSTot: CARDINAL _ 0; finishMinTot: CARDINAL _ 0; insUsed: CARDINAL _ 0; insTot, outsTot: CARDINAL _ 0; finishCS, finishMin: BOOL _ FALSE; max: CARDINAL _ 0; msgLineForm: IO.ROPE _ NIL; MSGLine: PROC[msg: IO.ROPE, card: CARDINAL] = { traceV.PutF[msgLineForm, IO.rope[msg], IO.card[index], IO.rope[oForm[index].name] ]; traceV.PutF[" [%2g] Terms: %3g %g", IO.card[oForm[index].bitSize], IO.card[card], TOD[]] }; Process.SetPriority[Process.priorityBackground]; log.PutF["\n\n%g _ %g - %g", IO.rope[dest], IO.rope[source], IO.time[]]; refPLA _ ReadPLAFile[source]; IF refPLA=NIL THEN {FinishUp[log, traceV]; RETURN}; log.PutF["\n%g\n", IO.rope[PLAHeader[refPLA]]]; log.Flush[]; newPLA _ NewPLA[refPLA.data, refPLA.out, refPLA.name]; iForm _ REFBit.Desc[refPLA.data].fieldForm; oForm _ REFBit.Desc[refPLA.out].fieldForm; IF first=177777B THEN {first _ 0; last _ oForm.size-1}; Trace _ FinishCS _ FinishMin _ Abort _ FALSE; max _ 0; FOR index IN [first..last] DO len: CARDINAL _ oForm[index].name.Length[]; max _ MAX[max, len] ENDLOOP; msgLineForm _ IO.PutFR["%g%g%g", IO.rope["\n%gField:%3g %"], IO.card[max], IO.rope["g"] ]; FOR index IN [first..last] DO ENABLE { UNWIND => GOTO AbortExit; ABORTED => GOTO AbortExit }; traceV.PutRope["\n"]; IF Abort THEN {log.PutRope["\n<<<>>>\n"]; log.Flush[]; EXIT}; dfList _ CopyTermListForField[ list: refPLA.termList, firstBit: oForm[index].firstBit, bitSize: oForm[index].bitSize ]; dfLength _ dfList.length; MSGLine["DEF ", dfLength]; IF dfLength=0 THEN {log.Flush[]; LOOP}; IF Abort THEN GOTO AbortExit; finishCS _ ConvertTermListToCompleteSum [list: dfList, addMerges: comSum, addConsensus: comSum, log: traceV]; csLength _ dfList.length; MSGLine["SUM ", csLength]; IF finishCS THEN traceV.PutRope[" ~finished"]; IF Abort THEN GOTO AbortExit; [initEssential, initDelete, cover, finishMin] _ FindAMinimalCover[list: dfList, time: time, log: traceV]; MSGLine["MIN ", cover]; IF finishMin THEN traceV.PutRope[" ~finished"]; insUsed _ InsUsed[dfList]; newPLA.termList _ Add[newPLA.termList, dfList]; outsTot _ outsTot + oForm[index].bitSize; dfSeqTot _ dfSeqTot + dfLength; csSeqTot _ csSeqTot + csLength; initEssentialTot _ initEssentialTot+ initEssential; initDeleteTot _ initDeleteTot + initDelete; coverTot _ coverTot + cover; finishCSTot _ finishCSTot + (IF finishCS THEN 1 ELSE 0); finishMinTot _ finishMinTot + (IF finishMin THEN 1 ELSE 0); log.PutF[msgLineForm, IO.rope[""], IO.card[index], IO.rope[oForm[index].name ] ]; log.PutF[" [%2gx%2g]",IO.card[insUsed], IO.card[oForm[index].bitSize]]; log.PutF[" Def:%3g %g:%3g", IO.card[dfLength], IO.rope[(IF comSum THEN "CS" ELSE "Sum")], IO.card[csLength] ]; log.PutF[" Ess:%3g Del:%3g Cov:%3g", IO.card[initEssential ], IO.card[initDelete ], IO.card[cover ] ]; log.PutF[" %g", TOD[]]; IF finishCS OR finishMin THEN { IF finishCS THEN log.PutRope[" CS"]; IF finishMin THEN log.PutRope[" Min"]; log.PutRope[" ~finished"]}; log.Flush[]; REPEAT AbortExit => {log.PutRope["\n<<<>>>\n"]; log.Flush[] } ENDLOOP; FOR index IN [0..iForm.size) DO insTot _ insTot + iForm[index].bitSize ENDLOOP; IF ~Abort THEN { traceV.PutRope["\n\nFinal Consolidation"]; finishCS _ ConvertTermListToCompleteSum [list: newPLA.termList, addMerges: FALSE, addConsensus: FALSE, log: traceV]; csLength _ newPLA.termList.length; traceV.PutF[msgLineForm, IO.rope["RES "], IO.rope["ALL"], IO.rope["Consolidated"] ]; traceV.PutF[" Terms: %3g %g", IO.card[csLength], TOD[]]; IF finishCS THEN traceV.PutRope[" ~finished"]; log.PutF["\n\nSummary:"]; log.PutF["\n Inputs Bits:%4g", IO.card[insTot]]; log.PutF["\n Total Outputs Bits:%4g", IO.card[outsTot]]; log.PutF["\n SourcePLA Terms:%4g", IO.card[refPLA.termList.length]]; log.PutF["\n Definition Terms:%4g", IO.card[dfSeqTot]]; log.PutF["\n Complete Sum Terms:%4g", IO.card[csSeqTot]]; log.PutF["\n Essential Terms:%4g", IO.card[initEssentialTot]]; log.PutF["\n Init Deletes Terms:%4g", IO.card[initDeleteTot]]; log.PutF["\n Cover Terms:%4g", IO.card[coverTot]]; log.PutF["\n Consolidation Terms:%4g", IO.card[csLength]]; log.PutF["\n CS Unfinished Srchs:%4g", IO.card[finishCSTot]]; log.PutF["\n Min Unfinished Srchs:%4g", IO.card[finishMinTot]]; log.PutF["\n\n"]; WritePLAFile[newPLA, dest, log] }; log.PutChar[IO.FF]; Trace _ FinishCS _ FinishMin _ Abort _ FALSE; FinishUp[log, traceV]}; plaOpsDoc: IO.ROPE = "PLAOpsCompress filename.ttt -c => complete sum -f => field or field range -m => multiple plas, one for each field -t => timeout minutes "; Commander.Register[key:"PLAOpsCompress", proc: PLACompress, doc: plaOpsDoc]; END. ΚPLAOpsImplE.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Last edited by Curry, October 5, 1985 8:29:39 am PDT Don Curry August 16, 1987 12:49:50 pm PDT PLACompress: Commander.CommandProc = { log, traceV: IO.STREAM; DO ENABLE { UNWIND => {log.Close[]; traceV.Close[]}; FS.Error => IF error.group = user THEN { cmd.err.PutRope[error.explanation]; EXIT }}; source, dest: IO.ROPE; first, last, time: CARDINAL; comSum, mult: BOOL; [source, first, last, time, comSum, mult] _ GetCommandLineParams[cmd]; IF source=NIL OR source.Length[]=0 THEN {cmd.err.PutF["\n%g\n", IO.rope[plaOpsDoc]]; RETURN}; source _ source.Substr[len: source.Index[s2: ".ttt"]]; source _ FS.ExpandName[source].fullFName; IF InUse THEN cmd.err.PutRope[" . . . waiting for PLA Compressor . . . \n"]; AcquireUseFlag[]; [traceV, log] _ OpenTraceAndLogStreams[source, IF mult THEN "field" ELSE "composite"]; dest _ source.Cat[IF mult THEN ".fld.ttt" ELSE ".com.ttt"]; source _ source.Cat[".ttt"]; IF mult THEN TRUSTED {Process.Detach[FORK CompressPLAFields [source, dest, first, last, comSum, time, log, traceV]]} ELSE TRUSTED {Process.Detach[FORK CompressPLA [source, dest, first, last, comSum, time, log, traceV]]}; EXIT ENDLOOP}; Κp˜šΠbl™Jšœ<™Jš€)£€œ€˜9Jšžœ žœ€"˜3Jšžœ žœ€"˜4Jš€˜Jšœ#˜#—Jš€ £€£€˜Jšœ'žœ˜-Jšœ˜—J˜šŸœžœ˜Jšœžœžœ˜Jšœ žœ˜Jšœžœ˜Jšœ žœ˜Jšœžœ˜Jšœ žœžœžœ˜.J˜Jšœ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜Jšœ˜Jšœžœ˜Jšœžœ˜$Jšœžœ˜$Jšœ"žœ˜/Jšœžœ˜)Jšœžœ˜#Jšœžœ˜ Jšœžœ˜ Jšœžœ˜Jšœžœ˜"Jšœžœžœ˜%J˜Jšœ žœ˜Jšœžœžœžœ˜ J˜š Ÿœžœžœžœžœ˜/šœ˜Jšžœ žœžœ˜;—šœ%˜%Jšžœžœ žœ˜7——J˜Jšœ0˜0J˜Jšœžœ žœžœ ˜HJšœ˜Jšžœžœžœžœ˜3Jšœžœ'˜