14 #ifndef FOXXLL_MNG_PREFETCH_POOL_HEADER 15 #define FOXXLL_MNG_PREFETCH_POOL_HEADER 19 #include <unordered_map> 24 #include <foxxll/config.hpp> 33 template <
class BlockType>
36 constexpr
static bool debug =
false;
40 using bid_type =
typename block_type::bid_type;
47 size_t result = size_t(bid.storage) +
48 size_t(bid.offset & 0xffffffff) +
49 size_t(bid.offset >> 32);
55 return (a.storage < b.storage) || (a.storage == b.storage && a.offset < b.offset);
82 : free_blocks_size(init_size)
85 for ( ; i < init_size; ++i)
104 while (!free_blocks.empty())
106 delete free_blocks.back();
107 free_blocks.pop_back();
113 for ( ; i2 != busy_blocks.end(); ++i2)
115 i2->second.second->wait();
116 delete i2->second.first;
126 return free_blocks_size + busy_blocks.size();
138 return busy_blocks.size();
144 free_blocks.push_back(block);
157 free_blocks.pop_back();
178 TLX_LOG <<
"prefetch_pool::hint2 bid=" << bid <<
" was already cached";
182 if (free_blocks_size)
186 free_blocks.pop_back();
187 TLX_LOG <<
"prefetch_pool::hint bid=" << bid <<
" => prefetching";
192 TLX_LOG <<
"prefetch_pool::hint bid=" << bid <<
" => no free blocks for prefetching";
216 TLX_LOG <<
"prefetch_pool::hint2 bid=" << bid <<
" was already cached";
220 if (free_blocks_size)
224 free_blocks.pop_back();
228 TLX_LOG <<
"prefetch_pool::hint2 bid=" << bid <<
" was in write cache at " << wp_request.first;
229 assert(wp_request.first != 0);
231 busy_blocks[bid] = wp_request;
234 TLX_LOG <<
"prefetch_pool::hint2 bid=" << bid <<
" => prefetching";
239 TLX_LOG <<
"prefetch_pool::hint2 bid=" << bid <<
" => no free blocks for prefetching";
247 if (cache_el == busy_blocks.end())
253 cache_el->second.second->cancel();
255 cache_el->second.second->wait();
257 free_blocks.push_back(cache_el->second.first);
258 busy_blocks.erase(cache_el);
265 return (busy_blocks.find(bid) != busy_blocks.end());
274 if (cache_el == busy_blocks.end())
277 return cache_el->second.second;
284 return req.
valid() ? req->poll() :
false;
304 if (cache_el == busy_blocks.end())
307 TLX_LOG <<
"prefetch_pool::read bid=" << bid <<
" => no copy in cache, retrieving to " << block;
308 return block->read(bid);
312 TLX_LOG <<
"prefetch_pool::read bid=" << bid <<
" => copy in cache exists";
314 free_blocks.push_back(block);
315 block = cache_el->second.first;
317 busy_blocks.erase(cache_el);
325 if (cache_el != busy_blocks.end())
328 TLX_LOG <<
"prefetch_pool::read bid=" << bid <<
" => copy in cache exists";
330 free_blocks.push_back(block);
331 block = cache_el->second.first;
333 busy_blocks.erase(cache_el);
341 TLX_LOG <<
"prefetch_pool::read bid=" << bid <<
" was in write cache at " << wp_request.first;
342 assert(wp_request.first != 0);
344 block = wp_request.first;
345 return wp_request.second;
349 TLX_LOG <<
"prefetch_pool::read bid=" << bid <<
" => no copy in cache, retrieving to " << block;
350 return block->read(bid);
361 int64_t diff = int64_t(new_size) - int64_t(
size());
364 free_blocks_size += diff;
371 while (diff < 0 && free_blocks_size > 0)
375 delete free_blocks.back();
376 free_blocks.pop_back();
388 template <
class BlockType>
397 #endif // !FOXXLL_MNG_PREFETCH_POOL_HEADER Implements dynamically resizable prefetching pool.
bool invalidate(bid_type bid)
Cancel a hint request in case the block is no longer desired.
typename std::list< block_type * >::iterator free_blocks_iterator
bool has_request(bid_type bid)
request_ptr read(block_type *&block, bid_type bid)
Reads block.
size_t size() const
Returns number of owned blocks.
request_ptr find(bid_type bid)
tlx::counting_ptr< request > request_ptr
A reference counting pointer for request.
prefetch_pool & operator=(const prefetch_pool &)=delete
non-copyable: delete assignment operator
Implements dynamically resizable buffered writing pool.
std::list< block_type * > free_blocks
contains free prefetch blocks
std::pair< block_type *, request_ptr > steal_request(bid_type bid)
void add(block_type *&block)
Add a new block to prefetch pool, enlarges size of pool.
bool valid() const noexcept
test for a non-nullptr pointer
unordered_map_type busy_blocks
blocks that are in reading or already read but not retrieved by user
typename unordered_map_type::iterator busy_blocks_iterator
static constexpr bool debug
size_t resize(size_t new_size)
bool in_prefetching(bid_type bid)
Checks if a block is in the hinted block set.
typename block_type::bid_type bid_type
virtual ~prefetch_pool()
Waits for completion of all ongoing read requests and frees memory.
size_t busy_size() const
Returns the number of busy prefetching blocks.
request_ptr read(block_type *&block, bid_type bid, write_pool< block_type > &w_pool)
High-performance smart pointer used as a wrapping reference counting pointer.
void swap(prefetch_pool &obj)
typename std::unordered_map< bid_type, busy_entry, bid_hash > unordered_map_type
void add(block_type *&block)
size_t free_blocks_size
count number of free blocks, since traversing the std::list is slow.
bool poll(bid_type bid)
Returns true if the blocks was hinted and the request is finished.
std::pair< block_type *, request_ptr > busy_entry
prefetch_pool(size_t init_size=1)
size_t free_size() const
Returns the number of free prefetching blocks.
bool hint(bid_type bid)
Gives a hint for prefetching a block, the block may or may not be read into a prefetch buffer...
size_t operator()(const bid_type &bid) const noexcept
bool hint(bid_type bid, write_pool< block_type > &w_pool)
Gives a hint for prefetching a block, the block may or may not be read into a prefetch buffer...
#define TLX_LOG
Default logging method: output if the local debug variable is true.
#define tlx_die_unless(X)