Stxxl  1.4.0
include/stxxl/bits/algo/scan.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines