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