STXXL  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
scan.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/algo/scan.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2002-2004 Roman Dementiev <[email protected]>
7  * Copyright (C) 2008, 2009 Andreas Beckmann <[email protected]>
8  * Copyright (C) 2013 Timo Bingmann <[email protected]>
9  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef STXXL_ALGO_SCAN_HEADER
16 #define STXXL_ALGO_SCAN_HEADER
17 
18 #include <stxxl/bits/namespace.h>
19 #include <stxxl/bits/mng/config.h>
22 
23 
25 
26 //! \addtogroup stlalgo
27 //! \{
28 
29 /*!
30  * \brief External equivalent of std::for_each, see \ref design_algo_foreach.
31  *
32  * stxxl::for_each applies the function object \c functor to each element in
33  * the range [first, last); \c functor's return value, if any, is
34  * ignored. Applications are performed in forward order, i.e. from first to
35  * last. stxxl::for_each returns the function object after it has been applied
36  * to each element. To overlap I/O and computation \c nbuffers used (a value
37  * at least \a D is recommended). The size of the buffers is derived from the
38  * container that is pointed by the iterators.
39  *
40  * \remark The implementation exploits STXXL buffered streams (computation and I/O overlapped).
41  *
42  * \param begin object of model of \c ext_random_access_iterator concept
43  * \param end object of model of \c ext_random_access_iterator concept
44  * \param functor function object of model of \c std::UnaryFunction concept
45  * \param nbuffers number of buffers (blocks) for internal use (should be at least 2*D )
46  * \return function object \c functor after it has been applied to the each element of the given range
47  *
48  * \warning nested stxxl::for_each are not supported
49  */
50 template <typename ExtIterator, typename UnaryFunction>
51 UnaryFunction for_each(ExtIterator begin, ExtIterator end, UnaryFunction functor, int_type nbuffers = 0)
52 {
53  if (begin == end)
54  return functor;
55 
57 
58  begin.flush(); // flush container
59 
60  if (nbuffers == 0)
61  nbuffers = 2 * config::get_instance()->disks_number();
62 
63  // create prefetching stream,
64  buf_istream_type in(begin.bid(), end.bid() + ((end.block_offset()) ? 1 : 0), nbuffers);
65 
66  ExtIterator cur = begin - begin.block_offset();
67 
68  // leave part of the block before begin untouched (e.g. copy)
69  for ( ; cur != begin; ++cur)
70  {
71  typename ExtIterator::value_type tmp;
72  in >> tmp;
73  }
74 
75  // apply functor to the range [begin,end)
76  for ( ; cur != end; ++cur)
77  {
78  typename ExtIterator::value_type tmp;
79  in >> tmp;
80  functor(tmp);
81  }
82 
83  // leave part of the block after end untouched
84  if (end.block_offset())
85  {
86  ExtIterator _last_block_end = end - end.block_offset() + ExtIterator::block_type::size;
87  for ( ; cur != _last_block_end; ++cur)
88  {
89  typename ExtIterator::value_type tmp;
90  in >> tmp;
91  }
92  }
93 
94  return functor;
95 }
96 
97 
98 /*!
99  * \brief External equivalent of std::for_each (mutating), see \ref design_algo_foreachm
100  *
101  * stxxl::for_each_m applies the function object \c functor to each element in
102  * the range [first, last); \c functor's return value, if any, is
103  * ignored. Applications are performed in forward order, i.e. from first to
104  * last. stxxl::for_each_m returns the function object after it has been
105  * applied to each element. To overlap I/O and computation \c nbuffers are used
106  * (a value at least \a 2D is recommended). The size of the buffers is derived
107  * from the container that is pointed by the iterators.
108  *
109  * \remark The implementation exploits STXXL buffered streams (computation and
110  * I/O overlapped)
111  *
112  * \param begin object of model of \c ext_random_access_iterator concept
113  * \param end object of model of \c ext_random_access_iterator concept
114  * \param functor object of model of \c std::UnaryFunction concept
115  * \param nbuffers number of buffers (blocks) for internal use (should be at least 2*D )
116  * \return function object \c functor after it has been applied to the each element of the given range
117  *
118  * \warning nested stxxl::for_each_m are not supported
119  */
120 template <typename ExtIterator, typename UnaryFunction>
121 UnaryFunction for_each_m(ExtIterator begin, ExtIterator end, UnaryFunction functor, int_type nbuffers = 0)
122 {
123  if (begin == end)
124  return functor;
125 
128 
129  begin.flush(); // flush container
130 
131  if (nbuffers == 0)
132  nbuffers = 2 * config::get_instance()->disks_number();
133 
134  // create prefetching stream,
135  buf_istream_type in(begin.bid(), end.bid() + ((end.block_offset()) ? 1 : 0), nbuffers / 2);
136  // create buffered write stream for blocks
137  buf_ostream_type out(begin.bid(), nbuffers / 2);
138  // REMARK: these two streams do I/O while
139  // functor is being computed (overlapping for free)
140 
141  ExtIterator cur = begin - begin.block_offset();
142 
143  // leave part of the block before begin untouched (e.g. copy)
144  for ( ; cur != begin; ++cur)
145  {
146  typename ExtIterator::value_type tmp;
147  in >> tmp;
148  out << tmp;
149  }
150 
151  // apply functor to the range [begin,end)
152  for ( ; cur != end; ++cur)
153  {
154  typename ExtIterator::value_type tmp;
155  in >> tmp;
156  functor(tmp);
157  out << tmp;
158  }
159 
160  // leave part of the block after end untouched
161  if (end.block_offset())
162  {
163  ExtIterator _last_block_end = end - end.block_offset() + ExtIterator::block_type::size;
164  for ( ; cur != _last_block_end; ++cur)
165  {
166  typename ExtIterator::value_type tmp;
167  in >> tmp;
168  out << tmp;
169  }
170  }
171 
172  return functor;
173 }
174 
175 
176 /*!
177  * \brief External equivalent of std::generate, see \ref design_algo_generate.
178  *
179  * Generate assigns the result of invoking \c generator, a function object that
180  * takes no arguments, to each element in the range [first, last). To overlap
181  * I/O and computation \c nbuffers are used (a value at least \a D is
182  * recommended). The size of the buffers is derived from the container that is
183  * pointed by the iterators.
184  *
185  * \remark The implementation exploits STXXL buffered streams (computation and
186  * I/O overlapped).
187  *
188  * \param begin object of model of \c ext_random_access_iterator concept
189  * \param end object of model of \c ext_random_access_iterator concept
190  * \param generator function object of model of \c std::generator concept
191  * \param nbuffers number of buffers (blocks) for internal use (should be at least 2*D, or zero for automaticl 2*D)
192  */
193 template <typename ExtIterator, typename Generator>
194 void generate(ExtIterator begin, ExtIterator end, Generator generator, int_type nbuffers = 0)
195 {
196  typedef typename ExtIterator::block_type block_type;
198 
199 
200  while (begin.block_offset()) // go to the beginning of the block
201  // of the external vector
202  {
203  if (begin == end)
204  return;
205 
206  *begin = generator();
207  ++begin;
208  }
209 
210  begin.flush(); // flush container
211 
212  if (nbuffers == 0)
213  nbuffers = 2 * config::get_instance()->disks_number();
214 
215  // create buffered write stream for blocks
216  buf_ostream_type outstream(begin.bid(), nbuffers);
217 
218  assert(begin.block_offset() == 0);
219 
220  // delay calling block_externally_updated() until the block is
221  // completely filled (and written out) in outstream
222  typename ExtIterator::const_iterator prev_block = begin;
223 
224  while (end != begin)
225  {
226  if (begin.block_offset() == 0) {
227  if (prev_block != begin) {
228  prev_block.block_externally_updated();
229  prev_block = begin;
230  }
231  }
232 
233  *outstream = generator();
234  ++begin;
235  ++outstream;
236  }
237 
238  typename ExtIterator::const_iterator out = begin;
239 
240  while (out.block_offset()) // filling the rest of the block
241  {
242  *outstream = *out;
243  ++out;
244  ++outstream;
245  }
246 
247  if (prev_block != out)
248  prev_block.block_externally_updated();
249 
250  begin.flush();
251 }
252 
253 
254 /*!
255  * \brief External equivalent of std::find, see \ref design_algo_find.
256  *
257  * Returns the first iterator \a i in the range [first, last) such that <tt>*i
258  * == value</tt>. Returns last if no such iterator exists. To overlap I/O and
259  * computation \c nbuffers are used (a value at least \a D is recommended). The
260  * size of the buffers is derived from the container that is pointed by the
261  * iterators.
262  *
263  * \remark The implementation exploits STXXL buffered streams (computation and
264  * I/O overlapped).
265  *
266  * \param begin object of model of \c ext_random_access_iterator concept
267  * \param end object of model of \c ext_random_access_iterator concept
268  * \param value value that is equality comparable to the ExtIterator's value type
269  * \param nbuffers number of buffers (blocks) for internal use (should be at least 2*D)
270  * \return first iterator \c i in the range [begin,end) such that *( \c i ) == \c value, if no
271  * such exists then \c end
272  */
273 template <typename ExtIterator, typename EqualityComparable>
274 ExtIterator find(ExtIterator begin, ExtIterator end, const EqualityComparable& value, int_type nbuffers = 0)
275 {
276  if (begin == end)
277  return end;
278 
280 
281  begin.flush(); // flush container
282 
283  if (nbuffers == 0)
284  nbuffers = 2 * config::get_instance()->disks_number();
285 
286  // create prefetching stream,
287  buf_istream_type in(begin.bid(), end.bid() + ((end.block_offset()) ? 1 : 0), nbuffers);
288 
289  ExtIterator cur = begin - begin.block_offset();
290 
291  // skip part of the block before begin untouched
292  for ( ; cur != begin; ++cur)
293  ++in;
294 
295  // search in the the range [begin,end)
296  for ( ; cur != end; ++cur)
297  {
298  typename ExtIterator::value_type tmp;
299  in >> tmp;
300  if (tmp == value)
301  return cur;
302  }
303 
304  return cur;
305 }
306 
307 //! \}
308 
310 
311 #endif // !STXXL_ALGO_SCAN_HEADER
312 // vim: et:ts=4:sw=4
_Self & flush()
Force flush of current block, for finishing writing within a block.
Definition: buf_ostream.h:111
Buffered output stream.
Definition: buf_ostream.h:31
UnaryFunction for_each(ExtIterator begin, ExtIterator end, UnaryFunction functor, int_type nbuffers=0)
External equivalent of std::for_each, see stxxl::for_each.
Definition: scan.h:51
UnaryFunction for_each_m(ExtIterator begin, ExtIterator end, UnaryFunction functor, int_type nbuffers=0)
External equivalent of std::for_each (mutating), see stxxl::for_each_m (mutating).
Definition: scan.h:121
choose_int_types< my_pointer_size >::int_type int_type
Definition: types.h:66
void generate(ExtIterator begin, ExtIterator end, Generator generator, int_type nbuffers=0)
External equivalent of std::generate, see stxxl::generate.
Definition: scan.h:194
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
Buffered input stream.
Definition: buf_istream.h:37
ExtIterator find(ExtIterator begin, ExtIterator end, const EqualityComparable &value, int_type nbuffers=0)
External equivalent of std::find, see stxxl::find.
Definition: scan.h:274
#define STXXL_END_NAMESPACE
Definition: namespace.h:17