Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
buf_istream_reverse.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * foxxll/mng/buf_istream_reverse.hpp
3  *
4  * Part of FOXXLL. See http://foxxll.org
5  *
6  * Copyright (C) 2002-2004 Roman Dementiev <[email protected]>
7  * Copyright (C) 2013 Timo Bingmann <[email protected]>
8  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
14 #ifndef FOXXLL_MNG_BUF_ISTREAM_REVERSE_HEADER
15 #define FOXXLL_MNG_BUF_ISTREAM_REVERSE_HEADER
16 
17 #include <algorithm>
18 
20 #include <foxxll/mng/bid.hpp>
22 #include <foxxll/mng/config.hpp>
23 
24 namespace foxxll {
25 
26 //! \addtogroup foxxll_schedlayer
27 //! \{
28 
29 // a paranoid check
30 #define BUF_ISTREAM_CHECK_END
31 
32 //! Buffered input stream, reading the items in the blocks in reverse order.
33 //!
34 //! Reads data records from the stream of blocks in reverse order.
35 //! \remark Reading performed in the background, i.e. with overlapping of I/O and computation
36 template <typename BlockType, typename BidIteratorType>
38 {
39 public:
40  using block_type = BlockType;
41  using bid_iterator_type = BidIteratorType;
42 
43  //-tb note that we redefine the BID type here, because there is no way to
44  //-derive it from BidIteratorType (which is usually just a POD pointer).
46 
47 private:
49 
50 protected:
53  size_t current_elem;
55  size_t* prefetch_seq;
56 #ifdef BUF_ISTREAM_CHECK_END
58 #endif
60 
61 public:
62  using reference = typename block_type::reference;
64 
65  //! Constructs input stream object, reading [first,last) blocks in reverse.
66  //! \param begin \c bid_iterator pointing to the first block of the stream
67  //! \param end \c bid_iterator pointing to the ( \b last + 1 ) block of the stream
68  //! \param nbuffers number of buffers for internal use
70  : current_elem(0),
72  not_finished(true),
73 #endif
74  bids_(end - begin)
75  {
76  // copy list of bids in reverse
77  std::reverse_copy(begin, end, bids_.begin());
78 
79  // calculate prefetch sequence
80  const size_t ndisks = config::get_instance()->disks_number();
81  const size_t mdevid = config::get_instance()->max_device_id();
82 
83  prefetch_seq = new size_t[bids_.size()];
84 
85  // optimal schedule
86  nbuffers = std::max(2 * ndisks, nbuffers - 1);
89  nbuffers, mdevid
90  );
91 
92  // create stream prefetcher
94 
95  // fetch block: last in sequence
96  current_blk = prefetcher->pull_block();
97  current_elem = block_type::size - 1;
98  }
99 
100  //! non-copyable: delete copy-constructor
101  buf_istream_reverse(const buf_istream_reverse&) = delete;
102  //! non-copyable: delete assignment operator
104 
105  //! Input stream operator, reads in \c record.
106  //! \param record reference to the block record type,
107  //! contains value of the next record in the stream after the call of the operator
108  //! \return reference to itself (stream object)
110  {
111 #ifdef BUF_ISTREAM_CHECK_END
112  assert(not_finished);
113 #endif
114 
115  record = current_blk->elem[current_elem];
116 
117  if (UNLIKELY(current_elem == 0))
118  {
119  current_elem = block_type::size - 1;
120 #ifdef BUF_ISTREAM_CHECK_END
122 #else
124 #endif
125  }
126  else
127  {
128  current_elem--;
129  }
130 
131  return (*this);
132  }
133 
134  //! Returns reference to the current record in the stream.
135  reference current() /* const */
136  {
137  return current_blk->elem[current_elem];
138  }
139 
140  //! Returns reference to the current record in the stream.
141  reference operator * () /* const */
142  {
143  return current_blk->elem[current_elem];
144  }
145 
146  //! Moves to the _previous_ record in the stream.
147  //! \return reference to itself after the advance
149  {
150 #ifdef BUF_ISTREAM_CHECK_END
151  assert(not_finished);
152 #endif
153 
154  if (UNLIKELY(current_elem == 0))
155  {
156  current_elem = block_type::size - 1;
157 #ifdef BUF_ISTREAM_CHECK_END
159 #else
161 #endif
162  }
163  else
164  {
165  current_elem--;
166  }
167 
168  return *this;
169  }
170 
171  //! Frees used internal objects.
173  {
174  delete prefetcher;
175  delete[] prefetch_seq;
176  }
177 };
178 
179 //! \}
180 
181 } // namespace foxxll
182 
183 #endif // !FOXXLL_MNG_BUF_ISTREAM_REVERSE_HEADER
184 
185 /**************************************************************************/
buf_istream_reverse(bid_iterator_type begin, bid_iterator_type end, size_t nbuffers)
iterator end() noexcept
return mutable iterator beyond last element
static uint_pair max()
return an uint_pair instance containing the largest value possible
Definition: uint_types.hpp:226
reference operator*()
Returns reference to the current record in the stream.
self_type & operator>>(reference record)
unsigned int max_device_id()
Returns automatic physical device id counter.
Definition: config.cpp:186
Simpler non-growing vector without initialization.
void compute_prefetch_schedule(const size_t *first, const size_t *last, size_t *out_first, size_t m, size_t D)
reference current()
Returns reference to the current record in the stream.
#define BUF_ISTREAM_CHECK_END
buf_istream_reverse & operator=(const buf_istream_reverse &)=delete
non-copyable: delete assignment operator
iterator begin() noexcept
return mutable iterator to first element
block_prefetcher< block_type, typename bid_vector_type::iterator > prefetcher_type
size_t disks_number()
Definition: config.hpp:195
size_type size() const noexcept
return number of items in vector
static instance_pointer get_instance()
Definition: singleton.hpp:44
typename block_type::reference reference
bool block_consumed(block_type *&buffer)
#define UNLIKELY(c)
Definition: utils.hpp:88
~buf_istream_reverse()
Frees used internal objects.