Stxxl  1.4.0
include/stxxl/bits/mng/buf_istream.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  include/stxxl/bits/mng/buf_istream.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  *
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_BUF_ISTREAM_HEADER
00014 #define STXXL_BUF_ISTREAM_HEADER
00015 
00016 #include <stxxl/bits/mng/config.h>
00017 #include <stxxl/bits/mng/block_prefetcher.h>
00018 #include <stxxl/bits/algo/async_schedule.h>
00019 
00020 
00021 __STXXL_BEGIN_NAMESPACE
00022 
00023 //! \addtogroup schedlayer
00024 //! \{
00025 
00026 
00027 // a paranoid check
00028 #define BUF_ISTREAM_CHECK_END
00029 
00030 
00031 //! \brief Buffered input stream
00032 //!
00033 //! Reads data records from the stream of blocks.
00034 //! \remark Reading performed in the background, i.e. with overlapping of I/O and computation
00035 template <typename BlkTp_, typename BIDIteratorTp_>
00036 class buf_istream
00037 {
00038 public:
00039     typedef BlkTp_ block_type;
00040     typedef BIDIteratorTp_ bid_iterator_type;
00041 
00042 private:
00043     buf_istream() { }
00044 
00045 protected:
00046     typedef block_prefetcher<block_type, bid_iterator_type> prefetcher_type;
00047     prefetcher_type * prefetcher;
00048     bid_iterator_type begin_bid, end_bid;
00049     int_type current_elem;
00050     block_type * current_blk;
00051     int_type * prefetch_seq;
00052 #ifdef BUF_ISTREAM_CHECK_END
00053     bool not_finished;
00054 #endif
00055 
00056 public:
00057     typedef typename block_type::reference reference;
00058     typedef buf_istream<block_type, bid_iterator_type> _Self;
00059 
00060     //! \brief Constructs input stream object
00061     //! \param _begin \c bid_iterator pointing to the first block of the stream
00062     //! \param _end \c bid_iterator pointing to the ( \b last + 1 ) block of the stream
00063     //! \param nbuffers number of buffers for internal use
00064     buf_istream(bid_iterator_type _begin, bid_iterator_type _end, int_type nbuffers) :
00065         current_elem(0)
00066 #ifdef BUF_ISTREAM_CHECK_END
00067         , not_finished(true)
00068 #endif
00069     {
00070         //int_type i;
00071         const unsigned_type ndisks = config::get_instance()->disks_number();
00072         const int_type seq_length = _end - _begin;
00073         prefetch_seq = new int_type[seq_length];
00074 
00075         // obvious schedule
00076         //for(int_type i = 0; i< seq_length; ++i)
00077         //      prefetch_seq[i] = i;
00078 
00079         // optimal schedule
00080         nbuffers = STXXL_MAX(2 * ndisks, unsigned_type(nbuffers - 1));
00081         compute_prefetch_schedule(_begin, _end, prefetch_seq,
00082                                   nbuffers, ndisks);
00083 
00084 
00085         prefetcher = new prefetcher_type(_begin, _end, prefetch_seq, nbuffers);
00086 
00087         current_blk = prefetcher->pull_block();
00088     }
00089 
00090     //! \brief Input stream operator, reads in \c record
00091     //! \param record reference to the block record type,
00092     //!        contains value of the next record in the stream after the call of the operator
00093     //! \return reference to itself (stream object)
00094     _Self & operator >> (reference record)
00095     {
00096 #ifdef BUF_ISTREAM_CHECK_END
00097         assert(not_finished);
00098 #endif
00099 
00100         record = current_blk->elem[current_elem++];
00101 
00102         if (UNLIKELY(current_elem >= block_type::size))
00103         {
00104             current_elem = 0;
00105 #ifdef BUF_ISTREAM_CHECK_END
00106             not_finished = prefetcher->block_consumed(current_blk);
00107 #else
00108             prefetcher->block_consumed(current_blk);
00109 #endif
00110         }
00111 
00112         return (*this);
00113     }
00114 
00115     //! \brief Returns reference to the current record in the stream
00116     //! \return reference to the current record in the stream
00117     reference current()     /* const */
00118     {
00119         return current_blk->elem[current_elem];
00120     }
00121 
00122     //! \brief Returns reference to the current record in the stream
00123     //! \return reference to the current record in the stream
00124     reference operator * ()     /* const */
00125     {
00126         return current_blk->elem[current_elem];
00127     }
00128 
00129     //! \brief Moves to the next record in the stream
00130     //! \return reference to itself after the advance
00131     _Self & operator ++ ()
00132     {
00133 #ifdef BUF_ISTREAM_CHECK_END
00134         assert(not_finished);
00135 #endif
00136 
00137         current_elem++;
00138 
00139         if (UNLIKELY(current_elem >= block_type::size))
00140         {
00141             current_elem = 0;
00142 #ifdef BUF_ISTREAM_CHECK_END
00143             not_finished = prefetcher->block_consumed(current_blk);
00144 #else
00145             prefetcher->block_consumed(current_blk);
00146 #endif
00147         }
00148         return *this;
00149     }
00150 
00151     //! \brief Frees used internal objects
00152     virtual ~buf_istream()
00153     {
00154         delete prefetcher;
00155         delete[] prefetch_seq;
00156     }
00157 };
00158 
00159 //! \}
00160 
00161 __STXXL_END_NAMESPACE
00162 
00163 #endif // !STXXL_BUF_ISTREAM_HEADER
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines