* ./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:
parent
5dd8cb502a
commit
a1726771b6
|
@ -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)
|
|
@ -0,0 +1 @@
|
|||
install ( FILES FindEQUINOX.cmake DESTINATION /share/cmake_modules )
|
|
@ -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)
|
||||
|
|
@ -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)
|
|
@ -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 )
|
||||
|
||||
|
|
@ -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
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -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.
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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*>;
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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__
|
|
@ -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__
|
|
@ -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__
|
|
@ -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__
|
|
@ -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__
|
|
@ -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__
|
|
@ -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__
|
|
@ -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
|
|
@ -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
|
|
@ -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__
|
|
@ -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
|
|
@ -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__
|
|
@ -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__
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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__
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue