// This file is part of the Coriolis Project. // Copyright (C) Laboratoire LIP6 - Departement ASIM // Universite Pierre et Marie Curie // // Main contributors : // Christophe Alexandre // Sophie Belloeil // Hugo Clément // Jean-Paul Chaput // Damien Dupuis // Christian Masson // Marek Sroka // // The Coriolis Project is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // The Coriolis Project 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 GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with the Coriolis Project; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // // License-Tag // // Date : 19/07/2006 // Author : Christophe Alexandre // // Authors-Tag #include "SubRow.h" #include "Surface.h" #include "Row.h" namespace MAUKA { Row::Row(Cell* cell, Surface* surface, const Box& box, bool orientation) :Inherit(cell, box) , _surface(surface) , _subRowVector() , _subRowXMax() , _subRowXMinInv() , _orientation(orientation) , _size(0) , _capa(0) {} Row* Row::Create(Cell* cell, Surface* surface, const Box& box, bool orientation) { if (!surface) throw Error("Can't create " + _TName("Row") + " : empty surface"); Row* row = new Row(cell, surface, box, orientation); row->_PostCreate(); return row; } void Row::_PreDelete() { Inherit::_PreDelete(); for (SubRowVector::iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { (*srit)->Delete(); } _subRowVector.clear(); } namespace { struct SubRowSortByX { bool operator()(const SubRow* subrow1, const SubRow* subrow2) const { return subrow1->GetXMin() < subrow2->GetXMin(); } }; } void Row::_InsertSubRow(SubRow* subrow) { if (_subRowVector.size() == 0) _subRowVector.push_back(subrow); else { SubRowVector::iterator srvit = lower_bound(_subRowVector.begin(), _subRowVector.end(), subrow, SubRowSortByX()); if (srvit == _subRowVector.end()) { _subRowVector.push_back(subrow); } else if ((*srvit)->GetXMin() == subrow->GetXMin()) { throw Error("Bug in SubRow insertion"); } else { _subRowVector.insert(srvit, subrow); } } _box.Merge(subrow->GetBox()); } void Row::_ComputeSubRows() { _subRowXMax.clear(); _subRowXMinInv.clear(); for (unsigned i = 0; i < _subRowVector.size(); i++) { SubRow* subRow = _subRowVector[i]; _subRowXMax[subRow->GetXMax()] = i; _subRowXMinInv[subRow->GetXMin()] = i; } } SubRow* Row::GetSubRowBetween(Unit x1, Unit x2) { assert(x1 <= x2); assert(x1 >= GetXMin()); assert(x2 <= GetXMax()); if (_subRowVector.size() == 1) return _subRowVector[0]; SubRowXMax::iterator rinf = _subRowXMax.upper_bound(x1); SubRowXMax::iterator rsup = _subRowXMinInv.upper_bound(x2); unsigned randidx = rinf->second + (unsigned)((rsup->second - rinf->second + 1) * (rand() / (RAND_MAX+1.0))); #if 0 //cerr << x1 << endl; //cerr << x2 << endl; for (SubRowXMax::iterator srit = _subRowXMax.begin(); srit != _subRowXMax.end(); srit++) { cerr << srit->first << "," << srit->second << endl; } cerr << randidx << endl << endl;; #endif return _subRowVector[randidx]; } void Row::_AddSize(Unit value) { _size += value; } double Row::GetCost() const { return abs(GetValue(_size - _capa)); } double Row::GetBinCost() const { double binCost = 0.0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { binCost += (*srit)->GetBinCost(); } return binCost; } Unit Row::GetBinsSize() const { Unit totalBinsSize = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { totalBinsSize += (*srit)->GetBinsSize(); } return totalBinsSize; } Unit Row::GetBinsCapa() const { Unit totalBinsCapa = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { totalBinsCapa += (*srit)->GetBinsCapa(); } return totalBinsCapa; } Unit Row::GetSubRowsWidth() const { Unit subRowsWidth = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { subRowsWidth += (*srit)->GetWidth(); } return subRowsWidth; } Unit Row::GetSubRowsCapa() const { Unit totalSubRowsCapa = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { totalSubRowsCapa += (*srit)->GetCapa(); } return totalSubRowsCapa; } void Row::_ComputeCapacity(double margin) { _capa = 0; for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { (*srit)->_ComputeCapacity(margin); _capa += (*srit)->_capa; } } void Row::DisplayBinHits() const { for (SubRowVector::const_iterator srit = _subRowVector.begin(); srit != _subRowVector.end(); srit++) { (*srit)->DisplayBinHits(); } } Cell* Row::GetCell() const { return _surface->GetCell(); } }