- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# qtconcurrentfilterkernel.h

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 **
    00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    00004 ** All rights reserved.
    00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
    00006 **
    00007 ** This file is part of the QtCore module of the Qt Toolkit.
    00008 **
    00009 ** $QT_BEGIN_LICENSE:LGPL$
    00010 ** Commercial Usage
    00011 ** Licensees holding valid Qt Commercial licenses may use this file in
    00012 ** accordance with the Qt Commercial License Agreement provided with the
    00013 ** Software or, alternatively, in accordance with the terms contained in
    00014 ** a written agreement between you and Nokia.
    00015 **
    00016 ** GNU Lesser General Public License Usage
    00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
    00018 ** General Public License version 2.1 as published by the Free Software
    00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
    00020 ** packaging of this file.  Please review the following information to
    00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
    00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    00023 **
    00024 ** In addition, as a special exception, Nokia gives you certain additional
    00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
    00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
    00027 **
    00028 ** GNU General Public License Usage
    00029 ** Alternatively, this file may be used under the terms of the GNU
    00030 ** General Public License version 3.0 as published by the Free Software
    00031 ** Foundation and appearing in the file LICENSE.GPL included in the
    00032 ** packaging of this file.  Please review the following information to
    00033 ** ensure the GNU General Public License version 3.0 requirements will be
    00034 ** met: http://www.gnu.org/copyleft/gpl.html.
    00035 **
    00036 ** If you have questions regarding the use of this file, please contact
    00037 ** Nokia at qt-info@nokia.com.
    00038 ** $QT_END_LICENSE$
    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 // Implementation of filter
    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 // Implementation of filter-reduce
    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 // Implementation of filter that reports individual results via QFutureInterface
    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 } // namespace QtConcurrent
    00343
    00344 #endif // qdoc
    00345
    00346 QT_END_NAMESPACE
    00347 QT_END_HEADER
    00348
    00349 #endif // QT_NO_CONCURRENT
    00350
    00351 #endif