00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00025
00026
00027
00028 #define BUF_ISTREAM_CHECK_END
00029
00030
00035 template <typename BlkTp_, typename BIDIteratorTp_>
00036 class buf_istream
00037 {
00038 typedef BlkTp_ block_type;
00039 typedef BIDIteratorTp_ bid_iterator_type;
00040
00041 buf_istream() { }
00042
00043 protected:
00044 typedef block_prefetcher<block_type, bid_iterator_type> prefetcher_type;
00045 prefetcher_type * prefetcher;
00046 bid_iterator_type begin_bid, end_bid;
00047 int_type current_elem;
00048 block_type * current_blk;
00049 int_type * prefetch_seq;
00050 #ifdef BUF_ISTREAM_CHECK_END
00051 bool not_finished;
00052 #endif
00053
00054 public:
00055 typedef typename block_type::reference reference;
00056 typedef buf_istream<block_type, bid_iterator_type> _Self;
00057
00062 buf_istream(bid_iterator_type _begin, bid_iterator_type _end, int_type nbuffers) :
00063 current_elem(0)
00064 #ifdef BUF_ISTREAM_CHECK_END
00065 , not_finished(true)
00066 #endif
00067 {
00068
00069 const unsigned_type ndisks = config::get_instance()->disks_number();
00070 const int_type seq_length = _end - _begin;
00071 prefetch_seq = new int_type[seq_length];
00072
00073
00074
00075
00076
00077
00078 nbuffers = STXXL_MAX(2 * ndisks, unsigned_type(nbuffers - 1));
00079 compute_prefetch_schedule(_begin, _end, prefetch_seq,
00080 nbuffers, ndisks);
00081
00082
00083 prefetcher = new prefetcher_type(_begin, _end, prefetch_seq, nbuffers);
00084
00085 current_blk = prefetcher->pull_block();
00086 }
00087
00092 _Self & operator >> (reference record)
00093 {
00094 #ifdef BUF_ISTREAM_CHECK_END
00095 assert(not_finished);
00096 #endif
00097
00098 record = current_blk->elem[current_elem++];
00099
00100 if (current_elem >= block_type::size)
00101 {
00102 current_elem = 0;
00103 #ifdef BUF_ISTREAM_CHECK_END
00104 not_finished = prefetcher->block_consumed(current_blk);
00105 #else
00106 prefetcher->block_consumed(current_blk);
00107 #endif
00108 }
00109
00110 return (*this);
00111 }
00112
00115 reference current()
00116 {
00117 return current_blk->elem[current_elem];
00118 }
00119
00122 reference operator * ()
00123 {
00124 return current_blk->elem[current_elem];
00125 }
00126
00129 _Self & operator ++ ()
00130 {
00131 #ifdef BUF_ISTREAM_CHECK_END
00132 assert(not_finished);
00133 #endif
00134
00135 current_elem++;
00136
00137 if (current_elem >= block_type::size)
00138 {
00139 current_elem = 0;
00140 #ifdef BUF_ISTREAM_CHECK_END
00141 not_finished = prefetcher->block_consumed(current_blk);
00142 #else
00143 prefetcher->block_consumed(current_blk);
00144 #endif
00145 }
00146 return *this;
00147 }
00148
00150 virtual ~buf_istream()
00151 {
00152 delete prefetcher;
00153 delete[] prefetch_seq;
00154 }
00155 };
00156
00158
00159 __STXXL_END_NAMESPACE
00160
00161 #endif // !STXXL_BUF_ISTREAM_HEADER