14 #ifndef STXXL_PREFETCH_POOL_HEADER
15 #define STXXL_PREFETCH_POOL_HEADER
19 #ifdef STXXL_BOOST_CONFIG
20 #include <boost/config.hpp>
23 #include <stxxl/bits/mng/write_pool.h>
24 #include <stxxl/bits/compat_hash_map.h>
27 __STXXL_BEGIN_NAMESPACE
33 template <
class BlockType>
37 typedef BlockType block_type;
38 typedef typename block_type::bid_type bid_type;
43 size_t operator () (
const bid_type & bid)
const
45 size_t result = size_t(bid.storage) +
46 size_t(bid.offset & 0xffffffff) + size_t(bid.offset >> 32);
50 bool operator () (
const bid_type & a,
const bid_type & b)
const
52 return (a.storage < b.storage) || (a.storage == b.storage && a.offset < b.offset);
61 typedef std::pair<block_type *, request_ptr> busy_entry;
62 typedef typename compat_hash_map<bid_type, busy_entry, bid_hash>::result hash_map_type;
63 typedef typename std::list<block_type *>::iterator free_blocks_iterator;
64 typedef typename hash_map_type::iterator busy_blocks_iterator;
67 std::list<block_type *> free_blocks;
69 hash_map_type busy_blocks;
71 unsigned_type free_blocks_size;
76 explicit prefetch_pool(unsigned_type init_size = 1) : free_blocks_size(init_size)
79 for ( ; i < init_size; ++i)
80 free_blocks.push_back(
new block_type);
85 std::swap(free_blocks, obj.free_blocks);
86 std::swap(busy_blocks, obj.busy_blocks);
87 std::swap(free_blocks_size, obj.free_blocks_size);
93 while (!free_blocks.empty())
95 delete free_blocks.back();
96 free_blocks.pop_back();
101 busy_blocks_iterator i2 = busy_blocks.begin();
102 for ( ; i2 != busy_blocks.end(); ++i2)
104 i2->second.second->wait();
105 delete i2->second.first;
112 unsigned_type
size()
const {
return free_blocks_size + busy_blocks.size(); }
124 if (in_prefetching(bid)) {
125 STXXL_VERBOSE2(
"prefetch_pool::hint2 bid=" << bid <<
" was already cached");
129 if (free_blocks_size)
132 block_type * block = free_blocks.back();
133 free_blocks.pop_back();
134 STXXL_VERBOSE2(
"prefetch_pool::hint bid=" << bid <<
" => prefetching");
136 busy_blocks[bid] = busy_entry(block, req);
139 STXXL_VERBOSE2(
"prefetch_pool::hint bid=" << bid <<
" => no free blocks for prefetching");
146 if (in_prefetching(bid)) {
147 STXXL_VERBOSE2(
"prefetch_pool::hint2 bid=" << bid <<
" was already cached");
151 if (free_blocks_size)
154 block_type * block = free_blocks.back();
155 free_blocks.pop_back();
156 if (w_pool.has_request(bid))
158 busy_entry wp_request = w_pool.steal_request(bid);
159 STXXL_VERBOSE1(
"prefetch_pool::hint2 bid=" << bid <<
" was in write cache at " << wp_request.first);
160 assert(wp_request.first != 0);
162 busy_blocks[bid] = wp_request;
165 STXXL_VERBOSE2(
"prefetch_pool::hint2 bid=" << bid <<
" => prefetching");
167 busy_blocks[bid] = busy_entry(block, req);
170 STXXL_VERBOSE2(
"prefetch_pool::hint2 bid=" << bid <<
" => no free blocks for prefetching");
174 bool invalidate(bid_type bid)
176 busy_blocks_iterator cache_el = busy_blocks.find(bid);
177 if (cache_el == busy_blocks.end())
182 if (cache_el->second.second->get_type() == request::READ)
183 cache_el->second.second->cancel();
185 cache_el->second.second->wait();
187 free_blocks.push_back(cache_el->second.first);
188 busy_blocks.erase(cache_el);
192 bool in_prefetching(bid_type bid)
194 return (busy_blocks.find(bid) != busy_blocks.end());
205 busy_blocks_iterator cache_el = busy_blocks.find(bid);
206 if (cache_el == busy_blocks.end())
209 STXXL_VERBOSE1(
"prefetch_pool::read bid=" << bid <<
" => no copy in cache, retrieving to " << block);
210 return block->read(bid);
214 STXXL_VERBOSE1(
"prefetch_pool::read bid=" << bid <<
" => copy in cache exists");
216 free_blocks.push_back(block);
217 block = cache_el->second.first;
219 busy_blocks.erase(cache_el);
226 busy_blocks_iterator cache_el = busy_blocks.find(bid);
227 if (cache_el != busy_blocks.end())
230 STXXL_VERBOSE1(
"prefetch_pool::read bid=" << bid <<
" => copy in cache exists");
232 free_blocks.push_back(block);
233 block = cache_el->second.first;
235 busy_blocks.erase(cache_el);
240 if (w_pool.has_request(bid))
242 busy_entry wp_request = w_pool.steal_request(bid);
243 STXXL_VERBOSE1(
"prefetch_pool::read bid=" << bid <<
" was in write cache at " << wp_request.first);
244 assert(wp_request.first != 0);
246 block = wp_request.first;
247 return wp_request.second;
251 STXXL_VERBOSE1(
"prefetch_pool::read bid=" << bid <<
" => no copy in cache, retrieving to " << block);
252 return block->read(bid);
261 unsigned_type
resize(unsigned_type new_size)
263 int_type diff = int_type(new_size) - int_type(
size());
266 free_blocks_size += diff;
268 free_blocks.push_back(
new block_type);
274 while (diff < 0 && free_blocks_size > 0)
278 delete free_blocks.back();
279 free_blocks.pop_back();
287 __STXXL_END_NAMESPACE
291 template <
class BlockType>
292 void swap(stxxl::prefetch_pool<BlockType> & a,
293 stxxl::prefetch_pool<BlockType> & b)
299 #endif // !STXXL_PREFETCH_POOL_HEADER
bool hint(bid_type bid)
Gives a hint for prefetching a block.
Definition: prefetch_pool.h:121
Implements dynamically resizable prefetching pool.
Definition: prefetch_pool.h:34
Implements dynamically resizable buffered writing pool.
Definition: write_pool.h:36
unsigned_type resize(unsigned_type new_size)
Resizes size of the pool.
Definition: prefetch_pool.h:261
prefetch_pool(unsigned_type init_size=1)
Constructs pool.
Definition: prefetch_pool.h:76
request_ptr read(block_type *&block, bid_type bid)
Reads block. If this block is cached block is not read but passed from the cache. ...
Definition: prefetch_pool.h:203
Implemented as reference counting smart pointer.
Definition: request_ptr.h:34
unsigned_type size() const
Returns number of owned blocks.
Definition: prefetch_pool.h:112
virtual ~prefetch_pool()
Waits for completion of all ongoing read requests and frees memory.
Definition: prefetch_pool.h:91