Implementation of a red-black tree and an interval tree.
* New: In Hurricane::RbTree, template for red-black tree. Standard implementation but well integrated in the Hurricane database and ready to be derived (both iterator and Collection support). * New: In Hurricane::IntervalTree, template for interval tree, derived from RbTree. * New: unittests tool to perform unit tests. * Change: In Bora::ChannelRouting, now implemented with IntervalTree. There is something suspicious here : the "thick" version of addWireoccupation() seems never to be called. Have to check the wide wire support implementation.
This commit is contained in:
parent
ac51ac3910
commit
c76fa034ba
|
@ -502,6 +502,7 @@ namespace Anabatic {
|
|||
public:
|
||||
inline bool isBipoint () const;
|
||||
inline bool isSourceVertex ( Vertex* ) const;
|
||||
inline Net* getNet () const;
|
||||
inline bool isTargetVertex ( Vertex* ) const;
|
||||
inline DbU::Unit getSearchAreaHalo () const;
|
||||
template<typename DistanceT>
|
||||
|
@ -542,7 +543,6 @@ namespace Anabatic {
|
|||
void _initiateUpdateIntervals ( Vertex* );
|
||||
bool _updateIntervals ( bool&, Vertex*, bool&, int&, Edge* );
|
||||
void _updateRealOccupancy ( Vertex* );
|
||||
|
||||
private:
|
||||
AnabaticEngine* _anabatic;
|
||||
vector<Vertex*> _vertexes;
|
||||
|
@ -566,6 +566,7 @@ namespace Anabatic {
|
|||
inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); }
|
||||
inline bool Dijkstra::isSourceVertex ( Vertex* v ) const { return (_sources.find(v) != _sources.end()); }
|
||||
inline bool Dijkstra::isTargetVertex ( Vertex* v ) const { return (_targets.find(v) != _targets.end()); }
|
||||
inline Net* Dijkstra::getNet () const { return _net; }
|
||||
inline DbU::Unit Dijkstra::getSearchAreaHalo () const { return _searchAreaHalo; }
|
||||
inline void Dijkstra::setSearchAreaHalo ( DbU::Unit halo ) { _searchAreaHalo = halo; }
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ projects = [
|
|||
, "cumulus"
|
||||
, "stratus1"
|
||||
, "documentation"
|
||||
, "unittests"
|
||||
]
|
||||
, 'repository': 'ssh://asim-t/users/largo2/git/coriolis.git' }
|
||||
]
|
||||
|
|
|
@ -229,7 +229,7 @@ namespace Bora {
|
|||
if ( not (state and state->isSymSlave()) ) {
|
||||
slicingtree->setVertexRestriction( net, katana );
|
||||
dijkstra->run();
|
||||
slicingtree->updateWireOccupation( dijkstra->getSources() );
|
||||
slicingtree->updateWireOccupation( dijkstra );
|
||||
}
|
||||
}
|
||||
katana->setState( Anabatic::EngineState::EngineGlobalLoaded );
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace Bora {
|
|||
|
||||
|
||||
ChannelRouting::ChannelRouting ()
|
||||
: _wireIntervals()
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -48,16 +49,13 @@ namespace Bora {
|
|||
|
||||
void ChannelRouting::reset ()
|
||||
{
|
||||
_limits.clear();
|
||||
_counts.clear();
|
||||
_wireIntervals.clear();
|
||||
}
|
||||
|
||||
|
||||
int ChannelRouting::getMaxCount () const
|
||||
{
|
||||
int maxCount = 0;
|
||||
for ( int count : _counts ) maxCount = std::max( maxCount, count );
|
||||
return maxCount;
|
||||
return _wireIntervals.getThickness();
|
||||
}
|
||||
|
||||
|
||||
|
@ -68,92 +66,28 @@ namespace Bora {
|
|||
<< DbU::getValueString(xy2) << "] width:"
|
||||
<< w << endl;
|
||||
|
||||
for ( unsigned int i=0; i<w; ++i ) insertChannel( xy1, xy2 );
|
||||
for ( unsigned int i=0; i<w; ++i ) insertChannel( xy1, xy2, (Net*)NULL );
|
||||
}
|
||||
|
||||
|
||||
void ChannelRouting::insertChannel ( DbU::Unit xy1, DbU::Unit xy2 )
|
||||
void ChannelRouting::insertChannel ( DbU::Unit xy1, DbU::Unit xy2, Net* net )
|
||||
{
|
||||
cdebug_log(535,0) << "ChannelRouting::insertChannel(DbU::Unit,DbU::Unit) ["
|
||||
<< DbU::getValueString(xy1) << " : "
|
||||
<< DbU::getValueString(xy2) << "]" << endl;
|
||||
<< DbU::getValueString(xy2) << "] "
|
||||
<< net
|
||||
<< endl;
|
||||
|
||||
DbU::Unit min = xy1;
|
||||
DbU::Unit max = xy2;
|
||||
|
||||
if (_limits.empty()) {
|
||||
_limits.push_back( min );
|
||||
_limits.push_back( max );
|
||||
_counts.push_back( 1 );
|
||||
} else {
|
||||
if (max < _limits.front()) {
|
||||
_limits.insert( _limits.begin(), max );
|
||||
_limits.insert( _limits.begin(), min );
|
||||
_counts.insert( _counts.begin(), 0 );
|
||||
_counts.insert( _counts.begin(), 1 );
|
||||
} else if (min > _limits.back()) {
|
||||
_limits.push_back( min );
|
||||
_limits.push_back( max );
|
||||
_counts.push_back( 0 );
|
||||
_counts.push_back( 1 );
|
||||
} else {
|
||||
int index = 0;
|
||||
vector<DbU::Unit>::iterator itL = _limits.begin();
|
||||
vector<int>::iterator itC = _counts.begin();
|
||||
|
||||
if (min < (*itL)) {
|
||||
_limits.insert( itL, min );
|
||||
_counts.insert( itC, 1 );
|
||||
} else {
|
||||
while( ((*itL) < min) and (itL != _limits.end()) ) {
|
||||
itL++;
|
||||
index++;
|
||||
if (itC != _counts.end()) itC++;
|
||||
}
|
||||
|
||||
if ((*itL) != min) {
|
||||
_limits.insert( itL, min );
|
||||
_counts.insert( itC, *(itC-1) );
|
||||
itL = _limits.begin() + index;
|
||||
itC = _counts.begin() + index;
|
||||
}
|
||||
itL = _limits.begin() + index;
|
||||
itC = _counts.begin() + index;
|
||||
|
||||
while( ((*itL) < max) && (itL != _limits.end()) ){
|
||||
itL++;
|
||||
index++;
|
||||
if (itC != _counts.end()) {
|
||||
(*itC) += 1;
|
||||
itC++;
|
||||
}
|
||||
}
|
||||
if (itL != _limits.end()) {
|
||||
if ((*(itL)) > max){
|
||||
_limits.insert( itL, max );
|
||||
_counts.insert( itC, *(itC-1)-1 );
|
||||
}
|
||||
} else {
|
||||
if ((*(itL-1)) != max) {
|
||||
_limits.push_back( max );
|
||||
_counts.push_back( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_wireIntervals.insert( WireInterval(net,xy1,xy2) );
|
||||
}
|
||||
|
||||
|
||||
void ChannelRouting::print () const
|
||||
{
|
||||
cerr << "limits: ";
|
||||
for ( DbU::Unit limit : _limits ) cerr << DbU::getPhysical(limit,DbU::Micro) << " - ";
|
||||
cerr << endl;
|
||||
|
||||
cerr << "count: ";
|
||||
for ( int count : _counts ) cerr << count << " - ";
|
||||
cerr << endl;
|
||||
cerr << "Thickness: " << getMaxCount() << endl;
|
||||
cerr << "Wires:" << endl;
|
||||
for ( const WireInterval& wire : _wireIntervals.getElements() )
|
||||
cerr << "| " << wire << endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1279,12 +1279,12 @@ namespace Bora {
|
|||
}
|
||||
|
||||
|
||||
void HVSlicingNode::updateWireOccupation ( Anabatic::VertexSet sources )
|
||||
void HVSlicingNode::updateWireOccupation ( Anabatic::Dijkstra* dijkstra )
|
||||
{
|
||||
cdebug_log(535,1) << "HVSlicingNode::updateWireOccupation() on " << this << endl;
|
||||
|
||||
if (not _parent) {
|
||||
for ( Anabatic::Vertex* vertex : sources ) {
|
||||
for ( Anabatic::Vertex* vertex : dijkstra->getSources() ) {
|
||||
cdebug_log(535,0) << "> " << vertex << endl;
|
||||
|
||||
Anabatic::GCell* gcell = vertex->getGCell();
|
||||
|
@ -1294,7 +1294,7 @@ namespace Bora {
|
|||
cdebug_log(535,0) << "| isRouting():" << snode->isRouting() << endl;
|
||||
|
||||
if (snode->isRouting() and vertex->hasAData() )
|
||||
snode->addWireOccupation( vertex->getIMin(), vertex->getIMax() );
|
||||
snode->addWireOccupation( vertex->getIMin(), vertex->getIMax(), dijkstra->getNet() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,8 +175,8 @@ namespace Bora {
|
|||
}
|
||||
|
||||
|
||||
void RHVSlicingNode::addWireOccupation ( DbU::Unit min, DbU::Unit max )
|
||||
{ if ( _wireOccupation and (min != max) ) _wireOccupation->insertChannel(min, max); }
|
||||
void RHVSlicingNode::addWireOccupation ( DbU::Unit min, DbU::Unit max, Net* net )
|
||||
{ if ( _wireOccupation and (min != max) ) _wireOccupation->insertChannel(min, max, net); }
|
||||
|
||||
|
||||
void RHVSlicingNode::resetWireOccupation ()
|
||||
|
|
|
@ -871,7 +871,7 @@ namespace Bora {
|
|||
{ cerr << Error( "SlicingNode::updateMatrixGContacts(): Base class method must never be called." ) << endl; }
|
||||
|
||||
|
||||
void SlicingNode::addWireOccupation ( DbU::Unit , DbU::Unit )
|
||||
void SlicingNode::addWireOccupation ( DbU::Unit , DbU::Unit, Net* )
|
||||
{ cerr << Error( "SlicingNode::addWireOccupation(): Base class method must never be called." ) << endl; }
|
||||
|
||||
|
||||
|
@ -1158,7 +1158,7 @@ namespace Bora {
|
|||
{ cerr << Error( "SlicingNode::flattenDigitalNets(): Base class method must never be called." ) << endl; }
|
||||
|
||||
|
||||
void SlicingNode::updateWireOccupation ( Anabatic::VertexSet )
|
||||
void SlicingNode::updateWireOccupation ( Anabatic::Dijkstra* )
|
||||
{ cerr << Error( "SlicingNode::updateWireOccupation(): Base class method must never be called." ) << endl; }
|
||||
|
||||
|
||||
|
|
|
@ -18,12 +18,17 @@
|
|||
#define BORA_CHANNEL_ROUTING_H
|
||||
|
||||
|
||||
#include "hurricane/DbU.h"
|
||||
|
||||
#include "hurricane/IntervalTree.h"
|
||||
namespace Hurricane {
|
||||
class Net;
|
||||
}
|
||||
|
||||
namespace Bora {
|
||||
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::IntervalData;
|
||||
using Hurricane::IntervalTree;
|
||||
using Hurricane::Net;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -32,6 +37,9 @@ namespace Bora {
|
|||
|
||||
class ChannelRouting
|
||||
{
|
||||
private:
|
||||
typedef IntervalData<Net*> WireInterval;
|
||||
typedef IntervalTree<Net*> WireIntervals;
|
||||
private:
|
||||
ChannelRouting ();
|
||||
~ChannelRouting ();
|
||||
|
@ -39,13 +47,12 @@ namespace Bora {
|
|||
static ChannelRouting* create ();
|
||||
void destroy ();
|
||||
int getMaxCount () const;
|
||||
void insertChannel ( DbU::Unit xy1, DbU::Unit xy2 );
|
||||
void insertChannel ( DbU::Unit xy1, DbU::Unit xy2, Net* );
|
||||
void insertChannel ( DbU::Unit xy1, DbU::Unit xy2, unsigned int w );
|
||||
void reset ();
|
||||
void print () const;
|
||||
private:
|
||||
std::vector<DbU::Unit> _limits;
|
||||
std::vector<int> _counts;
|
||||
WireIntervals _wireIntervals;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ namespace Bora {
|
|||
void updateSymNetAxis ();
|
||||
void flattenDigitalNets ();
|
||||
|
||||
void updateWireOccupation ( Anabatic::VertexSet );
|
||||
void updateWireOccupation ( Anabatic::Dijkstra* );
|
||||
void resetWireOccupation ();
|
||||
protected:
|
||||
VSlicingNodes _children;
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace Bora {
|
|||
void _place ( DbU::Unit x=0, DbU::Unit y=0, bool replace=false );
|
||||
void setRailInstance ( Hurricane::Instance* i );
|
||||
inline Hurricane::Instance* getRailInstance () const ;
|
||||
void addWireOccupation ( DbU::Unit min, DbU::Unit max );
|
||||
void addWireOccupation ( DbU::Unit min, DbU::Unit max, Net* );
|
||||
void resetWireOccupation ();
|
||||
int getMaxWireOccupation ();
|
||||
protected:
|
||||
|
|
|
@ -287,9 +287,9 @@ namespace Bora {
|
|||
static bool isRailSegments ( Hurricane::Plug* );
|
||||
void createRailCell ();
|
||||
virtual void flattenDigitalNets ();
|
||||
virtual void updateWireOccupation ( Anabatic::VertexSet );
|
||||
virtual void updateWireOccupation ( Anabatic::Dijkstra* );
|
||||
virtual void resetWireOccupation ();
|
||||
virtual void addWireOccupation ( DbU::Unit min, DbU::Unit max );
|
||||
virtual void addWireOccupation ( DbU::Unit min, DbU::Unit max, Net* );
|
||||
virtual int getMaxWireOccupation ();
|
||||
protected:
|
||||
static CRL::RoutingGauge* _rg;
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
hurricane/Interval.h hurricane/Intervals.h
|
||||
hurricane/IntrusiveMap.h
|
||||
hurricane/IntrusiveSet.h
|
||||
hurricane/RbTree.h
|
||||
hurricane/IntervalTree.h
|
||||
hurricane/Layer.h hurricane/Layers.h
|
||||
hurricane/Libraries.h hurricane/Library.h
|
||||
hurricane/ListCollection.h
|
||||
|
|
|
@ -105,17 +105,20 @@ bool Interval::contains(const Interval& interval) const
|
|||
return !isEmpty() && !interval.isEmpty() && (_vMin <= interval._vMin) && (interval._vMax <= _vMax);
|
||||
}
|
||||
|
||||
bool Interval::intersect(const Interval& interval) const
|
||||
// *****************************************************
|
||||
bool Interval::intersect(const Interval& interval, bool strict) const
|
||||
// ******************************************************************
|
||||
{
|
||||
return !isEmpty() && !interval.isEmpty() && !((_vMax < interval._vMin) || (interval._vMax < _vMin));
|
||||
if (isEmpty() or interval.isEmpty()) return false;
|
||||
if ( (_vMax < interval._vMin) or (interval._vMax < _vMin) ) return false;
|
||||
|
||||
return not strict or ( (_vMax != interval._vMin) and (interval._vMax != _vMin) );
|
||||
}
|
||||
|
||||
bool Interval::inferior(const Interval& interval, bool strict) const
|
||||
// *****************************************************************
|
||||
{
|
||||
if (_vMax < interval._vMin) return true;
|
||||
return !strict && (_vMax == interval._vMin);
|
||||
return not strict and (_vMax == interval._vMin);
|
||||
}
|
||||
|
||||
bool Interval::superior(const Interval& interval, bool strict) const
|
||||
|
@ -234,8 +237,8 @@ string Interval::_getString() const
|
|||
// ********************************
|
||||
{
|
||||
if ( isEmpty() )
|
||||
return "<" + _TName("Interval") + " (empty) " + DbU::getValueString(_vMin) + " " + DbU::getValueString(_vMax) + ">";
|
||||
return "<" + _TName("Interval") + " " + DbU::getValueString(_vMin) + " " + DbU::getValueString(_vMax) + ">";
|
||||
return "[empty " + DbU::getValueString(_vMin) + " " + DbU::getValueString(_vMax) + "]";
|
||||
return "[" + DbU::getValueString(_vMin) + " " + DbU::getValueString(_vMax) + "]";
|
||||
}
|
||||
|
||||
Record* Interval::_getRecord() const
|
||||
|
|
|
@ -19,12 +19,7 @@
|
|||
// License along with Hurricane. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ===================================================================
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// x-----------------------------------------------------------------x
|
||||
// | |
|
||||
// +-----------------------------------------------------------------+
|
||||
// | H U R R I C A N E |
|
||||
// | V L S I B a c k e n d D a t a - B a s e |
|
||||
// | |
|
||||
|
@ -32,10 +27,7 @@
|
|||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./Record.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/Commons.h"
|
||||
|
|
|
@ -1,110 +1,113 @@
|
|||
// ****************************************************************************************************
|
||||
// File: ./hurricane/Interval.h
|
||||
// Authors: R. Escassut
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
|
||||
//
|
||||
// This file is part of Hurricane.
|
||||
//
|
||||
// Hurricane is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
// Lesser General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
// Hurricane is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// Hurricane is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
|
||||
// Hurricane is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-
|
||||
// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If
|
||||
// not, see <http://www.gnu.org/licenses/>.
|
||||
// ****************************************************************************************************
|
||||
// You should have received a copy of the Lesser GNU General Public
|
||||
// License along with Hurricane. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | H U R R I C A N E |
|
||||
// | V L S I B a c k e n d D a t a - B a s e |
|
||||
// | |
|
||||
// | Author : Rémy Escassut |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./hurricane/Interval.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef HURRICANE_INTERVAL
|
||||
#define HURRICANE_INTERVAL
|
||||
|
||||
#ifndef HURRICANE_INTERVAL_H
|
||||
#define HURRICANE_INTERVAL_H
|
||||
|
||||
#include "hurricane/DbU.h"
|
||||
|
||||
namespace Hurricane {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Hurricane::Interval".
|
||||
|
||||
// ****************************************************************************************************
|
||||
// Interval declaration
|
||||
// ****************************************************************************************************
|
||||
|
||||
class Interval {
|
||||
// ***********
|
||||
|
||||
// Attributes
|
||||
// **********
|
||||
|
||||
private: DbU::Unit _vMin;
|
||||
private: DbU::Unit _vMax;
|
||||
|
||||
// Constructors
|
||||
// ************
|
||||
|
||||
public: Interval(bool makeEmpty=true);
|
||||
public: Interval(const DbU::Unit& v);
|
||||
public: Interval(const DbU::Unit& v1, const DbU::Unit& v2);
|
||||
public: Interval(const Interval& interval);
|
||||
|
||||
// Operators
|
||||
// *********
|
||||
|
||||
public: Interval& operator=(const Interval& interval);
|
||||
|
||||
public: bool operator==(const Interval& interval) const;
|
||||
public: bool operator!=(const Interval& interval) const;
|
||||
|
||||
// Accessors
|
||||
// *********
|
||||
|
||||
public: const DbU::Unit& getVMin() const {return _vMin;};
|
||||
public: const DbU::Unit& getVMax() const {return _vMax;};
|
||||
public: DbU::Unit& getVMin() {return _vMin;};
|
||||
public: DbU::Unit& getVMax() {return _vMax;};
|
||||
public: DbU::Unit getCenter() const {return ((_vMin + _vMax) / 2);};
|
||||
public: DbU::Unit getSize() const;
|
||||
public: DbU::Unit getHalfSize() const {return (getSize() / 2);};
|
||||
public: Interval getUnion(const Interval& interval) const;
|
||||
public: Interval getIntersection(const Interval& interval) const;
|
||||
|
||||
// Predicates
|
||||
// **********
|
||||
|
||||
public: bool isEmpty() const { return (_vMax < _vMin);};
|
||||
public: bool isFull() const { return (_vMin == DbU::Min) and (_vMax == DbU::Max); };
|
||||
public: bool isPonctual() const { return (_vMax == _vMin);};
|
||||
public: bool contains(const DbU::Unit& v) const;
|
||||
public: bool contains(const Interval& interval) const;
|
||||
public: bool intersect(const Interval& interval) const;
|
||||
public: bool inferior(const Interval& interval, bool strict=true) const;
|
||||
public: bool superior(const Interval& interval, bool strict=true) const;
|
||||
public: bool isConstrainedBy(const Interval& interval) const;
|
||||
|
||||
// Updators
|
||||
// ********
|
||||
|
||||
public: Interval& makeEmpty();
|
||||
public: Interval& shrinkVMin(const DbU::Unit& vMin);
|
||||
public: Interval& shrinkVMax(const DbU::Unit& vMax);
|
||||
public: Interval& inflate(const DbU::Unit& dv);
|
||||
public: Interval& inflate(const DbU::Unit& dvMin, const DbU::Unit& dvMax);
|
||||
public: Interval& merge(const DbU::Unit& v);
|
||||
public: Interval& merge(const Interval& interval);
|
||||
public: Interval& intersection(const DbU::Unit& vMin, const DbU::Unit& vMax);
|
||||
public: Interval& intersection(const Interval& interval);
|
||||
public: Interval& translate(const DbU::Unit& dv);
|
||||
|
||||
// Others
|
||||
// ******
|
||||
|
||||
public: string _getTypeName() const { return _TName("Interval"); };
|
||||
public: string _getString() const;
|
||||
public: Record* _getRecord() const;
|
||||
|
||||
public:
|
||||
class CompareByMin {
|
||||
public:
|
||||
inline bool operator() ( const Interval& rhs, const Interval& lhs ) const;
|
||||
inline bool operator() ( const Interval* rhs, const Interval* lhs ) const;
|
||||
};
|
||||
public:
|
||||
Interval ( bool makeEmpty=true );
|
||||
Interval ( const DbU::Unit& );
|
||||
Interval ( const DbU::Unit& v1, const DbU::Unit& v2 );
|
||||
Interval ( const Interval& );
|
||||
public:
|
||||
Interval& operator= ( const Interval& );
|
||||
bool operator== ( const Interval& ) const;
|
||||
bool operator!= ( const Interval& ) const;
|
||||
public:
|
||||
inline const DbU::Unit& getVMin () const;
|
||||
inline const DbU::Unit& getVMax () const;
|
||||
inline DbU::Unit& getVMin ();
|
||||
inline DbU::Unit& getVMax ();
|
||||
inline DbU::Unit getCenter () const;
|
||||
inline DbU::Unit getSize () const;
|
||||
inline DbU::Unit getHalfSize () const;
|
||||
Interval getUnion ( const Interval& ) const;
|
||||
Interval getIntersection ( const Interval& ) const;
|
||||
inline bool isEmpty () const;
|
||||
inline bool isFull () const;
|
||||
inline bool isPonctual () const;
|
||||
bool contains ( const DbU::Unit& ) const;
|
||||
bool contains ( const Interval& ) const;
|
||||
bool intersect ( const Interval& , bool strict=false ) const;
|
||||
bool inferior ( const Interval& , bool strict=true ) const;
|
||||
bool superior ( const Interval& , bool strict=true ) const;
|
||||
bool isConstrainedBy ( const Interval& ) const;
|
||||
public:
|
||||
Interval& makeEmpty ();
|
||||
Interval& shrinkVMin ( const DbU::Unit& vMin );
|
||||
Interval& shrinkVMax ( const DbU::Unit& vMax );
|
||||
Interval& inflate ( const DbU::Unit& dv );
|
||||
Interval& inflate ( const DbU::Unit& dvMin, const DbU::Unit& dvMax );
|
||||
Interval& merge ( const DbU::Unit& );
|
||||
Interval& merge ( const Interval& );
|
||||
Interval& intersection ( const DbU::Unit& vMin, const DbU::Unit& vMax );
|
||||
Interval& intersection ( const Interval& );
|
||||
Interval& translate ( const DbU::Unit& );
|
||||
public:
|
||||
inline string _getTypeName () const;
|
||||
string _getString () const;
|
||||
Record* _getRecord () const;
|
||||
private:
|
||||
DbU::Unit _vMin;
|
||||
DbU::Unit _vMax;
|
||||
};
|
||||
|
||||
|
||||
inline const DbU::Unit& Interval::getVMin () const {return _vMin;};
|
||||
inline const DbU::Unit& Interval::getVMax () const {return _vMax;};
|
||||
inline DbU::Unit& Interval::getVMin () {return _vMin;};
|
||||
inline DbU::Unit& Interval::getVMax () {return _vMax;};
|
||||
inline DbU::Unit Interval::getCenter () const {return ((_vMin + _vMax) / 2);};
|
||||
inline DbU::Unit Interval::getHalfSize () const {return (getSize() / 2);};
|
||||
inline bool Interval::isEmpty () const { return (_vMax < _vMin);};
|
||||
inline bool Interval::isFull () const { return (_vMin == DbU::Min) and (_vMax == DbU::Max); };
|
||||
inline bool Interval::isPonctual () const { return (_vMax == _vMin);};
|
||||
inline string Interval::_getTypeName () const { return _TName("Interval"); };
|
||||
|
||||
inline DbU::Unit Interval::getSize () const
|
||||
{
|
||||
if (isEmpty()) return 0;
|
||||
|
@ -113,8 +116,15 @@ class Interval {
|
|||
}
|
||||
|
||||
|
||||
inline bool Interval::CompareByMin::operator() ( const Interval& lhs, const Interval& rhs ) const
|
||||
{ return lhs.getVMin() < rhs.getVMin(); }
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
|
||||
inline bool Interval::CompareByMin::operator() ( const Interval* lhs, const Interval* rhs ) const
|
||||
{ return lhs->getVMin() < rhs->getVMin(); }
|
||||
|
||||
|
||||
} // Hurricane namespace.
|
||||
|
||||
|
||||
inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane::Interval* interval )
|
||||
|
@ -129,9 +139,4 @@ inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane:
|
|||
INSPECTOR_PV_SUPPORT(Hurricane::Interval);
|
||||
|
||||
|
||||
#endif // HURRICANE_INTERVAL
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
|
||||
// ****************************************************************************************************
|
||||
#endif // HURRICANE_INTERVAL_H
|
||||
|
|
|
@ -0,0 +1,415 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (c) BULL S.A. 2018-2018, All Rights Reserved
|
||||
//
|
||||
// This file is part of Hurricane.
|
||||
//
|
||||
// Hurricane is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// Hurricane is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-
|
||||
// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the Lesser GNU General Public
|
||||
// License along with Hurricane. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | H U R R I C A N E |
|
||||
// | V L S I B a c k e n d D a t a - B a s e |
|
||||
// | |
|
||||
// | Author : Jean-Paul Chaput |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./hurricane/IntervalTree.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
//
|
||||
// References:
|
||||
// 1. Wikipedia, https://en.wikipedia.org/wiki/Red-black_tree
|
||||
// 2. Introduction to Algorithms, Cormen & Al,
|
||||
// Third edition, MIT press, 2011, p. 348.
|
||||
|
||||
|
||||
#ifndef HURRICANE_INTERVAL_TREE_H
|
||||
#define HURRICANE_INTERVAL_TREE_H
|
||||
|
||||
#include "hurricane/Interval.h"
|
||||
#include "hurricane/RbTree.h"
|
||||
|
||||
namespace Hurricane {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Hurricane::IntervalData".
|
||||
|
||||
|
||||
template< typename Data >
|
||||
class IntervalData : public Interval {
|
||||
public:
|
||||
inline IntervalData ();
|
||||
inline IntervalData ( const Data&, DbU::Unit vmin, DbU::Unit vmax );
|
||||
inline Data& getData () const;
|
||||
inline DbU::Unit getChildsVMax () const;
|
||||
inline DbU::Unit updateChildsVMax ( DbU::Unit lvmax, DbU::Unit rvmax );
|
||||
string _getString () const;
|
||||
Record* _getRecord () const;
|
||||
private:
|
||||
DbU::Unit childsVMax_;
|
||||
Data data_;
|
||||
};
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalData<Data>::IntervalData ()
|
||||
: Interval(1,-1)
|
||||
, childsVMax_(0)
|
||||
, data_ ()
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalData<Data>::IntervalData ( const Data& data, DbU::Unit vmin, DbU::Unit vmax )
|
||||
: Interval(vmin,vmax)
|
||||
, childsVMax_(vmax)
|
||||
, data_ (data)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline Data& IntervalData<Data>::getData () const
|
||||
{ return const_cast< IntervalData<Data>* >( this )->data_; }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline DbU::Unit IntervalData<Data>::getChildsVMax () const
|
||||
{ return childsVMax_; }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline DbU::Unit IntervalData<Data>::updateChildsVMax ( DbU::Unit lvmax, DbU::Unit rvmax )
|
||||
{ childsVMax_ = std::max( getVMax(), std::max( lvmax, rvmax ) ); return childsVMax_; }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
std::string IntervalData<Data>::_getString () const
|
||||
{
|
||||
string s = Interval::_getString();
|
||||
s.insert( s.size(), " max:"+DbU::getValueString(childsVMax_) );
|
||||
s.insert( s.size(), " v:"+getString(data_) );
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
Record* IntervalData<Data>::_getRecord () const
|
||||
{
|
||||
Record* record = Interval::_getRecord();
|
||||
if (record) {
|
||||
record->add(DbU::getValueSlot("childsVMax_", &childsVMax_));
|
||||
record->add(getSlot ("data_" , &data_ ));
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Hurricane::IntervalTree".
|
||||
|
||||
|
||||
template< typename Data >
|
||||
class IntervalTree : public RbTree< IntervalData<Data>, Interval::CompareByMin > {
|
||||
public:
|
||||
typedef RbTree< IntervalData<Data>, Interval::CompareByMin > Super;
|
||||
public:
|
||||
class overlap_iterator : public Super::iterator {
|
||||
public:
|
||||
friend class IntervalTree;
|
||||
private:
|
||||
inline overlap_iterator ( const typename Super::Node*, const Interval& );
|
||||
public:
|
||||
virtual overlap_iterator& operator++ ();
|
||||
private:
|
||||
Interval overlap_;
|
||||
};
|
||||
public:
|
||||
class OverlapElements : public Collection< IntervalData<Data> > {
|
||||
public:
|
||||
// Sub-Class: Locator.
|
||||
class Locator : public Hurricane::Locator< IntervalData<Data> > {
|
||||
public:
|
||||
Locator ( const IntervalTree&, const Interval& span );
|
||||
inline Locator ( const Locator& );
|
||||
virtual IntervalData<Data> getElement () const;
|
||||
virtual Locator* getClone () const;
|
||||
virtual bool isValid () const;
|
||||
virtual void progress ();
|
||||
virtual string _getString () const;
|
||||
protected:
|
||||
overlap_iterator iterator_;
|
||||
};
|
||||
public:
|
||||
// Class Elements.
|
||||
inline OverlapElements ( const IntervalTree&, const Interval& );
|
||||
inline OverlapElements ( const OverlapElements& );
|
||||
virtual Collection< IntervalData<Data> >* getClone () const;
|
||||
virtual Locator* getLocator () const;
|
||||
virtual string _getString () const;
|
||||
protected:
|
||||
const IntervalTree& tree_;
|
||||
const Interval span_;
|
||||
};
|
||||
public:
|
||||
virtual void postRotateLeft ( typename Super::Node* );
|
||||
virtual void postRotateRight ( typename Super::Node* );
|
||||
virtual void postInsert ( typename Super::Node* );
|
||||
virtual void postRemove ( typename Super::Node* );
|
||||
size_t getThickness () const;
|
||||
overlap_iterator beginOverlaps ( const Interval& ) const;
|
||||
inline OverlapElements getOverlaps ( const Interval& ) const;
|
||||
private:
|
||||
inline void updateChildsVMax ( typename Super::Node* );
|
||||
};
|
||||
|
||||
|
||||
template< typename Data >
|
||||
IntervalTree<Data>::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap )
|
||||
: Super::iterator(node)
|
||||
, overlap_(overlap)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::overlap_iterator& IntervalTree<Data>::overlap_iterator::operator++ ()
|
||||
{
|
||||
while (this->isValid()) {
|
||||
Super::iterator::operator++();
|
||||
|
||||
cdebug_log(0,0) << "IntervalTree::overlap_iterator::operator++() "
|
||||
<< ::getString(this->getNode()) << std::endl;
|
||||
|
||||
if (this->getNode()->getValue().intersect(overlap_,true)) break;
|
||||
cdebug_log(0,0) << "NO intersections" << endl;
|
||||
if (overlap_.inferior(this->getNode()->getValue(),true)) {
|
||||
cdebug_log(0,0) << "Node is inferior, stop here." << endl;
|
||||
this->setNode( NULL );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Hurricane::IntervalTree::OverlapOverlapElements" (implementation)
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalTree<Data>::OverlapElements::Locator::Locator ( const Locator &locator )
|
||||
: Hurricane::Locator< IntervalData<Data> >()
|
||||
, iterator_(locator.iterator_)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
IntervalTree<Data>::OverlapElements::Locator::Locator ( const IntervalTree<Data>& tree, const Interval& span )
|
||||
: Hurricane::Locator< IntervalData<Data> >()
|
||||
, iterator_(tree.beginOverlaps(span))
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::OverlapElements::Locator* IntervalTree<Data>::OverlapElements::Locator::getClone () const
|
||||
{ return new Locator(*this); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
IntervalData<Data> IntervalTree<Data>::OverlapElements::Locator::getElement () const
|
||||
{ return (*iterator_); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
bool IntervalTree<Data>::OverlapElements::Locator::isValid () const
|
||||
{ return iterator_.isValid(); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::OverlapElements::Locator::progress ()
|
||||
{
|
||||
if (isValid()) ++iterator_;
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
std::string IntervalTree<Data>::OverlapElements::Locator::_getString () const
|
||||
{
|
||||
std::string s = "<" + _TName("OverlapElements::Locator")
|
||||
+ ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalTree<Data>::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span )
|
||||
: Collection< IntervalData<Data> >()
|
||||
, tree_(tree)
|
||||
, span_(span)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalTree<Data>::OverlapElements::OverlapElements ( const OverlapElements& elements )
|
||||
: Collection< IntervalData<Data> >()
|
||||
, tree_(elements.tree_)
|
||||
, span_(elements.span_)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
Collection< IntervalData<Data> >* IntervalTree<Data>::OverlapElements::getClone () const
|
||||
{ return new OverlapElements(*this); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::OverlapElements::Locator* IntervalTree<Data>::OverlapElements::getLocator () const
|
||||
{ return new Locator( tree_, span_ ); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
std::string IntervalTree<Data>::OverlapElements::_getString () const
|
||||
{
|
||||
std::string s = "<" + _TName("OverlapElements") + " "
|
||||
+ getString(tree_)
|
||||
+ ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Hurricane::IntervalTree" (implementation).
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline void IntervalTree<Data>::updateChildsVMax ( typename Super::Node* node )
|
||||
{
|
||||
DbU::Unit lchildVMax = (node->getLeft ()) ? node->getLeft ()->getValue().getChildsVMax() : node->getValue().getVMax();
|
||||
DbU::Unit rchildVMax = (node->getRight()) ? node->getRight()->getValue().getChildsVMax() : node->getValue().getVMax();
|
||||
|
||||
const_cast< IntervalData<Data>& >( node->getValue() ).updateChildsVMax( lchildVMax, rchildVMax );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::postRotateLeft ( typename Super::Node* node )
|
||||
{
|
||||
updateChildsVMax( node );
|
||||
if (node->getParent()) updateChildsVMax( node->getParent() );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::postRotateRight ( typename Super::Node* node )
|
||||
{
|
||||
updateChildsVMax( node );
|
||||
if (node->getParent()) updateChildsVMax( node->getParent() );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::postInsert ( typename Super::Node* node )
|
||||
{
|
||||
cdebug_log(0,1) << "IntervalTree::postInsert() " << node << std::endl;
|
||||
|
||||
while ( node ) {
|
||||
cdebug_log(0,0) << "| " << node << std::endl;
|
||||
|
||||
updateChildsVMax( node );
|
||||
node = node->getParent();
|
||||
}
|
||||
|
||||
cdebug_tabw(0,-1);
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::postRemove ( typename Super::Node* node )
|
||||
{
|
||||
typename Super::Node* parent = node->getParent();
|
||||
if (parent) {
|
||||
typename Super::Node* child = NULL;
|
||||
|
||||
if (parent->hasLeftChild(node)) child = parent->getRight();
|
||||
else child = parent->getLeft ();
|
||||
|
||||
DbU::Unit childVMax = (child) ? child->getValue().getChildsVMax() : parent->getValue().getVMax();
|
||||
const_cast< IntervalData<Data>& >( parent->getValue() ).updateChildsVMax( childVMax, childVMax );
|
||||
|
||||
postInsert( parent->getParent() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
size_t IntervalTree<Data>::getThickness () const
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalTree::getThickness() " << std::endl;
|
||||
|
||||
vector<DbU::Unit> intervalMaxes;
|
||||
for ( const Interval& interval : *this ) {
|
||||
intervalMaxes.push_back( interval.getVMax() );
|
||||
}
|
||||
std::sort( intervalMaxes.begin(), intervalMaxes.end() );
|
||||
|
||||
size_t maxThickness = 0;
|
||||
size_t curThickness = 0;
|
||||
size_t iMax = 0;
|
||||
for ( const Interval& interval : *this ) {
|
||||
while ( (iMax < intervalMaxes.size()) and (intervalMaxes[iMax] <= interval.getVMin()) ) {
|
||||
--curThickness;
|
||||
cdebug_log(0,0) << "| end:" << intervalMaxes[iMax] << " thickness:" << curThickness << endl;
|
||||
++iMax;
|
||||
}
|
||||
|
||||
maxThickness = std::max( maxThickness, ++curThickness );
|
||||
cdebug_log(0,0) << "| begin:" << interval << " thickness:" << curThickness << endl;
|
||||
}
|
||||
|
||||
return maxThickness;
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::overlap_iterator IntervalTree<Data>::beginOverlaps ( const Interval& overlap ) const
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalTree::beginOverlaps() " << overlap << std::endl;
|
||||
|
||||
const typename Super::Node* current = this->getRoot();
|
||||
const typename Super::Node* leftMost = NULL;
|
||||
while ( current ) {
|
||||
cdebug_log(0,0) << "| " << ::getString(current) << endl;
|
||||
|
||||
if (current->getValue().intersect(overlap)) leftMost = current;
|
||||
if ( current->getLeft()
|
||||
and (overlap.getVMin() < current->getLeft()->getValue().getChildsVMax()) )
|
||||
current = current->getLeft();
|
||||
else
|
||||
current = current->getRight();
|
||||
}
|
||||
return overlap_iterator( leftMost, overlap );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::OverlapElements IntervalTree<Data>::getOverlaps ( const Interval& overlap ) const
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalTree::getOverlaps() " << overlap << std::endl;
|
||||
return OverlapElements( *this, overlap );
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // HUrricane namespace.
|
||||
|
||||
#endif // HURRICANE_INTERVAL_TREE_H
|
File diff suppressed because it is too large
Load Diff
|
@ -81,23 +81,17 @@ namespace Hurricane {
|
|||
|
||||
template<typename Data>
|
||||
class SlotTemplate : public Slot {
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
SlotTemplate ( const string& name, Data data );
|
||||
SlotTemplate ( string& name, Data data );
|
||||
// Accessors.
|
||||
virtual string getDataString () const;
|
||||
virtual Record* getDataRecord () const;
|
||||
virtual SlotTemplate<Data>*
|
||||
getClone () const;
|
||||
|
||||
const Data& getData () const;
|
||||
protected:
|
||||
// Internal: Attributes.
|
||||
Data _data;
|
||||
|
||||
private:
|
||||
// Internal: Constructors.
|
||||
SlotTemplate ( const SlotTemplate& );
|
||||
SlotTemplate& operator= ( const SlotTemplate& );
|
||||
};
|
||||
|
@ -106,7 +100,10 @@ namespace Hurricane {
|
|||
// Inline Member Functions.
|
||||
template<typename Data>
|
||||
SlotTemplate<Data>::SlotTemplate ( const string& name, Data data )
|
||||
: Slot(name), _data(data) { }
|
||||
: Slot(name), _data(data)
|
||||
{
|
||||
//std::cerr << "SlotTemplate<Data>::SlotTemplate() ( \"" << name << "\" )" << std::endl;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
SlotTemplate<Data>::SlotTemplate ( string& name, Data data )
|
||||
|
@ -122,29 +119,30 @@ namespace Hurricane {
|
|||
SlotTemplate<Data>* SlotTemplate<Data>::getClone () const
|
||||
{ return new SlotTemplate(_name,_data); }
|
||||
|
||||
template<typename Data>
|
||||
const Data& SlotTemplate<Data>::getData () const
|
||||
{
|
||||
//std::cerr << "SlotTemplate<Data>::getData()" << std::endl;
|
||||
return _data;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "SlotTemplate<const Data>".
|
||||
|
||||
template<typename Data>
|
||||
class SlotTemplate<const Data> : public Slot {
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
SlotTemplate ( const string& name, const Data data );
|
||||
SlotTemplate ( string& name, const Data data );
|
||||
// Accessors.
|
||||
virtual string getDataString () const;
|
||||
virtual Record* getDataRecord () const;
|
||||
virtual SlotTemplate<const Data>*
|
||||
getClone () const;
|
||||
|
||||
const Data& getData () const;
|
||||
protected:
|
||||
// Internal: Attributes.
|
||||
const Data _data;
|
||||
|
||||
private:
|
||||
// Internal: Constructors.
|
||||
SlotTemplate ( const SlotTemplate& );
|
||||
SlotTemplate& operator= ( const SlotTemplate& );
|
||||
};
|
||||
|
@ -153,22 +151,29 @@ namespace Hurricane {
|
|||
// Inline Member Functions.
|
||||
template<typename Data>
|
||||
SlotTemplate<const Data>::SlotTemplate ( const string& name, const Data data )
|
||||
: Slot(name), _data(data) { }
|
||||
: Slot(name), _data(data)
|
||||
{
|
||||
//std::cerr << "SlotTemplate<Data>::SlotTemplate(const Data) ( \"" << name << "\" )" << std::endl;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
SlotTemplate<const Data>::SlotTemplate ( string& name, const Data data )
|
||||
: Slot(name), _data(data) { }
|
||||
|
||||
template<typename Data>
|
||||
string SlotTemplate<const Data>::getDataString () const { return getString(_data); }
|
||||
string SlotTemplate<const Data>::getDataString () const { return ::getString(_data); }
|
||||
|
||||
template<typename Data>
|
||||
Record* SlotTemplate<const Data>::getDataRecord () const { return getRecord(_data); }
|
||||
Record* SlotTemplate<const Data>::getDataRecord () const { return ::getRecord(_data); }
|
||||
|
||||
template<typename Data>
|
||||
SlotTemplate<const Data>* SlotTemplate<const Data>::getClone () const
|
||||
{ return new SlotTemplate(_name,_data); }
|
||||
|
||||
template<typename Data>
|
||||
const Data& SlotTemplate<const Data>::getData () const
|
||||
{ return _data; }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "SlotTemplate".
|
||||
|
@ -176,32 +181,29 @@ namespace Hurricane {
|
|||
|
||||
template<typename Data>
|
||||
class SlotTemplate<Data*> : public Slot {
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
SlotTemplate ( const string& name, Data* data );
|
||||
SlotTemplate ( string& name, Data* data );
|
||||
// Accessors.
|
||||
virtual string getDataString () const;
|
||||
virtual Record* getDataRecord () const;
|
||||
virtual SlotTemplate<Data*>*
|
||||
getClone () const;
|
||||
|
||||
protected:
|
||||
// Internal: Attributes.
|
||||
Data* _data;
|
||||
|
||||
Data* getData () const;
|
||||
private:
|
||||
// Internal: Constructors.
|
||||
SlotTemplate ( const SlotTemplate& );
|
||||
SlotTemplate& operator= ( const SlotTemplate& );
|
||||
protected:
|
||||
Data* _data;
|
||||
};
|
||||
|
||||
|
||||
// Inline Member Functions.
|
||||
template<typename Data>
|
||||
SlotTemplate<Data*>::SlotTemplate ( const string& name, Data* data )
|
||||
: Slot(name), _data(data) {}
|
||||
: Slot(name), _data(data)
|
||||
{
|
||||
//std::cerr << "SlotTemplate<Data*>::SlotTemplate(Data*) \"" << name << "\"" << std::endl;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
SlotTemplate<Data*>::SlotTemplate ( string& name, Data* data )
|
||||
|
@ -211,12 +213,23 @@ namespace Hurricane {
|
|||
string SlotTemplate<Data*>::getDataString () const { return ::getString(_data); }
|
||||
|
||||
template<typename Data>
|
||||
Record* SlotTemplate<Data*>::getDataRecord () const { return ::getRecord(_data); }
|
||||
Record* SlotTemplate<Data*>::getDataRecord () const
|
||||
{
|
||||
//std::cerr << "SlotTemplate<Data*>::getDataRecord()" << std::endl;
|
||||
return ::getRecord(_data);
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
SlotTemplate<Data*>* SlotTemplate<Data*>::getClone () const
|
||||
{ return new SlotTemplate(_name,_data); }
|
||||
|
||||
template<typename Data>
|
||||
Data* SlotTemplate<Data*>::getData () const
|
||||
{
|
||||
//std::cerr << "SlotTemplate<Data*>::getData()" << _data << std::endl;
|
||||
return _data;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "SlotTemplate".
|
||||
|
@ -224,32 +237,29 @@ namespace Hurricane {
|
|||
|
||||
template<typename Data>
|
||||
class SlotTemplate<Data* const> : public Slot {
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
SlotTemplate ( const string& name, Data* const data );
|
||||
SlotTemplate ( string& name, Data* const data );
|
||||
// Accessors.
|
||||
virtual string getDataString () const;
|
||||
virtual Record* getDataRecord () const;
|
||||
virtual SlotTemplate<Data* const>*
|
||||
getClone () const;
|
||||
|
||||
protected:
|
||||
// Internal: Attributes.
|
||||
Data* const _data;
|
||||
|
||||
Data* const getData () const;
|
||||
private:
|
||||
// Internal: Constructors.
|
||||
SlotTemplate ( const SlotTemplate& );
|
||||
SlotTemplate& operator= ( const SlotTemplate& );
|
||||
protected:
|
||||
Data* const _data;
|
||||
};
|
||||
|
||||
|
||||
// Inline Member Functions.
|
||||
template<typename Data>
|
||||
SlotTemplate<Data* const>::SlotTemplate ( const string& name, Data* const data )
|
||||
: Slot(name), _data(data) {}
|
||||
: Slot(name), _data(data)
|
||||
{
|
||||
//std::cerr << "SlotTemplate<Data>::SlotTemplate(Data* const) ( \"" << name << "\" )" << std::endl;
|
||||
}
|
||||
|
||||
template<typename Data>
|
||||
SlotTemplate<Data* const>::SlotTemplate ( string& name, Data* const data )
|
||||
|
@ -265,6 +275,10 @@ namespace Hurricane {
|
|||
SlotTemplate<Data* const>* SlotTemplate<Data* const>::getClone () const
|
||||
{ return new SlotTemplate(_name,_data); }
|
||||
|
||||
template<typename Data>
|
||||
Data* const SlotTemplate<Data* const>::getData () const
|
||||
{ return _data; }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "SlotTemplate".
|
||||
|
@ -272,31 +286,27 @@ namespace Hurricane {
|
|||
|
||||
template<>
|
||||
class SlotTemplate<Record*> : public Slot {
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
inline SlotTemplate ( const string& name, Record* data );
|
||||
inline SlotTemplate ( string& name, Record* data );
|
||||
// Accessors.
|
||||
inline virtual string getDataString () const;
|
||||
inline virtual Record* getDataRecord () const;
|
||||
inline virtual SlotTemplate<Record*>*
|
||||
getClone () const;
|
||||
|
||||
protected:
|
||||
// Internal: Attributes.
|
||||
Record* _data;
|
||||
|
||||
private:
|
||||
// Internal: Constructors.
|
||||
SlotTemplate ( const SlotTemplate& );
|
||||
SlotTemplate& operator= ( const SlotTemplate& );
|
||||
protected:
|
||||
Record* _data;
|
||||
};
|
||||
|
||||
|
||||
// Inline Member Functions.
|
||||
inline SlotTemplate<Record*>::SlotTemplate ( const string& name, Record* data )
|
||||
: Slot(name), _data(data) {}
|
||||
: Slot(name), _data(data)
|
||||
{
|
||||
//std::cerr << "SlotTemplate<Data>::SlotTemplate(Record*) ( \"" << name << "\" )" << std::endl;
|
||||
}
|
||||
|
||||
inline SlotTemplate<Record*>::SlotTemplate ( string& name, Record* data )
|
||||
: Slot(name), _data(data) {}
|
||||
|
@ -331,6 +341,7 @@ template<typename Data>
|
|||
inline Hurricane::Slot* getSlot( const std::string& name, Data d )
|
||||
{
|
||||
//std::cerr << "getSlot<const string&,Data>( \"" << name << "\" )" << std::endl;
|
||||
//std::cerr << " Data = " << typeid(d).name() << std::endl;
|
||||
return new Hurricane::SlotTemplate<Data> ( name, d );
|
||||
}
|
||||
|
||||
|
@ -339,6 +350,7 @@ template<typename Data>
|
|||
inline Hurricane::Slot* getSlot( const std::string& name, Data* d )
|
||||
{
|
||||
//std::cerr << "getSlot<const string&,Data*>( \"" << name << "\" )" << std::endl;
|
||||
//std::cerr << " Data = " << typeid(d).name() << std::endl;
|
||||
return new Hurricane::SlotTemplate<Data*> ( name, d );
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# -*- mode: CMAKE explicit-buffer-name: "CMakeLists.txt<unittests>" -*-
|
||||
|
||||
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
||||
project(UNITTEST)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.9)
|
||||
|
||||
set(ignoreVariables "${BUILD_DOC}")
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
setup_project_paths(CORIOLIS)
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${CRLCORE_SOURCE_DIR}/cmake_modules/")
|
||||
print_cmake_module_path()
|
||||
|
||||
set_cmake_policies()
|
||||
check_distribution()
|
||||
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
|
||||
setup_boost(program_options python regex wave)
|
||||
setup_qt()
|
||||
|
||||
find_package(Libbfd)
|
||||
find_package(Libexecinfo REQUIRED)
|
||||
find_package(PythonLibs 2 REQUIRED)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(VLSISAPD REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
|
||||
add_subdirectory(src)
|
|
@ -0,0 +1,43 @@
|
|||
# -*- explicit-buffer-name: "CMakeLists.txt<unittests/src>" -*-
|
||||
|
||||
include_directories ( ${CORIOLIS_INCLUDE_DIR}
|
||||
${HURRICANE_INCLUDE_DIR}
|
||||
${UTILITIES_INCLUDE_DIR}
|
||||
${QtX_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set ( mocincludes
|
||||
)
|
||||
set ( cpps unittests.cpp
|
||||
)
|
||||
|
||||
qtX_wrap_cpp ( mocCpps ${mocincludes} )
|
||||
|
||||
if(NOT WITH_QT5)
|
||||
list ( APPEND cpps ${mocCpps} )
|
||||
endif()
|
||||
|
||||
add_executable ( unittests ${cpps} )
|
||||
target_link_libraries ( unittests ${CORIOLIS_PYTHON_LIBRARIES}
|
||||
${CORIOLIS_LIBRARIES}
|
||||
${HURRICANE_PYTHON_LIBRARIES}
|
||||
${HURRICANE_GRAPHICAL_LIBRARIES}
|
||||
${HURRICANE_LIBRARIES}
|
||||
${BOOKSHELF_LIBRARY}
|
||||
${AGDS_LIBRARY}
|
||||
${CIF_LIBRARY}
|
||||
${CONFIGURATION_LIBRARY}
|
||||
${UTILITIES_LIBRARY}
|
||||
${LEFDEF_LIBRARIES}
|
||||
${OA_LIBRARIES}
|
||||
${QtX_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${PYTHON_LIBRARIES}
|
||||
-lutil
|
||||
${LIBXML2_LIBRARIES}
|
||||
${LIBEXECINFO_LIBRARIES}
|
||||
${LIBBFD_LIBRARIES}
|
||||
)
|
||||
install ( TARGETS unittests DESTINATION bin )
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
namespace boptions = boost::program_options;
|
||||
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Interval.h"
|
||||
#include "hurricane/RbTree.h"
|
||||
#include "hurricane/IntervalTree.h"
|
||||
#include "crlcore/Utilities.h"
|
||||
|
||||
namespace Hurricane {
|
||||
|
||||
typedef IntervalData<std::string> IntvString;
|
||||
typedef RbTree<Interval,Interval::CompareByMin> RbInterval;
|
||||
typedef IntervalTree<std::string> IntervalTreeString;
|
||||
typedef GenericCollection<Interval> Intervals;
|
||||
typedef GenericCollection<IntvString> IntvStrings;
|
||||
|
||||
}
|
||||
|
||||
INSPECTOR_PV_SUPPORT(Hurricane::RbInterval);
|
||||
INSPECTOR_PV_SUPPORT(Hurricane::RbInterval::Node);
|
||||
INSPECTOR_PV_SUPPORT(Hurricane::IntvString);
|
||||
INSPECTOR_PV_SUPPORT(Hurricane::IntervalTreeString);
|
||||
INSPECTOR_PV_SUPPORT(Hurricane::IntervalTreeString::Node);
|
||||
|
||||
using namespace std;
|
||||
using namespace Hurricane;
|
||||
using namespace CRL;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace std;
|
||||
using namespace Hurricane;
|
||||
|
||||
|
||||
inline DbU::Unit l ( long v ) { return DbU::fromLambda(v); }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Test : "testRbTree".
|
||||
|
||||
|
||||
int testRbTree ()
|
||||
{
|
||||
//typedef IntervalTree RbInterval;
|
||||
RbInterval rb;
|
||||
|
||||
long count = 13;
|
||||
for ( long key=0 ; key<count ; ++key ) {
|
||||
if (key == 5) {
|
||||
for ( long j=0 ; j<4 ; ++j ) rb.insert( Interval( l(key), l(key+1) ) );
|
||||
}
|
||||
rb.insert( Interval( l(key), l(key+1) ) );
|
||||
//rb.insert( count-1 - key );
|
||||
|
||||
RbInterval::iterator lb = rb.lower_bound( Interval(l(5),l(6)) );
|
||||
RbInterval::iterator ub = rb.upper_bound( Interval(l(5),l(6)) );
|
||||
cerr << "range of 5: [ ";
|
||||
for ( ; lb != ub ; ++lb ) cerr << *lb << " ";
|
||||
cerr << "]" << endl;
|
||||
//cerr << "Thickness: " << rb.getThickness() << endl;
|
||||
cerr << endl << endl;
|
||||
}
|
||||
|
||||
rb.write( "finalRbTree.gv" );
|
||||
|
||||
for ( Interval intv : rb.getElements() ) {
|
||||
cerr << intv << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Test : "testIntervalTree".
|
||||
|
||||
|
||||
int testIntervalTree ()
|
||||
{
|
||||
IntervalTreeString itree;
|
||||
|
||||
long count = 13;
|
||||
for ( long key=0 ; key<count ; ++key ) {
|
||||
if (key == 5) {
|
||||
for ( long j=0 ; j<4 ; ++j ) itree.insert( IntvString( "b", l(key), l(key+1) ) );
|
||||
}
|
||||
itree.insert( IntvString( "a", l(key), l(key+1) ) );
|
||||
//rb.insert( count-1 - key );
|
||||
|
||||
IntervalTreeString::iterator lb = itree.lower_bound( IntvString("c",l(5),l(6)) );
|
||||
IntervalTreeString::iterator ub = itree.upper_bound( IntvString("c",l(5),l(6)) );
|
||||
cerr << "range of 5: [ ";
|
||||
for ( ; lb != ub ; ++lb ) cerr << *lb << " ";
|
||||
cerr << "]" << endl;
|
||||
cerr << "Thickness: " << itree.getThickness() << endl;
|
||||
cerr << endl << endl;
|
||||
}
|
||||
|
||||
itree.write( "finalIntervalTree.gv" );
|
||||
|
||||
for ( IntervalData<string> intv : itree.getElements() ) {
|
||||
cerr << intv << endl;
|
||||
}
|
||||
|
||||
IntervalTreeString::overlap_iterator ob = itree.beginOverlaps( Interval(l(2),l(4)) );
|
||||
cerr << "overlap of [2:4]: [ ";
|
||||
for ( ; ob != itree.end() ; ++ob )
|
||||
cerr << *ob << " ";
|
||||
cerr << "]" << endl;
|
||||
cerr << endl << endl;
|
||||
|
||||
ob = itree.beginOverlaps( Interval(l(-2),l(-1)) );
|
||||
cerr << "overlap of [-2:-1]: [ ";
|
||||
for ( ; ob != itree.end() ; ++ob )
|
||||
cerr << *ob << " ";
|
||||
cerr << "]" << endl;
|
||||
cerr << endl << endl;
|
||||
|
||||
ob = itree.beginOverlaps( Interval(l(6),l(9)) );
|
||||
cerr << "overlap of [6:9]: [ ";
|
||||
for ( ; ob != itree.end() ; ++ob )
|
||||
cerr << *ob << " ";
|
||||
cerr << "]" << endl;
|
||||
cerr << endl << endl;
|
||||
|
||||
cerr << "overlap of [6:9]: [ ";
|
||||
for ( const IntvString& intv : itree.getOverlaps( Interval( l(6), l(9) ) ) )
|
||||
cerr << intv << " ";
|
||||
cerr << "]" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
int main ( int argc, char* argv[] )
|
||||
{
|
||||
int returnCode = 0;
|
||||
|
||||
try {
|
||||
bool coreDump = false;
|
||||
bool rbTree = false;
|
||||
bool intvTree = false;
|
||||
|
||||
boptions::options_description options ("Command line arguments & options");
|
||||
options.add_options()
|
||||
( "help,h" , "Print this help." )
|
||||
( "core-dump,D", boptions::bool_switch(&coreDump)->default_value(false)
|
||||
, "Enable core dumping.")
|
||||
( "rb-tree" , boptions::bool_switch(&rbTree )->default_value(false)
|
||||
, "Test of the red/black tree \"hurricane/RbTree.h\".")
|
||||
( "intv-tree" , boptions::bool_switch(&intvTree)->default_value(false)
|
||||
, "Test of the interval tree \"hurricane/IntervalTree.h\".");
|
||||
|
||||
boptions::variables_map arguments;
|
||||
boptions::store ( boptions::parse_command_line(argc,argv,options), arguments );
|
||||
boptions::notify( arguments );
|
||||
|
||||
if (arguments.count("help")) {
|
||||
cerr << options << endl;
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
|
||||
System::get()->setCatchCore( not coreDump );
|
||||
DebugSession::open( 0, 1000 );
|
||||
|
||||
if (rbTree ) returnCode += testRbTree();
|
||||
if (intvTree) returnCode += testIntervalTree();
|
||||
|
||||
DebugSession::close();
|
||||
}
|
||||
catch ( Error& e ) {
|
||||
cerr << e.what() << endl;
|
||||
exit( 127 );
|
||||
}
|
||||
catch ( boptions::error& e ) {
|
||||
cerr << "[ERROR] " << e.what() << endl;
|
||||
exit( 127 );
|
||||
}
|
||||
catch ( exception& e ) {
|
||||
cerr << "[ERROR] " << e.what() << endl;
|
||||
exit( 127 );
|
||||
}
|
||||
catch ( ... ) {
|
||||
cerr << "[ERROR] Abnormal termination: unmanaged exception.\n" << endl;
|
||||
exit( 126 );
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
Loading…
Reference in New Issue