All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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