/* * Scheduler.hh * * Created on: Dec 3, 2012 * Author: f.casimir */ #ifndef Scheduler_HH_ #define Scheduler_HH_ #include "vector" #include #include "AMDA_exception.hh" #include "DicError.hh" #include "Parameter.hh" #include "ParamData.hh" #include "Operation.hh" using namespace std; using namespace boost; using namespace AMDA::Parameters; namespace AMDA { namespace Merge { /** * name space of base class, implementation are template class */ namespace Base { /** * @brief abstract class can write in paramDatas output * @details is the strategy interface in the Strategy pattern * the implementation arc made by template Pusher class */ class Pusher { public: virtual ~Pusher() {} virtual void write(unsigned int /*index*/) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("Pusher operation not supported")); } }; /** * @brief the operation of MergeProcess * @detail write one line by paramData input * The implementation are made by template class. */ class Scheduler : public Operation { public: /** * @brief Constructor */ Scheduler(Process& pProcess) : Operation(pProcess) {} /** * @brief Destructor */ virtual ~Scheduler() { for(auto operation : _operationList) { delete operation; } } /** * @brief add an input paramData */ virtual void push_back(ParamData*) = 0; protected: /** * @brief store a Base::Pusher by ParamDataInput */ std::vector _operationList; }; } // Base; /** * Definition of Pucher class template */ template class Pusher : public Base::Pusher { public: /** * @brief Constructor */ Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} private: /** * @brief paramData Output */ ParamOutput& _paramOutput; /** * @brief paramData Input */ ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput and ParamInput are ParamDataSpec with ElType are standard C++ type as float */ template class Pusher >,ParamDataSpec > > : public Base::Pusher { public: typedef ParamDataSpec > ParamOutput; typedef ParamDataSpec > ParamInput; /** * @brief Constructor */ Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} /** * @overload operation::write(unsigned int index) */ void write(unsigned int index) { _paramOutput.pushTime(_paramInput.getTime(index)); const std::vector& lData = _paramInput.getDataList()[index]; _paramOutput.getDataList().push_back(std::vector(lData.begin(),lData.end())); } private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput and ParamInput are ParamDataSpec */ template<> class Pusher >,ParamDataSpec > > : public Base::Pusher { public: typedef ParamDataSpec > ParamOutput; typedef ParamDataSpec > ParamInput; /** * @brief Constructor */ Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} /** * @overload operation::write(unsigned int index) */ void write(unsigned int index) { _paramOutput.pushTime(_paramInput.getTime(index)); _paramOutput.getDataList().push_back(_paramInput.getDataList()[index]); } private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput are ParamDataSpec * and ParamInput are ParamDataSpec with ElType are standard C++ type as float * throw an exception if use @see Base::Pusher::write() */ template class Pusher >,ParamDataSpec > > : public Base::Pusher { public: typedef ParamDataSpec > ParamOutput; typedef ParamDataSpec > ParamInput; /** * @brief Constructor */ Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput are ParamDataSpec with ElType are standard C++ type as float * and ParamInput are ParamDataSpec * throw an exception if use @see Base::Pusher::write() */ template class Pusher >,ParamDataSpec > > : public Base::Pusher { public: typedef ParamDataSpec > ParamOutput; typedef ParamDataSpec > ParamInput; Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput and ParamInput are ParamDataSpec with ElType are standard C++ type as float */ template class Pusher >,ParamDataSpec > > : public Base::Pusher { public: typedef ParamDataSpec > ParamOutput; typedef ParamDataSpec > ParamInput; /** * @brief Constructor */ Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} /** * @overload operation::write(unsigned int index) */ void write(unsigned int index) { _paramOutput.pushTime(_paramInput.getTime(index)); _paramOutput.getDataList().push_back(_paramInput.getDataList()[index]); } private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput and ParamInput are ParamDataSpec with ElType are standard C++ type as float */ template class Pusher,ParamDataSpec > : public Base::Pusher { public: typedef ParamDataSpec ParamOutput; typedef ParamDataSpec ParamInput; Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} /** * @overload operation::write(unsigned int index) */ void write(unsigned int index) { _paramOutput.pushTime(_paramInput.getTime(index)); _paramOutput.getDataList().push_back(_paramInput.getDataList()[index]); } private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput is is ParamDataSpec * and ParamInput is any * throw an exception if use @see Base::Pusher::write() */ template class Pusher,TParamInput> : public Base::Pusher { public: typedef ParamDataSpec ParamOutput; typedef TParamInput ParamInput; Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput is any * and ParamInput are ParamDataSpec * throw an exception if use @see Base::Pusher::write() */ template class Pusher > : public Base::Pusher { public: typedef TParamOutput ParamOutput; typedef ParamDataSpec ParamInput; Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief vector implementation of Pusher template * @detail ParamOutput and ParamInput are ParamDataSpec * throw an exception if use @see Base::Pusher::write() */ template<> class Pusher,ParamDataSpec > : public Base::Pusher { public: typedef ParamDataSpec ParamOutput; typedef ParamDataSpec ParamInput; Pusher(ParamOutput& pParamOutput, ParamInput& pParamInput) : _paramOutput(pParamOutput), _paramInput(pParamInput) {} /** * @overload operation::write(unsigned int index) */ void write(unsigned int index) { _paramOutput.pushTime(_paramInput.getTime(index)); _paramOutput.getDataList().push_back(_paramInput.getDataList()[index]); } private: ParamOutput& _paramOutput; ParamInput& _paramInput; }; /** * @brief Create the specific Pusher class * @details used the visitor pattern for find the good Pusher in function of ParamInput type */ template class PusherCreator : public VisitorOfParamData { public: /** * @brief Constructor. */ PusherCreator(TParamOutput& pOutputParamData,ParamData& pInputParamData) : _outputParamData(pOutputParamData), _operation(nullptr) { pInputParamData.accept(*this); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireShort *) */ void visit(ParamDataScalaireShort *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireFloat *) */ void visit(ParamDataScalaireFloat *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireDouble *) */ void visit(ParamDataScalaireDouble *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireLongDouble *) */ void visit(ParamDataScalaireLongDouble *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireInt *) */ void visit(ParamDataScalaireInt *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataLogicalData *) */ void visit(ParamDataLogicalData *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DShort *) */ void visit(ParamDataTab1DShort *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DFloat *) */ void visit(ParamDataTab1DFloat *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DDouble *) */ void visit(ParamDataTab1DDouble *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DLongDouble *) */ void visit(ParamDataTab1DLongDouble *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DInt *) */ void visit(ParamDataTab1DInt *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DLogicalData *) */ void visit(ParamDataTab1DLogicalData *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DShort *) */ void visit(ParamDataTab2DShort *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DFloat *) */ void visit(ParamDataTab2DFloat *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DDouble *) */ void visit(ParamDataTab2DDouble *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DLongDouble *) */ void visit(ParamDataTab2DLongDouble *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DInt *) */ void visit(ParamDataTab2DInt *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DLogicalData *) */ void visit(ParamDataTab2DLogicalData *pInputParamData) { _operation = new Pusher( _outputParamData,*pInputParamData); } Base::Pusher *getPusher() { return _operation; } private: TParamOutput &_outputParamData; Base::Pusher *_operation; }; /** * @brief Base::Scheduler implementation */ template class Scheduler : public Base::Scheduler { public: Scheduler(Process& pProcess) : Base::Scheduler(pProcess), _paramOutput(new TParamOutput()) { _paramDataOutput=_paramOutput; } /** * @overload Base::Scheduler::write(ParamDataIndexInfo &pParamDataIndexInfo) */ void push_back(ParamData* pInputParam) { PusherCreator lPusherCreator(*_paramOutput,*pInputParam); _operationList.push_back(lPusherCreator.getPusher()); } /** * @overload Operation::write(ParamDataIndexInfo &pParamDataIndexInfo) */ void write(ParamDataIndexInfo &pParamDataIndexInfo) { unsigned int index = pParamDataIndexInfo._startIndex; for (; index< pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; index++) { for(auto operation : _operationList) { operation->write(index); } } } protected: /** * @brief It is the channel of the data shifted. */ TParamOutput *_paramOutput; }; } /* namespace Merge */ } /* namespace AMDA */ #endif /* Scheduler_HH_ */