42 #ifndef QTCONCURRENT_REDUCEKERNEL_H 43 #define QTCONCURRENT_REDUCEKERNEL_H 45 #include <QtCore/qglobal.h> 47 #ifndef QT_NO_CONCURRENT 49 #include <QtCore/qatomic.h> 50 #include <QtCore/qlist.h> 51 #include <QtCore/qmap.h> 52 #include <QtCore/qmutex.h> 53 #include <QtCore/qthread.h> 54 #include <QtCore/qthreadpool.h> 55 #include <QtCore/qvector.h> 74 ReduceQueueStartLimit = 20,
75 ReduceQueueThrottleLimit = 30
82 class IntermediateResults
103 template <
typename ReduceFunctor,
typename ReduceResultType,
typename T>
108 const ReduceOptions reduceOptions;
111 int progress, resultsMapSize, threadCount;
112 ResultsMap resultsMap;
114 bool canReduce(
int begin)
const 119 && progress == begin));
122 void reduceResult(ReduceFunctor &reduce,
124 const IntermediateResults<T> &result)
126 for (
int i = 0; i < result.vector.size(); ++i) {
127 reduce(r, result.vector.at(i));
131 void reduceResults(ReduceFunctor &reduce,
135 typename ResultsMap::iterator
it = map.begin();
136 while (it != map.end()) {
137 reduceResult(reduce, r, it.value());
143 ReduceKernel(ReduceOptions _reduceOptions)
144 : reduceOptions(_reduceOptions), progress(0), resultsMapSize(0),
148 void runReduce(ReduceFunctor &reduce,
150 const IntermediateResults<T> &result)
153 if (!canReduce(result.begin)) {
155 resultsMap.insert(result.begin, result);
165 reduceResult(reduce, r, result);
169 while (!resultsMap.isEmpty()) {
170 ResultsMap resultsMapCopy = resultsMap;
174 reduceResults(reduce, r, resultsMapCopy);
177 resultsMapSize -= resultsMapCopy.size();
184 reduceResult(reduce, r, result);
188 progress += result.end - result.begin;
191 typename ResultsMap::iterator
it = resultsMap.begin();
192 while (it != resultsMap.end()) {
193 if (it.value().begin != progress)
197 reduceResult(reduce, r, it.value());
201 progress += it.value().end - it.value().begin;
202 it = resultsMap.erase(it);
208 void finish(ReduceFunctor &reduce, ReduceResultType &r)
210 reduceResults(reduce, r, resultsMap);
213 inline bool shouldThrottle()
215 return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
218 inline bool shouldStartThread()
220 return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
224 template <
typename Sequence,
typename Base,
typename Functor1,
typename Functor2>
225 struct SequenceHolder2 :
public Base
227 SequenceHolder2(
const Sequence &_sequence,
230 ReduceOptions reduceOptions)
231 : Base(_sequence.begin(), _sequence.end(), functor1, functor2, reduceOptions),
242 sequence = Sequence();
253 #endif // QT_NO_CONCURRENT #define QT_END_NAMESPACE
This macro expands to.
The QMutex class provides access serialization between threads.
#define Q_DECLARE_FLAGS(Flags, Enum)
The Q_DECLARE_FLAGS() macro expands to.
#define it(className, varName)
void unlock()
Unlocks this mutex locker.
The QVector class is a template class that provides a dynamic array.
void relock()
Relocks an unlocked mutex locker.
#define QT_BEGIN_NAMESPACE
This macro expands to.
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
The Q_DECLARE_OPERATORS_FOR_FLAGS() macro declares global operator|() functions for Flags...
ReduceOption
This enum specifies the order of which results from the map or filter function are passed to the redu...
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
The QtConcurrent namespace provides high-level APIs that make it possible to write multi-threaded pro...
static QThreadPool * globalInstance()
Returns the global QThreadPool instance.
static const KeyPair *const end
The QMap class is a template class that provides a skip-list-based dictionary.