<> <> DIRECTORY AbSets, BasicTime, BiRels, FS, Histograms, HistogramsViewing, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenFromExtPrivate, LichenIntBasics, RefText, Rope, SetBasics; LichenFromExtImpl3: CEDAR MONITOR LOCKS dr USING dr: DesignReading IMPORTS AbSets, BiRels, FS, Histograms, HistogramsViewing, IntStuff, IO, LichenDataStructure, LichenFromExtPrivate, RefText, Rope, SetBasics EXPORTS LichenFromExtPrivate = BEGIN OPEN LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, LichenFromExtPrivate, Sets:AbSets; nsh: Histograms.Histogram ~ Histograms.Create1D[]; TestRangeMerges: PROC [fileNamePattern: ROPE, log: IO.STREAM, range: BOOL] ~ { buffer: REFTEXT ~ RefText.New[200]; token: REFTEXT; PerName: PROC [fullFName: ROPE] RETURNS [continue: BOOL] ~ { in: IO.STREAM ~ FS.StreamOpen[fullFName]; i1, i2, i3: INT; DO i1 _ in.GetIndex[]; [] _ in.SkipWhitespace[]; i2 _ in.GetIndex[]; IF in.EndOf[] THEN EXIT; [token,] _ in.GetToken[TokenBreak, buffer]; i3 _ in.GetIndex[]; IF RefText.Equal[token, "merge"] THEN { DO char: CHAR ~ in.GetChar[]; SELECT char FROM '\n => IF range THEN { log.PutF["%g[%g]\n", [rope[fullFName]], [integer[in.GetIndex]]]; in.Close[]; RETURN [TRUE]} ELSE EXIT; ': => IF range THEN { [] _ in.GetLine[buffer]; EXIT} ELSE { log.PutF["%g[%g]\n", [rope[fullFName]], [integer[in.GetIndex]]]; in.Close[]; RETURN [TRUE]}; ENDCASE => NULL; ENDLOOP; } ELSE [] _ in.GetLine[buffer]; ENDLOOP; in.Close[]; RETURN [TRUE]}; FS.EnumerateForNames[fileNamePattern, PerName]; RETURN}; DoMerges: PUBLIC PROC [s: Source, cr: CellReading] = { from: CellType = cr.ct; dr: DesignReading = cr.dr; nSets: INT ~ dr.toMerge.Size[].EN; i: INT _ 0; lastPath: Path _ []; firstSet: REF Set--of Path-- _ NIL; DoAMerge: PROC [ra: Sets.Value] ~ { path: Path ~ VPath[ra]; IF lastPath # [] THEN [] _ MergeWork[cr, lastPath, path]; IF nSets=1 THEN lastPath _ path; RETURN}; DoASet: PROC [pair: BiRels.Pair] ~ { arrayPrefix: Path ~ VPath[pair[left]]; rs: REF Set--of Path-- ~ NARROW[pair[right].VA]; IF i=0 THEN firstSet _ rs; IF nSets=1 AND arrayPrefix.cells#NIL THEN ERROR; IF nSets=1 OR i>0 THEN rs^.Enumerate[DoAMerge]; lastPath _ VPath[rs^.First[].Val]; IF i=1 THEN firstSet^.Enumerate[DoAMerge]; i _ i + 1; RETURN}; nsh.Increment[nSets]; dr.toMerge.Enumerate[DoASet]; IF i # nSets THEN ERROR; dr.toMerge.Erase[]; IF NOT dr.toMerge.Empty[] THEN ERROR; dr.mostRecentPathToMerge _ []}; MergeWork: PUBLIC PROC [cr: CellReading, path1, path2: Path] RETURNS [success: BOOL] = { ct: CellType = cr.ct; IF ct.asArray # NIL THEN ERROR; IF path1.cells # NIL AND path2.cells # NIL THEN WITH path1.cells.first SELECT FROM x: ROPE => WITH path2.cells.first SELECT FROM y: ROPE => IF x.Equal[y] THEN { ci: CellInstance = FetchSubcell[ct, OSn[x]]; it: CellType ~ cr.dr.d.CiT[ci]; IF it.asArray # NIL THEN { CheckArrayUsage[cr.dr.d, it]; success _ ArrayMerge[cr, ci, x, path1.PTail, path2.PTail, cr.dr.curArray]; IF cr.dr.curArray AND NOT success THEN cr.waitingMerges _ CONS[NEW [PathPairPrivate _ [path1, path2]], cr.waitingMerges]; IF cr.dr.curArray OR success THEN RETURN; }; }; y: REF Range2 => ERROR; ENDCASE => ERROR; x: REF Range2 => ERROR; ENDCASE => ERROR; MergeFinal[cr.dr, ct, path1, path2]; success _ TRUE; }; FmtPath: PUBLIC PROC [path: Path] RETURNS [r: ROPE] = { wr: ROPE ~ path.wireName.UnparseSteppyName[]; r _ NIL; FOR cells: LORA _ path.cells, cells.rest WHILE cells # NIL DO step: ROPE _ WITH cells.first SELECT FROM x: ROPE => x, x: REF Range2 => IO.PutFR["[%g:%g,%g:%g]", [integer[x[X].min]], [integer[x[X].maxPlusOne-1]], [integer[x[Y].min]], [integer[x[Y].maxPlusOne-1]]], ENDCASE => ERROR; r _ (IF r # NIL THEN r.Concat["/"] ELSE r).Concat[step]; ENDLOOP; r _ IF r#NIL THEN r.Cat["/", wr] ELSE wr; RETURN}; Start: PROC = { [] _ HistogramsViewing.Show[h: nsh, viewerInit: [name: "LichenFromExt2Impl.DoMerges.nSets"], updatePeriod: 5]; RETURN}; Start[]; END.