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:
Jean-Paul Chaput 2018-11-07 23:48:43 +01:00
parent ac51ac3910
commit c76fa034ba
21 changed files with 1998 additions and 320 deletions

View File

@ -502,6 +502,7 @@ namespace Anabatic {
public: public:
inline bool isBipoint () const; inline bool isBipoint () const;
inline bool isSourceVertex ( Vertex* ) const; inline bool isSourceVertex ( Vertex* ) const;
inline Net* getNet () const;
inline bool isTargetVertex ( Vertex* ) const; inline bool isTargetVertex ( Vertex* ) const;
inline DbU::Unit getSearchAreaHalo () const; inline DbU::Unit getSearchAreaHalo () const;
template<typename DistanceT> template<typename DistanceT>
@ -542,7 +543,6 @@ namespace Anabatic {
void _initiateUpdateIntervals ( Vertex* ); void _initiateUpdateIntervals ( Vertex* );
bool _updateIntervals ( bool&, Vertex*, bool&, int&, Edge* ); bool _updateIntervals ( bool&, Vertex*, bool&, int&, Edge* );
void _updateRealOccupancy ( Vertex* ); void _updateRealOccupancy ( Vertex* );
private: private:
AnabaticEngine* _anabatic; AnabaticEngine* _anabatic;
vector<Vertex*> _vertexes; 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::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::isSourceVertex ( Vertex* v ) const { return (_sources.find(v) != _sources.end()); }
inline bool Dijkstra::isTargetVertex ( Vertex* v ) const { return (_targets.find(v) != _targets.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 DbU::Unit Dijkstra::getSearchAreaHalo () const { return _searchAreaHalo; }
inline void Dijkstra::setSearchAreaHalo ( DbU::Unit halo ) { _searchAreaHalo = halo; } inline void Dijkstra::setSearchAreaHalo ( DbU::Unit halo ) { _searchAreaHalo = halo; }

View File

@ -36,6 +36,7 @@ projects = [
, "cumulus" , "cumulus"
, "stratus1" , "stratus1"
, "documentation" , "documentation"
, "unittests"
] ]
, 'repository': 'ssh://asim-t/users/largo2/git/coriolis.git' } , 'repository': 'ssh://asim-t/users/largo2/git/coriolis.git' }
] ]

View File

@ -229,7 +229,7 @@ namespace Bora {
if ( not (state and state->isSymSlave()) ) { if ( not (state and state->isSymSlave()) ) {
slicingtree->setVertexRestriction( net, katana ); slicingtree->setVertexRestriction( net, katana );
dijkstra->run(); dijkstra->run();
slicingtree->updateWireOccupation( dijkstra->getSources() ); slicingtree->updateWireOccupation( dijkstra );
} }
} }
katana->setState( Anabatic::EngineState::EngineGlobalLoaded ); katana->setState( Anabatic::EngineState::EngineGlobalLoaded );

View File

@ -27,6 +27,7 @@ namespace Bora {
ChannelRouting::ChannelRouting () ChannelRouting::ChannelRouting ()
: _wireIntervals()
{ } { }
@ -48,16 +49,13 @@ namespace Bora {
void ChannelRouting::reset () void ChannelRouting::reset ()
{ {
_limits.clear(); _wireIntervals.clear();
_counts.clear();
} }
int ChannelRouting::getMaxCount () const int ChannelRouting::getMaxCount () const
{ {
int maxCount = 0; return _wireIntervals.getThickness();
for ( int count : _counts ) maxCount = std::max( maxCount, count );
return maxCount;
} }
@ -68,92 +66,28 @@ namespace Bora {
<< DbU::getValueString(xy2) << "] width:" << DbU::getValueString(xy2) << "] width:"
<< w << endl; << 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) [" cdebug_log(535,0) << "ChannelRouting::insertChannel(DbU::Unit,DbU::Unit) ["
<< DbU::getValueString(xy1) << " : " << DbU::getValueString(xy1) << " : "
<< DbU::getValueString(xy2) << "]" << endl; << DbU::getValueString(xy2) << "] "
<< net
<< endl;
DbU::Unit min = xy1; _wireIntervals.insert( WireInterval(net,xy1,xy2) );
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 );
}
}
}
}
}
} }
void ChannelRouting::print () const void ChannelRouting::print () const
{ {
cerr << "limits: "; cerr << "Thickness: " << getMaxCount() << endl;
for ( DbU::Unit limit : _limits ) cerr << DbU::getPhysical(limit,DbU::Micro) << " - "; cerr << "Wires:" << endl;
cerr << endl; for ( const WireInterval& wire : _wireIntervals.getElements() )
cerr << "| " << wire << endl;
cerr << "count: ";
for ( int count : _counts ) cerr << count << " - ";
cerr << endl;
} }

View File

@ -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; cdebug_log(535,1) << "HVSlicingNode::updateWireOccupation() on " << this << endl;
if (not _parent) { if (not _parent) {
for ( Anabatic::Vertex* vertex : sources ) { for ( Anabatic::Vertex* vertex : dijkstra->getSources() ) {
cdebug_log(535,0) << "> " << vertex << endl; cdebug_log(535,0) << "> " << vertex << endl;
Anabatic::GCell* gcell = vertex->getGCell(); Anabatic::GCell* gcell = vertex->getGCell();
@ -1294,7 +1294,7 @@ namespace Bora {
cdebug_log(535,0) << "| isRouting():" << snode->isRouting() << endl; cdebug_log(535,0) << "| isRouting():" << snode->isRouting() << endl;
if (snode->isRouting() and vertex->hasAData() ) if (snode->isRouting() and vertex->hasAData() )
snode->addWireOccupation( vertex->getIMin(), vertex->getIMax() ); snode->addWireOccupation( vertex->getIMin(), vertex->getIMax(), dijkstra->getNet() );
} }
} }
} }

View File

@ -175,8 +175,8 @@ namespace Bora {
} }
void RHVSlicingNode::addWireOccupation ( DbU::Unit min, DbU::Unit max ) void RHVSlicingNode::addWireOccupation ( DbU::Unit min, DbU::Unit max, Net* net )
{ if ( _wireOccupation and (min != max) ) _wireOccupation->insertChannel(min, max); } { if ( _wireOccupation and (min != max) ) _wireOccupation->insertChannel(min, max, net); }
void RHVSlicingNode::resetWireOccupation () void RHVSlicingNode::resetWireOccupation ()

View File

@ -871,7 +871,7 @@ namespace Bora {
{ cerr << Error( "SlicingNode::updateMatrixGContacts(): Base class method must never be called." ) << endl; } { 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; } { 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; } { 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; } { cerr << Error( "SlicingNode::updateWireOccupation(): Base class method must never be called." ) << endl; }

View File

@ -18,12 +18,17 @@
#define BORA_CHANNEL_ROUTING_H #define BORA_CHANNEL_ROUTING_H
#include "hurricane/DbU.h" #include "hurricane/IntervalTree.h"
namespace Hurricane {
class Net;
}
namespace Bora { namespace Bora {
using Hurricane::DbU; using Hurricane::DbU;
using Hurricane::IntervalData;
using Hurricane::IntervalTree;
using Hurricane::Net;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -32,6 +37,9 @@ namespace Bora {
class ChannelRouting class ChannelRouting
{ {
private:
typedef IntervalData<Net*> WireInterval;
typedef IntervalTree<Net*> WireIntervals;
private: private:
ChannelRouting (); ChannelRouting ();
~ChannelRouting (); ~ChannelRouting ();
@ -39,13 +47,12 @@ namespace Bora {
static ChannelRouting* create (); static ChannelRouting* create ();
void destroy (); void destroy ();
int getMaxCount () const; 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 insertChannel ( DbU::Unit xy1, DbU::Unit xy2, unsigned int w );
void reset (); void reset ();
void print () const; void print () const;
private: private:
std::vector<DbU::Unit> _limits; WireIntervals _wireIntervals;
std::vector<int> _counts;
}; };

View File

@ -145,7 +145,7 @@ namespace Bora {
void updateSymNetAxis (); void updateSymNetAxis ();
void flattenDigitalNets (); void flattenDigitalNets ();
void updateWireOccupation ( Anabatic::VertexSet ); void updateWireOccupation ( Anabatic::Dijkstra* );
void resetWireOccupation (); void resetWireOccupation ();
protected: protected:
VSlicingNodes _children; VSlicingNodes _children;

View File

@ -56,7 +56,7 @@ namespace Bora {
void _place ( DbU::Unit x=0, DbU::Unit y=0, bool replace=false ); void _place ( DbU::Unit x=0, DbU::Unit y=0, bool replace=false );
void setRailInstance ( Hurricane::Instance* i ); void setRailInstance ( Hurricane::Instance* i );
inline Hurricane::Instance* getRailInstance () const ; inline Hurricane::Instance* getRailInstance () const ;
void addWireOccupation ( DbU::Unit min, DbU::Unit max ); void addWireOccupation ( DbU::Unit min, DbU::Unit max, Net* );
void resetWireOccupation (); void resetWireOccupation ();
int getMaxWireOccupation (); int getMaxWireOccupation ();
protected: protected:

View File

@ -287,9 +287,9 @@ namespace Bora {
static bool isRailSegments ( Hurricane::Plug* ); static bool isRailSegments ( Hurricane::Plug* );
void createRailCell (); void createRailCell ();
virtual void flattenDigitalNets (); virtual void flattenDigitalNets ();
virtual void updateWireOccupation ( Anabatic::VertexSet ); virtual void updateWireOccupation ( Anabatic::Dijkstra* );
virtual void resetWireOccupation (); 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 (); virtual int getMaxWireOccupation ();
protected: protected:
static CRL::RoutingGauge* _rg; static CRL::RoutingGauge* _rg;

View File

@ -49,6 +49,8 @@
hurricane/Interval.h hurricane/Intervals.h hurricane/Interval.h hurricane/Intervals.h
hurricane/IntrusiveMap.h hurricane/IntrusiveMap.h
hurricane/IntrusiveSet.h hurricane/IntrusiveSet.h
hurricane/RbTree.h
hurricane/IntervalTree.h
hurricane/Layer.h hurricane/Layers.h hurricane/Layer.h hurricane/Layers.h
hurricane/Libraries.h hurricane/Library.h hurricane/Libraries.h hurricane/Library.h
hurricane/ListCollection.h hurricane/ListCollection.h

View File

@ -105,17 +105,20 @@ bool Interval::contains(const Interval& interval) const
return !isEmpty() && !interval.isEmpty() && (_vMin <= interval._vMin) && (interval._vMax <= _vMax); 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 bool Interval::inferior(const Interval& interval, bool strict) const
// ***************************************************************** // *****************************************************************
{ {
if (_vMax < interval._vMin) return true; 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 bool Interval::superior(const Interval& interval, bool strict) const
@ -234,8 +237,8 @@ string Interval::_getString() const
// ******************************** // ********************************
{ {
if ( isEmpty() ) if ( isEmpty() )
return "<" + _TName("Interval") + " (empty) " + DbU::getValueString(_vMin) + " " + DbU::getValueString(_vMax) + ">"; return "[empty " + DbU::getValueString(_vMin) + " " + DbU::getValueString(_vMax) + "]";
return "<" + _TName("Interval") + " " + DbU::getValueString(_vMin) + " " + DbU::getValueString(_vMax) + ">"; return "[" + DbU::getValueString(_vMin) + " " + DbU::getValueString(_vMax) + "]";
} }
Record* Interval::_getRecord() const Record* Interval::_getRecord() const

View File

@ -19,12 +19,7 @@
// License along with Hurricane. If not, see // License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
// //
// =================================================================== // +-----------------------------------------------------------------+
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | H U R R I C A N E | // | 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 | // | 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 | // | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Module : "./Record.cpp" | // | C++ Module : "./Record.cpp" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "hurricane/Commons.h" #include "hurricane/Commons.h"

View File

@ -1,109 +1,112 @@
// **************************************************************************************************** // -*- C++ -*-
// File: ./hurricane/Interval.h //
// Authors: R. Escassut
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved // Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
// //
// This file is part of Hurricane. // This file is part of Hurricane.
// //
// Hurricane is free software: you can redistribute it and/or modify it under the terms of the GNU // Hurricane is free software: you can redistribute it and/or modify
// Lesser General Public License as published by the Free Software Foundation, either version 3 of the // 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. // 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 // Hurricane is distributed in the hope that it will be useful, but
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU // 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. // General Public License for more details.
// //
// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If // You should have received a copy of the Lesser GNU General Public
// not, see <http://www.gnu.org/licenses/>. // 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" #include "hurricane/DbU.h"
namespace Hurricane { namespace Hurricane {
// -------------------------------------------------------------------
// Class : "Hurricane::Interval".
// ****************************************************************************************************
// Interval declaration
// ****************************************************************************************************
class Interval { class Interval {
// *********** 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;
};
// 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;
};
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 inline DbU::Unit Interval::getSize () const
{ {
@ -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 ) 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); INSPECTOR_PV_SUPPORT(Hurricane::Interval);
#endif // HURRICANE_INTERVAL #endif // HURRICANE_INTERVAL_H
// ****************************************************************************************************
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
// ****************************************************************************************************

View File

@ -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

View File

@ -81,23 +81,17 @@ namespace Hurricane {
template<typename Data> template<typename Data>
class SlotTemplate : public Slot { class SlotTemplate : public Slot {
public: public:
// Constructor.
SlotTemplate ( const string& name, Data data ); SlotTemplate ( const string& name, Data data );
SlotTemplate ( string& name, Data data ); SlotTemplate ( string& name, Data data );
// Accessors.
virtual string getDataString () const; virtual string getDataString () const;
virtual Record* getDataRecord () const; virtual Record* getDataRecord () const;
virtual SlotTemplate<Data>* virtual SlotTemplate<Data>*
getClone () const; getClone () const;
const Data& getData () const;
protected: protected:
// Internal: Attributes.
Data _data; Data _data;
private: private:
// Internal: Constructors.
SlotTemplate ( const SlotTemplate& ); SlotTemplate ( const SlotTemplate& );
SlotTemplate& operator= ( const SlotTemplate& ); SlotTemplate& operator= ( const SlotTemplate& );
}; };
@ -106,7 +100,10 @@ namespace Hurricane {
// Inline Member Functions. // Inline Member Functions.
template<typename Data> template<typename Data>
SlotTemplate<Data>::SlotTemplate ( const string& name, Data 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> template<typename Data>
SlotTemplate<Data>::SlotTemplate ( string& name, Data data ) SlotTemplate<Data>::SlotTemplate ( string& name, Data data )
@ -122,29 +119,30 @@ namespace Hurricane {
SlotTemplate<Data>* SlotTemplate<Data>::getClone () const SlotTemplate<Data>* SlotTemplate<Data>::getClone () const
{ return new SlotTemplate(_name,_data); } { 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>". // Class : "SlotTemplate<const Data>".
template<typename Data> template<typename Data>
class SlotTemplate<const Data> : public Slot { class SlotTemplate<const Data> : public Slot {
public: public:
// Constructor.
SlotTemplate ( const string& name, const Data data ); SlotTemplate ( const string& name, const Data data );
SlotTemplate ( string& name, const Data data ); SlotTemplate ( string& name, const Data data );
// Accessors.
virtual string getDataString () const; virtual string getDataString () const;
virtual Record* getDataRecord () const; virtual Record* getDataRecord () const;
virtual SlotTemplate<const Data>* virtual SlotTemplate<const Data>*
getClone () const; getClone () const;
const Data& getData () const;
protected: protected:
// Internal: Attributes.
const Data _data; const Data _data;
private: private:
// Internal: Constructors.
SlotTemplate ( const SlotTemplate& ); SlotTemplate ( const SlotTemplate& );
SlotTemplate& operator= ( const SlotTemplate& ); SlotTemplate& operator= ( const SlotTemplate& );
}; };
@ -153,22 +151,29 @@ namespace Hurricane {
// Inline Member Functions. // Inline Member Functions.
template<typename Data> template<typename Data>
SlotTemplate<const Data>::SlotTemplate ( const string& name, const Data 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> template<typename Data>
SlotTemplate<const Data>::SlotTemplate ( string& name, const Data data ) SlotTemplate<const Data>::SlotTemplate ( string& name, const Data data )
: Slot(name), _data(data) { } : Slot(name), _data(data) { }
template<typename 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> template<typename Data>
Record* SlotTemplate<const Data>::getDataRecord () const { return getRecord(_data); } Record* SlotTemplate<const Data>::getDataRecord () const { return ::getRecord(_data); }
template<typename Data> template<typename Data>
SlotTemplate<const Data>* SlotTemplate<const Data>::getClone () const SlotTemplate<const Data>* SlotTemplate<const Data>::getClone () const
{ return new SlotTemplate(_name,_data); } { return new SlotTemplate(_name,_data); }
template<typename Data>
const Data& SlotTemplate<const Data>::getData () const
{ return _data; }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "SlotTemplate". // Class : "SlotTemplate".
@ -176,32 +181,29 @@ namespace Hurricane {
template<typename Data> template<typename Data>
class SlotTemplate<Data*> : public Slot { class SlotTemplate<Data*> : public Slot {
public: public:
// Constructor.
SlotTemplate ( const string& name, Data* data ); SlotTemplate ( const string& name, Data* data );
SlotTemplate ( string& name, Data* data ); SlotTemplate ( string& name, Data* data );
// Accessors.
virtual string getDataString () const; virtual string getDataString () const;
virtual Record* getDataRecord () const; virtual Record* getDataRecord () const;
virtual SlotTemplate<Data*>* virtual SlotTemplate<Data*>*
getClone () const; getClone () const;
Data* getData () const;
protected:
// Internal: Attributes.
Data* _data;
private: private:
// Internal: Constructors.
SlotTemplate ( const SlotTemplate& ); SlotTemplate ( const SlotTemplate& );
SlotTemplate& operator= ( const SlotTemplate& ); SlotTemplate& operator= ( const SlotTemplate& );
protected:
Data* _data;
}; };
// Inline Member Functions. // Inline Member Functions.
template<typename Data> template<typename Data>
SlotTemplate<Data*>::SlotTemplate ( const string& name, Data* 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> template<typename Data>
SlotTemplate<Data*>::SlotTemplate ( string& name, Data* data ) SlotTemplate<Data*>::SlotTemplate ( string& name, Data* data )
@ -211,12 +213,23 @@ namespace Hurricane {
string SlotTemplate<Data*>::getDataString () const { return ::getString(_data); } string SlotTemplate<Data*>::getDataString () const { return ::getString(_data); }
template<typename 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> template<typename Data>
SlotTemplate<Data*>* SlotTemplate<Data*>::getClone () const SlotTemplate<Data*>* SlotTemplate<Data*>::getClone () const
{ return new SlotTemplate(_name,_data); } { 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". // Class : "SlotTemplate".
@ -224,32 +237,29 @@ namespace Hurricane {
template<typename Data> template<typename Data>
class SlotTemplate<Data* const> : public Slot { class SlotTemplate<Data* const> : public Slot {
public: public:
// Constructor.
SlotTemplate ( const string& name, Data* const data ); SlotTemplate ( const string& name, Data* const data );
SlotTemplate ( string& name, Data* const data ); SlotTemplate ( string& name, Data* const data );
// Accessors.
virtual string getDataString () const; virtual string getDataString () const;
virtual Record* getDataRecord () const; virtual Record* getDataRecord () const;
virtual SlotTemplate<Data* const>* virtual SlotTemplate<Data* const>*
getClone () const; getClone () const;
Data* const getData () const;
protected:
// Internal: Attributes.
Data* const _data;
private: private:
// Internal: Constructors.
SlotTemplate ( const SlotTemplate& ); SlotTemplate ( const SlotTemplate& );
SlotTemplate& operator= ( const SlotTemplate& ); SlotTemplate& operator= ( const SlotTemplate& );
protected:
Data* const _data;
}; };
// Inline Member Functions. // Inline Member Functions.
template<typename Data> template<typename Data>
SlotTemplate<Data* const>::SlotTemplate ( const string& name, Data* const 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> template<typename Data>
SlotTemplate<Data* const>::SlotTemplate ( string& name, Data* const data ) SlotTemplate<Data* const>::SlotTemplate ( string& name, Data* const data )
@ -265,6 +275,10 @@ namespace Hurricane {
SlotTemplate<Data* const>* SlotTemplate<Data* const>::getClone () const SlotTemplate<Data* const>* SlotTemplate<Data* const>::getClone () const
{ return new SlotTemplate(_name,_data); } { return new SlotTemplate(_name,_data); }
template<typename Data>
Data* const SlotTemplate<Data* const>::getData () const
{ return _data; }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "SlotTemplate". // Class : "SlotTemplate".
@ -272,31 +286,27 @@ namespace Hurricane {
template<> template<>
class SlotTemplate<Record*> : public Slot { class SlotTemplate<Record*> : public Slot {
public: public:
// Constructor.
inline SlotTemplate ( const string& name, Record* data ); inline SlotTemplate ( const string& name, Record* data );
inline SlotTemplate ( string& name, Record* data ); inline SlotTemplate ( string& name, Record* data );
// Accessors.
inline virtual string getDataString () const; inline virtual string getDataString () const;
inline virtual Record* getDataRecord () const; inline virtual Record* getDataRecord () const;
inline virtual SlotTemplate<Record*>* inline virtual SlotTemplate<Record*>*
getClone () const; getClone () const;
protected:
// Internal: Attributes.
Record* _data;
private: private:
// Internal: Constructors.
SlotTemplate ( const SlotTemplate& ); SlotTemplate ( const SlotTemplate& );
SlotTemplate& operator= ( const SlotTemplate& ); SlotTemplate& operator= ( const SlotTemplate& );
protected:
Record* _data;
}; };
// Inline Member Functions. // Inline Member Functions.
inline SlotTemplate<Record*>::SlotTemplate ( const string& name, Record* data ) 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 ) inline SlotTemplate<Record*>::SlotTemplate ( string& name, Record* data )
: Slot(name), _data(data) {} : Slot(name), _data(data) {}
@ -331,6 +341,7 @@ template<typename Data>
inline Hurricane::Slot* getSlot( const std::string& name, Data d ) inline Hurricane::Slot* getSlot( const std::string& name, Data d )
{ {
//std::cerr << "getSlot<const string&,Data>( \"" << name << "\" )" << std::endl; //std::cerr << "getSlot<const string&,Data>( \"" << name << "\" )" << std::endl;
//std::cerr << " Data = " << typeid(d).name() << std::endl;
return new Hurricane::SlotTemplate<Data> ( name, d ); return new Hurricane::SlotTemplate<Data> ( name, d );
} }
@ -339,6 +350,7 @@ template<typename Data>
inline Hurricane::Slot* getSlot( const std::string& name, Data* d ) inline Hurricane::Slot* getSlot( const std::string& name, Data* d )
{ {
//std::cerr << "getSlot<const string&,Data*>( \"" << name << "\" )" << std::endl; //std::cerr << "getSlot<const string&,Data*>( \"" << name << "\" )" << std::endl;
//std::cerr << " Data = " << typeid(d).name() << std::endl;
return new Hurricane::SlotTemplate<Data*> ( name, d ); return new Hurricane::SlotTemplate<Data*> ( name, d );
} }

30
unittests/CMakeLists.txt Normal file
View File

@ -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)

View File

@ -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 )

197
unittests/src/unittests.cpp Normal file
View File

@ -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;
}