/usr/include/stxxl/bits/mng
Edit: /usr/include/stxxl/bits/mng/buf_istream_reverse.h (5272B)
/***************************************************************************
* include/stxxl/bits/mng/buf_istream_reverse.h
*
* Part of the STXXL. See http://stxxl.sourceforge.net
*
* Copyright (C) 2002-2004 Roman Dementiev
* Copyright (C) 2013 Timo Bingmann
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
**************************************************************************/
#ifndef STXXL_MNG_BUF_ISTREAM_REVERSE_HEADER
#define STXXL_MNG_BUF_ISTREAM_REVERSE_HEADER
#include
#include
#include
#include
#include
STXXL_BEGIN_NAMESPACE
//! \addtogroup schedlayer
//! \{
// a paranoid check
#define BUF_ISTREAM_CHECK_END
//! Buffered input stream, reading the items in the blocks in reverse order.
//!
//! Reads data records from the stream of blocks in reverse order.
//! \remark Reading performed in the background, i.e. with overlapping of I/O and computation
template
class buf_istream_reverse : private noncopyable
{
public:
typedef BlockType block_type;
typedef BidIteratorType bid_iterator_type;
//-tb note that we redefine the BID type here, because there is no way to
//-derive it from BidIteratorType (which is usually just a POD pointer).
typedef BIDArray bid_vector_type;
private:
buf_istream_reverse() { }
protected:
typedef block_prefetcher prefetcher_type;
prefetcher_type* prefetcher;
int_type current_elem;
block_type* current_blk;
int_type* prefetch_seq;
#ifdef BUF_ISTREAM_CHECK_END
bool not_finished;
#endif
bid_vector_type bids_;
public:
typedef typename block_type::reference reference;
typedef buf_istream_reverse self_type;
//! Constructs input stream object, reading [first,last) blocks in reverse.
//! \param begin \c bid_iterator pointing to the first block of the stream
//! \param end \c bid_iterator pointing to the ( \b last + 1 ) block of the stream
//! \param nbuffers number of buffers for internal use
buf_istream_reverse(bid_iterator_type begin, bid_iterator_type end, int_type nbuffers)
: current_elem(0),
#ifdef BUF_ISTREAM_CHECK_END
not_finished(true),
#endif
bids_(end - begin)
{
// copy list of bids in reverse
std::reverse_copy(begin, end, bids_.begin());
// calculate prefetch sequence
const unsigned_type ndisks = config::get_instance()->disks_number();
const unsigned_type mdevid = config::get_instance()->get_max_device_id();
prefetch_seq = new int_type[bids_.size()];
// optimal schedule
nbuffers = STXXL_MAX(2 * ndisks, unsigned_type(nbuffers - 1));
compute_prefetch_schedule(bids_.begin(), bids_.end(), prefetch_seq,
nbuffers, mdevid);
// create stream prefetcher
prefetcher = new prefetcher_type(bids_.begin(), bids_.end(), prefetch_seq, nbuffers);
// fetch block: last in sequence
current_blk = prefetcher->pull_block();
current_elem = block_type::size - 1;
}
//! Input stream operator, reads in \c record.
//! \param record reference to the block record type,
//! contains value of the next record in the stream after the call of the operator
//! \return reference to itself (stream object)
self_type& operator >> (reference record)
{
#ifdef BUF_ISTREAM_CHECK_END
assert(not_finished);
#endif
record = current_blk->elem[current_elem--];
if (UNLIKELY(current_elem < 0))
{
current_elem = block_type::size - 1;
#ifdef BUF_ISTREAM_CHECK_END
not_finished = prefetcher->block_consumed(current_blk);
#else
prefetcher->block_consumed(current_blk);
#endif
}
return (*this);
}
//! Returns reference to the current record in the stream.
reference current() /* const */
{
return current_blk->elem[current_elem];
}
//! Returns reference to the current record in the stream.
reference operator * () /* const */
{
return current_blk->elem[current_elem];
}
//! Moves to the _previous_ record in the stream.
//! \return reference to itself after the advance
self_type& operator ++ ()
{
#ifdef BUF_ISTREAM_CHECK_END
assert(not_finished);
#endif
current_elem--;
if (UNLIKELY(current_elem < 0))
{
current_elem = block_type::size - 1;
#ifdef BUF_ISTREAM_CHECK_END
not_finished = prefetcher->block_consumed(current_blk);
#else
prefetcher->block_consumed(current_blk);
#endif
}
return *this;
}
//! Frees used internal objects.
~buf_istream_reverse()
{
delete prefetcher;
delete[] prefetch_seq;
}
};
//! \}
STXXL_END_NAMESPACE
#endif // !STXXL_MNG_BUF_ISTREAM_REVERSE_HEADER