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

Last change on this file since 554 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}.