Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/algo/scan.h 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2002-2004 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2008, 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00008 * 00009 * Distributed under the Boost Software License, Version 1.0. 00010 * (See accompanying file LICENSE_1_0.txt or copy at 00011 * http://www.boost.org/LICENSE_1_0.txt) 00012 **************************************************************************/ 00013 00014 #ifndef STXXL_SCAN_HEADER 00015 #define STXXL_SCAN_HEADER 00016 00017 #include <stxxl/bits/namespace.h> 00018 #include <stxxl/bits/mng/buf_istream.h> 00019 #include <stxxl/bits/mng/buf_ostream.h> 00020 00021 00022 __STXXL_BEGIN_NAMESPACE 00023 00024 //! \addtogroup stlalgo 00025 //! \{ 00026 00027 //! \brief External equivalent of std::for_each 00028 //! \remark The implementation exploits \c <stxxl> buffered streams (computation and I/O overlapped) 00029 //! \param _begin object of model of \c ext_random_access_iterator concept 00030 //! \param _end object of model of \c ext_random_access_iterator concept 00031 //! \param _functor function object of model of \c std::UnaryFunction concept 00032 //! \param nbuffers number of buffers (blocks) for internal use (should be at least 2*D ) 00033 //! \return function object \c _functor after it has been applied to the each element of the given range 00034 //! 00035 //! \warning nested stxxl::for_each are not supported 00036 template <typename _ExtIterator, typename _UnaryFunction> 00037 _UnaryFunction for_each(_ExtIterator _begin, _ExtIterator _end, _UnaryFunction _functor, int_type nbuffers) 00038 { 00039 if (_begin == _end) 00040 return _functor; 00041 00042 typedef buf_istream<typename _ExtIterator::block_type, typename _ExtIterator::bids_container_iterator> buf_istream_type; 00043 00044 _begin.flush(); // flush container 00045 00046 // create prefetching stream, 00047 buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers); 00048 00049 _ExtIterator _cur = _begin - _begin.block_offset(); 00050 00051 // leave part of the block before _begin untouched (e.g. copy) 00052 for ( ; _cur != _begin; ++_cur) 00053 { 00054 typename _ExtIterator::value_type tmp; 00055 in >> tmp; 00056 } 00057 00058 // apply _functor to the range [_begin,_end) 00059 for ( ; _cur != _end; ++_cur) 00060 { 00061 typename _ExtIterator::value_type tmp; 00062 in >> tmp; 00063 _functor(tmp); 00064 } 00065 00066 // leave part of the block after _end untouched 00067 if (_end.block_offset()) 00068 { 00069 _ExtIterator _last_block_end = _end - _end.block_offset() + _ExtIterator::block_type::size; 00070 for ( ; _cur != _last_block_end; ++_cur) 00071 { 00072 typename _ExtIterator::value_type tmp; 00073 in >> tmp; 00074 } 00075 } 00076 00077 return _functor; 00078 } 00079 00080 00081 //! \brief External equivalent of std::for_each (mutating) 00082 //! \remark The implementation exploits \c <stxxl> buffered streams (computation and I/O overlapped) 00083 //! \param _begin object of model of \c ext_random_access_iterator concept 00084 //! \param _end object of model of \c ext_random_access_iterator concept 00085 //! \param _functor 00086 //! \param nbuffers number of buffers (blocks) for internal use (should be at least 2*D ) 00087 //! \return function object \c _functor after it has been applied to the each element of the given range 00088 //! 00089 //! \warning nested stxxl::for_each_m are not supported 00090 template <typename _ExtIterator, typename _UnaryFunction> 00091 _UnaryFunction for_each_m(_ExtIterator _begin, _ExtIterator _end, _UnaryFunction _functor, int_type nbuffers) 00092 { 00093 if (_begin == _end) 00094 return _functor; 00095 00096 typedef buf_istream<typename _ExtIterator::block_type, typename _ExtIterator::bids_container_iterator> buf_istream_type; 00097 typedef buf_ostream<typename _ExtIterator::block_type, typename _ExtIterator::bids_container_iterator> buf_ostream_type; 00098 00099 _begin.flush(); // flush container 00100 00101 // create prefetching stream, 00102 buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers / 2); 00103 // create buffered write stream for blocks 00104 buf_ostream_type out(_begin.bid(), nbuffers / 2); 00105 // REMARK: these two streams do I/O while 00106 // _functor is being computed (overlapping for free) 00107 00108 _ExtIterator _cur = _begin - _begin.block_offset(); 00109 00110 // leave part of the block before _begin untouched (e.g. copy) 00111 for ( ; _cur != _begin; ++_cur) 00112 { 00113 typename _ExtIterator::value_type tmp; 00114 in >> tmp; 00115 out << tmp; 00116 } 00117 00118 // apply _functor to the range [_begin,_end) 00119 for ( ; _cur != _end; ++_cur) 00120 { 00121 typename _ExtIterator::value_type tmp; 00122 in >> tmp; 00123 _functor(tmp); 00124 out << tmp; 00125 } 00126 00127 // leave part of the block after _end untouched 00128 if (_end.block_offset()) 00129 { 00130 _ExtIterator _last_block_end = _end - _end.block_offset() + _ExtIterator::block_type::size; 00131 for ( ; _cur != _last_block_end; ++_cur) 00132 { 00133 typename _ExtIterator::value_type tmp; 00134 in >> tmp; 00135 out << tmp; 00136 } 00137 } 00138 00139 return _functor; 00140 } 00141 00142 00143 //! \brief External equivalent of std::generate 00144 //! \remark The implementation exploits \c <stxxl> buffered streams (computation and I/O overlapped) 00145 //! \param _begin object of model of \c ext_random_access_iterator concept 00146 //! \param _end object of model of \c ext_random_access_iterator concept 00147 //! \param _generator function object of model of \c std::Generator concept 00148 //! \param nbuffers number of buffers (blocks) for internal use (should be at least 2*D ) 00149 template <typename _ExtIterator, typename _Generator> 00150 void generate(_ExtIterator _begin, _ExtIterator _end, _Generator _generator, int_type nbuffers) 00151 { 00152 typedef typename _ExtIterator::block_type block_type; 00153 typedef buf_ostream<block_type, typename _ExtIterator::bids_container_iterator> buf_ostream_type; 00154 00155 00156 while (_begin.block_offset()) // go to the beginning of the block 00157 // of the external vector 00158 { 00159 if (_begin == _end) 00160 return; 00161 00162 *_begin = _generator(); 00163 ++_begin; 00164 } 00165 00166 _begin.flush(); // flush container 00167 00168 // create buffered write stream for blocks 00169 buf_ostream_type outstream(_begin.bid(), nbuffers); 00170 00171 assert(_begin.block_offset() == 0); 00172 00173 // delay calling block_externally_updated() until the block is 00174 // completely filled (and written out) in outstream 00175 typename _ExtIterator::const_iterator prev_block = _begin; 00176 00177 while (_end != _begin) 00178 { 00179 if (_begin.block_offset() == 0) { 00180 if (prev_block != _begin) { 00181 prev_block.block_externally_updated(); 00182 prev_block = _begin; 00183 } 00184 } 00185 00186 *outstream = _generator(); 00187 ++_begin; 00188 ++outstream; 00189 } 00190 00191 typename _ExtIterator::const_iterator out = _begin; 00192 00193 while (out.block_offset()) // filling the rest of the block 00194 { 00195 *outstream = *out; 00196 ++out; 00197 ++outstream; 00198 } 00199 00200 if (prev_block != out) 00201 prev_block.block_externally_updated(); 00202 00203 _begin.flush(); 00204 } 00205 00206 //! \brief External equivalent of std::find 00207 //! \remark The implementation exploits \c <stxxl> buffered streams (computation and I/O overlapped) 00208 //! \param _begin object of model of \c ext_random_access_iterator concept 00209 //! \param _end object of model of \c ext_random_access_iterator concept 00210 //! \param _value value that is equality comparable to the _ExtIterator's value type 00211 //! \param nbuffers number of buffers (blocks) for internal use (should be at least 2*D ) 00212 //! \return first iterator \c i in the range [_begin,_end) such that *( \c i ) == \c _value, if no 00213 //! such exists then \c _end 00214 template <typename _ExtIterator, typename _EqualityComparable> 00215 _ExtIterator find(_ExtIterator _begin, _ExtIterator _end, const _EqualityComparable & _value, int_type nbuffers) 00216 { 00217 if (_begin == _end) 00218 return _end; 00219 00220 typedef buf_istream<typename _ExtIterator::block_type, typename _ExtIterator::bids_container_iterator> buf_istream_type; 00221 00222 _begin.flush(); // flush container 00223 00224 // create prefetching stream, 00225 buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers); 00226 00227 _ExtIterator _cur = _begin - _begin.block_offset(); 00228 00229 // skip part of the block before _begin untouched 00230 for ( ; _cur != _begin; ++_cur) 00231 ++in; 00232 00233 00234 // search in the the range [_begin,_end) 00235 for ( ; _cur != _end; ++_cur) 00236 { 00237 typename _ExtIterator::value_type tmp; 00238 in >> tmp; 00239 if (tmp == _value) 00240 return _cur; 00241 } 00242 00243 return _cur; 00244 } 00245 00246 //! \} 00247 00248 __STXXL_END_NAMESPACE 00249 00250 #endif // !STXXL_SCAN_HEADER 00251 // vim: et:ts=4:sw=4