13 #ifndef STXXL_PREFETCH_POOL_HEADER
14 #define STXXL_PREFETCH_POOL_HEADER
18 #ifdef STXXL_BOOST_CONFIG
19 #include <boost/config.hpp>
22 #include <stxxl/bits/mng/mng.h>
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 (busy_blocks.find(bid) != busy_blocks.end())
128 if (free_blocks_size)
130 STXXL_VERBOSE2(
"prefetch_pool::hint bid= " << bid <<
" => prefetching");
133 block_type * block = free_blocks.back();
134 free_blocks.pop_back();
136 busy_blocks[bid] = busy_entry(block, req);
139 STXXL_VERBOSE2(
"prefetch_pool::hint bid=" << bid <<
" => no free blocks for prefetching");
146 if (busy_blocks.find(bid) != busy_blocks.end())
150 if (free_blocks_size)
152 STXXL_VERBOSE2(
"prefetch_pool::hint2 bid= " << bid <<
" => prefetching");
154 block_type * block = free_blocks.back();
155 free_blocks.pop_back();
159 block_type * w_block = w_pool.
steal(bid);
160 STXXL_VERBOSE1(
"prefetch_pool::hint2 bid= " << bid <<
" was in write cache at " << w_block);
161 assert(w_block != 0);
163 busy_blocks[bid] = busy_entry(w_block, req);
166 req = block->read(bid);
167 busy_blocks[bid] = busy_entry(block, req);
170 STXXL_VERBOSE2(
"prefetch_pool::hint2 bid=" << bid <<
" => no free blocks for prefetching");
174 bool in_prefetching(bid_type bid)
176 return (busy_blocks.find(bid) != busy_blocks.end());
187 busy_blocks_iterator cache_el = busy_blocks.find(bid);
188 if (cache_el == busy_blocks.end())
191 STXXL_VERBOSE1(
"prefetch_pool::read bid=" << bid <<
" => no copy in cache, retrieving to " << block);
192 return block->read(bid);
196 STXXL_VERBOSE1(
"prefetch_pool::read bid=" << bid <<
" => copy in cache exists");
198 free_blocks.push_back(block);
199 block = cache_el->second.first;
201 busy_blocks.erase(cache_el);
211 unsigned_type
resize(unsigned_type new_size)
213 int_type diff = int_type(new_size) - int_type(
size());
216 free_blocks_size += diff;
218 free_blocks.push_back(
new block_type);
224 while (diff < 0 && free_blocks_size > 0)
228 delete free_blocks.back();
229 free_blocks.pop_back();
237 __STXXL_END_NAMESPACE
241 template <
class BlockType>
242 void swap(stxxl::prefetch_pool<BlockType> & a,
243 stxxl::prefetch_pool<BlockType> & b)
249 #endif // !STXXL_PREFETCH_POOL_HEADER