📄 cellbackup.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: CellBackup.java * Written by: Dmitry Nadezhin, Sun Microsystems. * * Copyright (c) 2005 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.database;import static com.sun.electric.database.UsageCollector.EMPTY_BITSET;import com.sun.electric.database.geometry.ERectangle;import com.sun.electric.database.id.IdManager;import com.sun.electric.database.id.IdReader;import com.sun.electric.database.id.IdWriter;import com.sun.electric.database.id.NodeProtoId;import com.sun.electric.database.id.PortProtoId;import com.sun.electric.database.id.PrimitiveNodeId;import com.sun.electric.database.text.ArrayIterator;import com.sun.electric.database.text.CellName;import com.sun.electric.database.text.ImmutableArrayList;import com.sun.electric.technology.AbstractShapeBuilder;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.BoundsBuilder;import com.sun.electric.technology.TechPool;import com.sun.electric.technology.Technology;import com.sun.electric.tool.Job;import java.io.IOException;import java.util.Arrays;import java.util.BitSet;import java.util.Comparator;import java.util.Iterator;/** * CellBackup is a pair of CellRevision and TechPool. * It caches data that can be calculated when Technology is already * known, but subcells are unknown. */public class CellBackup { public static final CellBackup[] NULL_ARRAY = {}; public static final ImmutableArrayList<CellBackup> EMPTY_LIST = new ImmutableArrayList<CellBackup>(NULL_ARRAY); static int cellBackupsCreated = 0; static int cellBackupsMemoized = 0; /** Cell data. */ public final CellRevision cellRevision; /** Technologies mapping */ public final TechPool techPool; /** "Modified" flag of the Cell. */ public final boolean modified; /** Memoized data for size computation (connectivity etc). */ private volatile Memoization m; /** Arc shrinkage data */ private AbstractShapeBuilder.Shrinkage shrinkage; /** Bounds of primitive arcs in this Cell. */ private ERectangle primitiveBounds; /** Creates a new instance of CellBackup */ private CellBackup(CellRevision cellRevision, TechPool techPool, boolean modified) { this.cellRevision = cellRevision; this.techPool = techPool; this.modified = modified; cellBackupsCreated++; if (Job.getDebug()) check(); } /** Creates a new instance of CellBackup */ public static CellBackup newInstance(ImmutableCell d, TechPool techPool) { if (d.cellId.idManager != techPool.idManager) throw new IllegalArgumentException(); if (techPool.getTech(d.techId) == null) throw new IllegalArgumentException(); CellRevision cellRevision = new CellRevision(d); TechPool restrictedPool = techPool.restrict(cellRevision.techUsages, techPool); return new CellBackup(cellRevision, restrictedPool, true); } /** * Creates a new instance of CellBackup which differs from this CellBackup. * Four array parameters are supplied. Each parameter may be null if its contents is the same as in this Snapshot. * @param d new persistent data of a cell. * @param nodesArray new array of nodes * @param arcsArray new array of arcs * @param exportsArray new array of exports * @param superPool TechPool which defines all used technologies * @return new snapshot which differs froms this Snapshot or this Snapshot. * @throws IllegalArgumentException on invariant violation. * @throws ArrayOutOfBoundsException on some invariant violations. */ public CellBackup with(ImmutableCell d, ImmutableNodeInst[] nodesArray, ImmutableArcInst[] arcsArray, ImmutableExport[] exportsArray, TechPool superPool) { CellRevision newRevision = cellRevision.with(d, nodesArray, arcsArray, exportsArray); TechPool restrictedPool = superPool.restrict(newRevision.techUsages, techPool); if (newRevision == cellRevision && restrictedPool == techPool) return this; if (arcsArray != null) { for (ImmutableArcInst a: arcsArray) { if (a != null && !a.check(restrictedPool)) throw new IllegalArgumentException("arc " + a.name + " is not compatible with TechPool"); } } return new CellBackup(newRevision, restrictedPool, true); } /** * Creates a new instance of CellBackup which differs from this CellBackup by revision date. * @param revisionDate new revision date. * @return new CellBackup which differs from this CellBackup by revision date. */ public CellBackup withRevisionDate(long revisionDate) { CellRevision newRevision = cellRevision.withRevisionDate(revisionDate); if (newRevision == cellRevision) return this; return new CellBackup(newRevision, this.techPool, true); } /** * Creates a new instance of CellBackup with modified flag off. * @return new snapshot which differs froms this Snapshot or this Snapshot. */ public CellBackup withoutModified() { if (!this.modified) return this; return new CellBackup(this.cellRevision, this.techPool, false); } /** * Returns CellBackup which differs from this CellBackup by TechPool. * @param techPool technology map. * @return CellBackup with new TechPool. */ public CellBackup withTechPool(TechPool techPool) { TechPool restrictedPool = techPool.restrict(cellRevision.techUsages, this.techPool); if (this.techPool == restrictedPool) return this; if (techPool.idManager != this.techPool.idManager) throw new IllegalArgumentException();// for (Technology tech: this.techPool.values()) {// if (techPool.get(tech.getId()) != tech)// throw new IllegalArgumentException();// } return new CellBackup(this.cellRevision, restrictedPool, this.modified); } /** * Returns CellBackup which differs from this CellBackup by renamed Ids. * @param idMapper a map from old Ids to new Ids. * @return CellBackup with renamed Ids. */ CellBackup withRenamedIds(IdMapper idMapper, CellName newGroupName) { CellRevision newRevision = cellRevision.withRenamedIds(idMapper, newGroupName); if (newRevision == cellRevision) return this; return new CellBackup(newRevision, this.techPool, true); } /** * Writes this CellBackup to IdWriter. * @param writer where to write. */ void write(IdWriter writer) throws IOException { cellRevision.write(writer); writer.writeBoolean(modified); } /** * Reads CellBackup from SnapshotReader. * @param reader where to read. */ static CellBackup read(IdReader reader, TechPool techPool) throws IOException { CellRevision newRevision = CellRevision.read(reader); boolean modified = reader.readBoolean(); TechPool restrictedPool = techPool.restrict(newRevision.techUsages, techPool); return new CellBackup(newRevision, restrictedPool, modified); } /** * Checks invariant of this CellBackup. * @throws AssertionError if invariant is broken. */ public void check() { cellRevision.check(); IdManager idManager = cellRevision.d.cellId.idManager; assert techPool.idManager == idManager; BitSet techUsages = new BitSet(); for (Technology tech: techPool.values()) { int techIndex = tech.getId().techIndex; assert !techUsages.get(techIndex); techUsages.set(techIndex); } assert techUsages.equals(cellRevision.techUsages);// for (int techIndex = 0; techIndex < cellRevision.techUsages.length(); techIndex++) {// if (cellRevision.techUsages.get(techIndex))// assert techPool.getTech(idManager.getTechId(techIndex)) != null;// } for (ImmutableArcInst a: cellRevision.arcs) { if (a != null) a.check(techPool); } if (m != null) m.check(); } @Override public String toString() { return cellRevision.toString(); } /** * Returns data for size computation (connectivity etc). * @return data for size computation. */ public Memoization getMemoization() { Memoization m = this.m; if (m != null) return m; return this.m = new Memoization(); } /** * Returns data for arc shrinkage computation. * @return data for arc shrinkage computation. */ public AbstractShapeBuilder.Shrinkage getShrinkage() { if (shrinkage == null) shrinkage = new AbstractShapeBuilder.Shrinkage(this); return shrinkage; } /** * Returns bounds of all primitive arcs in this Cell or null if there are not primitives. * @return bounds of all primitive arcs or null. */ public ERectangle getPrimitiveBounds() { ERectangle primitiveBounds = this.primitiveBounds; if (primitiveBounds != null) return primitiveBounds; return this.primitiveBounds = computePrimitiveBounds(); } public ERectangle computePrimitiveBounds() { ImmutableArrayList<ImmutableArcInst> arcs = cellRevision.arcs; if (arcs.isEmpty()) return null; int intMinX = Integer.MAX_VALUE, intMinY = Integer.MAX_VALUE, intMaxX = Integer.MIN_VALUE, intMaxY = Integer.MIN_VALUE; int[] intCoords = new int[4]; BoundsBuilder boundsBuilder = new BoundsBuilder(this); for (ImmutableArcInst a: arcs) { if (boundsBuilder.genBoundsEasy(a, intCoords)) { int x1 = intCoords[0]; if (x1 < intMinX) intMinX = x1; int y1 = intCoords[1]; if (y1 < intMinY) intMinY = y1; int x2 = intCoords[2]; if (x2 > intMaxX) intMaxX = x2; int y2 = intCoords[3]; if (y2 > intMaxY) intMaxY = y2; continue; } boundsBuilder.genShapeOfArc(a); } ERectangle bounds = boundsBuilder.makeBounds(); if (bounds == null) { assert intMinX <= intMaxX && intMinY <= intMaxY; int iw = intMaxX - intMinX; int ih = intMaxY - intMinY; return ERectangle.fromGrid(intMinX, intMinY, iw >= 0 ? iw : (long)intMaxX - (long)intMinX, ih >= 0 ? ih : (long)intMaxY - (long)intMinY); } if (intMinX > intMaxX) return bounds; long longMinX = Math.min(bounds.getGridMinX(), intMinX); long longMinY = Math.min(bounds.getGridMinY(), intMinY); long longMaxX = Math.max(bounds.getGridMaxX(), intMaxX); long longMaxY = Math.max(bounds.getGridMaxY(), intMaxY); return ERectangle.fromGrid(longMinX, longMinY, longMaxX - longMinX, longMaxY - longMinY); } /** * Class which memoizes data for size computation (connectivity etc). */ public class Memoization {// /**// * ImmutableNodeInsts accessed by their nodeId.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -