Stxxl  1.3.2
scan.h
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  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
14 #ifndef STXXL_SCAN_HEADER
15 #define STXXL_SCAN_HEADER
16 
17 #include <stxxl/bits/namespace.h>
18 #include <stxxl/bits/mng/buf_istream.h>
19 #include <stxxl/bits/mng/buf_ostream.h>
20 
21 
22 __STXXL_BEGIN_NAMESPACE
23 
26 
36 template <typename _ExtIterator, typename _UnaryFunction>
37 _UnaryFunction for_each(_ExtIterator _begin, _ExtIterator _end, _UnaryFunction _functor, int_type nbuffers)
38 {
39  if (_begin == _end)
40  return _functor;
41 
43 
44  _begin.flush(); // flush container
45 
46  // create prefetching stream,
47  buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers);
48 
49  _ExtIterator _cur = _begin - _begin.block_offset();
50 
51  // leave part of the block before _begin untouched (e.g. copy)
52  for ( ; _cur != _begin; ++_cur)
53  {
54  typename _ExtIterator::value_type tmp;
55  in >> tmp;
56  }
57 
58  // apply _functor to the range [_begin,_end)
59  for ( ; _cur != _end; ++_cur)
60  {
61  typename _ExtIterator::value_type tmp;
62  in >> tmp;
63  _functor(tmp);
64  }
65 
66  // leave part of the block after _end untouched
67  if (_end.block_offset())
68  {
69  _ExtIterator _last_block_end = _end - _end.block_offset() + _ExtIterator::block_type::size;
70  for ( ; _cur != _last_block_end; ++_cur)
71  {
72  typename _ExtIterator::value_type tmp;
73  in >> tmp;
74  }
75  }
76 
77  return _functor;
78 }
79 
80 
90 template <typename _ExtIterator, typename _UnaryFunction>
91 _UnaryFunction for_each_m(_ExtIterator _begin, _ExtIterator _end, _UnaryFunction _functor, int_type nbuffers)
92 {
93  if (_begin == _end)
94  return _functor;
95 
98 
99  _begin.flush(); // flush container
100 
101  // create prefetching stream,
102  buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers / 2);
103  // create buffered write stream for blocks
104  buf_ostream_type out(_begin.bid(), nbuffers / 2);
105  // REMARK: these two streams do I/O while
106  // _functor is being computed (overlapping for free)
107 
108  _ExtIterator _cur = _begin - _begin.block_offset();
109 
110  // leave part of the block before _begin untouched (e.g. copy)
111  for ( ; _cur != _begin; ++_cur)
112  {
113  typename _ExtIterator::value_type tmp;
114  in >> tmp;
115  out << tmp;
116  }
117 
118  // apply _functor to the range [_begin,_end)
119  for ( ; _cur != _end; ++_cur)
120  {
121  typename _ExtIterator::value_type tmp;
122  in >> tmp;
123  _functor(tmp);
124  out << tmp;
125  }
126 
127  // leave part of the block after _end untouched
128  if (_end.block_offset())
129  {
130  _ExtIterator _last_block_end = _end - _end.block_offset() + _ExtIterator::block_type::size;
131  for ( ; _cur != _last_block_end; ++_cur)
132  {
133  typename _ExtIterator::value_type tmp;
134  in >> tmp;
135  out << tmp;
136  }
137  }
138 
139  return _functor;
140 }
141 
142 
149 template <typename _ExtIterator, typename _Generator>
150 void generate(_ExtIterator _begin, _ExtIterator _end, _Generator _generator, int_type nbuffers)
151 {
152  typedef typename _ExtIterator::block_type block_type;
154 
155 
156  while (_begin.block_offset()) // go to the beginning of the block
157  // of the external vector
158  {
159  if (_begin == _end)
160  return;
161 
162  *_begin = _generator();
163  ++_begin;
164  }
165 
166  _begin.flush(); // flush container
167 
168  // create buffered write stream for blocks
169  buf_ostream_type outstream(_begin.bid(), nbuffers);
170 
171  assert(_begin.block_offset() == 0);
172 
173  // delay calling block_externally_updated() until the block is
174  // completely filled (and written out) in outstream
175  typename _ExtIterator::const_iterator prev_block = _begin;
176 
177  while (_end != _begin)
178  {
179  if (_begin.block_offset() == 0) {
180  if (prev_block != _begin) {
181  prev_block.block_externally_updated();
182  prev_block = _begin;
183  }
184  }
185 
186  *outstream = _generator();
187  ++_begin;
188  ++outstream;
189  }
190 
191  typename _ExtIterator::const_iterator out = _begin;
192 
193  while (out.block_offset()) // filling the rest of the block
194  {
195  *outstream = *out;
196  ++out;
197  ++outstream;
198  }
199 
200  if (prev_block != out)
201  prev_block.block_externally_updated();
202 
203  _begin.flush();
204 }
205 
214 template <typename _ExtIterator, typename _EqualityComparable>
215 _ExtIterator find(_ExtIterator _begin, _ExtIterator _end, const _EqualityComparable & _value, int_type nbuffers)
216 {
217  if (_begin == _end)
218  return _end;
219 
221 
222  _begin.flush(); // flush container
223 
224  // create prefetching stream,
225  buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers);
226 
227  _ExtIterator _cur = _begin - _begin.block_offset();
228 
229  // skip part of the block before _begin untouched
230  for ( ; _cur != _begin; ++_cur)
231  ++in;
232 
233 
234  // search in the the range [_begin,_end)
235  for ( ; _cur != _end; ++_cur)
236  {
237  typename _ExtIterator::value_type tmp;
238  in >> tmp;
239  if (tmp == _value)
240  return _cur;
241  }
242 
243  return _cur;
244 }
245 
247 
248 __STXXL_END_NAMESPACE
249 
250 #endif // !STXXL_SCAN_HEADER
251 // vim: et:ts=4:sw=4
Buffered input stream.
Definition: buf_istream.h:36
_UnaryFunction for_each_m(_ExtIterator _begin, _ExtIterator _end, _UnaryFunction _functor, int_type nbuffers)
External equivalent of std::for_each (mutating)
Definition: scan.h:91
void generate(_ExtIterator _begin, _ExtIterator _end, _Generator _generator, int_type nbuffers)
External equivalent of std::generate.
Definition: scan.h:150
_UnaryFunction for_each(_ExtIterator _begin, _ExtIterator _end, _UnaryFunction _functor, int_type nbuffers)
External equivalent of std::for_each.
Definition: scan.h:37
Buffered output stream.
Definition: buf_ostream.h:30
_ExtIterator find(_ExtIterator _begin, _ExtIterator _end, const _EqualityComparable &_value, int_type nbuffers)
External equivalent of std::find.
Definition: scan.h:215