15 #ifndef FOXXLL_MNG_BLOCK_PREFETCHER_HEADER 16 #define FOXXLL_MNG_BLOCK_PREFETCHER_HEADER 39 : switch_(_switch), on_complete_(on_complete) { }
55 template <
typename BlockType,
typename B
idIteratorType>
58 constexpr
static bool debug =
false;
64 using bid_type =
typename block_type::bid_type;
89 TLX_LOG <<
"block_prefetcher: waiting block " << iblock;
95 TLX_LOG <<
"block_prefetcher: finished waiting block " << iblock;
96 size_t ibuffer = pref_buffer[iblock];
97 TLX_LOG <<
"block_prefetcher: returning buffer " << ibuffer;
98 assert(ibuffer >= 0 && ibuffer < nreadblocks);
99 return (read_buffers + ibuffer);
114 size_t _prefetch_buf_size,
116 : consume_seq_begin(_cons_begin),
117 consume_seq_end(_cons_end),
118 seq_length(_cons_end - _cons_begin),
119 prefetch_seq(_pref_seq),
120 nextread(
std::
min(_prefetch_buf_size, seq_length)),
122 nreadblocks(nextread),
123 do_after_fetch(do_after_fetch)
125 TLX_LOG <<
"block_prefetcher: seq_length=" << seq_length;
126 TLX_LOG <<
"block_prefetcher: _prefetch_buf_size=" << _prefetch_buf_size;
127 assert(seq_length > 0);
128 assert(_prefetch_buf_size > 0);
132 read_bids =
new bid_type[nreadblocks];
133 pref_buffer =
new size_t[seq_length];
135 std::fill(pref_buffer, pref_buffer + seq_length, -1);
139 for (i = 0; i < nreadblocks; ++i)
141 assert(prefetch_seq[i] < seq_length);
142 read_bids[i] = *(consume_seq_begin + prefetch_seq[i]);
143 TLX_LOG <<
"block_prefetcher: reading block " << i <<
144 " prefetch_seq[" << i <<
"]=" << prefetch_seq[i] <<
145 " @ " << &read_buffers[i] <<
146 " @ " << read_bids[i];
147 read_reqs[i] = read_buffers[i].read(
151 pref_buffer[prefetch_seq[i]] = i;
164 TLX_LOG <<
"block_prefetcher: pulling a block";
165 return wait(nextconsume++);
174 size_t ibuffer = buffer - read_buffers;
175 TLX_LOG <<
"block_prefetcher: buffer " << ibuffer <<
" consumed";
176 if (read_reqs[ibuffer].valid())
177 read_reqs[ibuffer]->wait();
179 read_reqs[ibuffer] =
nullptr;
181 if (nextread < seq_length)
183 assert(ibuffer >= 0 && ibuffer < nreadblocks);
184 size_t next_2_prefetch = prefetch_seq[nextread++];
185 TLX_LOG <<
"block_prefetcher: prefetching block " << next_2_prefetch;
187 assert(next_2_prefetch < seq_length);
188 assert(!completed[next_2_prefetch].is_on());
190 pref_buffer[next_2_prefetch] = ibuffer;
192 bid_type(*(consume_seq_begin + next_2_prefetch));
193 read_reqs[ibuffer] = read_buffers[ibuffer].read(
199 if (nextconsume >= seq_length)
202 buffer = wait(nextconsume++);
211 return nextconsume >= seq_length;
223 for (
size_t i = 0; i < nreadblocks; ++i)
224 if (read_reqs[i].valid())
225 read_reqs[i]->wait();
230 delete[] pref_buffer;
231 delete[] read_buffers;
239 #endif // !FOXXLL_MNG_BLOCK_PREFETCHER_HEADER void wait_for_on()
wait for switch to turn ON
block_type * pull_block()
BidIteratorType bid_iterator_type
bid_iterator_type consume_seq_begin
block_type * wait(size_t iblock)
block_prefetcher(bid_iterator_type _cons_begin, bid_iterator_type _cons_end, size_t *_pref_seq, size_t _prefetch_buf_size, completion_handler do_after_fetch=completion_handler())
~block_prefetcher()
Frees used memory.
tlx::delegate< void(request *r, bool success)> completion_handler
completion handler
void on()
turn switch ON and notify one waiter
completion_handler do_after_fetch
static constexpr bool debug
bool block_consumed(block_type *&buffer)
High-performance smart pointer used as a wrapping reference counting pointer.
void operator()(request *req, bool success)
typename block_type::bid_type bid_type
size_t pos() const
Index of the next element in the consume sequence.
static uint_pair min()
return an uint_pair instance containing the smallest value possible
block_type * read_buffers
set_switch_handler(onoff_switch &_switch, const completion_handler &on_complete)
completion_handler on_complete_
Request object encapsulating basic properties like file and offset.
bid_iterator_type consume_seq_end
#define TLX_LOG
Default logging method: output if the local debug variable is true.