00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef QTCONCURRENT_MAPKERNEL_H
00043 #define QTCONCURRENT_MAPKERNEL_H
00044
00045 #include <QtCore/qglobal.h>
00046
00047 #ifndef QT_NO_CONCURRENT
00048
00049 #include <QtCore/qtconcurrentiteratekernel.h>
00050 #include <QtCore/qtconcurrentreducekernel.h>
00051
00052 QT_BEGIN_HEADER
00053 QT_BEGIN_NAMESPACE
00054
00055 QT_MODULE(Core)
00056
00057 #ifndef qdoc
00058 namespace QtConcurrent {
00059
00060
00061 template <typename Iterator, typename MapFunctor>
00062 class MapKernel : public IterateKernel<Iterator, void>
00063 {
00064 MapFunctor map;
00065 public:
00066 typedef void ReturnType;
00067 MapKernel(Iterator begin, Iterator end, MapFunctor _map)
00068 : IterateKernel<Iterator, void>(begin, end), map(_map)
00069 { }
00070
00071 bool runIteration(Iterator it, int, void *)
00072 {
00073 map(*it);
00074 return false;
00075 }
00076
00077 bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, void *)
00078 {
00079 Iterator it = sequenceBeginIterator;
00080 advance(it, beginIndex);
00081 for (int i = beginIndex; i < endIndex; ++i) {
00082 runIteration(it, i, 0);
00083 advance(it, 1);
00084 }
00085
00086 return false;
00087 }
00088 };
00089
00090 template <typename ReducedResultType,
00091 typename Iterator,
00092 typename MapFunctor,
00093 typename ReduceFunctor,
00094 typename Reducer = ReduceKernel<ReduceFunctor,
00095 ReducedResultType,
00096 typename MapFunctor::result_type> >
00097 class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType>
00098 {
00099 ReducedResultType reducedResult;
00100 MapFunctor map;
00101 ReduceFunctor reduce;
00102 Reducer reducer;
00103 public:
00104 typedef ReducedResultType ReturnType;
00105 MappedReducedKernel(Iterator begin, Iterator end, MapFunctor _map, ReduceFunctor _reduce, ReduceOptions reduceOptions)
00106 : IterateKernel<Iterator, ReducedResultType>(begin, end), reducedResult(), map(_map), reduce(_reduce), reducer(reduceOptions)
00107 { }
00108
00109 MappedReducedKernel(ReducedResultType initialValue,
00110 MapFunctor _map,
00111 ReduceFunctor _reduce)
00112 : reducedResult(initialValue), map(_map), reduce(_reduce)
00113 { }
00114
00115 bool runIteration(Iterator it, int index, ReducedResultType *)
00116 {
00117 IntermediateResults<typename MapFunctor::result_type> results;
00118 results.begin = index;
00119 results.end = index + 1;
00120
00121 results.vector.append(map(*it));
00122 reducer.runReduce(reduce, reducedResult, results);
00123 return false;
00124 }
00125
00126 bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *)
00127 {
00128 IntermediateResults<typename MapFunctor::result_type> results;
00129 results.begin = begin;
00130 results.end = end;
00131 results.vector.reserve(end - begin);
00132
00133 Iterator it = sequenceBeginIterator;
00134 advance(it, begin);
00135 for (int i = begin; i < end; ++i) {
00136 results.vector.append(map(*(it)));
00137 advance(it, 1);
00138 }
00139
00140 reducer.runReduce(reduce, reducedResult, results);
00141 return false;
00142 }
00143
00144 void finish()
00145 {
00146 reducer.finish(reduce, reducedResult);
00147 }
00148
00149 bool shouldThrottleThread()
00150 {
00151 return IterateKernel<Iterator, ReducedResultType>::shouldThrottleThread() || reducer.shouldThrottle();
00152 }
00153
00154 bool shouldStartThread()
00155 {
00156 return IterateKernel<Iterator, ReducedResultType>::shouldStartThread() && reducer.shouldStartThread();
00157 }
00158
00159 typedef ReducedResultType ResultType;
00160 ReducedResultType *result()
00161 {
00162 return &reducedResult;
00163 }
00164 };
00165
00166 template <typename Iterator, typename MapFunctor>
00167 class MappedEachKernel : public IterateKernel<Iterator, typename MapFunctor::result_type>
00168 {
00169 MapFunctor map;
00170 typedef typename MapFunctor::result_type T;
00171 public:
00172 typedef T ReturnType;
00173 typedef T ResultType;
00174
00175 MappedEachKernel(Iterator begin, Iterator end, MapFunctor _map)
00176 : IterateKernel<Iterator, T>(begin, end), map(_map) { }
00177
00178 bool runIteration(Iterator it, int, T *result)
00179 {
00180 *result = map(*it);
00181 return true;
00182 }
00183
00184 bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *results)
00185 {
00186
00187 Iterator it = sequenceBeginIterator;
00188 advance(it, begin);
00189 for (int i = begin; i < end; ++i) {
00190 runIteration(it, i, results + (i - begin));
00191 advance(it, 1);
00192 }
00193
00194 return true;
00195 }
00196 };
00197
00198 template <typename Iterator, typename Functor>
00199 inline ThreadEngineStarter<void> startMap(Iterator begin, Iterator end, Functor functor)
00200 {
00201 return startThreadEngine(new MapKernel<Iterator, Functor>(begin, end, functor));
00202 }
00203
00204 template <typename T, typename Iterator, typename Functor>
00205 inline ThreadEngineStarter<T> startMapped(Iterator begin, Iterator end, Functor functor)
00206 {
00207 return startThreadEngine(new MappedEachKernel<Iterator, Functor>(begin, end, functor));
00208 }
00209
00210
00211
00212
00213
00214 template <typename Sequence, typename Base, typename Functor>
00215 struct SequenceHolder1 : public Base
00216 {
00217 SequenceHolder1(const Sequence &_sequence, Functor functor)
00218 : Base(_sequence.begin(), _sequence.end(), functor), sequence(_sequence)
00219 { }
00220
00221 Sequence sequence;
00222
00223 void finish()
00224 {
00225 Base::finish();
00226
00227
00228 sequence = Sequence();
00229 }
00230 };
00231
00232 template <typename T, typename Sequence, typename Functor>
00233 inline ThreadEngineStarter<T> startMapped(const Sequence &sequence, Functor functor)
00234 {
00235 typedef SequenceHolder1<Sequence,
00236 MappedEachKernel<typename Sequence::const_iterator , Functor>, Functor>
00237 SequenceHolderType;
00238
00239 return startThreadEngine(new SequenceHolderType(sequence, functor));
00240 }
00241
00242 template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
00243 inline ThreadEngineStarter<ResultType> startMappedReduced(const Sequence & sequence,
00244 MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
00245 ReduceOptions options)
00246 {
00247 typedef typename Sequence::const_iterator Iterator;
00248 typedef ReduceKernel<ReduceFunctor, ResultType, IntermediateType> Reducer;
00249 typedef MappedReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> MappedReduceType;
00250 typedef SequenceHolder2<Sequence, MappedReduceType, MapFunctor, ReduceFunctor> SequenceHolderType;
00251 return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, options));
00252 }
00253
00254 template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
00255 inline ThreadEngineStarter<ResultType> startMappedReduced(Iterator begin, Iterator end,
00256 MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
00257 ReduceOptions options)
00258 {
00259 typedef ReduceKernel<ReduceFunctor, ResultType, IntermediateType> Reducer;
00260 typedef MappedReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> MappedReduceType;
00261 return startThreadEngine(new MappedReduceType(begin, end, mapFunctor, reduceFunctor, options));
00262 }
00263
00264 }
00265
00266 #endif //qdoc
00267
00268 QT_END_NAMESPACE
00269 QT_END_HEADER
00270
00271 #endif // QT_NO_CONCURRENT
00272
00273 #endif