source: trunk/src/corelib/concurrent/qtconcurrentmap.cpp@ 467

Last change on this file since 467 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 15.3 KB
Line 
1 /****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \namespace QtConcurrent
44 \since 4.4
45 \brief The QtConcurrent namespace provides high-level APIs that make it
46 possible to write multi-threaded programs without using low-level
47 threading primitives.
48
49 See the \l {threads.html#qtconcurrent-intro}{Qt Concurrent} section in the \l{threads.html}{threading} documentation.
50
51 \ingroup thread
52*/
53
54/*!
55 \namespace QtConcurrent::internal
56 \internal
57
58 \brief The QtConcurrent::internal namespace contains QtConcurrent
59 implementation details.
60
61 \ingroup thread
62*/
63
64/*!
65 \enum QtConcurrent::ReduceOption
66 This enum specifies the order of which results from the map or filter
67 function are passed to the reduce function.
68
69 \value UnorderedReduce Reduction is done in an arbitrary order.
70 \value OrderedReduce Reduction is done in the order of the
71 original sequence.
72 \value SequentialReduce Reduction is done sequentally: only one
73 thread will enter the reduce function at a time. (Parallel reduction
74 might be supported in a future version of Qt Concurrent.)
75*/
76
77/*!
78 \headerfile <QtConcurrentMap>
79 \title Concurrent Map and Map-Reduce
80 \ingroup threading
81
82 \brief The <QtConcurrentMap> header provides concurrent Map and MapReduce.
83
84 These functions are a part of the \l {threads.html#qtconcurrent-intro}{Qt Concurrent} framework.
85
86 The QtConcurrent::map(), QtConcurrent::mapped() and
87 QtConcurrent::mappedReduced() functions run computations in parallel on
88 the items in a sequence such as a QList or a QVector. QtConcurrent::map()
89 modifies a sequence in-place, QtConcurrent::mapped() returns a new
90 sequence containing the modified content, and QtConcurrent::mappedReduced()
91 returns a single result.
92
93 Each of the above functions has a blocking variant that returns
94 the final result instead of a QFuture. You use them in the same
95 way as the asynchronous variants.
96
97 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 7
98
99 Note that the result types above are not QFuture objects, but real result
100 types (in this case, QList<QImage> and QImage).
101
102 \section1 Concurrent Map
103
104 QtConcurrent::mapped() takes an input sequence and a map function. This map
105 function is then called for each item in the sequence, and a new sequence
106 containing the return values from the map function is returned.
107
108 The map function must be of the form:
109
110 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 0
111
112 T and U can be any type (and they can even be the same type), but T must
113 match the type stored in the sequence. The function returns the modified
114 or \e mapped content.
115
116 This example shows how to apply a scale function to all the items
117 in a sequence:
118
119 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 1
120
121 The results of the map are made available through QFuture. See the
122 QFuture and QFutureWatcher documentation for more information on how to
123 use QFuture in your applications.
124
125 If you want to modify a sequence in-place, use QtConcurrent::map(). The
126 map function must then be of the form:
127
128 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 2
129
130 Note that the return value and return type of the map function are not
131 used.
132
133 Using QtConcurrent::map() is similar to using QtConcurrent::mapped():
134
135 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 3
136
137 Since the sequence is modified in place, QtConcurrent::map() does not
138 return any results via QFuture. However, you can still use QFuture and
139 QFutureWatcher to monitor the status of the map.
140
141 \section1 Concurrent Map-Reduce
142
143 QtConcurrent::mappedReduced() is similar to QtConcurrent::mapped(), but
144 instead of returning a sequence with the new results, the results are
145 combined into a single value using a reduce function.
146
147 The reduce function must be of the form:
148
149 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 4
150
151 T is the type of the final result, U is the return type of the map
152 function. Note that the return value and return type of the reduce
153 function are not used.
154
155 Call QtConcurrent::mappedReduced() like this:
156
157 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 5
158
159 The reduce function will be called once for each result returned by the map
160 function, and should merge the \e{intermediate} into the \e{result}
161 variable. QtConcurrent::mappedReduced() guarantees that only one thread
162 will call reduce at a time, so using a mutex to lock the result variable
163 is not neccesary. The QtConcurrent::ReduceOptions enum provides a way to
164 control the order in which the reduction is done. If
165 QtConcurrent::UnorderedReduce is used (the default), the order is
166 undefined, while QtConcurrent::OrderedReduce ensures that the reduction
167 is done in the order of the original sequence.
168
169 \section1 Additional API Features
170
171 \section2 Using Iterators instead of Sequence
172
173 Each of the above functions has a variant that takes an iterator range
174 instead of a sequence. You use them in the same way as the sequence
175 variants:
176
177 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 6
178
179 \section2 Blocking Variants
180
181 Each of the above functions has a blocking variant that returns
182 the final result instead of a QFuture. You use them in the same
183 way as the asynchronous variants.
184
185 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 7
186
187 Note that the result types above are not QFuture objects, but real result
188 types (in this case, QList<QImage> and QImage).
189
190 \section2 Using Member Functions
191
192 QtConcurrent::map(), QtConcurrent::mapped(), and
193 QtConcurrent::mappedReduced() accept pointers to member functions.
194 The member function class type must match the type stored in the sequence:
195
196 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 8
197
198 Note that when using QtConcurrent::mappedReduced(), you can mix the use of
199 normal and member functions freely:
200
201 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 9
202
203 \section2 Using Function Objects
204
205 QtConcurrent::map(), QtConcurrent::mapped(), and
206 QtConcurrent::mappedReduced() accept function objects, which can be used to
207 add state to a function call. The result_type typedef must define the
208 result type of the function call operator:
209
210 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 14
211
212 \section2 Using Bound Function Arguments
213
214 Note that Qt does not provide support for bound functions. This is
215 provided by 3rd party libraries like
216 \l{http://www.boost.org/libs/bind/bind.html}{Boost} or
217 \l{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf}{C++
218 TR1 Library Extensions}.
219
220 If you want to use a map function that takes more than one argument you can
221 use boost::bind() or std::tr1::bind() to transform it onto a function that
222 takes one argument.
223
224 As an example, we'll use QImage::scaledToWidth():
225
226 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 10
227
228 scaledToWidth takes three arguments (including the "this" pointer) and
229 can't be used with QtConcurrent::mapped() directly, because
230 QtConcurrent::mapped() expects a function that takes one argument. To use
231 QImage::scaledToWidth() with QtConcurrent::mapped() we have to provide a
232 value for the \e{width} and the \e{transformation mode}:
233
234 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 11
235
236 The return value from boost::bind() is a function object (functor) with
237 the following signature:
238
239 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 12
240
241 This matches what QtConcurrent::mapped() expects, and the complete example
242 becomes:
243
244 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp 13
245*/
246
247/*!
248 \fn QFuture<void> QtConcurrent::map(Sequence &sequence, MapFunction function)
249 \relates <QtConcurrentMap>
250
251 Calls \a function once for each item in \a sequence. The \a function is
252 passed a reference to the item, so that any modifications done to the item
253 will appear in \a sequence.
254*/
255
256/*!
257 \fn QFuture<void> QtConcurrent::map(Iterator begin, Iterator end, MapFunction function)
258 \relates <QtConcurrentMap>
259
260 Calls \a function once for each item from \a begin to \a end. The
261 \a function is passed a reference to the item, so that any modifications
262 done to the item will appear in the sequence which the iterators belong to.
263*/
264
265/*!
266 \fn QFuture<T> QtConcurrent::mapped(const Sequence &sequence, MapFunction function)
267 \relates <QtConcurrentMap>
268
269 Calls \a function once for each item in \a sequence and returns a future
270 with each mapped item as a result. You can use QFuture::const_iterator or
271 QFutureIterator to iterate through the results.
272*/
273
274/*!
275 \fn QFuture<T> QtConcurrent::mapped(ConstIterator begin, ConstIterator end, MapFunction function)
276 \relates <QtConcurrentMap>
277
278 Calls \a function once for each item from \a begin to \a end and returns a
279 future with each mapped item as a result. You can use
280 QFuture::const_iterator or QFutureIterator to iterate through the results.
281*/
282
283/*!
284 \fn QFuture<T> QtConcurrent::mappedReduced(const Sequence &sequence,
285 MapFunction mapFunction, ReduceFunction reduceFunction,
286 QtConcurrent::ReduceOptions reduceOptions)
287
288 \relates <QtConcurrentMap>
289
290 Calls \a mapFunction once for each item in \a sequence. The return value of
291 each \a mapFunction is passed to \a reduceFunction.
292
293 Note that while \a mapFunction is called concurrently, only one thread at a
294 time will call \a reduceFunction. The order in which \a reduceFunction is
295 called is determined by \a reduceOptions.
296*/
297
298/*!
299 \fn QFuture<T> QtConcurrent::mappedReduced(ConstIterator begin,
300 ConstIterator end, MapFunction mapFunction, ReduceFunction reduceFunction,
301 QtConcurrent::ReduceOptions reduceOptions)
302
303 \relates <QtConcurrentMap>
304
305 Calls \a mapFunction once for each item from \a begin to \a end. The return
306 value of each \a mapFunction is passed to \a reduceFunction.
307
308 Note that while \a mapFunction is called concurrently, only one thread at a
309 time will call \a reduceFunction. By default, the order in which
310 \a reduceFunction is called is undefined.
311
312 \note QtConcurrent::OrderedReduce results in the ordered reduction.
313*/
314
315/*!
316 \fn void QtConcurrent::blockingMap(Sequence &sequence, MapFunction function)
317
318 Calls \a function once for each item in \a sequence. The \a function is
319 passed a reference to the item, so that any modifications done to the item
320 will appear in \a sequence.
321
322 \note This function will block until all items in the sequence have been processed.
323
324 \sa map()
325*/
326
327/*!
328 \fn void QtConcurrent::blockingMap(Iterator begin, Iterator end, MapFunction function)
329
330 Calls \a function once for each item from \a begin to \a end. The
331 \a function is passed a reference to the item, so that any modifications
332 done to the item will appear in the sequence which the iterators belong to.
333
334 \note This function will block until the iterator reaches the end of the
335 sequence being processed.
336
337 \sa map()
338*/
339
340/*!
341 \fn T QtConcurrent::blockingMapped(const Sequence &sequence, MapFunction function)
342
343 Calls \a function once for each item in \a sequence and returns a Sequence containing
344 the results. The type of the results will match the type returned my the MapFunction.
345
346 \note This function will block until all items in the sequence have been processed.
347
348 \sa mapped()
349*/
350
351/*!
352 \fn T QtConcurrent::blockingMapped(ConstIterator begin, ConstIterator end, MapFunction function)
353
354 Calls \a function once for each item from \a begin to \a end and returns a
355 container with the results. Specify the type of container as the a template
356 argument, like this:
357
358 \code
359 QList<int> ints = QtConcurrent::blockingMapped<QList<int> >(beginIterator, endIterator, fn);
360 \endcode
361
362 \note This function will block until the iterator reaches the end of the
363 sequence being processed.
364
365 \sa mapped()
366*/
367
368/*!
369 \fn T QtConcurrent::blockingMappedReduced(const Sequence &sequence, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
370
371 \relates <QtConcurrentMap>
372
373 Calls \a mapFunction once for each item in \a sequence. The return value of
374 each \a mapFunction is passed to \a reduceFunction.
375
376 Note that while \a mapFunction is called concurrently, only one thread at a
377 time will call \a reduceFunction. The order in which \a reduceFunction is
378 called is determined by \a reduceOptions.
379
380 \note This function will block until all items in the sequence have been processed.
381
382 \sa mapped()
383*/
384
385/*!
386 \fn T QtConcurrent::blockingMappedReduced(ConstIterator begin, ConstIterator end, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
387
388 \relates <QtConcurrentMap>
389
390 Calls \a mapFunction once for each item from \a begin to \a end. The return
391 value of each \a mapFunction is passed to \a reduceFunction.
392
393 Note that while \a mapFunction is called concurrently, only one thread at a
394 time will call \a reduceFunction. The order in which \a reduceFunction is
395 called is undefined.
396
397 \note This function will block until the iterator reaches the end of the
398 sequence being processed.
399
400 \sa blockingMappedReduced()
401*/
Note: See TracBrowser for help on using the repository browser.