http://stxxl.sourceforge.net
<dementiev@mpi-sb.mpg.de>
http://www.boost.org/LICENSE_1_0.txt
#ifndef STXXL_BUF_ISTREAM_HEADER
#define STXXL_BUF_ISTREAM_HEADER
#include <stxxl/bits/mng/config.h>
#include <stxxl/bits/mng/block_prefetcher.h>
#include <stxxl/bits/algo/async_schedule.h>
__STXXL_BEGIN_NAMESPACE
#define BUF_ISTREAM_CHECK_END
template <typename BlkTp_, typename BIDIteratorTp_>
class buf_istream
{
public:
typedef BlkTp_ block_type;
typedef BIDIteratorTp_ bid_iterator_type;
private:
buf_istream() { }
protected:
typedef block_prefetcher<block_type, bid_iterator_type> prefetcher_type;
prefetcher_type * prefetcher;
bid_iterator_type begin_bid, end_bid;
int_type current_elem;
block_type * current_blk;
int_type * prefetch_seq;
#ifdef BUF_ISTREAM_CHECK_END
bool not_finished;
#endif
public:
typedef typename block_type::reference reference;
typedef buf_istream<block_type, bid_iterator_type> _Self;
buf_istream(bid_iterator_type _begin, bid_iterator_type _end, int_type nbuffers) :
current_elem(0)
#ifdef BUF_ISTREAM_CHECK_END
, not_finished(true)
#endif
{
const unsigned_type ndisks = config::get_instance()->disks_number();
const int_type seq_length = _end - _begin;
prefetch_seq = new int_type[seq_length];
nbuffers = STXXL_MAX(2 * ndisks, unsigned_type(nbuffers - 1));
compute_prefetch_schedule(_begin, _end, prefetch_seq,
nbuffers, ndisks);
prefetcher = new prefetcher_type(_begin, _end, prefetch_seq, nbuffers);
current_blk = prefetcher->pull_block();
}
_Self & operator >> (reference record)
{
#ifdef BUF_ISTREAM_CHECK_END
assert(not_finished);
#endif
record = current_blk->elem[current_elem++];
if (UNLIKELY(current_elem >= block_type::size))
{
current_elem = 0;
#ifdef BUF_ISTREAM_CHECK_END
not_finished = prefetcher->block_consumed(current_blk);
#else
prefetcher->block_consumed(current_blk);
#endif
}
return (*this);
}
reference current()
{
return current_blk->elem[current_elem];
}
reference operator * ()
{
return current_blk->elem[current_elem];
}
_Self & operator ++ ()
{
#ifdef BUF_ISTREAM_CHECK_END
assert(not_finished);
#endif
current_elem++;
if (UNLIKELY(current_elem >= block_type::size))
{
current_elem = 0;
#ifdef BUF_ISTREAM_CHECK_END
not_finished = prefetcher->block_consumed(current_blk);
#else
prefetcher->block_consumed(current_blk);
#endif
}
return *this;
}
virtual ~buf_istream()
{
delete prefetcher;
delete[] prefetch_seq;
}
};
__STXXL_END_NAMESPACE
#endif