* ./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