* ./hurricane/src/hviewer,

./coriolis/src/crlcore,
     ./coriolis/src/knik,
     ./coriolis/src/katabatic,
     ./coriolis/src/kite,
     ./coriolis/src/equinox,
     ./coriolis/src/solstice,
     ./coriolis/src/ispd:
     - SVN MOVE: Source tree simplification & uniformisation. Now all tools
         are at the same level, directly under the root of the repository.
         No more "coriolis/src".
This commit is contained in:
Jean-Paul Chaput 2010-03-09 15:25:20 +00:00
parent 5dd8cb502a
commit a1726771b6
32 changed files with 6827 additions and 0 deletions

26
equinox/CMakeLists.txt Normal file
View File

@ -0,0 +1,26 @@
PROJECT(EQUINOX)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0)
IF(COMMAND CMAKE_POLICY)
CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND CMAKE_POLICY)
SET(CMAKE_C_FLAGS_DEBUG "-g -Wall" CACHE STRING "Debug options." FORCE)
SET(CMAKE_CXX_FLAGS_DEBUG "-Winline -g -Wall" CACHE STRING "Debug options." FORCE)
SET(CMAKE_LINKER_FLAGS_DEBUG "-Winline -pg" CACHE STRING "Debug options." FORCE)
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "-Winline -pg" CACHE STRING "Debug options." FORCE)
SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-Winline -pg" CACHE STRING "Debug options." FORCE)
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "-Winline -pg" CACHE STRING "Debug options." FORCE)
SET(CMAKE_MODULE_PATH "$ENV{HURRICANE_TOP}/share/cmake_modules/")
SET(QT_USE_QTXML "true")
FIND_PACKAGE(Qt4 REQUIRED) # find and setup Qt4 for this project
FIND_PACKAGE(HURRICANE REQUIRED)
FIND_PACKAGE(CORIOLIS REQUIRED)
SET_LIB_LINK_MODE()
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(cmake_modules)

View File

@ -0,0 +1 @@
install ( FILES FindEQUINOX.cmake DESTINATION /share/cmake_modules )

View File

@ -0,0 +1,48 @@
# - Find the Equinox includes and libraries.
# The following variables are set if Coriolis is found. If EQUINOX is not
# found, EQUINOX_FOUND is set to false.
# EQUINOX_FOUND - True when the Coriolis include directory is found.
# EQUINOX_INCLUDE_DIR - the path to where the Coriolis include files are.
# EQUINOX_LIBRARIES - The path to where the Coriolis library files are.
SET(EQUINOX_INCLUDE_PATH_DESCRIPTION "directory containing the Equinox include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis")
SET(EQUINOX_DIR_MESSAGE "Set the EQUINOX_INCLUDE_DIR cmake cache entry to the ${EQUINOX_INCLUDE_PATH_DESCRIPTION}")
# don't even bother under WIN32
IF(UNIX)
SET(EQUINOX_DIR_SEARCH $ENV{CORIOLIS_TOP} $ENV{HURRICANE_TOP})
#
# Look for an installation.
#
FIND_PATH(EQUINOX_INCLUDE_PATH NAMES equinox/Equi.h PATHS
# Look in other places.
${EQUINOX_DIR_SEARCH}
PATH_SUFFIXES include/coriolis
# Help the user find it if we cannot.
DOC "The ${EQUINOX_INCLUDE_PATH_DESCRIPTION}"
)
FIND_LIBRARY(EQUINOX_LIBRARY_PATH
NAMES equinox
PATHS ${EQUINOX_DIR_SEARCH}
PATH_SUFFIXES lib
# Help the user find it if we cannot.
DOC "The ${EQUINOX_INCLUDE_PATH_DESCRIPTION}"
)
FIND_LIBRARY(EQUINOX_STATIC_LIBRARY_PATH
NAMES equinox-static
PATHS ${EQUINOX_DIR_SEARCH}
PATH_SUFFIXES lib
# Help the user find it if we cannot.
DOC "The ${EQUINOX_INCLUDE_PATH_DESCRIPTION}"
)
SET_LIBRARIES_PATH(EQUINOX EQUINOX)
HURRICANE_CHECK_LIBRARIES(EQUINOX)
ENDIF(UNIX)

View File

@ -0,0 +1,47 @@
# - Find the Equinox includes and libraries.
# The following variables are set if Coriolis is found. If EQUINOX is not
# found, EQUINOX_FOUND is set to false.
# EQUINOX_FOUND - True when the Coriolis include directory is found.
# EQUINOX_INCLUDE_DIR - the path to where the Coriolis include files are.
# EQUINOX_LIBRARIES - The path to where the Coriolis library files are.
SET(EQUINOX_INCLUDE_PATH_DESCRIPTION "directory containing the Equinox include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis")
SET(EQUINOX_DIR_MESSAGE "Set the EQUINOX_INCLUDE_DIR cmake cache entry to the ${EQUINOX_INCLUDE_PATH_DESCRIPTION}")
# don't even bother under WIN32
IF(UNIX)
SET(EQUINOX_DIR_SEARCH $ENV{CORIOLIS_TOP} $ENV{HURRICANE_TOP})
#
# Look for an installation.
#
FIND_PATH(EQUINOX_INCLUDE_PATH NAMES equinox/Equi.h PATHS
# Look in other places.
${EQUINOX_DIR_SEARCH}
PATH_SUFFIXES include/coriolis
# Help the user find it if we cannot.
DOC "The ${EQUINOX_INCLUDE_PATH_DESCRIPTION}"
)
FIND_LIBRARY(EQUINOX_LIBRARY_PATH
NAMES equinox
PATHS ${EQUINOX_DIR_SEARCH}
PATH_SUFFIXES lib
# Help the user find it if we cannot.
DOC "The ${EQUINOX_INCLUDE_PATH_DESCRIPTION}"
)
FIND_LIBRARY(EQUINOX_STATIC_LIBRARY_PATH
NAMES equinox-static
PATHS ${EQUINOX_DIR_SEARCH}
PATH_SUFFIXES lib
# Help the user find it if we cannot.
DOC "The ${EQUINOX_INCLUDE_PATH_DESCRIPTION}"
)
SET_LIBRARIES_PATH(EQUINOX EQUINOX)
HURRICANE_CHECK_LIBRARIES(EQUINOX)
ENDIF(UNIX)

View File

@ -0,0 +1,55 @@
include ( ${QT_USE_FILE} )
include_directories ( ${EQUINOX_SOURCE_DIR}/src
${EQUINOX_SOURCE_DIR}/src/intervalTree/src
${HURRICANE_INCLUDE_DIR}
${CORIOLIS_INCLUDE_DIR}
)
set ( includes equinox/EquinoxFilters.h
equinox/EquinoxCollections.h
equinox/Equi.h equinox/Equis.h
equinox/EquinoxEngine.h
equinox/Strategy.h
equinox/Tile.h equinox/Tiles.h
equinox/UnionFind.h
equinox/SweepLine.h equinox/TileSweepLine.h
)
set ( mocIncludes equinox/GraphicEquinoxEngine.h )
set ( cpps EquinoxFilters.cpp
EquinoxCollections.cpp
Equi.cpp
TileSweepLine.cpp
Tile.cpp
Strategy.cpp
EquinoxEngine.cpp
UnionFind.cpp
GraphicEquinoxEngine.cpp
)
set ( intervalTreeIncludes intervalTree/src/equinox/Interval.h
intervalTree/src/equinox/IntervalTree.h )
set ( intervalTreeCpps intervalTree/src/IntervalTree.cpp )
qt4_wrap_cpp ( mocCpps ${mocIncludes} )
add_library ( equinox ${cpps} ${mocCpps} )
target_link_libraries ( equinox intervalTree
${CORIOLIS_LIBRARIES}
${HURRICANE_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
${QT_LIBRARIES}
${LEFDEF_LIBRARIES}
${OA_LIBRARIES}
)
add_library (intervalTree ${intervalTreeCpps} )
target_link_libraries (intervalTree ${CORIOLIS_LIBRARIES}
${HURRICANE_LIBRARIES} )
install ( TARGETS equinox intervalTree DESTINATION /lib)
install ( FILES ${includes}
${mocIncludes}
${intervalTreeIncludes} DESTINATION /include/coriolis/equinox )

186
equinox/src/Equi.cpp Normal file
View File

@ -0,0 +1,186 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./Equi.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <string>
using namespace std;
#include "hurricane/Box.h"
#include "hurricane/Cell.h"
#include "hurricane/Component.h"
#include "hurricane/Occurrence.h"
#include "hurricane/Collection.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Entity.h"
#include "hurricane/Filter.h"
#include "hurricane/Net.h"
#include "hurricane/Commons.h"
#include "hurricane/Error.h"
#include "hurricane/Relation.h"
#include "hurricane/Locator.h"
#include "crlcore/Utilities.h"
#include "crlcore/ToolEngine.h"
#include "equinox/Tile.h"
#include "equinox/Equi.h"
#include "equinox/Strategy.h"
#include "equinox/EquinoxEngine.h"
#include "equinox/EquinoxFilters.h"
#include "equinox/EquinoxCollections.h"
namespace Equinox {
using namespace Hurricane;
// -------------------------------------------------------------------
// Class : "Equinox::Equi".
map<Net*, unsigned long> Equi::_map_net2nb_usefulcomponent;
void Equi::_preDestroy()
{
if(_nextequi) _nextequi->decrementCount();
_equinox->removeEqui(this);
Entity::_preDestroy();
}
void Equi::factorizeComponents()
{
// get all components to netmap (net2Component)
map<Net*, set<Occurrence> > netmap;
forEach(Occurrence,occurrence,getComponentOccurrences()) {
netmap[( dynamic_cast<Component*>((*occurrence).getEntity()))->getNet()].insert((*occurrence));
}
for ( map<Net*, set<Occurrence> >::iterator i = netmap.begin();
i != netmap.end();
i++ )
{
Net * net = (*i).first;
//process nb_component and map_net2nb_usefulcomponent[net]
unsigned long nb_component = 0;
map<Net*, unsigned long>::iterator end = _map_net2nb_usefulcomponent.end();
if(_map_net2nb_usefulcomponent.find(net)==end) { /* haven't been calculed */
nb_component = net->getComponents().getSubSet(IsUsedByExtractFilter()).getSize();
_map_net2nb_usefulcomponent[net] = nb_component;
}
else {
nb_component = _map_net2nb_usefulcomponent[net] ;
}
if( (*i).second.size() == nb_component ){
forEach (Occurrence,occurrence,getCollection((*i).second)) _occurrences.erase((*occurrence));
_occurrences.insert(Occurrence(net));
}
}
}
void Equi::_postCreate()
{
Entity::_postCreate();
_equinox->addEqui(this);
}
string Equi::_getString() const
{
return "<Equi " + getString(_number) + " - " + getString(_occurrences.size()) + " occurences>";
}
Equi::Equi(EquinoxEngine* equinox, Equi* nextequi, const unsigned long& number)
: Entity()
, _equinox(equinox)
, _occurrences()
, _nextequi(nextequi)
, _count(0)
, _number(number)
{
if(!equinox){
throw Error("Can't create Equi: equinox is null");
}
}
Equi * Equi::create(EquinoxEngine* equinox, Equi* nextequi, const unsigned long& number)
{
Equi * equi = new Equi(equinox, nextequi, number);
if(!equi) {
throw Error("can't create Equi : allocation error");
}
equi->_postCreate();
return equi;
}
Cell* Equi::getCell() const
{
return _equinox->getCell();
}
// filters
GenericFilter<Occurrence> Equi::getIsEquiFilter (){ return IsEquiFilter();}
GenericFilter<Occurrence> Equi::getIsComponentFilter (){ return IsComponentFilter();}
GenericFilter<Occurrence> Equi::getIsNetFilter (){ return IsNetFilter();}
GenericFilter<Occurrence> Equi::getIsLeafEquiFilter (){ return IsLeafEquiFilter(); }
GenericFilter<Occurrence> Equi::getIsNotLeafEquiFilter (){ return !IsLeafEquiFilter(); }
// GenericFilter<Component*> Equi::getIsUsedByExtractFilter (){ return IsUsedByExtractFilter();}
GenericFilter<Occurrence> Equi::getIsNetOrComponentFilter (){ return IsNetOrComponentFilter();}
Occurrences Equi::getAllOccurrences () const { return AllOccurrencesCollection(this);}
Occurrences Equi::getEquiOccurrences () const { return getOccurrences().getSubSet(IsEquiFilter());};
Occurrences Equi::getComponentOccurrences () const { return getOccurrences().getSubSet(IsComponentFilter());};
Occurrences Equi::getNetOccurrences () const { return getOccurrences().getSubSet(IsNetFilter());};
Occurrences Equi::getNetAndComponentOccurrences () const { return getOccurrences().getSubSet(IsNetOrComponentFilter());};
Occurrences Equi::getEquiComponentOccurrences () const { return EquiComponentOccurrencesCollection(this);};
Occurrences Equi::getCurrentComponentOccurrences () const { return CurrentComponentOccurrencesCollection(this); };
bool Equi::isLeafEqui () const { GenericLocator<Occurrence> l = getEquiOccurrences().getLocator(); return !(l.isValid());};
bool Equi::hasNetOccurrence () const { GenericLocator<Occurrence> l = getNetOccurrences().getLocator(); return (l.isValid());};
bool Equi::hasComponentOccurrence () const { GenericLocator<Occurrence> l = getComponentOccurrences().getLocator(); return (l.isValid());};
}// End of namespace Equinox

View File

@ -0,0 +1,721 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./EquinoxCollections.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
/********************************************************************
* This file contains : *
* - See "./equinox/EquinoxCollections.h" *
********************************************************************/
#include <hurricane/Collection.h>
#include <hurricane/Occurrence.h>
#include <hurricane/Occurrences.h>
#include <hurricane/Net.h>
#include <equinox/Equi.h>
#include <equinox/EquinoxFilters.h>
#include <equinox/EquinoxCollections.h>
namespace Equinox {
AllOccurrencesCollection::AllOccurrencesCollection()
// ***************************************************
: Inherit()
, _equi(NULL)
{
}
AllOccurrencesCollection::AllOccurrencesCollection(const Equi* equi)
// ******************************************************************
: Inherit()
, _equi(equi)
{
}
AllOccurrencesCollection::AllOccurrencesCollection(const AllOccurrencesCollection& occurrences)
// ***********************************************************************************************
: Inherit()
, _equi(occurrences._equi)
{
}
AllOccurrencesCollection& AllOccurrencesCollection::operator=(const AllOccurrencesCollection& occurrences)
// **********************************************************************************************************
{
_equi = occurrences._equi;
return *this;
}
Collection<Occurrence> * AllOccurrencesCollection::getClone() const
// *****************************************************************
{
return new AllOccurrencesCollection(*this);
}
Locator<Occurrence>* AllOccurrencesCollection::getLocator() const
// ***************************************************************
{
return new Locator(_equi);
}
string AllOccurrencesCollection::_getString() const
// *************************************************
{
string s = "<Equi::AllOccurrences";
if(_equi) {
s += " " + getString(_equi);
}
s += ">";
return s;
}
// **********************************************************************************************************
// AllOccurrencesCollection::Locator implementation
// **********************************************************************************************************
AllOccurrencesCollection::Locator::Locator()
// ******************************************
: Inherit()
, _equi(NULL)
, _state(0)
, _componentLocator()
, _equioccurrenceLocator()
, _occurrenceLocator()
{
}
AllOccurrencesCollection::Locator::Locator(const Equi* equi)
// **********************************************************
: Inherit()
, _equi(equi)
, _state(0)
, _componentLocator()
, _equioccurrenceLocator()
, _occurrenceLocator()
{
if(_equi ) { // If this is un locator valid
_componentLocator = _equi->getNetAndComponentOccurrences().getLocator();
if(_componentLocator.isValid())
_state = 1;
else {
_equioccurrenceLocator = _equi->getEquiOccurrences().getLocator();
while(!_state && _equioccurrenceLocator.isValid()) {
Equi * equi = dynamic_cast<Equi*>(_equioccurrenceLocator.getElement().getEntity());
_occurrenceLocator = equi->getAllOccurrences().getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_equioccurrenceLocator.progress();
}
}
}
}
AllOccurrencesCollection::Locator::Locator(const Locator& locator)
// ****************************************************************
: Inherit()
,_equi(locator._equi)
,_state(locator._state)
,_componentLocator(locator._componentLocator)
,_equioccurrenceLocator(locator._equioccurrenceLocator)
,_occurrenceLocator(locator._occurrenceLocator)
{
}
AllOccurrencesCollection::Locator& AllOccurrencesCollection::Locator::operator=(const Locator& locator)
// *****************************************************************************************************
{
_equi = locator._equi;
_state = locator._state;
_componentLocator = locator._componentLocator;
_equioccurrenceLocator = locator._equioccurrenceLocator;
_occurrenceLocator = locator._occurrenceLocator;
return *this;
}
Occurrence AllOccurrencesCollection::Locator::getElement() const
// **************************************************************
{
if(_state) { // If locator is valid
switch(_state) {
case 1 : return Occurrence(_componentLocator.getElement());
case 2 : {
Occurrence occurrence = _occurrenceLocator.getElement();
Entity* entity = occurrence.getEntity();
Path path = Path(_equioccurrenceLocator.getElement().getPath().getHeadInstance() , occurrence.getPath());
return Occurrence(entity, path);
}
}
}
return Occurrence();
}
Locator<Occurrence> * AllOccurrencesCollection::Locator::getClone() const
// ***********************************************************************
{
return new Locator(*this);
}
bool AllOccurrencesCollection::Locator::isValid() const
// *****************************************************
{
return (_state!=0);
}
void AllOccurrencesCollection::Locator::progress()
// *************************************************
{
if(_state) {
switch(_state) {
case 1 :
_componentLocator.progress();
if(!_componentLocator.isValid()) {
_state = 0;
_equioccurrenceLocator = _equi-> getEquiOccurrences().getLocator();
while(!_state && _equioccurrenceLocator.isValid()) {
Equi* equi = dynamic_cast<Equi*>(_equioccurrenceLocator.getElement().getEntity());
_occurrenceLocator = equi->getAllOccurrences().getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_equioccurrenceLocator.progress();
}
}
break;
case 2 :
_occurrenceLocator.progress();
if(!_occurrenceLocator.isValid()) {
_state = 0;
if(_equioccurrenceLocator.isValid()) {
_equioccurrenceLocator.progress();
while(!_state && _equioccurrenceLocator.isValid()) {
Equi* equi = dynamic_cast<Equi*>(_equioccurrenceLocator.getElement().getEntity());
_occurrenceLocator = equi->getAllOccurrences().getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_equioccurrenceLocator.progress();
}
}
}
break;
}
}
}
string AllOccurrencesCollection::Locator::_getString() const
// **********************************************************
{
string s ="<Equi::AllOccurrences::Locator";
if(_equi) {
s += " " + getString(_equi);
}
s += ">";
return s;
}
EquiComponentOccurrencesCollection::EquiComponentOccurrencesCollection()
// ***************************************************
: Inherit()
, _equi(NULL)
{
}
EquiComponentOccurrencesCollection::EquiComponentOccurrencesCollection(const Equi* equi)
// ******************************************************************
: Inherit()
, _equi(equi)
{
}
EquiComponentOccurrencesCollection::EquiComponentOccurrencesCollection(const EquiComponentOccurrencesCollection& occurrences)
// ***********************************************************************************************
: Inherit()
, _equi(occurrences._equi)
{
}
EquiComponentOccurrencesCollection& EquiComponentOccurrencesCollection::operator=(const EquiComponentOccurrencesCollection& occurrences)
// **********************************************************************************************************
{
_equi = occurrences._equi;
return *this;
}
Collection<Occurrence> * EquiComponentOccurrencesCollection::getClone() const
// *****************************************************************
{
return new EquiComponentOccurrencesCollection(*this);
}
Locator<Occurrence>* EquiComponentOccurrencesCollection::getLocator() const
// ***************************************************************
{
return new Locator(_equi);
}
string EquiComponentOccurrencesCollection::_getString() const
// *************************************************
{
string s = "<Equi::EquiComponentOccurrences";
if(_equi) {
s += " " + getString(_equi);
}
s += ">";
return s;
}
// **********************************************************************************************************
// EquiComponentOccurrencesCollection::Locator implementation
// **********************************************************************************************************
EquiComponentOccurrencesCollection::Locator::Locator()
// ******************************************
: Inherit()
, _equi(NULL)
, _state(0)
, _componentLocator()
, _equioccurrenceLocator()
, _occurrenceLocator()
{
}
EquiComponentOccurrencesCollection::Locator::Locator(const Equi* equi)
// **********************************************************
: Inherit()
, _equi(equi)
, _state(0)
, _componentLocator()
, _equioccurrenceLocator()
, _occurrenceLocator()
{
if(_equi ) { // If this is un locator valid
_componentLocator = _equi->getCurrentComponentOccurrences().getLocator();
if(_componentLocator.isValid())
_state = 1;
else {
_equioccurrenceLocator = _equi->getEquiOccurrences().getLocator();
while(!_state && _equioccurrenceLocator.isValid()) {
Equi * equi = dynamic_cast<Equi*>(_equioccurrenceLocator.getElement().getEntity());
_occurrenceLocator = equi->getEquiComponentOccurrences().getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_equioccurrenceLocator.progress();
}
}
}
}
EquiComponentOccurrencesCollection::Locator::Locator(const Locator& locator)
// ****************************************************************
: Inherit()
,_equi(locator._equi)
,_state(locator._state)
,_componentLocator(locator._componentLocator)
,_equioccurrenceLocator(locator._equioccurrenceLocator)
,_occurrenceLocator(locator._occurrenceLocator)
{
}
EquiComponentOccurrencesCollection::Locator& EquiComponentOccurrencesCollection::Locator::operator=(const Locator& locator)
// *****************************************************************************************************
{
_equi = locator._equi;
_state = locator._state;
_componentLocator = locator._componentLocator;
_equioccurrenceLocator = locator._equioccurrenceLocator;
_occurrenceLocator = locator._occurrenceLocator;
return *this;
}
Occurrence EquiComponentOccurrencesCollection::Locator::getElement() const
// **************************************************************
{
if(_state) { // If locator is valid
switch(_state) {
case 1 : return Occurrence(_componentLocator.getElement());
case 2 : {
Occurrence occurrence = _occurrenceLocator.getElement();
Entity* entity = occurrence.getEntity();
Path path = Path(_equioccurrenceLocator.getElement().getPath().getHeadInstance() , occurrence.getPath());
return Occurrence(entity, path);
}
}
}
return Occurrence();
}
Locator<Occurrence> * EquiComponentOccurrencesCollection::Locator::getClone() const
// ***********************************************************************
{
return new Locator(*this);
}
bool EquiComponentOccurrencesCollection::Locator::isValid() const
// *****************************************************
{
return (_state!=0);
}
void EquiComponentOccurrencesCollection::Locator::progress()
// *************************************************
{
if(_state) {
switch(_state) {
case 1 :
_componentLocator.progress();
if(!_componentLocator.isValid()) {
_state = 0;
_equioccurrenceLocator = _equi-> getEquiOccurrences().getLocator();
while(!_state && _equioccurrenceLocator.isValid()) {
Equi* equi = dynamic_cast<Equi*>(_equioccurrenceLocator.getElement().getEntity());
_occurrenceLocator = equi->getEquiComponentOccurrences().getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_equioccurrenceLocator.progress();
}
}
break;
case 2 :
_occurrenceLocator.progress();
if(!_occurrenceLocator.isValid()) {
_state = 0;
if(_equioccurrenceLocator.isValid()) {
_equioccurrenceLocator.progress();
while(!_state && _equioccurrenceLocator.isValid()) {
Equi* equi = dynamic_cast<Equi*>(_equioccurrenceLocator.getElement().getEntity());
_occurrenceLocator = equi->getEquiComponentOccurrences().getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_equioccurrenceLocator.progress();
}
}
}
break;
}
}
}
string EquiComponentOccurrencesCollection::Locator::_getString() const
// **********************************************************
{
string s ="<Equi::EquiComponentOccurrences::Locator";
if(_equi) {
s += " " + getString(_equi);
}
s += ">";
return s;
}
CurrentComponentOccurrencesCollection::CurrentComponentOccurrencesCollection()
// ***************************************************
: Inherit()
, _equi(NULL)
{
}
CurrentComponentOccurrencesCollection::CurrentComponentOccurrencesCollection(const Equi* equi)
// ******************************************************************
: Inherit()
, _equi(equi)
{
}
CurrentComponentOccurrencesCollection::CurrentComponentOccurrencesCollection(const CurrentComponentOccurrencesCollection& occurrences)
// ***********************************************************************************************
: Inherit()
, _equi(occurrences._equi)
{
}
CurrentComponentOccurrencesCollection& CurrentComponentOccurrencesCollection::operator=(const CurrentComponentOccurrencesCollection& occurrences)
// **********************************************************************************************************
{
_equi = occurrences._equi;
return *this;
}
Collection<Occurrence> * CurrentComponentOccurrencesCollection::getClone() const
// *****************************************************************
{
return new CurrentComponentOccurrencesCollection(*this);
}
Locator<Occurrence>* CurrentComponentOccurrencesCollection::getLocator() const
// ***************************************************************
{
return new Locator(_equi);
}
string CurrentComponentOccurrencesCollection::_getString() const
// *************************************************
{
string s = "<Equi::currentComponentOccurrences";
if(_equi) {
s += " " + getString(_equi);
}
s += ">";
return s;
}
// **********************************************************************************************************
// CurrentComponentOccurrencesCollection::Locator implementation
// **********************************************************************************************************
CurrentComponentOccurrencesCollection::Locator::Locator()
// ******************************************
: Inherit()
, _equi(NULL)
, _state(0)
, _componentLocator()
, _netoccurrenceLocator()
, _occurrenceLocator()
{
}
CurrentComponentOccurrencesCollection::Locator::Locator(const Equi* equi)
// **********************************************************
: Inherit()
, _equi(equi)
, _state(0)
, _componentLocator()
, _netoccurrenceLocator()
, _occurrenceLocator()
{
if(_equi) { // If locator is valid
_componentLocator = _equi->getComponentOccurrences().getLocator();
if( _componentLocator.isValid() ) {
_state = 1;
}
else
{
_netoccurrenceLocator = _equi->getNetOccurrences().getLocator();
while(!_state && _netoccurrenceLocator.isValid()) {
Net * net = dynamic_cast<Net*>(_netoccurrenceLocator.getElement().getEntity());
_occurrenceLocator = net->getComponents().getSubSet(NetIsUsedByExtractorFilter()).getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_netoccurrenceLocator.progress();
}
}
}
}
CurrentComponentOccurrencesCollection::Locator::Locator(const Locator& locator)
// ****************************************************************
: Inherit()
,_equi(locator._equi)
,_state(locator._state)
,_componentLocator(locator._componentLocator)
,_netoccurrenceLocator(locator._netoccurrenceLocator)
,_occurrenceLocator(locator._occurrenceLocator)
{
}
CurrentComponentOccurrencesCollection::Locator& CurrentComponentOccurrencesCollection::Locator::operator=(const Locator& locator)
// *****************************************************************************************************
{
_equi = locator._equi;
_state = locator._state;
_componentLocator = locator._componentLocator;
_netoccurrenceLocator = locator._netoccurrenceLocator;
_occurrenceLocator = locator._occurrenceLocator;
return *this;
}
Occurrence CurrentComponentOccurrencesCollection::Locator::getElement() const
// **************************************************************
{
if(_state){ // If Locator is Valid
switch(_state) {
case 1 : return _componentLocator.getElement();
case 2 : {
return Occurrence( _occurrenceLocator.getElement(), Path() );
}
}
}
return Occurrence();
}
Locator<Occurrence> * CurrentComponentOccurrencesCollection::Locator::getClone() const
// ***********************************************************************
{
return new Locator(*this);
}
bool CurrentComponentOccurrencesCollection::Locator::isValid() const
// *****************************************************
{
return (_state!=0);
}
void CurrentComponentOccurrencesCollection::Locator::progress()
// *************************************************
{
if(_state) { // If locator is Valid
switch(_state) {
case 1 : {
_componentLocator.progress();
if(!_componentLocator.isValid()) {
_state = 0;
_netoccurrenceLocator = _equi->getNetOccurrences().getLocator();
while(!_state && _netoccurrenceLocator.isValid()) {
Net * net = dynamic_cast<Net*>(_netoccurrenceLocator.getElement().getEntity());
//_occurrenceLocator = net->GetComponents().GetLocator();
_occurrenceLocator = net->getComponents().getSubSet(NetIsUsedByExtractorFilter()).getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_netoccurrenceLocator.progress();
}
}
break;
}
case 2 : {
_occurrenceLocator.progress();
if(!_occurrenceLocator.isValid()) {
_state = 0;
if (_netoccurrenceLocator.isValid()) {
_netoccurrenceLocator.progress();
while(!_state && _netoccurrenceLocator.isValid()) {
Net * net = dynamic_cast<Net*>(_netoccurrenceLocator.getElement().getEntity());
//_occurrenceLocator = net->GetComponents().GetLocator();
_occurrenceLocator = net->getComponents().getSubSet(NetIsUsedByExtractorFilter()).getLocator();
if(_occurrenceLocator.isValid())
_state = 2;
else
_netoccurrenceLocator.progress();
}
}
}
break;
}
}
}
}
string CurrentComponentOccurrencesCollection::Locator::_getString() const
// **********************************************************
{
string s ="<Equi::currentComponentOccurrences::Locator";
if(_equi) {
s += " " + getString(_equi);
}
s += ">";
return s;
}
} // End of Equinox namespace.

View File

@ -0,0 +1,576 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | =============================================================== |
// | C++ Header : "./EquinoxEngine.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <iostream>
#include <vector>
#include "hurricane/Path.h"
#include "hurricane/Net.h"
#include "hurricane/Name.h"
#include "hurricane/Entity.h"
#include "hurricane/Error.h"
#include "hurricane/Collection.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Cell.h"
#include "hurricane/Occurrences.h"
#include "hurricane/Box.h"
#include "hurricane/Instance.h"
#include "hurricane/Components.h"
#include "crlcore/ToolEngine.h"
#include "crlcore/Utilities.h"
#include "equinox/EquinoxFilters.h"
#include "equinox/Equis.h"
#include "equinox/Equi.h"
#include "equinox/Tile.h"
#include "equinox/Tiles.h"
#include "equinox/Strategy.h"
#include "equinox/UnionFind.h"
#include "equinox/EquinoxEngine.h"
#include "equinox/TileSweepLine.h"
namespace Equinox {
using namespace std;
using namespace Hurricane;
// -------------------------------------------------------------------
// Class : "Equinox::EquinoxEngine".
/**/ Name EquinoxEngine::_toolName = "Equinox";
/**/ Strategy * EquinoxEngine::_strategy = NULL;
EquinoxEngine* EquinoxEngine::create (Cell* cell)
{
EquinoxEngine* equinox = new EquinoxEngine ( cell );
if(!equinox){
throw Error("can't create Equinox : allocation failed");
}
equinox->_postCreate ();
return equinox;
}
/**/ void EquinoxEngine::removeEquis ()
{
set<Equi*>::iterator i;
while(!_equis.empty()) {
i = _equis.begin();
(*i)->destroy(); // Delete also addresse of objet Equi from current Equinox
}
_occurrences.clear(); // Clear also map<Occurrence, Equi*>
}
Strategy* EquinoxEngine::getStrategy ()
{
if (!_strategy) {
_strategy = new DefaultStrategy();
}
return _strategy;
}
void EquinoxEngine::withAlimExtract(unsigned int nbwindows)
// **************************************************
{
setStrategy(new WithAlimStrategy());
/*DEBUG*/ cmess1 << " o extract " << endl;
extract(nbwindows);
/*DEBUG*/ cmess1 << " o printEqui " << endl;
printEquis();
/*DEBUG*/ cmess1 << " o Fin " << endl;
}
void EquinoxEngine::withoutAlimExtract(unsigned int nbwindows)
// **************************************************
{
setStrategy(new WithoutAlimStrategy());
/*DEBUG*/ cmess1 << " o extract " << endl;
extract(nbwindows);
/*DEBUG*/ cmess1 << " o printEqui " << endl;
printEquis();
/*DEBUG*/ cmess1 << " o Fin " << endl;
}
void EquinoxEngine::extract(unsigned int nbwindows)
{
// Test for parameter
// ******************
if(!getStrategy())
throw Error("Can't start extraction without mode, the current mode is null");
if( nbwindows >256 || nbwindows < 1 ) {
throw Error("Can't start extraction : the nbwindows " + getString(nbwindows) + " is not valid");
}
// Clean Equis
// ***********
if(isExtracted()) {
flushEquis(_cell);
}
// Start extraction.
// *****************
getStrategy()->run(this, nbwindows);
}
Record* EquinoxEngine::_getRecord () const
{
Record* record = ToolEngine::_getRecord ();
record->add ( getSlot ( "_isExtracted" , _isExtracted ) );
record->add ( getSlot ( "_equis" , _equis ) );
record->add ( getSlot ( "_occurrences" , _occurrences ) );
return ( record );
}
string EquinoxEngine::_getString () const
{
ostringstream os;
os << "<" << "Equinox " << _cell->getName () << ">";
return ( os.str() );
}
string EquinoxEngine::_getTypeName () const { return "Equinox"; }
Equi* EquinoxEngine::getEquiByOccurrence(Occurrence occurrence)
// *********************************************
{
map<Occurrence, Equi*>::iterator i = _occurrences.end();
if( _occurrences.find(occurrence) == i) {
Component * component = dynamic_cast<Component*>(occurrence.getEntity());
if( component && occurrence.getPath().isEmpty() )
{
// If this is a component , maybe it has been factorized, after extraction.
// *************************************************************************
if( _occurrences.find( Occurrence(component->getNet()) ) != i )
return _occurrences[Occurrence(component->getNet())];
}
return NULL;
}
else
return _occurrences[occurrence];
};
Occurrence EquinoxEngine::getEquiOccurrence(Occurrence occurrence)
// ***********************************************
{
map<Occurrence, Equi*>::iterator i = _occurrences.end();
if( _occurrences.find(occurrence) == i ) {
Component* component = dynamic_cast<Component*>(occurrence.getEntity());
if( component && occurrence.getPath().isEmpty() ) { // If this is a component, maybe it has been factorized.
if( _occurrences.find( Occurrence(component->getNet()) ) != i )
return Occurrence(static_cast<Entity*>(_occurrences[Occurrence(component->getNet())]));
}
return Occurrence();
}
else
return Occurrence(static_cast<Entity*>(_occurrences[occurrence]));
};
Occurrence EquinoxEngine::getUpperEquiOccurrence(Occurrence occurrence)
// *****************************************************
{
Path path = occurrence.getPath();
Equi * equi = NULL;
occurrence = Occurrence(occurrence.getEntity());
while(1) {
if(!path.isEmpty())
equi = get(path.getMasterCell())->getEquiByOccurrence(occurrence);
else
equi = this->getEquiByOccurrence(occurrence);
if(!equi) return occurrence;
occurrence = Occurrence(equi, Path(path.getTailInstance()));
path=path.getHeadPath();
}
return Occurrence();
};
void EquinoxEngine::setIsExtracted (const bool flag)
{
_isExtracted= flag;
};
void EquinoxEngine::selectWindowsSize ()
{
Box cellbox = _cell->getBoundingBox();
long cellwidth = cellbox.getWidth();
if ( cellwidth < 50000 ){ _nbWindows = 1; }
else if( cellwidth < 100000 ){ _nbWindows = 2; }
else { _nbWindows = cellwidth / 50000; }
if (_nbWindows > 256) _nbWindows = 256;
_nbWindows=20;
///*DEBUG*/ cmess1 << " o selectWindowsSize : _nbWindows = " << _nbWindows << endl ;
}
void EquinoxEngine::initTiles ()
{
getStrategy()->getTilesFor(this);
}
void EquinoxEngine::postSweepLine ()
{
getStrategy()->operationAfterScanLine(this);
}
void EquinoxEngine::scan (unsigned int nbwindows)
{
/*DEBUG*/ cmess1 << " o EquinoxEngine::scan " << getString(_cell) << endl;
TileSweepLine* sweepLine = TileSweepLine::create(this,getStrategy());
// Step 2 - Select Windows Size
// ****************************
/*DEBUG*/ cmess1 << " - Step 2 - Select Windows Size" << endl;
selectWindowsSize();
// Main algorithme
// ***************
for(_cWindows=0; _cWindows<_nbWindows; _cWindows++) {
// Step 3 - Init tiles vector
// **************************
/*DEBUG*/ cmess1 << " - Step 3 - Init tiles vector " << flush;
initTiles();
// Step 4 - Run Sweep Line
// ***********************
/*DEBUG*/ cmess1 << _tilesByXmin->size() <<" Tiles and SweepLine " << _cWindows << " sur " << _nbWindows << endl;
sweepLine->run(
_tilesByXmin,
_tilesByXmax,
_cWindows < _nbWindows-1,
((_cell->getBoundingBox().getXMin ()+(_cWindows+1)*_cell->getBoundingBox().getWidth()/_nbWindows)) );
} // end for
// Step 5 - Post Sweep Line
// ***********************
/*DEBUG*/ cmess1 << " - Step 4 - PostSweepLine" << endl;
postSweepLine();
// Step 6 - Clean SweepLine
// *************************
sweepLine->destroy();
}
void EquinoxEngine::getOccurrencesOfEquis()
// *******************************************
{
unsigned long count = 0;
forEach (Equi*,equi,getCollection(_equis))
{
// Factoriser occurrences of equi
(*equi)->factorizeComponents();
forEach(Occurrence,occurrence,((*equi)->getOccurrences()))
_occurrences[(*occurrence)] = *equi;
(*equi)->setNumber(++count);
}
}
void EquinoxEngine::cleanUpLeafCell()
// *************************************
{
///*DEBUG*/ cmess1 << " - cleanUpLeafCell() " << endl;
set<Net*> set_nets;
Net * externalnet = NULL;
unsigned long count = 1;
Occurrence o;
forEach(Equi*,equi,getCollection(_equis))
{
externalnet = NULL;
forEach( Occurrence,occurrence, (*equi)->getComponentOccurrences())
{
Net * net = dynamic_cast<Component*>((*occurrence).getEntity())->getNet();
// check for 2 externals nets on the same Equi
if(net->isExternal()) {
if(externalnet && (externalnet != net) )
throw Error("There is two external net in leaf cell : Library Error " + getString(externalnet)
+ " " + getString(net) + " with component "
+ getString((*occurrence)) + " " + getString(o));
if(!externalnet) {
o = (*occurrence);
externalnet = net;
}
}
set_nets.insert(net);
}
// If there is no externalNet, choice the first
if(!externalnet) externalnet = (*set_nets.begin());
forEach(Net*,net, getCollection(set_nets))
{
if( (*net)!= externalnet) {
externalnet->merge(*net);
}
}
_occurrences[Occurrence(externalnet)] = *equi; // Add <Occurrence, Equi*> to map<Occurrence, Equi*> _occurrences.
(*equi)->erase(); // Clean all component occurrences
(*equi)->addOccurrence(Occurrence(externalnet));// Add net occurrence
set_nets.clear();
(*equi)->setNumber(count++);
}
}
EquinoxEngine::EquinoxEngine ( Cell* cell )
: ToolEngine (cell)
, _cWindows(0)
, _nbWindows(0)
, _isExtracted(false)
, _tilesByXmin()
, _tilesByXmax()
{ }
void EquinoxEngine::flushEquis (Cell*cell) {
if(!_isExtracted) // If the top cell hasn't been extracted.
return ;
InstanceLocator instancelocator = cell->getInstances().getLocator();
if(instancelocator.isValid()){ // If the cell isn't a leaf cell.
EquinoxEngine * equinox = NULL;
Cell * mastercell = NULL;
while(instancelocator.isValid()) {
mastercell = instancelocator.getElement()->getMasterCell();
equinox = get(mastercell);
if(equinox && (equinox->isExtracted())) // If the sous-cell has been extracted.
flushEquis(mastercell);
instancelocator.progress();
}
}
EquinoxEngine * equinox = get(cell);
equinox->removeEquis();
equinox->setIsExtracted(false);
}
EquinoxEngine::~EquinoxEngine ()
{
}
void EquinoxEngine::_postCreate ()
{
ToolEngine::_postCreate ();
_tilesByXmin = new TileVector();
_tilesByXmax = new TileVector();
}
void EquinoxEngine::_preDestroy ()
{
ToolEngine::_preDestroy ();
removeEquis();
}
void EquinoxEngine::_destroy ()
{
_preDestroy();
_depthDestroy();
delete this;
}
void EquinoxEngine::_depthDestroy()
// **************************
{
GenericLocator<Instance*> locator = _cell->getInstances().getLocator();
EquinoxEngine * equinox = NULL;
if( !(locator.isValid()) ) {
this->destroy();
}
else {
while(locator.isValid()) {
Cell * cell = locator.getElement()->getMasterCell();
equinox = get(cell);
if(equinox)
equinox->_depthDestroy();
locator.progress();
}
this->destroy();
}
}
void EquinoxEngine::printEquis()
{
cmess1 << "Nombre d'equis"<< _equis.size() <<endl;
/*DEBUG*/// <<endl;
/*DEBUG*/// forEach(Equi*,equi,getCollection(_equis)) {
/*DEBUG*/// cmess1 << " o Equi : " << (*equi)->_getString() << endl;
/*DEBUG*/// forEach(Occurrence,occurrence,((*equi)->getOccurrences()))
/*DEBUG*/// {
/*DEBUG*///
/*DEBUG*/// //NET Occurrence
/*DEBUG*/// if (dynamic_cast<Net*>((*occurrence).getEntity()))
/*DEBUG*/// {
/*DEBUG*/// cmess1 << " - [NET]" << (*occurrence).getEntity() << " \t===>\t " << getHyperNetRootNetOccurrence((*occurrence).getEntity())._getString() << endl;
/*DEBUG*/// }
/*DEBUG*///
/*DEBUG*/// //COMPONENT Occurrence
/*DEBUG*/// if (dynamic_cast<Component*>((*occurrence).getEntity())) {
/*DEBUG*/// Component* composant = dynamic_cast<Component*>((*occurrence).getEntity());
/*DEBUG*/// cmess1 << " - [COM]" << composant << " \t===>\t " << getHyperNetRootNetOccurrence(composant->getNet())._getString() << endl;
/*DEBUG*/// }
/*DEBUG*///
/*DEBUG*/// //EQUI Occurrence
/*DEBUG*/// if (dynamic_cast<Equi*>((*occurrence).getEntity())) {
/*DEBUG*/// Equi* equi = dynamic_cast<Equi*>((*occurrence).getEntity());
/*DEBUG*/// cmess1 << " - [EQU]" << equi << endl;
/*DEBUG*/// }
/*DEBUG*/// }
/*DEBUG*/// }
}
void EquinoxEngine::removeInterval(Tile* item)
{
// on diminue le compteur de reference de l'Equi
item->getEqui()->decrementCount();
// on detruit le tile
item->destroy();
}
void EquinoxEngine::insertInterval(Tile* newtile,stack <Interval*>*enumResultStack)
{
//Application des contacts
Equi * newroot = NULL;
if( !(enumResultStack->empty()) ) { // contact > 0
if( newtile->getEqui() ) enumResultStack->push(newtile);
newroot = UnionFind::getRootEquiWithCompression(dynamic_cast<Tile*>(enumResultStack->top()) );
enumResultStack->pop();
while (!enumResultStack->empty()) {//while contact > 0
Equi * root = UnionFind::getRootEquiWithCompression(dynamic_cast<Tile*>(enumResultStack->top()) );
enumResultStack->pop();
if( root != newroot ) {
root->setNextEqui(newroot);
newroot->merge(root);
newroot->incrementCount();
}
}
if(newtile->getEqui() == NULL){
newtile->setEqui(newroot);
newroot->incrementCount();
newroot->addOccurrence(newtile->getOccurrence());
}
}
else { // contact == 0
if( newtile->getEqui() == NULL) {
newroot = Equi::create(this);
newroot->incrementCount();
newtile->setEqui(newroot);
newroot->addOccurrence(newtile->getOccurrence());
}
}
}
}// End of namespace Equinox

View File

@ -0,0 +1,240 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | =============================================================== |
// | C++ Header : "./EquinoxFilters.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "hurricane/Components.h"
#include "hurricane/Component.h"
#include "hurricane/Filter.h"
#include "hurricane/Collection.h"
#include "hurricane/Occurrence.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Net.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Cell.h"
#include "equinox/EquinoxFilters.h"
#include "equinox/Equi.h"
#include "equinox/Strategy.h"
namespace Equinox {
using Hurricane::GenericCollection;
using Hurricane::GenericLocator;
using Hurricane::GenericFilter;
using Hurricane::Filter;
using Hurricane::Occurrence;
using Hurricane::Component;
using Hurricane::Net;
using namespace Hurricane;
// -------------------------------------------------------------------
// Class : "Equinox::IsRoutingEquiFilter".
/**/ IsRoutingFilter::IsRoutingFilter () {};
/**/ IsRoutingFilter::IsRoutingFilter (const IsRoutingFilter&) {};
IsRoutingFilter& IsRoutingFilter::operator= (const IsRoutingFilter&) {return *this; };
Filter<Equi*>* IsRoutingFilter::getClone () const {return new IsRoutingFilter(*this); };
string IsRoutingFilter::_getString () const {return "<IsRoutingFilter>"; };
bool IsRoutingFilter::accept (Equi* item) const
{
if(item->isLeafEqui()) {
if( item->getCell()->isLeaf() ) {
OccurrenceLocator locator = item->getNetOccurrences().getLocator();
Net * net = dynamic_cast<Net*>(locator.getElement().getEntity());
if(!(net->isExternal()))
return false;
}
}
else
{
if( !(item->hasNetOccurrence() || item->hasComponentOccurrence()) )
if( item->getEquiOccurrences().getSize() == 1 ) {
OccurrenceLocator locator = item->getEquiOccurrences().getLocator();
Equi * subequi = dynamic_cast<Equi*>(locator.getElement().getEntity());
return accept(subequi);
}
}
return true;
};
// -------------------------------------------------------------------
// Class : "Equinox::IsUsedByExtractFilter".
/**/ IsUsedByExtractFilter::IsUsedByExtractFilter () {};
/**/ IsUsedByExtractFilter::IsUsedByExtractFilter (const IsUsedByExtractFilter&) {};
IsUsedByExtractFilter& IsUsedByExtractFilter::operator= (const IsUsedByExtractFilter&) {return *this; };
Filter<Component*>* IsUsedByExtractFilter::getClone () const {return new IsUsedByExtractFilter(*this); };
string IsUsedByExtractFilter::_getString () const {return "<IsUsedByExtractFilter>"; };
bool IsUsedByExtractFilter::accept (Component* item) const
{
Box box = item->getBoundingBox();
if( (box.getYMin() == box.getYMax()) || (box.getXMin() == box.getXMax()) )
return false;
forEach ( BasicLayer*, i, item->getLayer()->getBasicLayers() )
{
if ( Strategy::isExtractableLayer(*i)) return true;
}
return false;
};
/**/ IsEquiFilter::IsEquiFilter () {};
/**/ IsEquiFilter::IsEquiFilter (const IsEquiFilter&) {};
IsEquiFilter& IsEquiFilter::operator= (const IsEquiFilter&) {return *this; };
Filter<Occurrence>* IsEquiFilter::getClone () const {return new IsEquiFilter(*this); };
string IsEquiFilter::_getString () const {return "<IsEquiFilter>"; };
bool IsEquiFilter::accept (Occurrence item) const
{
return (dynamic_cast<Equi*>(item.getEntity())!=NULL);
}
/**/ IsComponentFilter::IsComponentFilter () {};
/**/ IsComponentFilter::IsComponentFilter (const IsComponentFilter&) {};
IsComponentFilter& IsComponentFilter::operator= (const IsComponentFilter&) {return *this; };
Filter<Occurrence>* IsComponentFilter::getClone () const {return new IsComponentFilter(*this); };
string IsComponentFilter::_getString () const {return "<IsComponentFilter>"; };
bool IsComponentFilter::accept (Occurrence item) const {
return (dynamic_cast<Component*>(item.getEntity())!=NULL);
}
/**/ IsNetFilter::IsNetFilter () {};
/**/ IsNetFilter::IsNetFilter (const IsNetFilter&) {};
IsNetFilter& IsNetFilter::operator= (const IsNetFilter&) {return *this; };
Filter<Occurrence>* IsNetFilter::getClone () const {return new IsNetFilter(*this); };
string IsNetFilter::_getString () const {return "<IsNetFilter>"; };
bool IsNetFilter::accept (Occurrence item) const
{
return (dynamic_cast<Net*>(item.getEntity())!= NULL);
}
/**/ IsNetOrComponentFilter::IsNetOrComponentFilter () {};
/**/ IsNetOrComponentFilter::IsNetOrComponentFilter (const IsNetOrComponentFilter&) {};
IsNetOrComponentFilter& IsNetOrComponentFilter::operator= (const IsNetOrComponentFilter&) {return *this; };
Filter<Occurrence>* IsNetOrComponentFilter::getClone () const {return new IsNetOrComponentFilter(*this); };
string IsNetOrComponentFilter::_getString () const {return "<IsNetOrComponentFilter>"; };
bool IsNetOrComponentFilter::accept (Occurrence item) const
{
if( dynamic_cast<Net*>(item.getEntity()) )
return true;
if( dynamic_cast<Component*>(item.getEntity()) )
return true;
return false;
}
/**/ IsLeafEquiFilter::IsLeafEquiFilter () {};
/**/ IsLeafEquiFilter::IsLeafEquiFilter (const IsLeafEquiFilter&) {};
IsLeafEquiFilter& IsLeafEquiFilter::operator= (const IsLeafEquiFilter&) {return *this; };
Filter<Occurrence>* IsLeafEquiFilter::getClone () const {return new IsLeafEquiFilter(*this); };
string IsLeafEquiFilter::_getString () const {return "<IsLeafEquiFilter>"; };
bool IsLeafEquiFilter::accept (Occurrence item) const {assert(false); return false;}
/**/ IsNotLeafEquiFilter::IsNotLeafEquiFilter () {};
/**/ IsNotLeafEquiFilter::IsNotLeafEquiFilter (const IsNotLeafEquiFilter&) {};
IsNotLeafEquiFilter& IsNotLeafEquiFilter::operator= (const IsNotLeafEquiFilter&) {return *this; };
Filter<Occurrence>* IsNotLeafEquiFilter::getClone () const {return new IsNotLeafEquiFilter(*this); };
string IsNotLeafEquiFilter::_getString () const {return "<IsNotLeafEquiFilter>"; };
bool IsNotLeafEquiFilter::accept (Occurrence item) const {assert(false); return false;}
// -------------------------------------------------------------------
// Class : "Equinox::NetIsUsedByExtractorNetFilter".
/**/ NetIsUsedByExtractorFilter::NetIsUsedByExtractorFilter () {};
/**/ NetIsUsedByExtractorFilter::NetIsUsedByExtractorFilter (const NetIsUsedByExtractorFilter&) {};
NetIsUsedByExtractorFilter& NetIsUsedByExtractorFilter::operator= (const NetIsUsedByExtractorFilter&) {return *this; };
Filter<Component*>* NetIsUsedByExtractorFilter::getClone () const {return new NetIsUsedByExtractorFilter(*this); };
string NetIsUsedByExtractorFilter::_getString () const {return "<NetIsUsedByExtractorFilter>"; };
bool NetIsUsedByExtractorFilter::accept (Component* item) const {
Box box = item->getBoundingBox();
if( (box.getYMin() == box.getYMax()) || (box.getXMin() == box.getXMax()) )
return false;
forEach ( BasicLayer*, i, item->getLayer()->getBasicLayers() )
{
if (WithAlimStrategy::isExtractableLayer(*i)) return true;
}
return false;
}
}// End of namespace Equinox

View File

@ -0,0 +1,228 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./GraphicEquinoxEngine.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <hurricane/Warning.h>
#include <hurricane/Go.h>
#include <hurricane/Error.h>
#include <hurricane/Cell.h>
#include <hurricane/viewer/Graphics.h>
#include <hurricane/viewer/CellWidget.h>
#include <hurricane/viewer/CellViewer.h>
#include <hurricane/DataBase.h>
#include <hurricane/Technology.h>
#include <crlcore/AllianceFramework.h>
#include <crlcore/GraphicToolEngine.h>
#include <crlcore/ToolEngine.h>
#include <equinox/Tiles.h>
#include <equinox/Tile.h>
#include <equinox/EquinoxEngine.h>
#include <equinox/Strategy.h>
#include <equinox/TileSweepLine.h>
#include <equinox/GraphicEquinoxEngine.h>
namespace Equinox {
using namespace std;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Graphics;
using CRL::AllianceFramework;
// -------------------------------------------------------------------
// Class : "Equinox::GraphicEquinoxEngine".
size_t GraphicEquinoxEngine::_references = 0;
GraphicEquinoxEngine* GraphicEquinoxEngine::_singleton = NULL;
EquinoxEngine* GraphicEquinoxEngine::createEngine ( )
{
Cell* cell = getCell ();
EquinoxEngine* equinox = EquinoxEngine::get ( cell );
if ( !equinox ) {
equinox = EquinoxEngine::create ( cell );
}
return equinox;
}
GraphicEquinoxEngine* GraphicEquinoxEngine::grab ()
{
if ( !_references )
_singleton = new GraphicEquinoxEngine ();
_references++;
return _singleton;
}
const Name& GraphicEquinoxEngine::getName () const
{ return EquinoxEngine::staticGetName (); }
Cell* GraphicEquinoxEngine::getCell ()
{
if ( !_viewer ) {
throw Error ( "<b>Equinox:</b> GraphicEquinoxEngine not bound to any Viewer." );
return NULL;
}
if ( !_viewer->getCell() ) {
throw Error ( "<b>Equinox:</b> No Cell is loaded into the Viewer." );
return NULL;
}
return _viewer->getCell();
}
size_t GraphicEquinoxEngine::release ()
{
_references--;
if ( !_references ) {
delete _singleton;
_singleton = NULL;
}
return _references;
}
void GraphicEquinoxEngine::addToMenu ( CellViewer* viewer )
{
assert ( _viewer == NULL );
_viewer = viewer;
QMenu* prMenu = _viewer->findChild<QMenu*>("viewer.menuBar.extract");
if ( !prMenu ) {
QMenuBar* menuBar = _viewer->findChild<QMenuBar*>("viewer.menuBar");
if ( !menuBar ) {
cerr << Warning("GraphicEquinoxEngine::addToMenu() - No MenuBar in parent widget.") << endl;
return;
}
prMenu = menuBar->addMenu ( tr("Extract") );
prMenu->setObjectName ( "viewer.menuBar.extract" );
prMenu->addSeparator ();
}
QAction* gRunWAAction = _viewer->findChild<QAction*>("viewer.menuBar.extract.equinox.withalim");
if ( gRunWAAction )
cerr << Warning("GraphicEquinoxEngine::addToMenu() - Equinox withalim already hooked in.") << endl;
else {
gRunWAAction = new QAction ( tr("Equinox - With alim"), _viewer );
gRunWAAction->setObjectName ( "viewer.menuBar.extract.equinox.withalim" );
gRunWAAction->setStatusTip ( tr("Run the <b>Equinox</b> withAlim Stategy") );
gRunWAAction->setVisible ( true );
prMenu->addAction ( gRunWAAction );
connect ( gRunWAAction, SIGNAL(triggered()), this, SLOT(runWithAlim()) );
}
QAction* gRunWoAAction = _viewer->findChild<QAction*>("viewer.menuBar.extract.equinox.withoutalim");
if ( gRunWoAAction )
cerr << Warning("GraphicEquinoxEngine::addToMenu() - Equinox withoutalim already hooked in.") << endl;
else {
gRunWoAAction = new QAction ( tr("Equinox - Without alim"), _viewer );
gRunWoAAction->setObjectName ( "viewer.menuBar.extract.equinox.withoutalim" );
gRunWoAAction->setStatusTip ( tr("Run the <b>Equinox</b> withoutAlim Stategy") );
gRunWoAAction->setVisible ( true );
prMenu->addAction ( gRunWoAAction );
connect ( gRunWoAAction, SIGNAL(triggered()), this, SLOT(runWithoutAlim()) );
}
// fin du sous menu
connect ( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) );
connect ( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) );
}
void GraphicEquinoxEngine::runWithAlim ()
{
EquinoxEngine* equinox = createEngine ( );
if ( !equinox ) return;
emit cellPreModificated ();
equinox->withAlimExtract(1);
emit cellPostModificated ();
}
void GraphicEquinoxEngine::runWithoutAlim ()
{
EquinoxEngine* equinox = createEngine ( );
if ( !equinox ) return;
emit cellPreModificated ();
equinox->withoutAlimExtract(1);
emit cellPostModificated ();
}
GraphicEquinoxEngine::GraphicEquinoxEngine ()
: GraphicTool ()
, _viewer (NULL)
{
}
GraphicEquinoxEngine::~GraphicEquinoxEngine()
{
}
} // End of Equinox namespace.

523
equinox/src/Strategy.cpp Normal file
View File

@ -0,0 +1,523 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./Strategy.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <vector>
#include <map>
#include <set>
#include "hurricane/Bug.h"
#include "hurricane/Net.h"
#include "hurricane/Name.h"
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Technology.h"
#include "hurricane/Collection.h"
#include "hurricane/Cell.h"
#include "hurricane/Box.h"
#include "hurricane/Locator.h"
#include "hurricane/Instance.h"
#include "hurricane/Occurrence.h"
#include "hurricane/Component.h"
#include "hurricane/DataBase.h"
#include "hurricane/DebugSession.h"
#include "crlcore/Utilities.h"
#include <crlcore/ToolEngine.h>
#include "equinox/Strategy.h"
#include "equinox/Equi.h"
#include "equinox/Tile.h"
#include "equinox/Tiles.h"
#include "equinox/EquinoxFilters.h"
#include "equinox/EquinoxEngine.h"
namespace {
}
namespace Equinox {
using namespace std;
using namespace Hurricane;
Strategy::Strategy() {}
bool const Strategy::isExtractableLayer(BasicLayer * basicLayer)
{
static Layer * _gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh");
static Layer * _gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv");
static Layer * _gcontact = DataBase::getDB()->getTechnology()->getLayer("gcontact");
if ( DataBase::getDB()->getTechnology()->isMetal(dynamic_cast<Layer *> ( basicLayer )) )
if (( ( (basicLayer) != _gmetalh ) && ( (basicLayer) != _gmetalv ) && ( (basicLayer) != _gcontact ) )) return true;
return false;
}
WithAlimStrategy::WithAlimStrategy() {}
WithAlimStrategy::~WithAlimStrategy() {}
void WithAlimStrategy::run(EquinoxEngine* equinox, unsigned nbwindows)
{
forEach(Instance*,instance, equinox->_cell->getInstances())
{
Cell * cell = instance->getMasterCell();
EquinoxEngine* subequinox = EquinoxEngine::get(cell);
if(!subequinox)
subequinox = EquinoxEngine::create(cell);
if( !(subequinox->isExtracted()) )
run(subequinox, nbwindows);
}
equinox->scan(nbwindows);
equinox->setIsExtracted(true);
}
void WithAlimStrategy::getTilesFor(EquinoxEngine* equinox)
{
// Init
//******
///*DEBUG*/ cmess1 << " o getTilesFor : " << endl ;
Box cellbox = equinox->_cell->getBoundingBox();
long cellwidth = cellbox.getWidth();
long ymax = cellbox.getYMax();
long ymin = cellbox.getYMin();
long xmin = cellbox.getXMin();
long xmax = cellbox.getXMax();
long interval = cellwidth/equinox->_nbWindows;
// Cas de la premiere fenetre
//****************************
if( equinox->_cWindows == 0 )
if ((equinox->_tilesByXmin->size()) + (equinox->_tilesByXmax->size()))
throw "Listes non vides avant constitution des Tiles";
// calcul de la UnderBox
//******************
long underbox_xmax = 0;
if( equinox->_cWindows == equinox->_nbWindows-1 )
underbox_xmax = xmax;
else
underbox_xmax = xmin + (equinox->_cWindows+1)*interval;
Box underbox(xmin+equinox->_cWindows*interval, ymin, underbox_xmax, ymax);
//Component Occurrence with a basiclayer on Metal at least
Occurrences componentoccurrences = equinox->_cell->getComponentOccurrencesUnder(underbox,
DataBase::getDB()->getTechnology()->_getMetalMask()).getSubSet((WithAlimStrategyFilter()));
Component * component = NULL;
Box box;
Tile * tile = NULL;
Equi * equi = NULL;
bool equicreated = false;
Occurrence o = NULL;
forEach(Occurrence,occurrence,componentoccurrences)
{
component = dynamic_cast<Component*>((*occurrence).getEntity());
box = (*occurrence).getBoundingBox();
tile = NULL;
equi = NULL;
equicreated = false;
// ignorer les occurrences inutiles
// *****************************
if( box.getXMin() < xmin || box.getXMin() >= xmax )
continue;
if((*occurrence)._getSharedPath()) {
o = (equinox->getUpperEquiOccurrence((*occurrence)));
if(!(o.isValid()))
throw Error("Can't use Equinox::GetTilesFor() : GetUpperEquiOccurrence Return Invalid Occurrence");
} else {
o = (*occurrence);
}
if (dynamic_cast<const BasicLayer*>(component->getLayer())) {
// BasicLayer
//************
tile = Tile::create((o), box, const_cast<BasicLayer*>(dynamic_cast<const BasicLayer*>(component->getLayer())), NULL);
equinox->_tilesByXmin->push_back(tile);
equinox->_tilesByXmax->push_back(tile);
} else {
// Not BasicLayer
//****************
forEach ( BasicLayer*, i, component->getLayer()->getBasicLayers() )
{
if (isExtractableLayer(*i))
{
if(!equicreated && tile){
equi = Equi::create(equinox);
tile->setEqui(equi);
equi->incrementCount();
equi->addOccurrence((o));
equicreated = true;
}
tile = Tile::create((o), box, (*i), equi);
equinox->_tilesByXmin->push_back(tile);
equinox->_tilesByXmax->push_back(tile);
if(equi)
equi->incrementCount();
}
}
}
}
// Sort these two vectors
// ***********************
sort<vector<Tile*>::iterator, CompByXmin<Tile*> >( equinox->_tilesByXmin->begin(), equinox->_tilesByXmin->end(), CompByXmin<Tile*>() );
sort<vector<Tile*>::iterator, CompByXmax<Tile*> >( equinox->_tilesByXmax->begin(), equinox->_tilesByXmax->end(), CompByXmax<Tile*>() );
}
void WithAlimStrategy::operationAfterScanLine(EquinoxEngine* equinox)
{
Cell * cell = equinox->_cell;
if( cell->isLeaf()) // If this is a leaf cell
equinox->cleanUpLeafCell();
else
equinox->getOccurrencesOfEquis();
}
WithoutAlimStrategy::WithoutAlimStrategy() {}
WithoutAlimStrategy::~WithoutAlimStrategy() {}
void WithoutAlimStrategy::run(EquinoxEngine* equinox, unsigned nbwindows)
{
forEach(Instance*,instance, equinox->_cell->getInstances())
{
Cell * cell = instance->getMasterCell();
EquinoxEngine* subequinox = EquinoxEngine::get(cell);
if(!subequinox)
subequinox = EquinoxEngine::create(cell);
if( !(subequinox->isExtracted()) )
run(subequinox, nbwindows);
}
equinox->scan(nbwindows);
equinox->setIsExtracted(true);
}
void WithoutAlimStrategy::getTilesFor(EquinoxEngine* equinox)
{
// Init
//******
///*DEBUG*/ cmess1 << " o getTilesFor : " << endl ;
Box cellbox = equinox->_cell->getBoundingBox();
long cellwidth = cellbox.getWidth();
long ymax = cellbox.getYMax();
long ymin = cellbox.getYMin();
long xmin = cellbox.getXMin();
long xmax = cellbox.getXMax();
long interval = cellwidth/equinox->_nbWindows;
// Cas de la premiere fenetre
//****************************
if( equinox->_cWindows == 0 )
{
///*DEBUG*/ cmess1 << " - vidage de tilesByXmin (" << equinox->_tilesByXmin->size() << ") et tilesByXmax (" << equinox->_tilesByXmax->size() << ")" << endl;
equinox->_tilesByXmin->clear();
equinox->_tilesByXmax->clear();
}
// calcul de la box
//******************
long underbox_xmax = 0;
if( equinox->_cWindows==equinox->_nbWindows-1 )
underbox_xmax = xmax;
else
underbox_xmax = xmin + (equinox->_cWindows+1)*interval;
Box underbox(xmin+equinox->_cWindows*interval, ymin, underbox_xmax, ymax);
///*DEBUG*/ cmess1 << " - underbox = "<< underbox << endl ;
Occurrences componentoccurrences ;
if(equinox->_cell->isLeaf())
componentoccurrences = equinox->_cell->getComponentOccurrencesUnder(underbox,
DataBase::getDB()->getTechnology()->_getMetalMask()).getSubSet((WithAlimStrategyFilter()));
else
componentoccurrences = equinox->_cell->getComponentOccurrencesUnder(underbox,
DataBase::getDB()->getTechnology()->_getMetalMask()).getSubSet((WithoutAlimStrategyFilter()));
Component * component = NULL;
Box box;
Tile * tile = NULL;
Equi * equi = NULL;
bool equicreated = false;
Occurrence o = NULL;
forEach(Occurrence,occurrence,componentoccurrences)
{
component = dynamic_cast<Component*>((*occurrence).getEntity());
box = (*occurrence).getBoundingBox();
tile = NULL;
equi = NULL;
equicreated = false;
// ignorer les occurrences inutiles
// *****************************
if( box.getXMin() < xmin || box.getXMin() >= xmax )
continue;
if((*occurrence)._getSharedPath()){
o = (equinox->getUpperEquiOccurrence((*occurrence)));
if(!(o.isValid()))
throw Error("Can't use Equinox::GetTilesFor() : GetUpperEquiOccurrence Return Invalid Occurrence");
} else {
o = (*occurrence);
}
//o = (*occurrence);
if (dynamic_cast<const BasicLayer*>(component->getLayer())) {
// BasicLayer
//************
tile = Tile::create((o), box, const_cast<BasicLayer*>(dynamic_cast<const BasicLayer*>(component->getLayer())), NULL);
equinox->_tilesByXmin->push_back(tile);
equinox->_tilesByXmax->push_back(tile);
/////*DEBUG*/ bt++;
} else {
// Not BasicLayer
//****************
forEach ( BasicLayer*, i, component->getLayer()->getBasicLayers() )
{
if ( isExtractableLayer(*i))
{
if(!equicreated && tile){
equi = Equi::create(equinox);
tile->setEqui(equi);
equi->incrementCount();
equi->addOccurrence((o));
equicreated = true;
}
tile = Tile::create((o), box, (*i), equi);
equinox->_tilesByXmin->push_back(tile);
equinox->_tilesByXmax->push_back(tile);
if(equi)
equi->incrementCount();
}
}
}
}
// Sort these two vectors
// ***********************
sort<vector<Tile*>::iterator, CompByXmin<Tile*> >( equinox->_tilesByXmin->begin(), equinox->_tilesByXmin->end(), CompByXmin<Tile*>() );
sort<vector<Tile*>::iterator, CompByXmax<Tile*> >( equinox->_tilesByXmax->begin(), equinox->_tilesByXmax->end(), CompByXmax<Tile*>() );
}
void WithoutAlimStrategy::operationAfterScanLine(EquinoxEngine* equinox)
{
Cell * cell = equinox->_cell;
if( cell->isLeaf()) // If this is a leaf cell
equinox->cleanUpLeafCell();
else
equinox->getOccurrencesOfEquis();
}
// -------------------------------------------------------------------
// Class : "Equinox::WithAlimStrategyFilter".
/**/ WithAlimStrategyFilter::WithAlimStrategyFilter () {};
/**/ WithAlimStrategyFilter::WithAlimStrategyFilter (const WithAlimStrategyFilter&) {};
WithAlimStrategyFilter& WithAlimStrategyFilter::operator= (const WithAlimStrategyFilter&) {return *this; };
Filter<Occurrence>* WithAlimStrategyFilter::getClone () const {return new WithAlimStrategyFilter(*this); };
string WithAlimStrategyFilter::_getString () const {return "<WithAlimStrategyFilter>"; };
bool WithAlimStrategyFilter::accept (Occurrence item) const
{
Component* component = dynamic_cast<Component*>(item.getEntity());
Box box = component->getBoundingBox();
// If box is not valid , this component occurrence is unuseful.
// ************************************************************
if( (box.getYMin() == box.getYMax()) || (box.getXMin() == box.getXMax()) )
return false;
forEach ( BasicLayer*, i, component->getLayer()->getBasicLayers() )
{
if (WithAlimStrategy::isExtractableLayer(*i)) return true;
}
return false;
};
// -------------------------------------------------------------------
// Class : "Equinox::WithoutAlimStrategyFilter".
/**/ WithoutAlimStrategyFilter::WithoutAlimStrategyFilter () {};
/**/ WithoutAlimStrategyFilter::WithoutAlimStrategyFilter (const WithoutAlimStrategyFilter&) {};
WithoutAlimStrategyFilter& WithoutAlimStrategyFilter::operator= (const WithoutAlimStrategyFilter&) {return *this; };
Filter<Occurrence>* WithoutAlimStrategyFilter::getClone () const {return new WithoutAlimStrategyFilter(*this); };
string WithoutAlimStrategyFilter::_getString () const {return "<WithoutAlimStrategyFilter>"; };
bool WithoutAlimStrategyFilter::accept (Occurrence item) const
{
Component* component = dynamic_cast<Component*>(item.getEntity());
Box box = component->getBoundingBox();
Net * net = component->getNet();
if(net->isGlobal() || net->isGround() || net->isPower()) {
return false;
}
// If box is not valid , this component occurrence is unuseful.
// ************************************************************
if( (box.getYMin() == box.getYMax()) || (box.getXMin() == box.getXMax()) )
return false;
forEach ( BasicLayer*, i, component->getLayer()->getBasicLayers() )
{
if (Strategy::isExtractableLayer(*i)) return true;
}
return false;
};
}// End of namespace Equinox

90
equinox/src/Tile.cpp Normal file
View File

@ -0,0 +1,90 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./Tile.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "hurricane/Error.h"
#include "hurricane/Occurrence.h"
#include "crlcore/Utilities.h"
#include "equinox/Tile.h"
#include "equinox/Equi.h"
namespace Equinox {
using Hurricane::Error;
// -------------------------------------------------------------------
// Class : "EQUINOX::Tile".
Tile::Tile (const Occurrence occurrence, const Box box, BasicLayer* basicLayer, Equi * equi)
: _occurrence(occurrence)
, _box(box)
, _basicLayer(basicLayer)
, _equi(equi)
{
}
Tile* Tile::create(const Occurrence occurrence, Box box,BasicLayer* basiclayer, Equi * equi)
{
Tile* tile = new Tile(occurrence, box, basiclayer, equi);
if(!tile){
throw Error("can't create Tile : allocation failed");
}
tile->_postCreate();
return tile;
}
string Tile::_getString() const
{
string s;
if (!_equi)
{
s = "<" + _getTypeName() + " " + getString(_occurrence) + " <NULL equi> >";
} else {
s = "<" + _getTypeName() + " " + getString(_occurrence) + " " + _equi->_getString() + ">";
}
return s;
}
}// End of namespace Equinox

View File

@ -0,0 +1,47 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./TileSweepLine.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <hurricane/ExtensionGo.h>
#include <hurricane/DataBase.h>
#include <hurricane/Technology.h>
#include <crlcore/Utilities.h>
#include <crlcore/ToolEngine.h>
#include <equinox/Strategy.h>
#include <equinox/IntervalTree.h>
#include <equinox/Tile.h>
#include <equinox/Tiles.h>
#include <equinox/SweepLine.h>
#include <equinox/EquinoxEngine.h>
#include <equinox/TileSweepLine.h>
namespace Equinox {
template class SweepLine<Tile*,EquinoxEngine*>;
}

91
equinox/src/UnionFind.cpp Normal file
View File

@ -0,0 +1,91 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./UnionFind.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "hurricane/Occurrence.h"
#include "crlcore/Utilities.h"
#include "equinox/UnionFind.h"
#include "equinox/Tile.h"
#include "equinox/Equi.h"
namespace Equinox {
// -------------------------------------------------------------------
// Class : "EQUINOX::UnionFind".
inline Equi * UnionFind::getRootEqui(Tile* tile)
{
assert(tile->getEqui()!=NULL);
Equi * equi = tile->getEqui();
while( equi->getNextEqui())
equi = equi->getNextEqui();
return equi;
};
Equi * UnionFind::findValidEqui(Equi* equi)
{
if( (equi->getCount()>1) || (equi == NULL) )
return equi;
else
return findValidEqui(equi->getNextEqui());
};
Equi * UnionFind::getRootEquiWithCompression(Tile* tile)
{
Equi * root = getRootEqui(tile);
Equi * x = tile->getEqui();
Equi * y = NULL;
while(x!= root) {
y = x->getNextEqui();
if( y == root )
break;
x->setNextEqui(root);
root->incrementCount();
if(y->getCount() == 1) {
Equi * tmpptr = findValidEqui(y);
assert (tmpptr!=NULL);
y->decrementCount();
y = tmpptr;
}
else
y->decrementCount();
x = y;
}
return root;
};
}// End of namespace Equinox

165
equinox/src/equinox/Equi.h Normal file
View File

@ -0,0 +1,165 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/Equi.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_EQUI__
#define __EQUINOX_EQUI__
#include "hurricane/Entity.h"
#include "hurricane/Occurrence.h"
#include "hurricane/Occurrences.h"
namespace Hurricane {
class Box;
class Cell;
class Net;
class Entity;
class Occurence;
class Component;
}
namespace Equinox {
using std::set;
using std::string;
using std::map;
using namespace Hurricane;
class EquinoxEngine;
class Equi : public Entity {
//Statics
public:
static Equi* create (EquinoxEngine* equinox,
Equi* nextequi = NULL,
const unsigned long& number = 0
);
//Some filters
static GenericFilter<Occurrence> getIsEquiFilter ();
static GenericFilter<Occurrence> getIsComponentFilter ();
static GenericFilter<Occurrence> getIsNetFilter ();
static GenericFilter<Occurrence> getIsLeafEquiFilter ();
static GenericFilter<Occurrence> getIsNotLeafEquiFilter ();
// static GenericFilter<Component*> getIsUsedByExtractFilter ();
static GenericFilter<Occurrence> getIsNetOrComponentFilter ();
//Entity
public :
virtual Cell* getCell () const;
inline virtual Box getBoundingBox () const;
//Functions
public:
/**/ bool isLeafEqui () const;
/**/ bool hasComponentOccurrence () const;
/**/ bool hasNetOccurrence () const;
/**/ Occurrences getEquiOccurrences () const;
/**/ Occurrences getNetOccurrences () const;
/**/ Occurrences getAllOccurrences () const;
/**/ Occurrences getNetAndComponentOccurrences () const;
/**/ Occurrences getEquiComponentOccurrences () const;
/**/ Occurrences getCurrentComponentOccurrences () const;
/**/ Occurrences getComponentOccurrences () const;
inline void setNextEqui (Equi* nextequi);
inline Equi * getNextEqui () const;
inline void setNumber (const unsigned long& number);
inline void incrementCount ();
inline void decrementCount ();
inline const unsigned long & getCount () const;
inline Occurrences getOccurrences () const;
inline void addOccurrence (const Occurrence& occurrence);
inline void erase ();
/**/ void factorizeComponents ();
inline void merge (Equi* equi);
virtual string _getString () const;
protected:
virtual void _postCreate ();
virtual void _preDestroy ();
//Attributes
protected :
static map<Net*, unsigned long> _map_net2nb_usefulcomponent;
private:
/**/ EquinoxEngine * _equinox ;
/**/ set<Occurrence> _occurrences ;
/**/ Equi * _nextequi ;
/**/ unsigned long _count ;
/**/ unsigned long _number ;
// Constructors & Destructors.
private:
/**/ Equi (EquinoxEngine * equinox,
Equi* nextequi = NULL,
const unsigned long& number = 0
);
inline virtual ~Equi ();
/**/ Equi (const Equi&);
/**/ Equi& operator= (const Equi&);
}; // End of class Equi
// Inline Functions.
inline Occurrences Equi::getOccurrences () const { return getCollection(_occurrences);};
inline Equi * Equi::getNextEqui () const { return _nextequi; };
inline const unsigned long & Equi::getCount () const { return _count; };
inline void Equi::setNextEqui (Equi* nextequi) { _nextequi = nextequi; } ;
inline void Equi::setNumber (const unsigned long& number) { _number = number; };
inline void Equi::incrementCount () { _count++ ; } ;
inline void Equi::decrementCount () { _count--; if( ( _count == 0 ) && ( _occurrences.empty() ) ) this->destroy(); };
inline void Equi::addOccurrence (const Occurrence& occurrence) { _occurrences.insert(occurrence);};
inline void Equi::erase () { _occurrences.clear();};
inline Box Equi::getBoundingBox () const { return Box();}
inline Equi::~Equi () {}
inline void Equi::merge (Equi* equi)
{
forEach(Occurrence,occurrence,equi->getOccurrences())
_occurrences.insert((*occurrence));
equi->erase();
};
} // End of Equinox namespace.
#endif // __EQUINOX_EQUI__

View File

@ -0,0 +1,269 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/EquinoxCollections.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
/********************************************************************
* This file contains : *
* - AllOccurrencesCollection *
* Return nets and components of Equi and all subEquis *
* *
* - EquiComponentOccurrencesCollection *
* Return all components Occurrences of hyperNets *
* of this Equi and all subEquis. *
* *
* - CurrentComponentOccurrencesCollection *
* Return all components Occurrences of hyperNets *
* of this Equi. *
********************************************************************/
#ifndef __EQUINOX_EQUINOX_COLLECTIONS__
#define __EQUINOX_EQUINOX_COLLECTIONS__
namespace Equinox {
class Equi;
using namespace Hurricane;
class AllOccurrencesCollection : public Collection<Occurrence> {
public : typedef Collection<Occurrence> Inherit;
public : class Locator : public Hurricane::Locator<Occurrence> {
// *************************************************************
public : typedef Hurricane::Locator<Occurrence> Inherit ;
private : const Equi* _equi;
private : int _state; // state = 0 locator is invalid
private : OccurrenceLocator _componentLocator;
private : OccurrenceLocator _equioccurrenceLocator;
private : OccurrenceLocator _occurrenceLocator;
public : Locator();
public : Locator(const Equi* equi);
public : Locator(const Locator& locator);
public : Locator& operator=(const Locator& locator);
public : virtual Occurrence getElement() const;
public : virtual Hurricane::Locator<Occurrence>* getClone() const;
public : virtual bool isValid() const;
public : virtual void progress();
public : virtual string _getString() const;
};
// Attributs
// *********
private : const Equi* _equi;
// Constructors
// ************
public : AllOccurrencesCollection();
public : AllOccurrencesCollection(const Equi* equi);
public : AllOccurrencesCollection(const AllOccurrencesCollection&);
// Operators
// *********
public : AllOccurrencesCollection& operator=(const AllOccurrencesCollection&);
// Accessors
// *********
public : virtual Collection<Occurrence>* getClone() const;
public : virtual Hurricane::Locator<Occurrence>* getLocator() const;
// Others
// ******
public : virtual string _getString() const ;
}; // end of class AllOccurrencesCollection
class EquiComponentOccurrencesCollection : public Collection<Occurrence> {
public : typedef Collection<Occurrence> Inherit;
public : class Locator : public Hurricane::Locator<Occurrence> {
// *************************************************************
public : typedef Hurricane::Locator<Occurrence> Inherit ;
private : const Equi* _equi;
private : int _state; // state = 0 locator is invalid
private : OccurrenceLocator _componentLocator;
private : OccurrenceLocator _equioccurrenceLocator;
private : OccurrenceLocator _occurrenceLocator;
public : Locator();
public : Locator(const Equi* equi);
public : Locator(const Locator& locator);
public : Locator& operator=(const Locator& locator);
public : virtual Occurrence getElement() const;
public : virtual Hurricane::Locator<Occurrence>* getClone() const;
public : virtual bool isValid() const;
public : virtual void progress();
public : virtual string _getString() const;
};
// Attributs
// *********
private : const Equi* _equi;
// Constructors
// ************
public : EquiComponentOccurrencesCollection();
public : EquiComponentOccurrencesCollection(const Equi* equi);
public : EquiComponentOccurrencesCollection(const EquiComponentOccurrencesCollection&);
// Operators
// *********
public : EquiComponentOccurrencesCollection& operator=(const EquiComponentOccurrencesCollection&);
// Accessors
// *********
public : virtual Collection<Occurrence>* getClone() const;
public : virtual Hurricane::Locator<Occurrence>* getLocator() const;
// Others
// ******
public : virtual string _getString() const ;
}; // end of class EquiComponentOccurrencesCollection
class CurrentComponentOccurrencesCollection : public Collection<Occurrence> {
public : typedef Collection<Occurrence> Inherit;
public : class Locator : public Hurricane::Locator<Occurrence> {
// *************************************************************
public : typedef Hurricane::Locator<Occurrence> Inherit ;
private : const Equi* _equi;
private : int _state; // state = 0 locator is invalid
private : OccurrenceLocator _componentLocator;
private : OccurrenceLocator _netoccurrenceLocator;
private : ComponentLocator _occurrenceLocator;
public : Locator();
public : Locator(const Equi* equi);
public : Locator(const Locator& locator);
public : Locator& operator=(const Locator& locator);
public : virtual Occurrence getElement() const;
public : virtual Hurricane::Locator<Occurrence>* getClone() const;
public : virtual bool isValid() const;
public : virtual void progress();
public : virtual string _getString() const;
};
// Attributs
// *********
private : const Equi* _equi;
// Constructors
// ************
public : CurrentComponentOccurrencesCollection();
public : CurrentComponentOccurrencesCollection(const Equi* equi);
public : CurrentComponentOccurrencesCollection(const CurrentComponentOccurrencesCollection&);
// Operators
// *********
public : CurrentComponentOccurrencesCollection& operator=(const CurrentComponentOccurrencesCollection&);
// Accessors
// *********
public : virtual Collection<Occurrence>* getClone() const;
public : virtual Hurricane::Locator<Occurrence>* getLocator() const;
// Others
// ******
public : virtual string _getString() const ;
}; // end of class CurrentComponentOccurrencesCollection
} //end of namespace
#endif // __EQUINOX_EQUINOX_COLLECTIONS__

View File

@ -0,0 +1,209 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : " ./equinox/EquinoxEngine.h |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_EQUINOX_ENGINE__
#define __EQUINOX_EQUINOX_ENGINE__
#include <equinox/IntervalTree.h>
#include <equinox/Equis.h>
#include <hurricane/Occurrences.h>
#include <hurricane/Components.h>
#include <equinox/EquinoxFilters.h>
#include <hurricane/SetCollection.h>
#include <equinox/Strategy.h>
namespace {
using namespace Hurricane;
}
namespace Hurricane {
class Box;
class Cell;
class Name;
class Record;
class Occurrence;
class BasicLayer;
template<class Type> class GenericFilter;
}
namespace CRL {
class ToolEngine;
}
namespace Equinox {
using std::string;
using std::set;
using std::map;
using std::vector;
using Hurricane::Cell;
using Hurricane::Box;
using Hurricane::Name;
using Hurricane::Record;
using Hurricane::GenericFilter;
using Hurricane::BasicLayer;
using Hurricane::OccurrenceFilter;
using Hurricane::Occurrence;
using Hurricane::Occurrences;
using Hurricane::ComponentFilter;
using CRL::ToolEngine;
class Tile;
class Equi;
template<typename ITEM,typename ENGINE>
class SweepLine;
// -------------------------------------------------------------------
// Class : "Equinox::EquinoxEngine".
class EquinoxEngine : public ToolEngine {
// Friends
public:
friend class GraphicEquinoxEngine;
friend class Strategy;
friend class WithAlimStrategy;
friend class WithoutAlimStrategy;
// Statics
public:
/**/ static EquinoxEngine* create (Cell*);
inline static const Name& staticGetName ();
inline static EquinoxEngine* get (const Cell* );
inline static GenericFilter<Equi*> getIsRoutingFilter ();
/**/ static Strategy * getStrategy ();
/**/ static ComponentFilter getIsUsedByExtractFilter ();
private:
inline static void setStrategy (Strategy *);
public :
inline virtual const Name& getName () const;
inline Equis getRoutingEquis () const;
inline Equis getEquis () const;
inline unsigned long long getNumOfEquis ();
inline void addEqui (Equi* equi);
inline void removeEqui (Equi* equi);
inline map<Occurrence, Equi*>& _getOccurrences ();
/**/ virtual Record* _getRecord () const;
/**/ virtual string _getString () const;
/**/ virtual string _getTypeName () const;
/**/ Occurrences getComponentOccurrencesBy (Occurrence);
inline bool isExtracted () const;
/**/ bool hasEqui (Equi* equi);
/**/ void removeEquis ();
/**/ bool _IsToFilter (const Equi*) const;
/**/ void _FilterEquis ();
/**/ Occurrence _GetTopNetOccurrence (const Equi* equi) const;
/**/ void _WriteNetlist ();
/**/ void _CheckOut (Equi*);
/**/ void withAlimExtract (unsigned int);
/**/ void withoutAlimExtract (unsigned int);
/**/ void deviceExtract (unsigned int);
/**/ void extract (unsigned int);
/**/ void test ();
/**/ Box _getSweepLineBox ();
/**/ void insertInterval (Tile*,stack <Equinox::Interval*>*enumResultStack);
/**/ void removeInterval (Tile* item);
protected:
/**/ Equi* getEquiByOccurrence (Occurrence occurrence);
/**/ Occurrence getEquiOccurrence (Occurrence occurrence);
/**/ Occurrence getUpperEquiOccurrence (Occurrence occurrence);
/**/ void setIsExtracted (const bool flag) ;
/**/ void scan (unsigned int);
/**/ void getOccurrencesOfEquis ();
/**/ void cleanUpLeafCell ();
/**/ void flushEquis (Cell*);
private:
/**/ void selectWindowsSize ();
/**/ void initTiles ();
/**/ void postSweepLine ();
/**/ void printEquis ();
// Attributes
private:
static Name _toolName;
/**/ unsigned int _cWindows ;
/**/ unsigned int _nbWindows ;
protected:
static Strategy * _strategy;
/**/ bool _isExtracted;
/**/ set<Equi*> _equis;
/**/ map<Occurrence, Equi*> _occurrences;
/**/ vector<Tile*>* _tilesByXmin;
/**/ vector<Tile*>* _tilesByXmax;
protected:
// Constructors & Destructors.
/**/ EquinoxEngine (Cell*);
/**/ virtual ~EquinoxEngine ();
/**/ virtual void _postCreate ();
/**/ virtual void _preDestroy ();
/**/ void _destroy ();
/**/ void _depthDestroy ();
private:
/**/ EquinoxEngine (const EquinoxEngine&);
/**/ EquinoxEngine& operator= (const EquinoxEngine&);
}; // End of class EquinoxEngine
// Inline Functions.
inline bool EquinoxEngine::isExtracted () const { return _isExtracted; };
inline const Name& EquinoxEngine::getName () const { return _toolName; };
inline EquinoxEngine* EquinoxEngine::get (const Cell* cell ) { return static_cast<EquinoxEngine*>(ToolEngine::get(cell,staticGetName())); };
inline const Name& EquinoxEngine::staticGetName () { return _toolName; }
inline map<Occurrence,Equi*>& EquinoxEngine::_getOccurrences () { return _occurrences; };
inline void EquinoxEngine::setStrategy (Strategy * s) { if (_strategy) delete _strategy; _strategy = s; };
inline EquiFilter EquinoxEngine::getIsRoutingFilter () { return IsRoutingFilter();}
inline Equis EquinoxEngine::getRoutingEquis () const { return getCollection(_equis).getSubSet(getIsRoutingFilter()); };
inline Equis EquinoxEngine::getEquis () const { return getCollection(_equis); };
inline unsigned long long EquinoxEngine::getNumOfEquis () { return _equis.size(); }
inline void EquinoxEngine::addEqui ( Equi* equi) { _equis.insert(equi); }
inline void EquinoxEngine::removeEqui ( Equi* equi) { _equis.erase(equi); }
} // End of Equinox namespace.
#endif // __EQUINOX_EQUINOX_ENGINE__

View File

@ -0,0 +1,250 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/EquinoxFilters.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_EQUINOX_FILTERS__
#define __EQUINOX_EQUINOX_FILTERS__
/**
Filter List :
- IsRouting (Equi)
- IsUsedByExtract (Component)
- IsEqui (Occurrence)
- IsComponent (Occurrence)
- IsNet (Occurrence)
- IsNetOrComponent (Occurrence)
- IsLeafEqui (Occurrence)
**/
namespace Hurricane {
template<class Type> class GenericLocator;
template<class Type> class GenericCollection;
template<class Type> class GenericFilter;
template<class Type> class Filter;
class Occurrence;
class Component;
class Layer;
class Net;
}
namespace Equinox {
using Hurricane::GenericCollection;
using Hurricane::GenericLocator;
using Hurricane::GenericFilter;
using Hurricane::Filter;
using Hurricane::Occurrence;
using Hurricane::Component;
using Hurricane::Layer;
using Hurricane::Net;
using std::string;
class Equi;
// -------------------------------------------------------------------
// Class : "Equinox::IsRoutingEquiFilter".
class IsRoutingFilter : public Filter<Equi*>
{
public:
/**/ IsRoutingFilter ();
/**/ IsRoutingFilter (const IsRoutingFilter&);
/**/ IsRoutingFilter& operator= (const IsRoutingFilter&);
virtual Filter<Equi*>* getClone () const;
virtual string _getString () const;
virtual bool accept (Equi* item) const;
}; // End of class IsRoutingFilter
// -------------------------------------------------------------------
// Class : "Equinox::IsUsedByExtractFilter".
class IsUsedByExtractFilter : public Filter<Component*>
{
public:
/**/ IsUsedByExtractFilter ();
virtual Filter<Component*>* getClone () const;
virtual string _getString () const;
virtual bool accept (Component*) const;
/**/ IsUsedByExtractFilter (const IsUsedByExtractFilter&);
/**/ IsUsedByExtractFilter& operator= (const IsUsedByExtractFilter&);
}; // End of class IsUsedByExtractFilter
// -------------------------------------------------------------------
// Class : "Equinox::IsNetOrComponentOccurrenceFilter".
class IsNetOrComponentFilter : public Filter<Occurrence>
{
public:
/**/ IsNetOrComponentFilter ();
/**/ IsNetOrComponentFilter (const IsNetOrComponentFilter&);
/**/ IsNetOrComponentFilter& operator= (const IsNetOrComponentFilter&);
virtual Filter<Occurrence>* getClone () const;
virtual string _getString () const;
virtual bool accept (Occurrence item) const;
}; // End of class IsNetOrComponentFilter
// -------------------------------------------------------------------
// Class : "Equinox::IsComponentOccurrenceFilter".
class IsComponentFilter : public Filter<Occurrence>
{
public:
/**/ IsComponentFilter ();
/**/ IsComponentFilter (const IsComponentFilter&);
/**/ IsComponentFilter& operator= (const IsComponentFilter&);
virtual Filter<Occurrence>* getClone () const;
virtual string _getString () const;
virtual bool accept (Occurrence item) const;
}; // End of class IsComponentFilter
// -------------------------------------------------------------------
// Class : "Equinox::IsNetOccurrenceFilter".
class IsNetFilter : public Filter<Occurrence>
{
public:
/**/ IsNetFilter ();
/**/ IsNetFilter (const IsNetFilter&);
/**/ IsNetFilter& operator= (const IsNetFilter&);
virtual Filter<Occurrence>* getClone () const;
virtual string _getString () const;
virtual bool accept (Occurrence item) const;
}; // End of class IsNetFilter
// -------------------------------------------------------------------
// Class : "Equinox::IsEquiOccurrenceFilter".
class IsEquiFilter : public Filter<Occurrence>
{
public:
/**/ IsEquiFilter ();
/**/ IsEquiFilter (const IsEquiFilter&);
/**/ IsEquiFilter& operator= (const IsEquiFilter&);
virtual Filter<Occurrence>* getClone () const;
virtual string _getString () const;
virtual bool accept (Occurrence item) const;
}; // End of class IsEquiFilter
// -------------------------------------------------------------------
// Class : "Equinox::IsEquiLeafOccurrenceFilter".
class IsLeafEquiFilter : public Filter<Occurrence>
{
public:
/**/ IsLeafEquiFilter ();
/**/ IsLeafEquiFilter (const IsLeafEquiFilter&);
/**/ IsLeafEquiFilter& operator= (const IsLeafEquiFilter&);
virtual Filter<Occurrence>* getClone () const;
virtual string _getString () const;
virtual bool accept (Occurrence item) const;
}; // End of class IsLeafEquiFilter
// -------------------------------------------------------------------
// Class : "Equinox::IsNotEquiLeafOccurrenceFilter".
class IsNotLeafEquiFilter : public Filter<Occurrence>
{
public:
/**/ IsNotLeafEquiFilter ();
/**/ IsNotLeafEquiFilter (const IsNotLeafEquiFilter&);
/**/ IsNotLeafEquiFilter& operator= (const IsNotLeafEquiFilter&);
virtual Filter<Occurrence>* getClone () const;
virtual string _getString () const;
virtual bool accept (Occurrence item) const;
}; // End of class IsLeafEquiFilter
class NetIsUsedByExtractorFilter : public Filter<Component*>
{
public:
/**/ NetIsUsedByExtractorFilter ();
/**/ NetIsUsedByExtractorFilter (const NetIsUsedByExtractorFilter&);
/**/ NetIsUsedByExtractorFilter& operator= (const NetIsUsedByExtractorFilter&);
virtual Filter<Component*>* getClone () const;
virtual string _getString () const;
virtual bool accept (Component* item) const;
}; // End of class NetIsUsedByExtractorFilter
} // End of Equinox namespace.
#endif // __EQUINOX_EQUINOX_FILTERS__

View File

@ -0,0 +1,60 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/Equis.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_EQUIS__
#define __EQUINOX_EQUIS__
namespace Hurricane {
template<class Type> class GenericLocator;
template<class Type> class GenericCollection;
template<class Type> class GenericFilter;
}
namespace Equinox {
using Hurricane::GenericCollection;
using Hurricane::GenericLocator;
using Hurricane::GenericFilter;
class Equi;
typedef GenericCollection<Equi*> Equis;
typedef GenericLocator<Equi*> EquiLocator;
typedef GenericFilter<Equi*> EquiFilter;
} // End of Equinox namespace.
#endif // __EQUINOX_EQUIS__

View File

@ -0,0 +1,98 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/GraphicEquinoxEngine.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_GRAPHIC_EQUINOX_ENGINE__
#define __EQUINOX_GRAPHIC_EQUINOX_ENGINE__
#include <QObject>
#include "crlcore/GraphicToolEngine.h"
namespace Hurricane {
class Go;
class BasicLayer;
class Transformation;
class CellWidget;
class CellViewer;
}
namespace Equinox {
using Hurricane::Cell;
using Hurricane::Go;
using Hurricane::Box;
using Hurricane::BasicLayer;
using Hurricane::Transformation;
using Hurricane::CellWidget;
using Hurricane::CellViewer;
using CRL::GraphicTool;
using CRL::Name;
class EquinoxEngine;
class Sweepline;
// -------------------------------------------------------------------
// Class : "Equinox::GraphicEquinoxEngine".
class GraphicEquinoxEngine : public GraphicTool {
Q_OBJECT;
public:
inline
/**/ EquinoxEngine* createEngine ();
/**/ static GraphicEquinoxEngine* grab ();
/**/ virtual const Name& getName () const;
/**/ Cell* getCell ();
/**/ virtual size_t release ();
/**/ virtual void addToMenu ( CellViewer* );
public slots:
/**/ void runWithAlim ();
/**/ void runWithoutAlim ();
private:
/**/ static size_t _references;
/**/ static GraphicEquinoxEngine* _singleton;
/**/ CellViewer* _viewer;
protected:
/**/ GraphicEquinoxEngine ();
/**/ virtual ~GraphicEquinoxEngine ();
};
} // End of Equinox namespace.
#endif // __EQUINOX_GRAPHIC_EQUINOX_ENGINE__

View File

@ -0,0 +1,54 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/Interval.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_INTERVAL__
#define __EQUINOX_INTERVAL__
namespace Equinox {
// -------------------------------------------------------------------
// Class : "EQUINOX::Interval".
class Interval {
public:
/**/ Interval ();
/**/ virtual ~Interval ();
/**/ virtual long GetLowPoint () const = 0;
/**/ virtual long GetHighPoint () const = 0;
/**/ virtual void Print () const;
};
} // end of namespace
#endif //__EQUINOX_INTERVAL__

View File

@ -0,0 +1,165 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/Strategy.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef _EQUINOX_STRATEGY_H
#define _EQUINOX_STRATEGY_H
namespace Hurricane {
class Net;
class Occurrence;
class Component;
}
namespace Equinox {
using std::vector;
using std::map;
using std::string;
using Hurricane::Cell;
using Hurricane::Occurrence;
using Hurricane::Box;
using Hurricane::Filter;
using Hurricane::BasicLayer;
using Hurricane::Component;
using Hurricane::_TName;
using Hurricane::Net;
class EquinoxEngine;
class Tile;
class Strategy {
public:
//implemented
static bool const isExtractableLayer(BasicLayer *);
public :
/**/ Strategy ();
virtual ~Strategy (){};
virtual void run (EquinoxEngine* , unsigned int){};
virtual void getTilesFor (EquinoxEngine*){};
virtual void operationAfterScanLine (EquinoxEngine*){};
//not implemented
//virtual void createIntervalSets (TileSweepLine::IntervalSets*);
private :
/**/ Strategy (const Strategy&);
/**/ Strategy& operator= (const Strategy&);
}; // End of Strategy
class WithAlimStrategy : public Strategy {
public :
/**/ WithAlimStrategy();
virtual ~WithAlimStrategy();
virtual void run(EquinoxEngine* , unsigned int);
virtual void getTilesFor(EquinoxEngine*) ;
virtual void operationAfterScanLine(EquinoxEngine*);
};// End of WithAlimStrategy
class WithoutAlimStrategy : public Strategy {
public :
/**/ WithoutAlimStrategy();
virtual ~WithoutAlimStrategy();
virtual void run(EquinoxEngine* , unsigned int);
virtual void getTilesFor(EquinoxEngine*) ;
virtual void operationAfterScanLine(EquinoxEngine*);
};// End of WithAlimStrategy
class DefaultStrategy : public WithAlimStrategy {
public :
/**/ DefaultStrategy() {};
};// End of DefaultStrategy
// -------------------------------------------------------------------
// Class : "Equinox::WithAlimStrategyFilter".
class WithAlimStrategyFilter : public Filter<Occurrence>
{
public:
/**/ WithAlimStrategyFilter ();
virtual Filter<Occurrence>* getClone () const;
virtual string _getString () const;
virtual bool accept (Occurrence item) const;
/**/ WithAlimStrategyFilter (const WithAlimStrategyFilter&);
/**/ WithAlimStrategyFilter& operator= (const WithAlimStrategyFilter&);
}; // End of class WithAlimStrategyFilter
// -------------------------------------------------------------------
// Class : "Equinox::WithoutAlimStrategyFilter".
class WithoutAlimStrategyFilter : public Filter<Occurrence>
{
public:
/**/ WithoutAlimStrategyFilter ();
virtual Filter<Occurrence>* getClone () const;
virtual string _getString () const;
virtual bool accept (Occurrence item) const;
/**/ WithoutAlimStrategyFilter (const WithoutAlimStrategyFilter&);
/**/ WithoutAlimStrategyFilter& operator= (const WithoutAlimStrategyFilter&);
}; // End of class WithoutAlimStrategyFilter
}// End of namespace Equinox
#endif // _EQUINOX_STRATEGY_H

View File

@ -0,0 +1,411 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/SweepLine.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef _EQUINOX_SWEEPLINE_H
#define _EQUINOX_SWEEPLINE_H
#define INTERVALTREE 1 /*Without use STL map, VERY SLOW*/
//#define ASSERT 1
#include "crlcore/Utilities.h"
namespace Hurricane {
class BasicLayer;
class DataBase;
}
namespace CRL {
class ToolEngine;
}
namespace Equinox {
class EquinoxEngine;
class Strategy;
using namespace Hurricane;
using CRL::ToolEngine;
// -------------------------------------------------------------------
// Class : "Equinox::SweepLine".
template < typename ITEM, typename ENGINE >
class SweepLine {
private :
map<ITEM , IntervalTreeNode*> _intervalTreeNodeMap;
int intervalsize;
float intervaltime;
int contactssize;
struct ItemComparator{
inline bool operator() ( ITEM const& t1, ITEM const& t2) const;
};
public:
typedef vector < ITEM > ItemList;
typedef set < ITEM , ItemComparator > IntervalSet;
#ifdef INTERVALTREE
typedef map < BasicLayer*, IntervalTree* > IntervalSets;
#else
typedef map < BasicLayer*, IntervalSet* > IntervalSets;
#endif
public:
static SweepLine* create (ENGINE,
Strategy*);
virtual void destroy ();
public:
/**/ Record* _getRecord () const;
/**/ string _getString () const;
/**/ Box getBoundingBox () const;
/**/ void run ( vector < ITEM >* _itemsByXmin,
vector < ITEM >* _itemsByXmax,
bool stopToMax,
int max);
/**/ void initIntervalSets () ;
/**/inline void insertInterval (ITEM newitem);
/**/inline void removeInterval (ITEM newitem);
public:
virtual const Name& getName () const;
/**/ Strategy* getStrategy () ;
protected:
static const Name _extensionName;
/**/ ENGINE _engine;
/**/ IntervalSets _intervalSets;
/**/ Strategy* _strategy;
protected:
/**/ void _postCreate ();
/**/ void _preDestroy ();
/**/ SweepLine ( ENGINE,
Strategy* );
virtual ~SweepLine ();
}; //end of SweepLine
template < typename ITEM, typename ENGINE >
inline bool SweepLine<ITEM,ENGINE>::ItemComparator::operator() ( ITEM const& t1, ITEM const& t2) const
{
#ifdef ASSERT
if (!t1 || !t2) throw Error("SweepLine Assert Error");
#endif
if( t1->getYmin() < t2->getYmin() )
return true;
if( t1->getYmin() == t2->getYmin() )
return t1 < t2;
return false;
}
template < typename ITEM, typename ENGINE >
const Name SweepLine<ITEM,ENGINE>::_extensionName = "Equinox::SweepLine";
template < typename ITEM, typename ENGINE >
Strategy* SweepLine<ITEM,ENGINE>::getStrategy ()
{
if (!_strategy) throw Error("Aucun strategy transmise pour la sweepLine");
return _strategy;
}
template < typename ITEM, typename ENGINE >
SweepLine<ITEM,ENGINE>* SweepLine<ITEM,ENGINE>::create (ENGINE engine, Strategy* strategy) {
SweepLine* sweepLine = new SweepLine ( engine , strategy );
if(!sweepLine){
throw Error("can't create SweepLine : allocation failed");
}
sweepLine->_postCreate ();
return sweepLine ;
}
template < typename ITEM, typename ENGINE >
/**/ SweepLine<ITEM,ENGINE>::SweepLine (ENGINE engine, Strategy* strategy) :
// ExtensionGo(cell),
_engine(engine),
_intervalSets(),
_strategy(strategy)
{
};
template < typename ITEM, typename ENGINE >
void SweepLine<ITEM,ENGINE>::_postCreate (){
// ExtensionGo::_postCreate();
initIntervalSets();
}
template < typename ITEM, typename ENGINE >
/**/ SweepLine<ITEM,ENGINE>::~SweepLine (){}
template < typename ITEM, typename ENGINE >
void SweepLine<ITEM,ENGINE>::destroy (){ _preDestroy(); delete this; }
template < typename ITEM, typename ENGINE >
void SweepLine<ITEM,ENGINE>::_preDestroy (){
// ExtensionGo::_preDestroy();
typename IntervalSets::iterator it_intervaltree_begin = _intervalSets.begin(),
it_intervaltree_end = _intervalSets.end();
while(it_intervaltree_begin!=it_intervaltree_end){
delete (*it_intervaltree_begin).second;
it_intervaltree_begin++;
}
}
template < typename ITEM, typename ENGINE >
void SweepLine<ITEM,ENGINE>::initIntervalSets()
{
forEach ( BasicLayer*, basicLayer, DataBase::getDB()->getTechnology()->getBasicLayers()) {
if (Strategy::isExtractableLayer(*basicLayer) ) {
#ifdef INTERVALTREE
(_intervalSets)[*basicLayer] = new IntervalTree();
#else
(_intervalSets)[*basicLayer] = new IntervalSet();
#endif
}
}
}
template < typename ITEM, typename ENGINE >
Record* SweepLine<ITEM,ENGINE>::_getRecord() const
// ***********************
{
//Record* record = Inherit::_getRecord();
Record* record = NULL;
if ( !record )
record = new Record ( getString ( this ) );
return record;
}
template < typename ITEM, typename ENGINE >
string SweepLine<ITEM,ENGINE>::_getString() const
// ****************************
{
return "<" + _TName ( "SweepLine" ) + ">";
}
template < typename ITEM, typename ENGINE >
const Name& SweepLine<ITEM,ENGINE>::getName () const {
return _extensionName;
}
template < typename ITEM, typename ENGINE >
inline void SweepLine<ITEM,ENGINE>::insertInterval(ITEM item)
{
#ifdef ASSERT
if (!item) throw Error("SweepLine : Insert null");
#endif
#ifdef INTERVALTREE
//recherche du Layer du Item
#ifdef ASSERT
if (_intervalSets.find(item->getBasicLayer()) == _intervalSets.end())
throw Error("Layer inconnu dans insertInterval");
#endif
IntervalTree* intervaltree = _intervalSets.find(item->getBasicLayer())->second;
// Récuperation des intersections avec ce Item dans enumResultStack
stack <Interval*>* enumResultStack = (intervaltree->Enumerate((item->getYmin()),( item->getYmax()) ));
#else
typename IntervalSets::const_iterator mySetsIt = _intervalSets.find(item->getBasicLayer());
#ifdef ASSERT
if (_intervalSets.find(item->getBasicLayer()) == _intervalSets.end())
throw Error("Layer inconnu dans insertInterval");
#endif
IntervalSet* intervaltree = mySetsIt->second;
stack <Interval*>* enumResultStack = new stack<Interval*>;
typename IntervalSet::iterator itmid2down = intervaltree->lower_bound( item ) ;
typename IntervalSet::iterator itbegin2mid = intervaltree->begin() ;
while ( itmid2down != intervaltree->end() )
{
if ( (*itmid2down)->getYmin() <= item->getYmax() ) { enumResultStack->push((*itmid2down)); itmid2down++;}
else break;
}
while ( itbegin2mid != ( intervaltree->upper_bound( item ) ) )
{
if ( (*itbegin2mid)->getYmax() >= item->getYmin() ) { enumResultStack->push((*itbegin2mid));}
itbegin2mid++;
}
#endif
_engine->insertInterval(item,enumResultStack);
#ifdef INTERVALTREE
_intervalTreeNodeMap[(item)] = intervaltree->Insert((item));
#else
//Ajout du Item aux intervals
intervaltree->insert(item);
#endif
delete enumResultStack;
}
template < typename ITEM, typename ENGINE >
inline void SweepLine<ITEM,ENGINE>::removeInterval(ITEM item)
{
// /*DEBUG*/ cmess1 << " o removeInterval : " << endl;
//recherche du Layer du Item
typename IntervalSets::const_iterator mySetsIt = _intervalSets.find(item->getBasicLayer());
#ifdef ASSERT
//Valide la liste des layers
if(mySetsIt ==_intervalSets.end()) throw Error("SweepLine : La clé des Layers n'existe pas pas");
//Valide l'item à supprimer
typename IntervalSet::const_iterator mySetIt = mySetsIt->second->find(item);
if(mySetIt == mySetsIt->second->end()) throw Error("SweepLine : Un item à detruire du champ n'existe pas");
#endif
#ifdef INTERVALTREE
//Suppression du Item
mySetsIt->second->DeleteNode(_intervalTreeNodeMap[item]);
_intervalTreeNodeMap.erase(item);
#else
mySetsIt->second->erase(item);
#endif
_engine->removeInterval(item);
///*DEBUG*/ cmess1 << " - destroy tile OK " << endl;
///*DEBUG*/ cmess1 << " - " << mySetsIt->second->size() << " interval(s) sur le Layer." <<endl;
}
template < typename ITEM, typename ENGINE >
void SweepLine<ITEM,ENGINE>::run (vector < ITEM >* _itemsByXmin, vector < ITEM >* _itemsByXmax,bool stopAtMax = false,int max = 0)
{
///*DEBUG*/ cmess1 << " o SweepLine :: run : " << endl;
//Making iterators
typename vector<ITEM>::iterator it1 = _itemsByXmin->begin();
typename vector<ITEM>::iterator it1_end = _itemsByXmin->end();
typename vector<ITEM>::iterator it2 = _itemsByXmax->begin();
typename vector<ITEM>::iterator it2_end = _itemsByXmax->end();
typename vector<ITEM>::iterator it2_begin = _itemsByXmax->begin();
while(it2!=it2_end)
{
if( (it1 != it1_end) && ((*it1)->getXmin() <= (*it2)->getXmax()) ) /* Get some tiles */
{
typename vector<ITEM>::iterator upper_it = upper_bound(it1, it1_end, *it1, CompByXmin_Upper_Bound<ITEM>() );
while(it1 != upper_it)
{
insertInterval(*it1);
it1++;
}
}
else /* Throw some tiles */
{
if(stopAtMax)
if ((*it2)->getXmax() >= max )
break;
typename vector<ITEM>::iterator upper_it = upper_bound(it2, it2_end, *it2, CompByXmax_Upper_Bound<ITEM>() );
while(it2 != upper_it)
{
removeInterval(*it2);
it2++;
}
}
} // end while
if (_itemsByXmin->size()) {
///*DEBUG*/ intervalsize= intervalsize / _tilesByXmin->size();
///*DEBUG*/ contactssize= contactssize / _tilesByXmin->size();
///*DEBUG*/ intervaltime= intervaltime / _tilesByXmin->size();
///*DEBUG*/ cmess1 << " -- FIN SWEEPLINE : intervalsize="<< intervalsize<< " contactssize=" <<contactssize<< " intervaltime=" <<intervaltime <<endl;
}
_itemsByXmin->clear();
_itemsByXmax->erase(it2_begin, it2);
}
} // namespace equinox
#endif // _EQUINOX_SWEEPLINE_H

156
equinox/src/equinox/Tile.h Normal file
View File

@ -0,0 +1,156 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/Tile.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_TILE__
#define __EQUINOX_TILE__
#include <hurricane/Occurrence.h>
#include <hurricane/Box.h>
#include <equinox/Interval.h>
namespace Hurricane {
class Box;
class Cell;
class Entity;
class BasicLayer;
class Record;
class Occurrence;
} // End of Hurricane namespace.
namespace Equinox {
using std::string;
using Hurricane::BasicLayer;
using Hurricane::Occurrence;
using Hurricane::Box;
using Hurricane::DbU;
using Hurricane::Record;
class Equi;
// -------------------------------------------------------------------
// Class : "EQUINOX::Tile".
class Tile : public Interval
{
//Statics
public:
static Tile* create (const Occurrence,
const Box,
BasicLayer*,
Equi* equi = NULL);
//Functions
public:
inline void destroy ();
public:
inline const Box& getBoundingBox ();
inline const Occurrence& getOccurrence () const;
inline BasicLayer* getBasicLayer () const;
inline Equi* getEqui () const;
inline void setEqui (Equi* equi);
inline const DbU::Unit& getXmin () const;
inline const DbU::Unit& getYmin () const;
inline const DbU::Unit& getXmax () const;
inline const DbU::Unit& getYmax () const;
inline bool isEmpty () const;
inline virtual long GetLowPoint () const;
inline virtual long GetHighPoint () const;
/**/ bool intersect (const Tile* tile) const;
inline virtual string _getTypeName () const;
/**/ virtual string _getString () const;
inline virtual Record* _getRecord () const;
private:
/**/ const Occurrence _occurrence;
/**/ const Box _box;
/**/ BasicLayer* _basicLayer;
/**/ Equi* _equi;
// Constructors & Destructors.
protected:
/**/ Tile (const Occurrence,
const Box,
BasicLayer*,
Equi* equi = NULL);
inline virtual ~Tile ();
inline virtual void _postCreate ();
inline virtual void _preDelete ();
private:
/**/ Tile (const Tile&);
/**/ Tile& operator= (const Tile&);
}; // End of class Equi
// Inline Functions.
inline Equi* Tile::getEqui () const { return _equi; };
inline const Box& Tile::getBoundingBox () { return _box; };
inline const Occurrence& Tile::getOccurrence () const { return _occurrence; };
inline BasicLayer* Tile::getBasicLayer () const { return _basicLayer; };
inline void Tile::setEqui (Equi* equi) { _equi = equi; };
inline long Tile::GetLowPoint () const { return _box.getYMin(); }
inline long Tile::GetHighPoint () const { return _box.getYMax(); }
inline string Tile::_getTypeName () const { return "Equinox::Tile"; }
inline const DbU::Unit& Tile::getXmin () const { return _box.getXMin(); };
inline const DbU::Unit& Tile::getYmin () const { return _box.getYMin(); };
inline const DbU::Unit& Tile::getXmax () const { return _box.getXMax(); };
inline const DbU::Unit& Tile::getYmax () const { return _box.getYMax(); };
inline bool Tile::isEmpty () const { return _box.isEmpty(); };
inline Record* Tile::_getRecord () const { return NULL; };
inline void Tile::destroy () { _preDelete(); delete this; };
inline void Tile::_postCreate () { };
inline void Tile::_preDelete () { };
inline /**/ Tile::~Tile () { };
} // End of Equinox namespace.
#endif // __EQUINOX_TILE__

View File

@ -0,0 +1,43 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | =============================================================== |
// | C++ Header : "./TileSweepLine.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef _EQUINOX_TILESWEEPLINE_H
#define _EQUINOX_TILESWEEPLINE_H
#include <equinox/SweepLine.h>
namespace Equinox {
class Tile;
class EquinoxEngine;
template<typename ITEM,typename ENGINE>
class SweepLine;
typedef SweepLine<Tile*,EquinoxEngine*> TileSweepLine;
}
#endif // _EQUINOX_TILESWEEPLINE_H

128
equinox/src/equinox/Tiles.h Normal file
View File

@ -0,0 +1,128 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | =============================================================== |
// | C++ Header : "./Tiles.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_TILES__
#define __EQUINOX_TILES__
namespace Equinox {
class Tile;
using namespace std;
// *********************************************************************************************************
// Functeurs
// *********************************************************************************************************
template<typename T1>
class CompByXmin
// ******************
{
public: bool operator()(const T1 t1, const T1 t2)
// **************************************
{
if( t1->getXmin() < t2->getXmin() )
return true;
if( t1->getXmin() == t2->getXmin() ) {
if( t1->getYmin() < t2->getYmin() )
return true;
if( t1->getYmin() == t2->getYmin() )
if( t1< t2 )
return true;
}
return false;
}
};
template<typename T1>
class CompByXmax
// ******************
{
public: bool operator()(const T1 t1, const T1 t2)
// ***************************************
{
if( t1->getXmax() < t2->getXmax() )
return true;
if( t1->getXmax() == t2->getXmax() ) {
if( t1->getYmax() < t2->getYmax() )
return true;
if( t1->getYmax() == t2->getYmax() )
if(t1 < t2)
return true;
}
return false;
}
};
template<typename T1>
class CompByXmin_Upper_Bound
// ***************************
{
public: bool operator()(const T1 t1, const T1 t2)
// ***************************************
{
if( t1->getXmin() < t2->getXmin() )
return true;
return false;
}
};
template<typename T1>
class CompByXmax_Upper_Bound
// ****************************
{
public: bool operator()(const T1 t1, const T1 t2)
// *************************************
{
if( t1->getXmax() < t2->getXmax() )
return true;
return false;
}
};
//typedef set<Tile*,CompByXmin <Tile*> > TilesByXmin;
//typedef set<Tile*,CompByXmax <Tile*> > TilesByXmax;
typedef vector<Tile*> TileVector;
} // End of Equinox namespace.
#endif // __EQUINOX_TILES__

View File

@ -0,0 +1,60 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/UnionFind.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_UNIONFIND__
#define __EQUINOX_UNIONFIND__
namespace Equinox {
class Tile;
class Equi;
class UnionFind {
public:
inline static Equi * getRootEqui (Tile* tile); /* internal inline */
/**/ static Equi * getRootEquiWithCompression (Tile* tile);
/**/ static Equi * findValidEqui (Equi* equi);
private :
/**/ UnionFind ();
/**/ UnionFind (const UnionFind&);
/**/ UnionFind& operator= (const UnionFind&);
};
} //End of equinox namespace
#endif //End of __EQUINOX_UNIONFIND__

View File

@ -0,0 +1,625 @@
//#ifndef E_INTERVAL_TREE
//#define E_INTERVAL_TREE
#ifndef INTERVALTREE_H
#define INTERVALTREE_H
#include<math.h>
#include<limits.h>
#include<iostream>
#include<stack>
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <hurricane/Error.h>
#include <equinox/Interval.h>
// The interval_tree.h and interval_tree.cc files contain code for
// interval trees implemented using red-black-trees as described in
// the book _Introduction_To_Algorithms_ by Cormen, Leisserson,
// and Rivest.
// CONVENTIONS:
// Function names: Each word in a function name begins with
// a capital letter. An example funcntion name is
// CreateRedTree(a,b,c). Furthermore, each function name
// should begin with a capital letter to easily distinguish
// them from variables.
//
// Variable names: Each word in a variable name begins with
// a capital letter EXCEPT the first letter of the variable
// name. For example, int newLongInt. Global variables have
// names beginning with "g". An example of a global
// variable name is gNewtonsConstant.
#ifndef MAX_LONG
#define MAX_LONG LONG_MAX // some architechturs define INT_MAX not MAX_INT
#define MIN_LONG -MAX_LONG
#endif
#define ITMax(a, b) ( (a > b) ? a : b )
//#ifndef MAX_INT
//#define MAX_INT INT_MAX // some architechturs define INT_MAX not MAX_INT
//#endif
// The Interval class is an Abstract Base Class. This means that no
// instance of the Interval class can exist. Only classes which
// inherit from the Interval class can exist. Furthermore any class
// which inherits from the Interval class must define the member
// functions GetLowPoint and GetHighPoint.
//
// The GetLowPoint should return the lowest point of the interval and
// the GetHighPoint should return the highest point of the interval.
namespace Equinox {
using std::stack;
using Hurricane::Error;
# if !defined(__DOXYGEN_PROCESSOR__)
static inline bool Overlap(long& a1, long& a2, long& b1, long& b2) {
// *****************************************************************
if (a1 <= b1) {
return( (b1 <= a2) );
} else {
return( (a1 <= b2) );
}
}
#endif
class IntervalTreeNode {
// *********************
friend class IntervalTree;
public:
IntervalTreeNode(Interval * );
# if !defined(__DOXYGEN_PROCESSOR__)
void Print(IntervalTreeNode*, IntervalTreeNode*) const;
IntervalTreeNode();
~IntervalTreeNode();
protected:
Interval * storedInterval;
long key;
long high;
long maxHigh;
long red; /* if red=0 then the node is black */
IntervalTreeNode * left;
IntervalTreeNode * right;
IntervalTreeNode * parent;
# endif
};
# if !defined(__DOXYGEN_PROCESSOR__)
struct it_recursion_node {
// ***********************
public:
/* this structure stores the information needed when we take the */
/* right branch in searching for intervals but possibly come back */
/* and check the left branch as well. */
IntervalTreeNode * start_node;
unsigned long parentIndex;
long tryRightBranch;
} ;
#endif
class IntervalTree {
// *****************
// constructors
// ************
public: IntervalTree();
// destructors
// ***********
public: ~IntervalTree();
// Prints
// ******
# if !defined(__DOXYGEN_PROCESSOR__)
public: void Print() const;
inline void * SafeMalloc(size_t size) {
void * result;
if ( (result = malloc(size)) ) { /* assignment intentional */
return(result);
} else {
char errorMessagePartOne [200];
char errorMessagePartTwo [200];
strcat(errorMessagePartOne,errorMessagePartTwo);
throw Error("Bad malloc");
return(0);
}
}
inline void * SafeCalloc(int numberOfElements , size_t size) {
void * result;
if ( (result = calloc(numberOfElements, size)) )
{ /* assignment intentional in above line */
return(result);
} else {
printf(" Exiting Program.\n");
throw Error("Bad calloc");
return(0);
}
}
// Operations
// **********
public : void FixUpMaxHigh(IntervalTreeNode * x) {
// *****************************************
while(x != root) {
x->maxHigh=ITMax(x->high,ITMax(x->left->maxHigh,x->right->maxHigh));
x=x->parent;
}
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#endif
};
protected: void LeftRotate(IntervalTreeNode* x) {
// ***********************************
IntervalTreeNode* y;
/* I originally wrote this function to use the sentinel for */
/* nil to avoid checking for nil. However this introduces a */
/* very subtle bug because sometimes this function modifies */
/* the parent pointer of nil. This can be a problem if a */
/* function which calls LeftRotate also uses the nil sentinel */
/* and expects the nil sentinel's parent pointer to be unchanged */
/* after calling this function. For example, when DeleteFixUP */
/* calls LeftRotate it expects the parent pointer of nil to be */
/* unchanged. */
y=x->right;
x->right=y->left;
if (y->left != nil) y->left->parent=x; /* used to use sentinel here */
/* and do an unconditional assignment instead of testing for nil */
y->parent=x->parent;
/* instead of checking if x->parent is the root as in the book, we */
/* count on the root sentinel to implicitly take care of this case */
if( x == x->parent->left) {
x->parent->left=y;
} else {
x->parent->right=y;
}
y->left=x;
x->parent=y;
x->maxHigh=ITMax(x->left->maxHigh,ITMax(x->right->maxHigh,x->high));
y->maxHigh=ITMax(x->maxHigh,ITMax(y->right->maxHigh,y->high));
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not red in ITLeftRotate");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITLeftRotate");
#endif
};
protected: void RightRotate(IntervalTreeNode* y) {
// ***************************************
IntervalTreeNode* x;
/* I originally wrote this function to use the sentinel for */
/* nil to avoid checking for nil. However this introduces a */
/* very subtle bug because sometimes this function modifies */
/* the parent pointer of nil. This can be a problem if a */
/* function which calls LeftRotate also uses the nil sentinel */
/* and expects the nil sentinel's parent pointer to be unchanged */
/* after calling this function. For example, when DeleteFixUP */
/* calls LeftRotate it expects the parent pointer of nil to be */
/* unchanged. */
x=y->left;
y->left=x->right;
if (nil != x->right) x->right->parent=y; /*used to use sentinel here */
/* and do an unconditional assignment instead of testing for nil */
/* instead of checking if x->parent is the root as in the book, we */
/* count on the root sentinel to implicitly take care of this case */
x->parent=y->parent;
if( y == y->parent->left) {
y->parent->left=x;
} else {
y->parent->right=x;
}
x->right=y;
y->parent=x;
y->maxHigh=ITMax(y->left->maxHigh,ITMax(y->right->maxHigh,y->high));
x->maxHigh=ITMax(x->left->maxHigh,ITMax(y->maxHigh,x->high));
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not red in ITRightRotate");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITRightRotate");
#endif
};
# endif
public: Interval * DeleteNode(IntervalTreeNode * z)
// *****************************************************
{
IntervalTreeNode* y;
IntervalTreeNode* x;
Interval * returnValue = z->storedInterval;
y= ((z->left == nil) || (z->right == nil)) ? z : GetSuccessorOf(z);
x= (y->left == nil) ? y->right : y->left;
if (root == (x->parent = y->parent)) { /* assignment of y->p to x->p is intentional */
root->left=x;
} else {
if (y == y->parent->left) {
y->parent->left=x;
} else {
y->parent->right=x;
}
}
if (y != z) { /* y should not be nil in this case */
#ifdef DEBUG_ASSERT
Assert( (y!=nil),"y is nil in DeleteNode \n");
#endif
/* y is the node to splice out and x is its child */
y->maxHigh = MIN_LONG;
y->left=z->left;
y->right=z->right;
y->parent=z->parent;
z->left->parent=z->right->parent=y;
if (z == z->parent->left) {
z->parent->left=y;
} else {
z->parent->right=y;
}
FixUpMaxHigh(x->parent);
if (!(y->red)) {
y->red = z->red;
DeleteFixUp(x);
} else
y->red = z->red;
delete z;
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not black in ITDelete");
Assert((nil->maxHigh=MIN_LONG),"nil->maxHigh != MIN_LONG in ITDelete");
#endif
} else {
FixUpMaxHigh(x->parent);
if (!(y->red)) DeleteFixUp(x);
delete y;
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not black in ITDelete");
Assert((nil->maxHigh=MIN_LONG),"nil->maxHigh != MIN_LONG in ITDelete");
#endif
}
return returnValue;
};
# if !defined(__DOXYGEN_PROCESSOR__)
protected: void TreeInsertHelp(IntervalTreeNode * z)
// **************************************
{
/* This function should only be called by InsertITTree (see above) */
IntervalTreeNode* x;
IntervalTreeNode* y;
z->left=z->right=nil;
y=root;
x=root->left;
while( x != nil) {
y=x;
if ( x->key > z->key) {
x=x->left;
} else { /* x->key <= z->key */
x=x->right;
}
}
z->parent=y;
if ( (y == root) ||
(y->key > z->key) ) {
y->left=z;
} else {
y->right=z;
}
#if defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not red in ITTreeInsertHelp");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITTreeInsertHelp");
#endif
};
protected: void DeleteFixUp(IntervalTreeNode * x)
// ***********************************
{
IntervalTreeNode * w;
IntervalTreeNode * rootLeft = root->left;
while( (!x->red) && (rootLeft != x)) {
if (x == x->parent->left) {
w=x->parent->right;
if (w->red) {
w->red=0;
x->parent->red=1;
LeftRotate(x->parent);
w=x->parent->right;
}
if ( (!w->right->red) && (!w->left->red) ) {
w->red=1;
x=x->parent;
} else {
if (!w->right->red) {
w->left->red=0;
w->red=1;
RightRotate(w);
w=x->parent->right;
}
w->red=x->parent->red;
x->parent->red=0;
w->right->red=0;
LeftRotate(x->parent);
x=rootLeft; /* this is to exit while loop */
}
} else { /* the code below is has left and right switched from above */
w=x->parent->left;
if (w->red) {
w->red=0;
x->parent->red=1;
RightRotate(x->parent);
w=x->parent->left;
}
if ( (!w->right->red) && (!w->left->red) ) {
w->red=1;
x=x->parent;
} else {
if (!w->left->red) {
w->right->red=0;
w->red=1;
LeftRotate(w);
w=x->parent->left;
}
w->red=x->parent->red;
x->parent->red=0;
w->left->red=0;
RightRotate(x->parent);
x=rootLeft; /* this is to exit while loop */
}
}
}
x->red=0;
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not black in ITDeleteFixUp");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITDeleteFixUp");
#endif
};
# endif
public: IntervalTreeNode * Insert(Interval * newInterval)
// **********************************************************
{
IntervalTreeNode * y;
IntervalTreeNode * x;
IntervalTreeNode * newNode;
x = new IntervalTreeNode(newInterval);
TreeInsertHelp(x);
FixUpMaxHigh(x->parent);
newNode = x;
x->red=1;
while(x->parent->red) { /* use sentinel instead of checking for root */
if (x->parent == x->parent->parent->left) {
y=x->parent->parent->right;
if (y->red) {
x->parent->red=0;
y->red=0;
x->parent->parent->red=1;
x=x->parent->parent;
} else {
if (x == x->parent->right) {
x=x->parent;
LeftRotate(x);
}
x->parent->red=0;
x->parent->parent->red=1;
RightRotate(x->parent->parent);
}
} else { /* case for x->parent == x->parent->parent->right */
/* this part is just like the section above with */
/* left and right interchanged */
y=x->parent->parent->left;
if (y->red) {
x->parent->red=0;
y->red=0;
x->parent->parent->red=1;
x=x->parent->parent;
} else {
if (x == x->parent->left) {
x=x->parent;
RightRotate(x);
}
x->parent->red=0;
x->parent->parent->red=1;
LeftRotate(x->parent->parent);
}
}
}
root->left->red=0;
return(newNode);
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not red in ITTreeInsert");
Assert(!root->red,"root not red in ITTreeInsert");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITTreeInsert");
#endif
};
/* The basic idea for the function below is to take the IntervalSearch */
/* function from the book and modify to find all overlapping intervals */
/* instead of just one. This means that any time we take the left */
/* branch down the tree we must also check the right branch if and only if */
/* we find an overlapping interval in that left branch. Note this is a */
/* recursive condition because if we go left at the root then go left */
/* again at the first left child and find an overlap in the left subtree */
/* of the left child of root we must recursively check the right subtree */
/* of the left child of root as well as the right child of root. */
public: stack<Interval *> * Enumerate(long low, long high)
// *****************************************************
{
stack<Interval *> * enumResultStack;
IntervalTreeNode* x=root->left;
long stuffToDo = (x != nil);
// Possible speed up: add min field to prune right searches //
#ifdef DEBUG_ASSERT
Assert((recursionNodeStackTop == 0),
"recursionStack not empty when entering IntervalTree::Enumerate");
#endif
currentParent = 0;
enumResultStack = new stack<Interval *>;
while(stuffToDo) {
if (Overlap(low,high,x->key,x->high) ) {
enumResultStack->push(x->storedInterval);
recursionNodeStack[currentParent].tryRightBranch=1;
}
if(x->left->maxHigh >= low) { // implies x != nil
if ( recursionNodeStackTop == recursionNodeStackSize ) {
recursionNodeStackSize *= 2;
recursionNodeStack = (it_recursion_node *)
realloc(recursionNodeStack,
recursionNodeStackSize * sizeof(it_recursion_node));
if (recursionNodeStack == NULL)
throw Error("realloc failed in IntervalTree::Enumerate\n");
}
recursionNodeStack[recursionNodeStackTop].start_node = x;
recursionNodeStack[recursionNodeStackTop].tryRightBranch = 0;
recursionNodeStack[recursionNodeStackTop].parentIndex = currentParent;
currentParent = recursionNodeStackTop++;
x = x->left;
} else {
x = x->right;
}
stuffToDo = (x != nil);
while( (!stuffToDo) && (recursionNodeStackTop > 1) ) {
if(recursionNodeStack[--recursionNodeStackTop].tryRightBranch) {
x=recursionNodeStack[recursionNodeStackTop].start_node->right;
currentParent=recursionNodeStack[recursionNodeStackTop].parentIndex;
recursionNodeStack[currentParent].tryRightBranch=1;
stuffToDo = ( x != nil);
}
}
}
#ifdef DEBUG_ASSERT
Assert((recursionNodeStackTop == 1),
"recursionStack not empty when exiting IntervalTree::Enumerate");
#endif
return(enumResultStack);
};
# if !defined(__DOXYGEN_PROCESSOR__)
protected: void CheckAssumptions() const;
/* A sentinel is used for root and for nil. These sentinels are */
/* created when ITTreeCreate is caled. root->left should always */
/* point to the node which is the root of the tree. nil points to a */
/* node which should always be black but has aribtrary children and */
/* parent and no key or info. The point of using these sentinels is so */
/* that the root and nil nodes do not require special cases in the code */
protected: IntervalTreeNode * root;
protected: IntervalTreeNode * nil;
public: IntervalTreeNode * GetPredecessorOf(IntervalTreeNode *) const;
public: IntervalTreeNode * GetSuccessorOf(IntervalTreeNode * ) const;
protected: void TreePrintHelper(IntervalTreeNode *) const;
protected: void CheckMaxHighFields(IntervalTreeNode *) const;
protected: long CheckMaxHighFieldsHelper(IntervalTreeNode * y,
const long currentHigh,
long match) const;
// Attributs
// *********
private: unsigned long recursionNodeStackSize;
private: it_recursion_node * recursionNodeStack;
private: unsigned long currentParent;
private: unsigned long recursionNodeStackTop;
# endif
};
} // end of namespace
#endif

View File

@ -0,0 +1,166 @@
#ifndef INC_E_MISC_DOT_H
#define INC_E_MISC_DOT_H
#include<stdio.h>
#include<stdlib.h>
#include<sys/unistd.h>
#include<unistd.h>
//#include<strings.h>
#include<string.h>
namespace EQUINOX {
/* CONVENTIONS */
/* */
/* Function names: Each word in a function name begins with */
/* a capital letter. An example funcntion name is */
/* CreateRedTree(a,b,c). Furthermore, each function name */
/* should begin with a capital letter to easily distinguish */
/* them from variables. */
/* */
/* Variable names: Each word in a variable name begins with */
/* a capital letter EXCEPT the first letter of the variable */
/* name. For example, int newLongInt. Global variables have */
/* names beginning with "g" or "global:. */
/* An example of a global variable name is gNewtonsConstant. */
// The ExitProgramMacro is used to exit the program when a
// catastrophe occurs (e.g. assertion failure). You can define
// your own version of the ExitProgramMacro to dump core, log
// things or do something else that you want. If the symbol
// ExitProgramMacro is not defined though, then a default
// definition is created.
#ifndef ExitProgramMacro
#define ExitProgramMacro(a) { \
printf("Error: "); printf(a); \
printf("Exiting from line %i in file %s\n",__LINE__,__FILE__); \
printf("\nCausing Segmentation Fault to exit ungracefully\n"); \
int * junk = NULL; (*junk)++;\
printf("%p\n",junk);}
// printf("%i\n",(int)junk);}
#endif /* ends #ifndef ExitProgramMacro */
#define VERIFY(condition) \
if (!(condition)) { \
fprintf(stderr, "Assumption \"%s\"\nFailed in file %s: at line:%i\n", \
#condition,__FILE__,__LINE__); \
ExitProgramMacro(#condition);}
#ifdef CHECK_ASSUMPTIONS
#define ASSUME(x) VERIFY(x)
#else
#define ASSUME(x) ;
#endif
/***********************************************************************/
/* FUNCTION: void Assert(int assertion, char* error) */
/**/
/* INPUTS: assertion should be a predicated that the programmer */
/* assumes to be true. If this assumption is not true the message */
/* error is printed and the program exits. */
/**/
/* OUTPUT: None. */
/**/
/* Modifies input: none */
/**/
/* Note: If DEBUG_ASSERT is not defined then assertions should not */
/* be in use as they will slow down the code. Therefore the */
/* compiler will complain if an assertion is used when */
/* DEBUG_ASSERT is undefined. */
/***********************************************************************/
inline void Assert(int assertion, char* error) {
if(!assertion) {
printf("Assertion Failed: %s\n",error);
ExitProgramMacro("Exiting From Function Assert(...)\n");
}
}
/***********************************************************************/
/* FUNCTION: SafeMalloc */
/**/
/* INPUTS: size is the size to malloc */
/**/
/* OUTPUT: returns pointer to allocated memory if succesful */
/**/
/* EFFECT: mallocs new memory. If malloc fails, prints error message */
/* and terminates program. */
/**/
/* Modifies Input: none */
/**/
/***********************************************************************/
inline void * SafeMalloc(size_t size) {
void * result;
if ( (result = malloc(size)) ) { /* assignment intentional */
return(result);
} else {
char errorMessagePartOne [200];
char errorMessagePartTwo [200];
sprintf(errorMessagePartOne,
"Exiting From SafeMalloc because malloc of size %i failed.\n",
size);
sprintf(errorMessagePartTwo,
"Calling sbrk(0) gives %x\n",(long)sbrk(0));
strcat(errorMessagePartOne,errorMessagePartTwo);
ExitProgramMacro(errorMessagePartOne);
return(0);
}
}
/***********************************************************************/
/* FUNCTION: SafeCalloc */
/**/
/* INPUTS: size is the size to calloc */
/**/
/* OUTPUT: returns pointer to allocated memory if succesful */
/**/
/* EFFECT: callocs new memory. If calloc fails, prints error message */
/* and terminates program. */
/**/
/* Modifies Input: none */
/**/
/***********************************************************************/
inline void * SafeCalloc(int numberOfElements , size_t size) {
void * result;
if ( (result = calloc(numberOfElements, size)) )
{ /* assignment intentional in above line */
return(result);
} else {
printf("memory overflow: calloc failed in SafeCalloc(%i,%i).",
numberOfElements, size);
printf("sbrk(0) gives %x\n",(long)sbrk(0));
printf(" Exiting Program.\n");
ExitProgramMacro("Exiting From Function SafeCalloc(...)\n");
return(0);
}
}
/* NullFunction does nothing it is included so that it can be passed */
/* as a function to RBTreeCreate when no other suitable function has */
/* been defined */
inline void NullFunction(void * ) { ; }
inline void NullFunction(const void * ) { ; }
}
#endif

View File

@ -0,0 +1,410 @@
#include <stdio.h>
#include <math.h>
// If the symbol CHECK_INTERVAL_TREE_ASSUMPTIONS is defined then the
// code does a lot of extra checking to make sure certain assumptions
// are satisfied. This only needs to be done if you suspect bugs are
// present or if you make significant changes and want to make sure
// your changes didn't mess anything up.
// #define CHECK_INTERVAL_TREE_ASSUMPTIONS 1
using namespace std;
#include "equinox/IntervalTree.h"
namespace Equinox {
//long MIN_LONG=-MAX_LONG;
// define a function to find the maximum of two objects.
#define ITMax(a, b) ( (a > b) ? a : b )
IntervalTreeNode::IntervalTreeNode(){
};
IntervalTreeNode::IntervalTreeNode(Interval * newInterval)
: storedInterval (newInterval) ,
key(newInterval->GetLowPoint()),
high(newInterval->GetHighPoint()) ,
maxHigh(high) {
};
IntervalTreeNode::~IntervalTreeNode(){
};
Interval::Interval(){
};
Interval::~Interval(){
};
void Interval::Print() const {
cout << "No Print Method defined for instance of Interval" << endl;
}
IntervalTree::IntervalTree()
{
nil = new IntervalTreeNode;
nil->left = nil->right = nil->parent = nil;
nil->red = 0;
nil->key = nil->high = nil->maxHigh = MIN_LONG;
nil->storedInterval = NULL;
root = new IntervalTreeNode;
root->parent = root->left = root->right = nil;
root->key = root->high = root->maxHigh = MAX_LONG;
root->red=0;
root->storedInterval = NULL;
/* the following are used for the Enumerate function */
recursionNodeStackSize = 128;
recursionNodeStack = (it_recursion_node *)
SafeMalloc(recursionNodeStackSize*sizeof(it_recursion_node));
recursionNodeStackTop = 1;
recursionNodeStack[0].start_node = NULL;
}
/***********************************************************************/
/* FUNCTION: LeftRotate */
/**/
/* INPUTS: the node to rotate on */
/**/
/* OUTPUT: None */
/**/
/* Modifies Input: this, x */
/**/
/* EFFECTS: Rotates as described in _Introduction_To_Algorithms by */
/* Cormen, Leiserson, Rivest (Chapter 14). Basically this */
/* makes the parent of x be to the left of x, x the parent of */
/* its parent before the rotation and fixes other pointers */
/* accordingly. Also updates the maxHigh fields of x and y */
/* after rotation. */
/***********************************************************************/
/***********************************************************************/
/* FUNCTION: RighttRotate */
/**/
/* INPUTS: node to rotate on */
/**/
/* OUTPUT: None */
/**/
/* Modifies Input?: this, y */
/**/
/* EFFECTS: Rotates as described in _Introduction_To_Algorithms by */
/* Cormen, Leiserson, Rivest (Chapter 14). Basically this */
/* makes the parent of x be to the left of x, x the parent of */
/* its parent before the rotation and fixes other pointers */
/* accordingly. Also updates the maxHigh fields of x and y */
/* after rotation. */
/***********************************************************************/
/***********************************************************************/
/* FUNCTION: TreeInsertHelp */
/**/
/* INPUTS: z is the node to insert */
/**/
/* OUTPUT: none */
/**/
/* Modifies Input: this, z */
/**/
/* EFFECTS: Inserts z into the tree as if it were a regular binary tree */
/* using the algorithm described in _Introduction_To_Algorithms_ */
/* by Cormen et al. This funciton is only intended to be called */
/* by the InsertTree function and not by the user */
/***********************************************************************/
/***********************************************************************/
/* FUNCTION: FixUpMaxHigh */
/**/
/* INPUTS: x is the node to start from*/
/**/
/* OUTPUT: none */
/**/
/* Modifies Input: this */
/**/
/* EFFECTS: Travels up to the root fixing the maxHigh fields after */
/* an insertion or deletion */
/***********************************************************************/
/* Before calling InsertNode the node x should have its key set */
/***********************************************************************/
/* FUNCTION: InsertNode */
/**/
/* INPUTS: newInterval is the interval to insert*/
/**/
/* OUTPUT: This function returns a pointer to the newly inserted node */
/* which is guarunteed to be valid until this node is deleted. */
/* What this means is if another data structure stores this */
/* pointer then the tree does not need to be searched when this */
/* is to be deleted. */
/**/
/* Modifies Input: tree */
/**/
/* EFFECTS: Creates a node node which contains the appropriate key and */
/* info pointers and inserts it into the tree. */
/***********************************************************************/
/***********************************************************************/
/* FUNCTION: GetSuccessorOf */
/**/
/* INPUTS: x is the node we want the succesor of */
/**/
/* OUTPUT: This function returns the successor of x or NULL if no */
/* successor exists. */
/**/
/* Modifies Input: none */
/**/
/* Note: uses the algorithm in _Introduction_To_Algorithms_ */
/***********************************************************************/
IntervalTreeNode * IntervalTree::GetSuccessorOf(IntervalTreeNode * x) const
// ***********************************************************************
{
IntervalTreeNode* y;
if (nil!= (y = x->right)) { /* assignment to y is intentional */
while(y->left != nil) { /* returns the minium of the right subtree of x */
y=y->left;
}
return(y);
} else {
y=x->parent;
while(x == y->right) { /* sentinel used instead of checking for nil */
x=y;
y=y->parent;
}
if (y == root) return(nil);
return(y);
}
}
/***********************************************************************/
/* FUNCTION: GetPredecessorOf */
/**/
/* INPUTS: x is the node to get predecessor of */
/**/
/* OUTPUT: This function returns the predecessor of x or NULL if no */
/* predecessor exists. */
/**/
/* Modifies Input: none */
/**/
/* Note: uses the algorithm in _Introduction_To_Algorithms_ */
/***********************************************************************/
IntervalTreeNode * IntervalTree::GetPredecessorOf(IntervalTreeNode * x) const {
IntervalTreeNode* y;
if (nil != (y = x->left)) { /* assignment to y is intentional */
while(y->right != nil) { /* returns the maximum of the left subtree of x */
y=y->right;
}
return(y);
} else {
y=x->parent;
while(x == y->left) {
if (y == root) return(nil);
x=y;
y=y->parent;
}
return(y);
}
}
/***********************************************************************/
/* FUNCTION: Print */
/**/
/* INPUTS: none */
/**/
/* OUTPUT: none */
/**/
/* EFFECTS: This function recursively prints the nodes of the tree */
/* inorder. */
/**/
/* Modifies Input: none */
/**/
/* Note: This function should only be called from ITTreePrint */
/***********************************************************************/
void IntervalTreeNode::Print(IntervalTreeNode * nil,
IntervalTreeNode * root) const {
storedInterval->Print();
printf(", k=%li, h=%li, mH=%li",key,high,maxHigh);
printf(" l->key=");
if( left == nil) printf("NULL"); else printf("%li",left->key);
printf(" r->key=");
if( right == nil) printf("NULL"); else printf("%li",right->key);
printf(" p->key=");
if( parent == root) printf("NULL"); else printf("%li",parent->key);
printf(" red=%li\n",red);
}
void IntervalTree::TreePrintHelper( IntervalTreeNode* x) const {
if (x != nil) {
TreePrintHelper(x->left);
x->Print(nil,root);
TreePrintHelper(x->right);
}
}
IntervalTree::~IntervalTree() {
IntervalTreeNode * x = root->left;
stack<IntervalTreeNode *> stuffToFree;
if (x != nil) {
if (x->left != nil) {
stuffToFree.push(x->left);
}
if (x->right != nil) {
stuffToFree.push(x->right);
}
// delete x->storedInterval;
delete x;
while(!stuffToFree.empty() ) {
x = stuffToFree.top();
stuffToFree.pop();
if (x->left != nil) {
stuffToFree.push(x->left);
}
if (x->right != nil) {
stuffToFree.push(x->right);
}
// delete x->storedInterval;
delete x;
}
}
delete nil;
delete root;
free(recursionNodeStack);
}
/***********************************************************************/
/* FUNCTION: Print */
/**/
/* INPUTS: none */
/**/
/* OUTPUT: none */
/**/
/* EFFECT: This function recursively prints the nodes of the tree */
/* inorder. */
/**/
/* Modifies Input: none */
/**/
/***********************************************************************/
void IntervalTree::Print() const {
TreePrintHelper(root->left);
}
/***********************************************************************/
/* FUNCTION: DeleteFixUp */
/**/
/* INPUTS: x is the child of the spliced */
/* out node in DeleteNode. */
/**/
/* OUTPUT: none */
/**/
/* EFFECT: Performs rotations and changes colors to restore red-black */
/* properties after a node is deleted */
/**/
/* Modifies Input: this, x */
/**/
/* The algorithm from this function is from _Introduction_To_Algorithms_ */
/***********************************************************************/
/***********************************************************************/
/* FUNCTION: DeleteNode */
/**/
/* INPUTS: tree is the tree to delete node z from */
/**/
/* OUTPUT: returns the Interval stored at deleted node */
/**/
/* EFFECT: Deletes z from tree and but don't call destructor */
/* Then calls FixUpMaxHigh to fix maxHigh fields then calls */
/* ITDeleteFixUp to restore red-black properties */
/**/
/* Modifies Input: z */
/**/
/* The algorithm from this function is from _Introduction_To_Algorithms_ */
/***********************************************************************/
/***********************************************************************/
/* FUNCTION: Enumerate */
/**/
/* INPUTS: tree is the tree to look for intervals overlapping the */
/* closed interval [low,high] */
/**/
/* OUTPUT: stack containing pointers to the nodes overlapping */
/* [low,high] */
/**/
/* Modifies Input: none */
/**/
/* EFFECT: Returns a stack containing pointers to nodes containing */
/* intervals which overlap [low,high] in O(max(N,k*log(N))) */
/* where N is the number of intervals in the tree and k is */
/* the number of overlapping intervals */
/**/
/* Note: This basic idea for this function comes from the */
/* _Introduction_To_Algorithms_ book by Cormen et al, but */
/* modifications were made to return all overlapping intervals */
/* instead of just the first overlapping interval as in the */
/* book. The natural way to do this would require recursive */
/* calls of a basic search function. I translated the */
/* recursive version into an interative version with a stack */
/* as described below. */
/***********************************************************************/
long IntervalTree::CheckMaxHighFieldsHelper(IntervalTreeNode * y,
const long currentHigh,
long match) const
{
if (y != nil) {
match = CheckMaxHighFieldsHelper(y->left,currentHigh,match) ?
1 : match;
if (y->high == currentHigh)
match = 1;
match = CheckMaxHighFieldsHelper(y->right,currentHigh,match) ?
1 : match;
}
return match;
}
/* Make sure the maxHigh fields for everything makes sense. *
* If something is wrong, print a warning and exit */
void IntervalTree::CheckMaxHighFields(IntervalTreeNode * x) const {
if (x != nil) {
CheckMaxHighFields(x->left);
if(!(CheckMaxHighFieldsHelper(x,x->maxHigh,0) > 0)) {
throw Error("pouet");
}
CheckMaxHighFields(x->right);
}
}
void IntervalTree::CheckAssumptions() const {
CheckMaxHighFields(root->left);
}
} // end of namespace

View File

@ -0,0 +1,54 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | E q u i n o x - E x t r a c t o r |
// | |
// | Author : Wu Yife |
// | E-mail : Wu.Yifei@lip6.fr |
// | |
// | Updater : Bodin bruno |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./equinox/Interval.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __EQUINOX_INTERVAL__
#define __EQUINOX_INTERVAL__
namespace Equinox {
// -------------------------------------------------------------------
// Class : "EQUINOX::Interval".
class Interval {
public:
/**/ Interval ();
/**/ virtual ~Interval ();
/**/ virtual long GetLowPoint () const = 0;
/**/ virtual long GetHighPoint () const = 0;
/**/ virtual void Print () const;
};
} // end of namespace
#endif //__EQUINOX_INTERVAL__

View File

@ -0,0 +1,625 @@
//#ifndef E_INTERVAL_TREE
//#define E_INTERVAL_TREE
#ifndef INTERVALTREE_H
#define INTERVALTREE_H
#include<math.h>
#include<limits.h>
#include<iostream>
#include<stack>
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <hurricane/Error.h>
#include <equinox/Interval.h>
// The interval_tree.h and interval_tree.cc files contain code for
// interval trees implemented using red-black-trees as described in
// the book _Introduction_To_Algorithms_ by Cormen, Leisserson,
// and Rivest.
// CONVENTIONS:
// Function names: Each word in a function name begins with
// a capital letter. An example funcntion name is
// CreateRedTree(a,b,c). Furthermore, each function name
// should begin with a capital letter to easily distinguish
// them from variables.
//
// Variable names: Each word in a variable name begins with
// a capital letter EXCEPT the first letter of the variable
// name. For example, int newLongInt. Global variables have
// names beginning with "g". An example of a global
// variable name is gNewtonsConstant.
#ifndef MAX_LONG
#define MAX_LONG LONG_MAX // some architechturs define INT_MAX not MAX_INT
#define MIN_LONG -MAX_LONG
#endif
#define ITMax(a, b) ( (a > b) ? a : b )
//#ifndef MAX_INT
//#define MAX_INT INT_MAX // some architechturs define INT_MAX not MAX_INT
//#endif
// The Interval class is an Abstract Base Class. This means that no
// instance of the Interval class can exist. Only classes which
// inherit from the Interval class can exist. Furthermore any class
// which inherits from the Interval class must define the member
// functions GetLowPoint and GetHighPoint.
//
// The GetLowPoint should return the lowest point of the interval and
// the GetHighPoint should return the highest point of the interval.
namespace Equinox {
using std::stack;
using Hurricane::Error;
# if !defined(__DOXYGEN_PROCESSOR__)
static inline bool Overlap(long& a1, long& a2, long& b1, long& b2) {
// *****************************************************************
if (a1 <= b1) {
return( (b1 <= a2) );
} else {
return( (a1 <= b2) );
}
}
#endif
class IntervalTreeNode {
// *********************
friend class IntervalTree;
public:
IntervalTreeNode(Interval * );
# if !defined(__DOXYGEN_PROCESSOR__)
void Print(IntervalTreeNode*, IntervalTreeNode*) const;
IntervalTreeNode();
~IntervalTreeNode();
protected:
Interval * storedInterval;
long key;
long high;
long maxHigh;
long red; /* if red=0 then the node is black */
IntervalTreeNode * left;
IntervalTreeNode * right;
IntervalTreeNode * parent;
# endif
};
# if !defined(__DOXYGEN_PROCESSOR__)
struct it_recursion_node {
// ***********************
public:
/* this structure stores the information needed when we take the */
/* right branch in searching for intervals but possibly come back */
/* and check the left branch as well. */
IntervalTreeNode * start_node;
unsigned long parentIndex;
long tryRightBranch;
} ;
#endif
class IntervalTree {
// *****************
// constructors
// ************
public: IntervalTree();
// destructors
// ***********
public: ~IntervalTree();
// Prints
// ******
# if !defined(__DOXYGEN_PROCESSOR__)
public: void Print() const;
inline void * SafeMalloc(size_t size) {
void * result;
if ( (result = malloc(size)) ) { /* assignment intentional */
return(result);
} else {
char errorMessagePartOne [200];
char errorMessagePartTwo [200];
strcat(errorMessagePartOne,errorMessagePartTwo);
throw Error("Bad malloc");
return(0);
}
}
inline void * SafeCalloc(int numberOfElements , size_t size) {
void * result;
if ( (result = calloc(numberOfElements, size)) )
{ /* assignment intentional in above line */
return(result);
} else {
printf(" Exiting Program.\n");
throw Error("Bad calloc");
return(0);
}
}
// Operations
// **********
public : void FixUpMaxHigh(IntervalTreeNode * x) {
// *****************************************
while(x != root) {
x->maxHigh=ITMax(x->high,ITMax(x->left->maxHigh,x->right->maxHigh));
x=x->parent;
}
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#endif
};
protected: void LeftRotate(IntervalTreeNode* x) {
// ***********************************
IntervalTreeNode* y;
/* I originally wrote this function to use the sentinel for */
/* nil to avoid checking for nil. However this introduces a */
/* very subtle bug because sometimes this function modifies */
/* the parent pointer of nil. This can be a problem if a */
/* function which calls LeftRotate also uses the nil sentinel */
/* and expects the nil sentinel's parent pointer to be unchanged */
/* after calling this function. For example, when DeleteFixUP */
/* calls LeftRotate it expects the parent pointer of nil to be */
/* unchanged. */
y=x->right;
x->right=y->left;
if (y->left != nil) y->left->parent=x; /* used to use sentinel here */
/* and do an unconditional assignment instead of testing for nil */
y->parent=x->parent;
/* instead of checking if x->parent is the root as in the book, we */
/* count on the root sentinel to implicitly take care of this case */
if( x == x->parent->left) {
x->parent->left=y;
} else {
x->parent->right=y;
}
y->left=x;
x->parent=y;
x->maxHigh=ITMax(x->left->maxHigh,ITMax(x->right->maxHigh,x->high));
y->maxHigh=ITMax(x->maxHigh,ITMax(y->right->maxHigh,y->high));
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not red in ITLeftRotate");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITLeftRotate");
#endif
};
protected: void RightRotate(IntervalTreeNode* y) {
// ***************************************
IntervalTreeNode* x;
/* I originally wrote this function to use the sentinel for */
/* nil to avoid checking for nil. However this introduces a */
/* very subtle bug because sometimes this function modifies */
/* the parent pointer of nil. This can be a problem if a */
/* function which calls LeftRotate also uses the nil sentinel */
/* and expects the nil sentinel's parent pointer to be unchanged */
/* after calling this function. For example, when DeleteFixUP */
/* calls LeftRotate it expects the parent pointer of nil to be */
/* unchanged. */
x=y->left;
y->left=x->right;
if (nil != x->right) x->right->parent=y; /*used to use sentinel here */
/* and do an unconditional assignment instead of testing for nil */
/* instead of checking if x->parent is the root as in the book, we */
/* count on the root sentinel to implicitly take care of this case */
x->parent=y->parent;
if( y == y->parent->left) {
y->parent->left=x;
} else {
y->parent->right=x;
}
x->right=y;
y->parent=x;
y->maxHigh=ITMax(y->left->maxHigh,ITMax(y->right->maxHigh,y->high));
x->maxHigh=ITMax(x->left->maxHigh,ITMax(y->maxHigh,x->high));
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not red in ITRightRotate");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITRightRotate");
#endif
};
# endif
public: Interval * DeleteNode(IntervalTreeNode * z)
// *****************************************************
{
IntervalTreeNode* y;
IntervalTreeNode* x;
Interval * returnValue = z->storedInterval;
y= ((z->left == nil) || (z->right == nil)) ? z : GetSuccessorOf(z);
x= (y->left == nil) ? y->right : y->left;
if (root == (x->parent = y->parent)) { /* assignment of y->p to x->p is intentional */
root->left=x;
} else {
if (y == y->parent->left) {
y->parent->left=x;
} else {
y->parent->right=x;
}
}
if (y != z) { /* y should not be nil in this case */
#ifdef DEBUG_ASSERT
Assert( (y!=nil),"y is nil in DeleteNode \n");
#endif
/* y is the node to splice out and x is its child */
y->maxHigh = MIN_LONG;
y->left=z->left;
y->right=z->right;
y->parent=z->parent;
z->left->parent=z->right->parent=y;
if (z == z->parent->left) {
z->parent->left=y;
} else {
z->parent->right=y;
}
FixUpMaxHigh(x->parent);
if (!(y->red)) {
y->red = z->red;
DeleteFixUp(x);
} else
y->red = z->red;
delete z;
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not black in ITDelete");
Assert((nil->maxHigh=MIN_LONG),"nil->maxHigh != MIN_LONG in ITDelete");
#endif
} else {
FixUpMaxHigh(x->parent);
if (!(y->red)) DeleteFixUp(x);
delete y;
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not black in ITDelete");
Assert((nil->maxHigh=MIN_LONG),"nil->maxHigh != MIN_LONG in ITDelete");
#endif
}
return returnValue;
};
# if !defined(__DOXYGEN_PROCESSOR__)
protected: void TreeInsertHelp(IntervalTreeNode * z)
// **************************************
{
/* This function should only be called by InsertITTree (see above) */
IntervalTreeNode* x;
IntervalTreeNode* y;
z->left=z->right=nil;
y=root;
x=root->left;
while( x != nil) {
y=x;
if ( x->key > z->key) {
x=x->left;
} else { /* x->key <= z->key */
x=x->right;
}
}
z->parent=y;
if ( (y == root) ||
(y->key > z->key) ) {
y->left=z;
} else {
y->right=z;
}
#if defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not red in ITTreeInsertHelp");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITTreeInsertHelp");
#endif
};
protected: void DeleteFixUp(IntervalTreeNode * x)
// ***********************************
{
IntervalTreeNode * w;
IntervalTreeNode * rootLeft = root->left;
while( (!x->red) && (rootLeft != x)) {
if (x == x->parent->left) {
w=x->parent->right;
if (w->red) {
w->red=0;
x->parent->red=1;
LeftRotate(x->parent);
w=x->parent->right;
}
if ( (!w->right->red) && (!w->left->red) ) {
w->red=1;
x=x->parent;
} else {
if (!w->right->red) {
w->left->red=0;
w->red=1;
RightRotate(w);
w=x->parent->right;
}
w->red=x->parent->red;
x->parent->red=0;
w->right->red=0;
LeftRotate(x->parent);
x=rootLeft; /* this is to exit while loop */
}
} else { /* the code below is has left and right switched from above */
w=x->parent->left;
if (w->red) {
w->red=0;
x->parent->red=1;
RightRotate(x->parent);
w=x->parent->left;
}
if ( (!w->right->red) && (!w->left->red) ) {
w->red=1;
x=x->parent;
} else {
if (!w->left->red) {
w->right->red=0;
w->red=1;
LeftRotate(w);
w=x->parent->left;
}
w->red=x->parent->red;
x->parent->red=0;
w->left->red=0;
RightRotate(x->parent);
x=rootLeft; /* this is to exit while loop */
}
}
}
x->red=0;
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not black in ITDeleteFixUp");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITDeleteFixUp");
#endif
};
# endif
public: IntervalTreeNode * Insert(Interval * newInterval)
// **********************************************************
{
IntervalTreeNode * y;
IntervalTreeNode * x;
IntervalTreeNode * newNode;
x = new IntervalTreeNode(newInterval);
TreeInsertHelp(x);
FixUpMaxHigh(x->parent);
newNode = x;
x->red=1;
while(x->parent->red) { /* use sentinel instead of checking for root */
if (x->parent == x->parent->parent->left) {
y=x->parent->parent->right;
if (y->red) {
x->parent->red=0;
y->red=0;
x->parent->parent->red=1;
x=x->parent->parent;
} else {
if (x == x->parent->right) {
x=x->parent;
LeftRotate(x);
}
x->parent->red=0;
x->parent->parent->red=1;
RightRotate(x->parent->parent);
}
} else { /* case for x->parent == x->parent->parent->right */
/* this part is just like the section above with */
/* left and right interchanged */
y=x->parent->parent->left;
if (y->red) {
x->parent->red=0;
y->red=0;
x->parent->parent->red=1;
x=x->parent->parent;
} else {
if (x == x->parent->left) {
x=x->parent;
RightRotate(x);
}
x->parent->red=0;
x->parent->parent->red=1;
LeftRotate(x->parent->parent);
}
}
}
root->left->red=0;
return(newNode);
#ifdef CHECK_INTERVAL_TREE_ASSUMPTIONS
CheckAssumptions();
#elif defined(DEBUG_ASSERT)
Assert(!nil->red,"nil not red in ITTreeInsert");
Assert(!root->red,"root not red in ITTreeInsert");
Assert((nil->maxHigh=MIN_LONG),
"nil->maxHigh != MIN_LONG in ITTreeInsert");
#endif
};
/* The basic idea for the function below is to take the IntervalSearch */
/* function from the book and modify to find all overlapping intervals */
/* instead of just one. This means that any time we take the left */
/* branch down the tree we must also check the right branch if and only if */
/* we find an overlapping interval in that left branch. Note this is a */
/* recursive condition because if we go left at the root then go left */
/* again at the first left child and find an overlap in the left subtree */
/* of the left child of root we must recursively check the right subtree */
/* of the left child of root as well as the right child of root. */
public: stack<Interval *> * Enumerate(long low, long high)
// *****************************************************
{
stack<Interval *> * enumResultStack;
IntervalTreeNode* x=root->left;
long stuffToDo = (x != nil);
// Possible speed up: add min field to prune right searches //
#ifdef DEBUG_ASSERT
Assert((recursionNodeStackTop == 0),
"recursionStack not empty when entering IntervalTree::Enumerate");
#endif
currentParent = 0;
enumResultStack = new stack<Interval *>;
while(stuffToDo) {
if (Overlap(low,high,x->key,x->high) ) {
enumResultStack->push(x->storedInterval);
recursionNodeStack[currentParent].tryRightBranch=1;
}
if(x->left->maxHigh >= low) { // implies x != nil
if ( recursionNodeStackTop == recursionNodeStackSize ) {
recursionNodeStackSize *= 2;
recursionNodeStack = (it_recursion_node *)
realloc(recursionNodeStack,
recursionNodeStackSize * sizeof(it_recursion_node));
if (recursionNodeStack == NULL)
throw Error("realloc failed in IntervalTree::Enumerate\n");
}
recursionNodeStack[recursionNodeStackTop].start_node = x;
recursionNodeStack[recursionNodeStackTop].tryRightBranch = 0;
recursionNodeStack[recursionNodeStackTop].parentIndex = currentParent;
currentParent = recursionNodeStackTop++;
x = x->left;
} else {
x = x->right;
}
stuffToDo = (x != nil);
while( (!stuffToDo) && (recursionNodeStackTop > 1) ) {
if(recursionNodeStack[--recursionNodeStackTop].tryRightBranch) {
x=recursionNodeStack[recursionNodeStackTop].start_node->right;
currentParent=recursionNodeStack[recursionNodeStackTop].parentIndex;
recursionNodeStack[currentParent].tryRightBranch=1;
stuffToDo = ( x != nil);
}
}
}
#ifdef DEBUG_ASSERT
Assert((recursionNodeStackTop == 1),
"recursionStack not empty when exiting IntervalTree::Enumerate");
#endif
return(enumResultStack);
};
# if !defined(__DOXYGEN_PROCESSOR__)
protected: void CheckAssumptions() const;
/* A sentinel is used for root and for nil. These sentinels are */
/* created when ITTreeCreate is caled. root->left should always */
/* point to the node which is the root of the tree. nil points to a */
/* node which should always be black but has aribtrary children and */
/* parent and no key or info. The point of using these sentinels is so */
/* that the root and nil nodes do not require special cases in the code */
protected: IntervalTreeNode * root;
protected: IntervalTreeNode * nil;
public: IntervalTreeNode * GetPredecessorOf(IntervalTreeNode *) const;
public: IntervalTreeNode * GetSuccessorOf(IntervalTreeNode * ) const;
protected: void TreePrintHelper(IntervalTreeNode *) const;
protected: void CheckMaxHighFields(IntervalTreeNode *) const;
protected: long CheckMaxHighFieldsHelper(IntervalTreeNode * y,
const long currentHigh,
long match) const;
// Attributs
// *********
private: unsigned long recursionNodeStackSize;
private: it_recursion_node * recursionNodeStack;
private: unsigned long currentParent;
private: unsigned long recursionNodeStackTop;
# endif
};
} // end of namespace
#endif