peoSynchronousMultiStart.h

00001 /* 
00002 * <peoSynchronousMultiStart.h>
00003 * Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2007
00004 * (C) OPAC Team, LIFL, 2002-2007
00005 *
00006 * Sebastien Cahon, Alexandru-Adrian Tantar
00007 *
00008 * This software is governed by the CeCILL license under French law and
00009 * abiding by the rules of distribution of free software.  You can  use,
00010 * modify and/ or redistribute the software under the terms of the CeCILL
00011 * license as circulated by CEA, CNRS and INRIA at the following URL
00012 * "http://www.cecill.info".
00013 *
00014 * As a counterpart to the access to the source code and  rights to copy,
00015 * modify and redistribute granted by the license, users are provided only
00016 * with a limited warranty  and the software's author,  the holder of the
00017 * economic rights,  and the successive licensors  have only  limited liability.
00018 *
00019 * In this respect, the user's attention is drawn to the risks associated
00020 * with loading,  using,  modifying and/or developing or reproducing the
00021 * software by the user in light of its specific status of free software,
00022 * that may mean  that it is complicated to manipulate,  and  that  also
00023 * therefore means  that it is reserved for developers  and  experienced
00024 * professionals having in-depth computer knowledge. Users are therefore
00025 * encouraged to load and test the software's suitability as regards their
00026 * requirements in conditions enabling the security of their systems and/or
00027 * data to be ensured and,  more generally, to use and operate it in the
00028 * same conditions as regards security.
00029 * The fact that you are presently reading this means that you have had
00030 * knowledge of the CeCILL license and that you accept its terms.
00031 *
00032 * ParadisEO WebSite : http://paradiseo.gforge.inria.fr
00033 * Contact: paradiseo-help@lists.gforge.inria.fr
00034 *
00035 */
00036 #ifndef __peoSynchronousMultiStart_h
00037 #define __peoSynchronousMultiStart_h
00038 
00039 #include <vector>
00040 
00041 #include "core/service.h"
00042 #include "core/messaging.h"
00043 
00044 
00045 template < typename EntityType > class peoSynchronousMultiStart : public Service {
00046 
00047 public:
00048 
00049         template < typename AlgorithmType > peoSynchronousMultiStart( AlgorithmType& externalAlgorithm ) { 
00050 
00051                 singularAlgorithm = new Algorithm< AlgorithmType >( externalAlgorithm );
00052                 algorithms.push_back( singularAlgorithm );
00053 
00054                 aggregationFunction = new NoAggregationFunction();
00055         }
00056 
00057         template < typename AlgorithmType, typename AggregationFunctionType > peoSynchronousMultiStart( std::vector< AlgorithmType* >& externalAlgorithms, AggregationFunctionType& externalAggregationFunction ) {
00058 
00059                 for ( unsigned int index = 0; index < externalAlgorithms; index++ ) {
00060 
00061                         algorithms.push_back( new Algorithm< AlgorithmType >( *externalAlgorithms[ index ] ) );
00062                 }
00063 
00064                 aggregationFunction = new Algorithm< AggregationFunctionType >( externalAggregationFunction );
00065         }
00066 
00067 
00068         ~peoSynchronousMultiStart() {
00069 
00070                 for ( unsigned int index = 0; index < data.size(); index++ ) delete data[ index ];
00071                 for ( unsigned int index = 0; index < algorithms.size(); index++ ) delete algorithms[ index ];
00072 
00073                 delete aggregationFunction;
00074         }
00075 
00076 
00077         template < typename Type > void operator()( Type& externalData ) {
00078 
00079                 for ( typename Type::iterator externalDataIterator = externalData.begin(); externalDataIterator != externalData.end(); externalDataIterator++ ) {
00080 
00081                         data.push_back( new DataType< EntityType >( *externalDataIterator ) );
00082                 }
00083                 
00084                 functionIndex = dataIndex = idx = num_term = 0;
00085                 requestResourceRequest( data.size() * algorithms.size() );
00086                 stop();
00087         }
00088 
00089 
00090         template < typename Type > void operator()( const Type& externalDataBegin, const Type& externalDataEnd ) {
00091 
00092                 for ( Type externalDataIterator = externalDataBegin; externalDataIterator != externalDataEnd; externalDataIterator++ ) {
00093 
00094                         data.push_back( new DataType< EntityType >( *externalDataIterator ) );
00095                 }
00096                 
00097                 functionIndex = dataIndex = idx = num_term = 0;
00098                 requestResourceRequest( data.size() * algorithms.size() );
00099                 stop();
00100         }
00101 
00102 
00103         void packData();
00104 
00105         void unpackData();
00106 
00107         void execute();
00108 
00109         void packResult();
00110 
00111         void unpackResult();
00112 
00113         void notifySendingData();
00114 
00115         void notifySendingAllResourceRequests();
00116 
00117 
00118 private:
00119 
00120         template < typename Type > struct DataType;
00121 
00122         struct AbstractDataType {
00123 
00124                 virtual ~AbstractDataType() { }
00125 
00126                 template < typename Type > operator Type& () {
00127 
00128                         return ( dynamic_cast< DataType< Type >& >( *this ) ).data;
00129                 }
00130         };
00131 
00132         template < typename Type > struct DataType : public AbstractDataType {
00133 
00134                 DataType( Type& externalData ) : data( externalData ) { }
00135 
00136                 Type& data;
00137         };
00138 
00139         struct AbstractAlgorithm {
00140 
00141                 virtual ~AbstractAlgorithm() { }
00142 
00143                 virtual void operator()( AbstractDataType& dataTypeInstance ) {}
00144         };
00145 
00146         template < typename AlgorithmType > struct Algorithm : public AbstractAlgorithm {
00147 
00148                 Algorithm( AlgorithmType& externalAlgorithm ) : algorithm( externalAlgorithm ) { }
00149 
00150                 void operator()( AbstractDataType& dataTypeInstance ) { algorithm( dataTypeInstance ); }
00151 
00152                 AlgorithmType& algorithm;
00153         }; 
00154 
00155 
00156 
00157         struct AbstractAggregationAlgorithm {
00158 
00159                 virtual ~AbstractAggregationAlgorithm() { }
00160 
00161                 virtual void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) {};
00162         };
00163 
00164         template < typename AggregationAlgorithmType > struct AggregationAlgorithm : public AbstractAggregationAlgorithm {
00165 
00166                 AggregationAlgorithm( AggregationAlgorithmType& externalAggregationAlgorithm ) : aggregationAlgorithm( externalAggregationAlgorithm ) { }
00167 
00168                 void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) {
00169 
00170                         aggregationAlgorithm( dataTypeInstanceA, dataTypeInstanceB );
00171                 }
00172 
00173                 AggregationAlgorithmType& aggregationAlgorithm;
00174         };
00175 
00176         struct NoAggregationFunction : public AbstractAggregationAlgorithm {
00177 
00178                 void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) {
00179 
00180                         static_cast< EntityType& >( dataTypeInstanceA ) = static_cast< EntityType& >( dataTypeInstanceB );
00181                 }
00182         };
00183 
00184 
00185 
00186         AbstractAlgorithm* singularAlgorithm;
00187 
00188         std::vector< AbstractAlgorithm* > algorithms;
00189         AbstractAggregationAlgorithm* aggregationFunction;
00190 
00191 
00192         EntityType entityTypeInstance;
00193         std::vector< AbstractDataType* > data;
00194 
00195         unsigned idx;
00196         unsigned num_term;
00197         unsigned dataIndex;
00198         unsigned functionIndex;
00199 };
00200 
00201 
00202 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::packData() {
00203 
00204         ::pack( functionIndex );
00205         ::pack( idx );
00206         ::pack( ( EntityType& ) *data[ idx++ ]  );
00207 
00208         // done with functionIndex for the entire data set - moving to another
00209         //  function/algorithm starting all over with the entire data set ( idx is set to 0 )
00210         if ( idx == data.size() ) {
00211 
00212                 ++functionIndex; idx = 0;
00213         }
00214 }
00215 
00216 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::unpackData() {
00217 
00218         ::unpack( functionIndex );
00219         ::unpack( dataIndex );
00220         ::unpack( entityTypeInstance );
00221 }
00222 
00223 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::execute() {
00224 
00225         // wrapping the unpacked data - the definition of an abstract algorithm imposes
00226         // that its internal function operator acts only on abstract data types
00227         AbstractDataType* entityWrapper = new DataType< EntityType >( entityTypeInstance );
00228         algorithms[ functionIndex ]->operator()( *entityWrapper );
00229 
00230         delete entityWrapper;
00231 }
00232 
00233 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::packResult() {
00234 
00235         ::pack( dataIndex );
00236         ::pack( entityTypeInstance );
00237 }
00238 
00239 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::unpackResult() {
00240 
00241         ::unpack( dataIndex );
00242         ::unpack( entityTypeInstance );
00243 
00244         // wrapping the unpacked data - the definition of an abstract algorithm imposes
00245         // that its internal function operator acts only on abstract data types
00246         AbstractDataType* entityWrapper = new DataType< EntityType >( entityTypeInstance );
00247         aggregationFunction->operator()( *data[ dataIndex ], *entityWrapper );
00248         delete entityWrapper;
00249 
00250         num_term++;
00251 
00252         if ( num_term == data.size() * algorithms.size() ) {
00253 
00254                 getOwner()->setActive();
00255                 resume();
00256         }
00257 }
00258 
00259 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::notifySendingData() {
00260 
00261 }
00262 
00263 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::notifySendingAllResourceRequests() {
00264 
00265         getOwner()->setPassive();
00266 }
00267 
00268 
00269 #endif

Generated on Mon Oct 8 11:16:46 2007 for ParadisEO-PEOMovingObjects by  doxygen 1.4.7