1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtCore module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #ifndef QTCONCURRENT_MAPKERNEL_H
43 #define QTCONCURRENT_MAPKERNEL_H
45 #include <QtCore/qglobal.h>
47 #ifndef QT_NO_CONCURRENT
49 #include <QtCore/qtconcurrentiteratekernel.h>
50 #include <QtCore/qtconcurrentreducekernel.h>
58 namespace QtConcurrent
{
60 // map kernel, works with both parallel-for and parallel-while
61 template <typename Iterator
, typename MapFunctor
>
62 class MapKernel
: public IterateKernel
<Iterator
, void>
66 typedef void ReturnType
;
67 MapKernel(Iterator begin
, Iterator end
, MapFunctor _map
)
68 : IterateKernel
<Iterator
, void>(begin
, end
), map(_map
)
71 bool runIteration(Iterator it
, int, void *)
77 bool runIterations(Iterator sequenceBeginIterator
, int beginIndex
, int endIndex
, void *)
79 Iterator it
= sequenceBeginIterator
;
80 advance(it
, beginIndex
);
81 for (int i
= beginIndex
; i
< endIndex
; ++i
) {
82 runIteration(it
, i
, 0);
90 template <typename ReducedResultType
,
93 typename ReduceFunctor
,
94 typename Reducer
= ReduceKernel
<ReduceFunctor
,
96 typename
MapFunctor::result_type
> >
97 class MappedReducedKernel
: public IterateKernel
<Iterator
, ReducedResultType
>
99 ReducedResultType reducedResult
;
101 ReduceFunctor reduce
;
104 typedef ReducedResultType ReturnType
;
105 MappedReducedKernel(Iterator begin
, Iterator end
, MapFunctor _map
, ReduceFunctor _reduce
, ReduceOptions reduceOptions
)
106 : IterateKernel
<Iterator
, ReducedResultType
>(begin
, end
), reducedResult(), map(_map
), reduce(_reduce
), reducer(reduceOptions
)
109 MappedReducedKernel(ReducedResultType initialValue
,
111 ReduceFunctor _reduce
)
112 : reducedResult(initialValue
), map(_map
), reduce(_reduce
)
115 bool runIteration(Iterator it
, int index
, ReducedResultType
*)
117 IntermediateResults
<typename
MapFunctor::result_type
> results
;
118 results
.begin
= index
;
119 results
.end
= index
+ 1;
121 results
.vector
.append(map(*it
));
122 reducer
.runReduce(reduce
, reducedResult
, results
);
126 bool runIterations(Iterator sequenceBeginIterator
, int begin
, int end
, ReducedResultType
*)
128 IntermediateResults
<typename
MapFunctor::result_type
> results
;
129 results
.begin
= begin
;
131 results
.vector
.reserve(end
- begin
);
133 Iterator it
= sequenceBeginIterator
;
135 for (int i
= begin
; i
< end
; ++i
) {
136 results
.vector
.append(map(*(it
)));
140 reducer
.runReduce(reduce
, reducedResult
, results
);
146 reducer
.finish(reduce
, reducedResult
);
149 bool shouldThrottleThread()
151 return IterateKernel
<Iterator
, ReducedResultType
>::shouldThrottleThread() || reducer
.shouldThrottle();
154 bool shouldStartThread()
156 return IterateKernel
<Iterator
, ReducedResultType
>::shouldStartThread() && reducer
.shouldStartThread();
159 typedef ReducedResultType ResultType
;
160 ReducedResultType
*result()
162 return &reducedResult
;
166 template <typename Iterator
, typename MapFunctor
>
167 class MappedEachKernel
: public IterateKernel
<Iterator
, typename
MapFunctor::result_type
>
170 typedef typename
MapFunctor::result_type T
;
172 typedef T ReturnType
;
173 typedef T ResultType
;
175 MappedEachKernel(Iterator begin
, Iterator end
, MapFunctor _map
)
176 : IterateKernel
<Iterator
, T
>(begin
, end
), map(_map
) { }
178 bool runIteration(Iterator it
, int, T
*result
)
184 bool runIterations(Iterator sequenceBeginIterator
, int begin
, int end
, T
*results
)
187 Iterator it
= sequenceBeginIterator
;
189 for (int i
= begin
; i
< end
; ++i
) {
190 runIteration(it
, i
, results
+ (i
- begin
));
198 template <typename Iterator
, typename Functor
>
199 inline ThreadEngineStarter
<void> startMap(Iterator begin
, Iterator end
, Functor functor
)
201 return startThreadEngine(new MapKernel
<Iterator
, Functor
>(begin
, end
, functor
));
204 template <typename T
, typename Iterator
, typename Functor
>
205 inline ThreadEngineStarter
<T
> startMapped(Iterator begin
, Iterator end
, Functor functor
)
207 return startThreadEngine(new MappedEachKernel
<Iterator
, Functor
>(begin
, end
, functor
));
211 The SequnceHolder class is used to hold a reference to the
212 sequence we are working on.
214 template <typename Sequence
, typename Base
, typename Functor
>
215 struct SequenceHolder1
: public Base
217 SequenceHolder1(const Sequence
&_sequence
, Functor functor
)
218 : Base(_sequence
.begin(), _sequence
.end(), functor
), sequence(_sequence
)
226 // Clear the sequence to make sure all temporaries are destroyed
227 // before finished is signaled.
228 sequence
= Sequence();
232 template <typename T
, typename Sequence
, typename Functor
>
233 inline ThreadEngineStarter
<T
> startMapped(const Sequence
&sequence
, Functor functor
)
235 typedef SequenceHolder1
<Sequence
,
236 MappedEachKernel
<typename
Sequence::const_iterator
, Functor
>, Functor
>
239 return startThreadEngine(new SequenceHolderType(sequence
, functor
));
242 template <typename IntermediateType
, typename ResultType
, typename Sequence
, typename MapFunctor
, typename ReduceFunctor
>
243 inline ThreadEngineStarter
<ResultType
> startMappedReduced(const Sequence
& sequence
,
244 MapFunctor mapFunctor
, ReduceFunctor reduceFunctor
,
245 ReduceOptions options
)
247 typedef typename
Sequence::const_iterator Iterator
;
248 typedef ReduceKernel
<ReduceFunctor
, ResultType
, IntermediateType
> Reducer
;
249 typedef MappedReducedKernel
<ResultType
, Iterator
, MapFunctor
, ReduceFunctor
, Reducer
> MappedReduceType
;
250 typedef SequenceHolder2
<Sequence
, MappedReduceType
, MapFunctor
, ReduceFunctor
> SequenceHolderType
;
251 return startThreadEngine(new SequenceHolderType(sequence
, mapFunctor
, reduceFunctor
, options
));
254 template <typename IntermediateType
, typename ResultType
, typename Iterator
, typename MapFunctor
, typename ReduceFunctor
>
255 inline ThreadEngineStarter
<ResultType
> startMappedReduced(Iterator begin
, Iterator end
,
256 MapFunctor mapFunctor
, ReduceFunctor reduceFunctor
,
257 ReduceOptions options
)
259 typedef ReduceKernel
<ReduceFunctor
, ResultType
, IntermediateType
> Reducer
;
260 typedef MappedReducedKernel
<ResultType
, Iterator
, MapFunctor
, ReduceFunctor
, Reducer
> MappedReduceType
;
261 return startThreadEngine(new MappedReduceType(begin
, end
, mapFunctor
, reduceFunctor
, options
));
264 } // namespace QtConcurrent
271 #endif // QT_NO_CONCURRENT