// -*- C++ -*-
namespace Kite {
/*! \class Track
* \brief Structure managing one routing track.
*
* \section secTrackPurpose Track Purpose
*
* We use an array of regularly spaced Track as a geometrical
* fast access structure. It allows to know whether an area is used or
* not. The whole area may be seen as a set of adjoining tiles of fixed
* \e width but variable \e length.
*
* The figure (1.b) show, for an horizontal, track the relation
* between y,min,max
and the occupied area of the plane.
* \c min and \c max must take into account segment extensions (\c e) and
* the minimal distance between two rectangles (\c MD) of the same layer.
* We assume that the width of the segment, augmented of all it's
* contraints is no greater than \c TS (in fact it's how \c TS must be
* calculated).
*
* For the whole track array, see RoutingPlane.
*
* \image html Track-0.png "Fig 1: Track Area"
*
*
* \section secTrackImplementation Track Implementation
*
* A Track is implemented with a sorted vector of TrackElement.
* TrackElements from differents nets must not overlap.
* The sorting order is defined as follow:
* - TrackElements are sorted by increasing source (\e min)
* positions.
* - In case of overlap (i.e. belongs to the same net), if
* they share the same source position, then they are sorted
* by \e decreasing length. This way, the longest one will be
* the first encountered when walking through the Track in
* increasing index order.
*
* Figure 2.b shows the details of the Track [1] of
* figure 1.a. Net \b \ show an exemple of overlapping.
*
* \image html Track-1.png "Fig 2: Track Structure"
* \image latex Track-1.pdf "Track Structure" width=0.7\textwidth
*
* In addition to the TrackSegments, the Track also manage additionnal
* informations through a second vector of TrackMarkers. TrackMarker
* are currently used only to hints at how strongly a terminal is
* dependant on that portion of Track to be accessed.
*
*
* \subsection ssecTrackIndexes Indexes vs. Iterators
*
* Numerical indexes have been prefered over iterators because they can
* be used more easily by objects other the Track itself for referencing.
* So internal managment follow the same rule, handling indexes or
* reference to indexes.
*
*
* \subsection ssecTrackUpdate Update Mechanism
*
* When a TrackElement is normaly inserted in a Track, a two way link
* is established. The Track has an entry in it's vector refering to
* TrackElement, and conversely, the TrackElement has it's \c track
* field pointing to it's owning Track.
*
* TrackElement Removal
*
* To remove a TrackElement from a Track, we break one of those two links:
* the TrackElement cease to refer to the owning Track, marking him for
* removal which will occurs at the next track revalidation (Track::doRemoval()).
* In figure 3, the TrackElement belonging to net \b \ is
* marked for removal.
*
* \image html Track-2.png "Fig 3: TrackElement Removal"
*
* TrackElement Insertion
*
* When a TrackElement is inserted into a Track, the two way link is
* immediatly created (but the TrackElement is not yet at it's final
* place in the Track's vector). Before inserting a TrackElement we
* check that it's been already detached (\c track field to \c NULL).
*
* It is at that step that the TrackElement axis is actually updated
* through a call to TrackElement::setAxis().
*
* Revalidation Sequence
*
* After a Track has been modificated either the Track element vector or
* the MarkerElement vector (or both) has been invalidateds. Revalidation
* take place in three steps:
* - Track::doRemoval(), remove all TrackElement marked for removal.
* - Track::insert(), insert the TrackElement into their new Track.
* - Track::doReorder(), sort the TrackElement of the vector, that is, put the
* newly inserted elements at their right place.
*
* Each step must be done for all Tracks before proceeding to the
* next. This way a TrackElement \c track field doesn't get set \e before
* it has been actually removed from it's previous Track.
*
*
*
* \subsection ssecTrackOperations Main Operations on Tracks
*
* Helper Function: Track::getBeginIndex()
*
* Return in \c begin the index of the TrackElement whose minimum is immediately
* below the requested \c position on the Track axis. The second returned
* parameter \c state is a set of flags to tell how the \c begin index
* has to be interpreted.
*
* Helper Function: Track::getOccupiedInterval()
*
* Returns the complete interval of a set of overlapping TrackElement from
* the same net.
*/
//! \enum Track::IndexState
//! Indicates how to compute the bounds of the interval enclosing
//! a given \c position on track axis.
//!
//! \note According to \e position, the interval can be a free interval
//! or a used interval.
//! \var Track::BeginIsTrackMin
//! (implies \c begin=0) there is no TrackElement \e before \c position
//! \var Track::BeginIsSegmentMin
//! The \c begin segment starts \e before \c position and ends \e after.
//! \var Track::BeginIsSegmentMax
//! The \c begin segment starts and ends \e before \c position.
//! \var Track::EndIsTrackMax
//! There is no TrackElement \e after \c position.
//! \var Track::EndIsSegmentMin
//! The \c begin segment starts \e before \c position.
//! \var Track::EndIsNextSegmentMin
//! The \c begin segment starts and ends \e before \c position. So the maximum
//! is given by the \c minimum of the \e next TrackElement.
//! \var Track::EndIsSegmentMax
//! The \c begin segment starts \e before \c position and ends \e after.
//! \var Track::BeforeFirstElement
//! the \c position is before the first TrackElement.
//! \var Track::InsideElement
//! the \c position is inside a TrackElement.
//! \var Track::OutsideElement
//! the \c position is in free zone between two TrackElements.
//! \var Track::AfterLastElement
//! the position is after the end of the last element.
//! \var Track::EmptyTrack
//! the track is still empty.
//! \var Track::BeginMask
//! To extract the \e begin part from a combination of flags.
//! \var Track::EndMask
//! To extract the \e end part from a combination of flags.
//! \var Track::npos;
//! A special index value (greatest integer) meaning that
//! an index is invalid.
//! \function bool Track::isHorizontal () const;
//! \sreturn \true if the Track in horizontal direction.
//! \function bool Track::isVertical () const;
//! \sreturn \true if the Track in vertical direction.
//! \function bool Track::isLocalAssigned () const;
//! \sreturn \true is the Track should be preferentially used for local routing.
//! \function RoutingPlane* Track::getRoutingPlane () const;
//! \sreturn The RoutingPlane owning this Track.
//! \function KiteEngine* Track::getKiteEngine () const;
//! \sreturn The KiteEngine owning this Track.
//! \function unsigned int Track::getDirection () const;
//! \sreturn The direction of the Track, either Katabatic::KbHorizontal or
//! Katabatic::KbVertical.
//! \function RoutingPlane* Track::getIndex () const;
//! \sreturn The index of this Track in the RoutingPlane Track vector.
//! \function unsigned int Track::getDepth () const;
//! \sreturn The depth (as given by the RoutingGauge) of the Track's layer.
//! \function Layer* Track::getLayer () const;
//! \sreturn The \Layer of the Track.
//! \function Layer* Track::getBlockageLayer () const;
//! \sreturn The associated blockage \Layer to the Track's layer.
//! \function DbU::Unit Track::getAxis () const;
//! \sreturn The Axis of the Track.
//! \function DbU::Unit Track::getMin () const;
//! \sreturn The minimal allowed coordinate of the Track.
//! \function DbU::Unit Track::getMax () const;
//! \sreturn The maximal allowed coordinate of the Track.
//! \function Track* Track::getNextTrack () const;
//! \sreturn The next Track in the \RoutingPlane vector. That is the
//! one with the axis immediatly superior.
//! \function Track* Track::getPreviousTrack () const;
//! \sreturn The previous Track in the \RoutingPlane vector. That is the
//! one with the axis immediatly inferior.
//! \function size_t Track::getSize () const;
//! \sreturn The total number of TrackSegment in the Track.
//! \function Point Track::getPosition ( DbU::Unit position ) const;
//! \sreturn the point at \c (position,getAxis()) for horizontal Track
//! at or \c (getAxis(),position) for vertical Track.
//! \function TrackSegment* Track::getSegment ( size_t index ) const;
//! \param index The index of the TrackSegment.
//! \return The TrackSegment at \e index. The result will be \NULL in the
//! follwing cases :
//! - \e index is outside the sorted zone.
//! - \e index points to a hole in the Track.
//! - \e index is equal to Track::npos.
//! \function TrackSegment* Track::getSegment ( DbU::Unit position ) const;
//! \param position The position where to search.
//! \return The TrackSegment whose starting point is immediatly inferior to \e position.
//! \function TrackSegment* Track::getNext ( size_t& index, Net* net ) const;
//! \param index Index of the starting TrackSegment.
//! \param net A \Net to ignore.
//! \return The next TrackSegment (\NULL if not found).
//!
//! Find, starting from TrackSegment at \e index the next TrackSegment
//! ignoring TrackSegment from \e net. \e index is modified to point
//! on the returned TrackSegment. If there's no next TrackSegment (\NULL)
//! then index is set to Track::npos.
//! \function TrackSegment* Track::getPrevious ( size_t& index, Net* net ) const;
//! \param index Index of the starting TrackSegment.
//! \param net A \Net to ignore.
//! \return The previous TrackSegment (\NULL if not found).
//!
//! find, starting from TrackSegment at \e index the previous TrackSegment
//! ignoring TrackSegment from \e net. \e index is modified to point
//! on the returned TrackSegment. If there's no previous TrackSegment (\NULL)
//! then index is set to Track::npos.
//! \function TrackSegment* Track::getNextFixed ( size_t& index ) const;
//! \param index Index of the starting TrackSegment.
//! \return The first previous \e Fixed TrackSegment.
//!
//! find, starting from TrackSegment at \e index the first previous
//! with a \e Fixed attribute set. \e index is modified to point on the
//! returned TrackSegment. If there's no previous TrackSegment (\NULL)
//! then index is set to Track::npos.
//! \function size_t Track::find ( const TrackElement* element ) const;
//! \sreturn the \e index of \e element inside the Track. If the \e element do
//! not belongs to the Track, return Track::npos.
//! \function DbU::Unit Track::getSourcePosition ( size_t index ) const;
//! \sreturn The source position of TrackSegment at index \e index.
//! If \e index is equal to Track::npos, returns zero.
//! \function DbU::Unit Track::getSourcePosition ( vector::iterator it ) const;
//! \sreturn The source position of TrackSegment pointed by iterator \e it.
//! If \e it is equal to \c end() , returns zero.
//! \function DbU::Unit Track::getMinimalPosition ( size_t index, unsigned int state ) const;
//! \sreturn Extract the minimal position from the interval at \c index in accordance
//! to \c state hinting.
//!
//! \sa Track::IndexState.
//! \function DbU::Unit Track::getMaximalPosition ( size_t index, unsigned int state ) const;
//! \sreturn Extract the maximal position from the interval at \c index in accordance
//! to \c state hinting.
//!
//! \sa Track::IndexState.
//! \function Interval Track::getFreeInterval ( DbU::Unit position, Net* net=NULL ) const;
//! \param position where fo find a free interval.
//! \param net for which net to find the free interval.
//! \sreturn The longuest free interval enclosing \e position (may be empty).
//! \function Interval Track::getOccupiedInterval ( size_t& begin ) const;
//! \param begin index of one of the TrackElement set. May be modificated.
//! \sreturn the whole interval used by a set of overlaping TrackSegment.
//!
//! As TrackElement from a same net can overlap, the interval of one of
//! them do not give the full extend of the Track occupation at this point.
//! This function looks for all overlaping segments and returns the
//! merged interval. Additionnaly it sets \c begin to the index of the
//! lowest TrackElement of the set.
//!
//! \image html TrackOccupiedInterval-1.png "Fig 4: Track::getOccuppiedInterval()"
//! \function Interval Track::expandFreeInterval ( size_t& begin, size_t& end, unsigned int state, Net* net ) const;
//! \param begin the lowest used TrackSegment.
//! \param end the highest used TrackSegment.
//! \param state tells how to interpret the \c begin & \c end indexes.
//! \param net the for wich we seek place.
//! \sreturn The longuest free interval between \c ]begin,end[ .
//!
//! Starting from the initial [begin,end]
interval, expand the
//! interval to encompass all free space or segments belonging to \c net.
//! \c state may be used to compute the interval bounds from \c begin
//! and \c end instead of directly using the returned \c interval.
//!
//! \note \c ]begin,end[ must define a free interval between two TrackSegment.
//! \function void Track::getBeginIndex ( DbU::Unit position, size_t& begin, unsigned int& state ) const;
//! \param position The position where to search.
//! \param begin Index of the immediatly inferior TrackElement.
//! \param state how to interpret the returned \c begin.
//!
//! Return in \c begin the index of the TrackElement whose minimum is immediately
//! below the requested \c position on the Track axis. The second returned
//! parameter \c state is a set of flags to tell how the \c begin index
//! has to be interpreted.
//!
//! Flags for the \c state are:
//! - Track::BeginIsTrackMin : (implies \c begin=0) there is no TrackElement
//! \e before \c position.
//! - Track::EndIsSegmentMin : The \c begin segment starts \e before \c position.
//! - Track::BeginIsSegmentMin : The \c begin segment starts \e before \c position
//! and ends \e after.
//! - Track::EndIsSegmentMax : The \c begin segment starts \e before \c position
//! and ends \e after.
//! - Track::BeginIsSegmentMax : The \c begin segment starts and ends \e before
//! \c position.
//! - Track::EndIsNextSegmentMin : The \c begin segment starts and ends \e before
//! \c position. So the maximum is given by the \c minimum of the \e next
//! TrackElement.
//! - Track::EndIsTrackMax : There is no TrackElement \e after \c position.
//!
//! Based on the previous flags, we build the \c state parameter:
//! - Track::BeforeFirstElement : the \c position is before the first TrackElement.
//! - Track::InsideElement : the \c position is inside a TrackElement.
//! - Track::OutsideElement : the \c position is in free zone between two
//! TrackElements.
//! - Track::AfterLastElement : the position is after the end of the last
//! element.
//! - Track::EmptyTrack : the track is still empty.
//!
//! To separate flags relevant to \e begin and \e end informations, two masks
//! are provideds:
//! - Track::BeginMask
//! - Track::EndMask
//!
//! \image html TrackBeginIndex-1.png "Fig 3: Track::getBeginIndex()"
//!
//! Reminder for myself:
//! The Track::getBeginIndex() function relies on the \STL \lower_bound
//! function. \c lower_bound() finds the TrackElement immediately \e superior
//! to \c position (shown on Figure 3 by the \c LB label in white on black).
//!
//! The relation between the returned \c begin index and the position is
//! given through the \c state parameter.
//! \function void Track::getOverlapBounds ( Interval interval, size_t& begin, size_t& end ) const;
//! \param interval the overlaping interval.
//! \param begin where to store the starting bound.
//! \param end where to store the ending bound.
//!
//! find the range of TrackSegment intersecting \e interval.
//! Note that when the \e interval lower bound crosses a set of
//! overlaping intervals from the same \Net, the interval at
//! \e begin will crosses the lower bound but some following
//! of the same \Net may not.
//! \function TrackCost Track::getOverlapCost ( Interval interval, Net* net, size_t begin, size_t end, unsigned int flags ) const;
//! \param interval the overlaping interval.
//! \param net a Net to ignore (null cost).
//! \param begin the starting bound.
//! \param end the ending bound.
//! \param flags passed to the overlap cost function.
//! \return The cost of the overlap.
//!
//! Compute the cost of the overlap of \e interval with the range
//! \c [begin,end] of TrackSegment. Any TrackSegment belonging to
//! \e net will be ignored.
//! \function TrackCost Track::getOverlapCost ( Interval interval, Net* net, unsigned int flags ) const;
//! \param interval the overlaping interval.
//! \param net a Net to ignore (null cost).
//! \param flags passed to the overlap cost function.
//!
//! Compute the overlap cost of \e interval with TrackSegment from
//! the current Track, ignoring thoses belonging to \e net.
//! \function TrackCost Track::getOverlapCost ( TrackElement* segment, unsigned int flags ) const;
//! \param segment under which to compute overlap cost.
//! \param flags passed to the overlap cost function.
//!
//! Compute the overlap cost of \c segment with TrackSegment from
//! the current Track (interval and net are deduced from \c segment).
//! \function void Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, unsigned int& weight ) const;
//! \param interval under which to compute terminal weight.
//! \param net a net to be ignored.
//! \param count incremented of the number of track markers under the
//! \c interval.
//! \param weight incremented of the sum of the weight of the track markers
//! under the \c interval.
//!
//! Compute and return the sum of the weight of the track markers (see TrackMarker)
//! under \c interval ignoring \c net (that is, \e for \c net).
//!
//! \remark The referenced variables \c count and \c weight are not reset to
//! zero by this function. It is of the caller's responsability.
//! \function bool Track::check ( unsigned int& overlaps, const char* message=NULL ) const;
//! \param overlaps The number of overlaping segments.
//! \param message An iformative message, only printed if an error occurs.
//! \return \true if the Track contains no incoherencies.
//!
//! Perform a complete Track check. Looks for the following incoherencies :
//! - TrackSegment do not refers this Track.
//! - TrackSegment is detached (TrackSegment::getTrack() is \NULL).
//! - TrackSegment is hollow, this one is very unlikely as hollow
//! TrackSegment are only created for the \lower_bound.
//! - \NULL pointers (should never occurs, nevertheless...)
//! - Two consecutive TrackSegment from different \Net must not
//! overlap.
//! - For TrackSegment starting from the same position, the
//! longuest must be first.
//! \function void Track::invalidate ();
//! Inconditionnaly invalidate the Track, regardless if it has been
//! modificated. The Track will be forced to be revalidated on closure
//! of the current session.
//! \function void Track::insert ( TrackElement* segment );
//! Adds \e segment to the Track. Must only be used inside a
//! Session. They must appears \e after Track::doRemoval()
//! and \e before Track::doReorder().
//!
//! \sa Kite::Session.
//! \function void Track::insert ( TrackMarker* marker );
//! Adds \e marker to the Track. Must only be used inside a
//! Session.
//!
//! \sa Kite::Session.
//! \function void Track::setSegment ( TrackElement* element, size_t index );
//! Directly affect the Track entry at position \c index to
//! \c element (use with great care).
//!
//! \sa Kite::Session.
//! \function size_t Track::doRemoval ();
//! \sreturn The number of removeds TrackSegment.
//!
//! Suppress all the TrackSegment that have been withdraw from the
//! Track. TrackSegment must be withdraw trough the TrackSegment::detach()
//! method which sets their owning Track to \NULL (the removal criterion).
//! It uses the \STL \e remove_if algorithm that put all the to be removed
//! elements at the end of the vector.
//!
//! \sa Kite::Session.
//! \function void Track::doReorder ();
//!
//! (Re)sort the TrackElement of the vector. Must be called \e after:
//! - Track::doRemoval() so no detached TrackSegment are presents.
//! - All calls to Track::insert(), as the newly inserted elements
//! are put at the back of the vector.
//!
//! \sa Kite::Session.
}