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_FILTERKERNEL_H
00043 #define QTCONCURRENT_FILTERKERNEL_H
00044
00045 #include <QtCore/qglobal.h>
00046
00047 #ifndef QT_NO_CONCURRENT
00048
00049 #include <QtCore/qtconcurrentiteratekernel.h>
00050 #include <QtCore/qtconcurrentmapkernel.h>
00051 #include <QtCore/qtconcurrentreducekernel.h>
00052
00053 QT_BEGIN_HEADER
00054 QT_BEGIN_NAMESPACE
00055
00056 QT_MODULE(Core)
00057
00058 #ifndef qdoc
00059
00060 namespace QtConcurrent {
00061
00062 template <typename T>
00063 struct qValueType
00064 {
00065 typedef typename T::value_type value_type;
00066 };
00067
00068 template <typename T>
00069 struct qValueType<const T*>
00070 {
00071 typedef T value_type;
00072 };
00073
00074 template <typename T>
00075 struct qValueType<T*>
00076 {
00077 typedef T value_type;
00078 };
00079
00080
00081 template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
00082 class FilterKernel : public IterateKernel<typename Sequence::const_iterator, void>
00083 {
00084 typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
00085 typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
00086 typedef typename ReduceFunctor::result_type T;
00087
00088 Sequence reducedResult;
00089 Sequence &sequence;
00090 KeepFunctor keep;
00091 ReduceFunctor reduce;
00092 Reducer reducer;
00093
00094 public:
00095 FilterKernel(Sequence &_sequence, KeepFunctor _keep, ReduceFunctor _reduce)
00096 : IterateKernelType(const_cast<const Sequence &>(_sequence).begin(), const_cast<const Sequence &>(_sequence).end()), reducedResult(),
00097 sequence(_sequence),
00098 keep(_keep),
00099 reduce(_reduce),
00100 reducer(OrderedReduce)
00101 { }
00102
00103 bool runIteration(typename Sequence::const_iterator it, int index, T *)
00104 {
00105 IntermediateResults<typename Sequence::value_type> results;
00106 results.begin = index;
00107 results.end = index + 1;
00108
00109 if (keep(*it))
00110 results.vector.append(*it);
00111
00112 reducer.runReduce(reduce, reducedResult, results);
00113 return false;
00114 }
00115
00116 bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *)
00117 {
00118 IntermediateResults<typename Sequence::value_type> results;
00119 results.begin = begin;
00120 results.end = end;
00121 results.vector.reserve(end - begin);
00122
00123
00124 typename Sequence::const_iterator it = sequenceBeginIterator;
00125 advance(it, begin);
00126 for (int i = begin; i < end; ++i) {
00127 if (keep(*it))
00128 results.vector.append(*it);
00129 advance(it, 1);
00130 }
00131
00132 reducer.runReduce(reduce, reducedResult, results);
00133 return false;
00134 }
00135
00136 void finish()
00137 {
00138 reducer.finish(reduce, reducedResult);
00139 sequence = reducedResult;
00140 }
00141
00142 inline bool shouldThrottleThread()
00143 {
00144 return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
00145 }
00146
00147 inline bool shouldStartThread()
00148 {
00149 return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
00150 }
00151
00152 typedef void ReturnType;
00153 typedef void ResultType;
00154 };
00155
00156
00157 template <typename ReducedResultType,
00158 typename Iterator,
00159 typename KeepFunctor,
00160 typename ReduceFunctor,
00161 typename Reducer = ReduceKernel<ReduceFunctor,
00162 ReducedResultType,
00163 typename qValueType<Iterator>::value_type> >
00164 class FilteredReducedKernel : public IterateKernel<Iterator, ReducedResultType>
00165 {
00166 ReducedResultType reducedResult;
00167 KeepFunctor keep;
00168 ReduceFunctor reduce;
00169 Reducer reducer;
00170 typedef IterateKernel<Iterator, ReducedResultType> IterateKernelType;
00171
00172 public:
00173 FilteredReducedKernel(Iterator begin,
00174 Iterator end,
00175 KeepFunctor _keep,
00176 ReduceFunctor _reduce,
00177 ReduceOptions reduceOption)
00178 : IterateKernelType(begin, end), reducedResult(), keep(_keep), reduce(_reduce), reducer(reduceOption)
00179 { }
00180
00181 #if 0
00182 FilteredReducedKernel(ReducedResultType initialValue,
00183 KeepFunctor keep,
00184 ReduceFunctor reduce,
00185 ReduceOption reduceOption)
00186 : reducedResult(initialValue), keep(keep), reduce(reduce), reducer(reduceOption)
00187 { }
00188 #endif
00189
00190 bool runIteration(Iterator it, int index, ReducedResultType *)
00191 {
00192 IntermediateResults<typename qValueType<Iterator>::value_type> results;
00193 results.begin = index;
00194 results.end = index + 1;
00195
00196 if (keep(*it))
00197 results.vector.append(*it);
00198
00199 reducer.runReduce(reduce, reducedResult, results);
00200 return false;
00201 }
00202
00203 bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *)
00204 {
00205 IntermediateResults<typename qValueType<Iterator>::value_type> results;
00206 results.begin = begin;
00207 results.end = end;
00208 results.vector.reserve(end - begin);
00209
00210 Iterator it = sequenceBeginIterator;
00211 advance(it, begin);
00212 for (int i = begin; i < end; ++i) {
00213 if (keep(*it))
00214 results.vector.append(*it);
00215 advance(it, 1);
00216 }
00217
00218 reducer.runReduce(reduce, reducedResult, results);
00219 return false;
00220 }
00221
00222 void finish()
00223 {
00224 reducer.finish(reduce, reducedResult);
00225 }
00226
00227 inline bool shouldThrottleThread()
00228 {
00229 return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
00230 }
00231
00232 inline bool shouldStartThread()
00233 {
00234 return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
00235 }
00236
00237 typedef ReducedResultType ReturnType;
00238 typedef ReducedResultType ResultType;
00239 ReducedResultType *result()
00240 {
00241 return &reducedResult;
00242 }
00243 };
00244
00245
00246 template <typename Iterator, typename KeepFunctor>
00247 class FilteredEachKernel : public IterateKernel<Iterator, typename qValueType<Iterator>::value_type>
00248 {
00249 typedef typename qValueType<Iterator>::value_type T;
00250 typedef IterateKernel<Iterator, T> IterateKernelType;
00251
00252 KeepFunctor keep;
00253
00254 public:
00255 typedef T ReturnType;
00256 typedef T ResultType;
00257
00258 FilteredEachKernel(Iterator begin, Iterator end, KeepFunctor _keep)
00259 : IterateKernelType(begin, end), keep(_keep)
00260 { }
00261
00262 void start()
00263 {
00264 if (this->futureInterface)
00265 this->futureInterface->setFilterMode(true);
00266 IterateKernelType::start();
00267 }
00268
00269 bool runIteration(Iterator it, int index, T *)
00270 {
00271 if (keep(*it))
00272 this->reportResult(&(*it), index);
00273 else
00274 this->reportResult(0, index);
00275 return false;
00276 }
00277
00278 bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *)
00279 {
00280 const int count = end - begin;
00281 IntermediateResults<typename qValueType<Iterator>::value_type> results;
00282 results.begin = begin;
00283 results.end = end;
00284 results.vector.reserve(count);
00285
00286 Iterator it = sequenceBeginIterator;
00287 advance(it, begin);
00288 for (int i = begin; i < end; ++i) {
00289 if (keep(*it))
00290 results.vector.append(*it);
00291 advance(it, 1);
00292 }
00293
00294 this->reportResults(results.vector, begin, count);
00295 return false;
00296 }
00297 };
00298
00299 template <typename Iterator, typename KeepFunctor>
00300 inline
00301 ThreadEngineStarter<typename qValueType<Iterator>::value_type>
00302 startFiltered(Iterator begin, Iterator end, KeepFunctor functor)
00303 {
00304 return startThreadEngine(new FilteredEachKernel<Iterator, KeepFunctor>(begin, end, functor));
00305 }
00306
00307 template <typename Sequence, typename KeepFunctor>
00308 inline ThreadEngineStarter<typename Sequence::value_type>
00309 startFiltered(const Sequence &sequence, KeepFunctor functor)
00310 {
00311 typedef SequenceHolder1<Sequence,
00312 FilteredEachKernel<typename Sequence::const_iterator, KeepFunctor>,
00313 KeepFunctor>
00314 SequenceHolderType;
00315 return startThreadEngine(new SequenceHolderType(sequence, functor));
00316 }
00317
00318 template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
00319 inline ThreadEngineStarter<ResultType> startFilteredReduced(const Sequence & sequence,
00320 MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
00321 ReduceOptions options)
00322 {
00323 typedef typename Sequence::const_iterator Iterator;
00324 typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type > Reducer;
00325 typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
00326 typedef SequenceHolder2<Sequence, FilteredReduceType, MapFunctor, ReduceFunctor> SequenceHolderType;
00327 return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, options));
00328 }
00329
00330
00331 template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
00332 inline ThreadEngineStarter<ResultType> startFilteredReduced(Iterator begin, Iterator end,
00333 MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
00334 ReduceOptions options)
00335 {
00336 typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type> Reducer;
00337 typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
00338 return startThreadEngine(new FilteredReduceType(begin, end, mapFunctor, reduceFunctor, options));
00339 }
00340
00341
00342 }
00343
00344 #endif // qdoc
00345
00346 QT_END_NAMESPACE
00347 QT_END_HEADER
00348
00349 #endif // QT_NO_CONCURRENT
00350
00351 #endif