
com.sun.electric.database.SnapshotAnalyze Maven / Gradle / Ivy
The newest version!
/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: SnapshotAnalyze.java
*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
*
* 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 com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.EDatabase;
import com.sun.electric.database.id.CellId;
import com.sun.electric.database.id.CellUsage;
import com.sun.electric.database.id.ExportId;
import com.sun.electric.database.topology.ArcInst;
import com.sun.electric.database.topology.NodeInst;
import com.sun.electric.database.variable.Variable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Class to analyze two different Snapshots and report the changes found.
*/
public class SnapshotAnalyze
{
private Map> added;
private Map> removed;
private Set portChanges;
private Set cellVariableChanges;
private List deletedCells;
private Snapshot newSnapshot;
/**
* Constructor analyzes nodes and arcs that changed between two snapshots.
* @param oldSnapshot the old Snapshot.
* @param newSnapshot the new Snapshot.
*/
public SnapshotAnalyze(Snapshot oldSnapshot, Snapshot newSnapshot)
{
this.newSnapshot = newSnapshot;
added = new HashMap>();
removed = new HashMap>();
portChanges = new HashSet();
cellVariableChanges = new HashSet();
deletedCells = new ArrayList();
// look at all cells that changed
for (CellId cellId : newSnapshot.getChangedCells(oldSnapshot))
{
CellBackup oldBackup = oldSnapshot.getCell(cellId);
CellBackup newBackup = newSnapshot.getCell(cellId);
assert oldBackup != newBackup;
// if the cell was created, ignore
if (oldBackup == null) continue;
// if the cell was deleted, add to list
if (newBackup == null)
{
deletedCells.add(cellId);
continue;
}
// cell changed: figure out how
CellRevision oldRevision = oldBackup.cellRevision;
CellRevision newRevision = newBackup.cellRevision;
Set addedToCell = getAddedList(cellId);
Set removedFromCell = getRemovedList(cellId);
// look for variable differences
Variable[] oldVars = oldRevision.d.getVars();
Variable[] newVars = newRevision.d.getVars();
if (oldVars.length != newVars.length) cellVariableChanges.add(cellId); else
{
for(int i=0; i changedParents = new HashSet();
for(int i=0; i removedList = getRemovedList(parentId);
for (ImmutableNodeInst n : oldParentBackup.cellRevision.nodes)
if (n.protoId == cellId) removedList.add(n);
}
if (newParentBackup != null)
{
Set addedList = getAddedList(parentId);
for (ImmutableNodeInst n : newParentBackup.cellRevision.nodes)
if (n.protoId == cellId) addedList.add(n);
}
}
}
// extra test for Export changes
if (!portChanges.contains(cellId))
{
// see if any export is from a node that gets redrawn
maxExportChronIndex = newRevision.getMaxExportChronIndex();
for(int chronIndex=0; chronIndex<=maxExportChronIndex; chronIndex++)
{
ExportId exportId = cellId.getPortId(chronIndex);
ImmutableExport iExportNew = newRevision.getExport(exportId);
if (iExportNew != null)
{
ImmutableNodeInst ini = newRevision.getNodeById(iExportNew.originalNodeId);
if (addedToCell.contains(ini))
{
portChanges.add(cellId);
break;
}
}
}
}
}
}
public Snapshot getNewSnapshot() { return newSnapshot; }
/**
* Method to clear the information in this analysis so that it is not used again.
*/
public void clear()
{
added.clear();
removed.clear();
portChanges.clear();
deletedCells.clear();
}
/**
* Method to return the Cells that changed.
* @return a Set of CellId objects for the Cells that changed.
*/
public Set changedCells()
{
Set cellsToUpdate = new HashSet();
for(CellId cid : added.keySet()) cellsToUpdate.add(cid);
for(CellId cid : removed.keySet()) cellsToUpdate.add(cid);
return cellsToUpdate;
}
/**
* Method to return a List of objects that were added in a given Cell.
* @param cid the CellId of the Cell in question.
* @return a List of ImmutableElectricObjects that were created in the Cell.
*/
public Set getAdded(CellId cid) { return added.get(cid); }
/**
* Method to return a List of objects that were deleted from a given Cell.
* @param cid the CellId of the Cell in question.
* @return a Set of ImmutableElectricObjects that were deleted from the Cell.
*/
public Set getRemoved(CellId cid) { return removed.get(cid); }
/**
* Method to return a List of Cells that were deleted.
* @return a List of CellIds that were deleted in the change.
*/
public List getDeletedCells() { return deletedCells; }
/**
* Method to return a List of Cells that had export changes.
* @return a Set of CellIds that had export changes.
*/
public Set getChangedExportCells() { return portChanges; }
/**
* Method to return a List of Cells that had variable changes.
* @return a Set of CellIds that had variable changes.
*/
public Set getChangedVariableCells() { return cellVariableChanges; }
/**
* Method to print the changes recorded in this SnapshotAnalyze.
*/
public void dumpChanges()
{
EDatabase db = EDatabase.currentDatabase();
System.out.println("++++ SUMMARY OF CHANGES: ++++");
for(CellId cid : removed.keySet())
{
Cell cell = db.getCell(cid);
Set removedSet = removed.get(cid);
if (removedSet != null)
{
for(ImmutableElectricObject obj : removedSet)
{
if (obj instanceof ImmutableNodeInst)
{
ImmutableNodeInst ini = (ImmutableNodeInst)obj;
System.out.println("REMOVED NODE " + describeImmutableObject(cell, ini) + " FROM CELL " + cell.describe(false));
} else
{
ImmutableArcInst iai = (ImmutableArcInst)obj;
System.out.println("REMOVED ARC " + describeImmutableObject(cell, iai) + " FROM CELL " + cell.describe(false));
}
}
}
Set addedSet = added.get(cid);
if (addedSet != null)
{
for(ImmutableElectricObject obj : addedSet)
{
if (obj instanceof ImmutableNodeInst)
{
ImmutableNodeInst ini = (ImmutableNodeInst)obj;
System.out.println("ADDED NODE " + describeImmutableObject(cell, ini) + " TO CELL " + cell.describe(false));
} else
{
ImmutableArcInst iai = (ImmutableArcInst)obj;
System.out.println("ADDED ARC " + describeImmutableObject(cell, iai) + " TO CELL " + cell.describe(false));
}
}
}
}
for(CellId cid : portChanges)
System.out.println("EXPORTS CHANGED ON CELL " + cid);
for(CellId cid : cellVariableChanges)
System.out.println("VARIABLES CHANGED ON CELL " + cid);
for(CellId cid : deletedCells)
System.out.println("DELETED CELL " + cid);
System.out.println("++++ END OF CHANGE SUMMARY ++++");
}
public static String describeImmutableObject(Cell cell, ImmutableElectricObject obj)
{
if (obj instanceof ImmutableNodeInst)
{
ImmutableNodeInst ini = (ImmutableNodeInst)obj;
NodeInst ni = cell.getNodeById(ini.nodeId);
if (ni == null) return "***DELETED NODE***";
return ni.describe(false);
}
ImmutableArcInst iai = (ImmutableArcInst)obj;
ArcInst ai = cell.getArcById(iai.arcId);
if (ai == null) return "***DELETED ARC***";
return ai.describe(false);
}
private Set getAddedList(CellId cid)
{
Set addedToCell = added.get(cid);
if (addedToCell == null) added.put(cid, addedToCell = new HashSet());
return addedToCell;
}
private Set getRemovedList(CellId cid)
{
Set removedFromCell = removed.get(cid);
if (removedFromCell == null) removed.put(cid, removedFromCell = new HashSet());
return removedFromCell;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy