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};
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};
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𡤏inishMinort ← 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𡤌onvert.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<<<<ABORT>>>>\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<<<<ABORT>>>>\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<<<<ABORT>>>>\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<<<<ABORT>>>>\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.