Stxxl
1.4.0
|
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