• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List

scan.h

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 <[email protected]>
00007  *
00008  *  Distributed under the Boost Software License, Version 1.0.
00009  *  (See accompanying file LICENSE_1_0.txt or copy at
00010  *  http://www.boost.org/LICENSE_1_0.txt)
00011  **************************************************************************/
00012 
00013 #ifndef STXXL_SCAN_HEADER
00014 #define STXXL_SCAN_HEADER
00015 
00016 #include <stxxl/bits/namespace.h>
00017 #include <stxxl/bits/mng/buf_istream.h>
00018 #include <stxxl/bits/mng/buf_ostream.h>
00019 
00020 
00021 __STXXL_BEGIN_NAMESPACE
00022 
00025 
00035 template <typename _ExtIterator, typename _UnaryFunction>
00036 _UnaryFunction for_each(_ExtIterator _begin, _ExtIterator _end, _UnaryFunction _functor, int_type nbuffers)
00037 {
00038     if (_begin == _end)
00039         return _functor;
00040 
00041     typedef buf_istream<typename _ExtIterator::block_type, typename _ExtIterator::bids_container_iterator> buf_istream_type;
00042 
00043     _begin.flush();     // flush container
00044 
00045     // create prefetching stream,
00046     buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers);
00047 
00048     _ExtIterator _cur = _begin - _begin.block_offset();
00049 
00050     // leave part of the block before _begin untouched (e.g. copy)
00051     for ( ; _cur != _begin; ++_cur)
00052     {
00053         typename _ExtIterator::value_type tmp;
00054         in >> tmp;
00055     }
00056 
00057     // apply _functor to the range [_begin,_end)
00058     for ( ; _cur != _end; ++_cur)
00059     {
00060         typename _ExtIterator::value_type tmp;
00061         in >> tmp;
00062         _functor(tmp);
00063     }
00064 
00065     // leave part of the block after _end untouched
00066     if (_end.block_offset())
00067     {
00068         _ExtIterator _last_block_end = _end - _end.block_offset() + _ExtIterator::block_type::size;
00069         for ( ; _cur != _last_block_end; ++_cur)
00070         {
00071             typename _ExtIterator::value_type tmp;
00072             in >> tmp;
00073         }
00074     }
00075 
00076     return _functor;
00077 }
00078 
00079 
00089 template <typename _ExtIterator, typename _UnaryFunction>
00090 _UnaryFunction for_each_m(_ExtIterator _begin, _ExtIterator _end, _UnaryFunction _functor, int_type nbuffers)
00091 {
00092     if (_begin == _end)
00093         return _functor;
00094 
00095     typedef buf_istream<typename _ExtIterator::block_type, typename _ExtIterator::bids_container_iterator> buf_istream_type;
00096     typedef buf_ostream<typename _ExtIterator::block_type, typename _ExtIterator::bids_container_iterator> buf_ostream_type;
00097 
00098     _begin.flush();     // flush container
00099 
00100     // create prefetching stream,
00101     buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers / 2);
00102     // create buffered write stream for blocks
00103     buf_ostream_type out(_begin.bid(), nbuffers / 2);
00104     // REMARK: these two streams do I/O while
00105     //         _functor is being computed (overlapping for free)
00106 
00107     _ExtIterator _cur = _begin - _begin.block_offset();
00108 
00109     // leave part of the block before _begin untouched (e.g. copy)
00110     for ( ; _cur != _begin; ++_cur)
00111     {
00112         typename _ExtIterator::value_type tmp;
00113         in >> tmp;
00114         out << tmp;
00115     }
00116 
00117     // apply _functor to the range [_begin,_end)
00118     for ( ; _cur != _end; ++_cur)
00119     {
00120         typename _ExtIterator::value_type tmp;
00121         in >> tmp;
00122         _functor(tmp);
00123         out << tmp;
00124     }
00125 
00126     // leave part of the block after _end untouched
00127     if (_end.block_offset())
00128     {
00129         _ExtIterator _last_block_end = _end - _end.block_offset() + _ExtIterator::block_type::size;
00130         for ( ; _cur != _last_block_end; ++_cur)
00131         {
00132             typename _ExtIterator::value_type tmp;
00133             in >> tmp;
00134             out << tmp;
00135         }
00136     }
00137 
00138     return _functor;
00139 }
00140 
00141 
00148 template <typename _ExtIterator, typename _Generator>
00149 void generate(_ExtIterator _begin, _ExtIterator _end, _Generator _generator, int_type nbuffers)
00150 {
00151     typedef typename _ExtIterator::block_type block_type;
00152     typedef buf_ostream<block_type, typename _ExtIterator::bids_container_iterator> buf_ostream_type;
00153 
00154 
00155     while (_begin.block_offset())    //  go to the beginning of the block
00156     //  of the external vector
00157     {
00158         if (_begin == _end)
00159             return;
00160 
00161         *_begin = _generator();
00162         ++_begin;
00163     }
00164 
00165     _begin.flush();     // flush container
00166 
00167     // create buffered write stream for blocks
00168     buf_ostream_type outstream(_begin.bid(), nbuffers);
00169 
00170     assert(_begin.block_offset() == 0);
00171 
00172     // delay calling block_externally_updated() until the block is
00173     // completely filled (and written out) in outstream
00174     typename _ExtIterator::const_iterator prev_block = _begin;
00175 
00176     while (_end != _begin)
00177     {
00178         if (_begin.block_offset() == 0) {
00179             if (prev_block != _begin) {
00180                 prev_block.block_externally_updated();
00181                 prev_block = _begin;
00182             }
00183         }
00184 
00185         *outstream = _generator();
00186         ++_begin;
00187         ++outstream;
00188     }
00189 
00190     typename _ExtIterator::const_iterator out = _begin;
00191 
00192     while (out.block_offset())    // filling the rest of the block
00193     {
00194         *outstream = *out;
00195         ++out;
00196         ++outstream;
00197     }
00198 
00199     if (prev_block != out)
00200         prev_block.block_externally_updated();
00201 
00202     _begin.flush();
00203 }
00204 
00213 template <typename _ExtIterator, typename _EqualityComparable>
00214 _ExtIterator find(_ExtIterator _begin, _ExtIterator _end, const _EqualityComparable & _value, int_type nbuffers)
00215 {
00216     if (_begin == _end)
00217         return _end;
00218 
00219     typedef buf_istream<typename _ExtIterator::block_type, typename _ExtIterator::bids_container_iterator> buf_istream_type;
00220 
00221     _begin.flush();     // flush container
00222 
00223     // create prefetching stream,
00224     buf_istream_type in(_begin.bid(), _end.bid() + ((_end.block_offset()) ? 1 : 0), nbuffers);
00225 
00226     _ExtIterator _cur = _begin - _begin.block_offset();
00227 
00228     // skip part of the block before _begin untouched
00229     for ( ; _cur != _begin; ++_cur)
00230         ++in;
00231 
00232 
00233     // search in the the range [_begin,_end)
00234     for ( ; _cur != _end; ++_cur)
00235     {
00236         typename _ExtIterator::value_type tmp;
00237         in >> tmp;
00238         if (tmp == _value)
00239             return _cur;
00240     }
00241 
00242     return _cur;
00243 }
00244 
00246 
00247 __STXXL_END_NAMESPACE
00248 
00249 #endif // !STXXL_SCAN_HEADER
00250 // vim: et:ts=4:sw=4

Generated by  doxygen 1.7.1