13 #ifndef STXXL_MNG_BLOCK_SCHEDULER_HEADER 
   14 #define STXXL_MNG_BLOCK_SCHEDULER_HEADER 
   35 template <
typename ValueType, 
unsigned BlockSize>
 
   39     static const unsigned_type raw_block_size = BlockSize * 
sizeof(ValueType);
 
   54     { block_manager::get_instance()->new_block(
striping(), external_data, ++disk_allocation_offset); }
 
   58         block_manager::get_instance()->delete_block(external_data);
 
   65         : external_data() , internal_data(0), dirty(false), reference_count(0) { }
 
   71     { 
return (internal_data != NULL); }
 
   79     { 
return external_data.valid(); }
 
   83     { 
return has_external_block() && ! is_dirty(); }
 
   87     { 
return reference_count > 0; }
 
   91     { 
return ! is_acquired() && is_internal(); }
 
   95     { 
return is_internal() || is_external(); }
 
  101         assert(is_acquired());
 
  102         return dirty = make_dirty || dirty;
 
  109         assert(is_internal());
 
  111         return *internal_data;
 
  117         assert(is_acquired());
 
  124         assert(is_acquired());
 
  125         return *internal_data;
 
  131         assert(is_acquired());
 
  132         return *internal_data;
 
  142         assert(is_internal());
 
  143         assert(has_external_block());
 
  148         return internal_data->read(external_data, on_cmpl);
 
  153     { read_async()->wait(); }
 
  161         if (! has_external_block())
 
  162             get_external_block();
 
  167         return internal_data->write(external_data, on_cmpl);
 
  181         assert(! is_internal());
 
  182         internal_data = iblock;
 
  189         assert(is_evictable());
 
  201         assert(! is_acquired());
 
  204         if (has_external_block())
 
  205             free_external_block();
 
  216         assert(! is_initialized());
 
  217         external_data = eblock;
 
  224         assert(! is_internal());
 
  231 template <
typename ValueType, 
unsigned BlockSize>
 
  232 unsigned_type swappable_block<ValueType, BlockSize>::disk_allocation_offset = 0;
 
  234 template <
class SwappableBlockType>
 
  237 template <
class SwappableBlockType>
 
  249 template <
class SwappableBlockType>
 
  283         op_extract_external_block
 
  294             : op(op), id(id), time(time) { }
 
  313     std::priority_queue<swappable_block_identifier_type, std::vector<swappable_block_identifier_type>,
 
  322         if (! free_internal_blocks.empty())
 
  326             free_internal_blocks.pop();
 
  329         else if (remaining_internal_blocks > 0)
 
  332             int_type num_blocks = 
std::min(max_internal_blocks_alloc_at_once, remaining_internal_blocks);
 
  333             remaining_internal_blocks -= num_blocks;
 
  335             internal_blocks_blocks.push(iblocks);
 
  336             for (
int_type i = num_blocks - 1; i > 0; --i)
 
  337                 free_internal_blocks.push(iblocks + i);
 
  349     { free_internal_blocks.push(iblock); }
 
  356           remaining_internal_blocks(max_internal_blocks),
 
  366         int_type num_freed_internal_blocks = 0;
 
  367         if (free_swappable_blocks.size() != swappable_blocks.size())
 
  370             STXXL_ERRMSG(
"not all swappable_blocks are free, those not acquired will be deinitialized");
 
  372             for (
typename std::vector<SwappableBlockType>::iterator it = swappable_blocks.begin();
 
  373                  it != swappable_blocks.end(); ++it)
 
  375                 if (! it->is_acquired() && it->deinitialize())
 
  377                     num_freed_internal_blocks++;
 
  380         if (
int_type nlost = (max_internal_blocks - remaining_internal_blocks)
 
  381                              - (free_internal_blocks.size() + num_freed_internal_blocks)) {
 
  382             STXXL_ERRMSG(nlost << 
" internal_blocks are lost. They will get deallocated.");
 
  384         while (! internal_blocks_blocks.empty())
 
  386             delete[] internal_blocks_blocks.top();
 
  387             internal_blocks_blocks.pop();
 
  396     { 
return algo->acquire(sbid, uninitialized); }
 
  403     { algo->release(sbid, dirty); }
 
  407     { algo->deinitialize(sbid); }
 
  416     { algo->initialize(sbid, eblock); }
 
  423     { 
return algo->extract_external_block(sbid); }
 
  429     { 
return algo->is_initialized(sbid); }
 
  434     { algo->explicit_timestep(); }
 
  439     { 
return swappable_blocks[sbid].get_internal_block(); }
 
  446         if (free_swappable_blocks.empty())
 
  449             sbid = swappable_blocks.size();
 
  450             swappable_blocks.resize(sbid + 1);
 
  451             algo->swappable_blocks_resize(sbid + 1);
 
  456             sbid = free_swappable_blocks.top();
 
  457             free_swappable_blocks.pop();
 
  467         free_swappable_blocks.push(sbid);
 
  473     { 
return algo->is_simulating(); }
 
  480         assert(&new_algo->
bs == 
this);
 
  495     { 
return algo->get_prediction_sequence(); }
 
  499         std::vector<request_ptr> requests;
 
  500         while (! algo->evictable_blocks_empty())
 
  503             request_ptr rq = swappable_blocks[sbid].clean_async();
 
  505                 requests.push_back(rq);
 
  506             return_free_internal_block(swappable_blocks[sbid].detach_internal_block());
 
  508         for (
typename std::vector<request_ptr>::reverse_iterator it = requests.rbegin();
 
  509              it != requests.rend(); ++it)
 
  516 template <
class SwappableBlockType>
 
  517 const int_type block_scheduler<SwappableBlockType>::max_internal_blocks_alloc_at_once = 128;
 
  520 template <
class SwappableBlockType>
 
  521 class block_scheduler_algorithm : 
private noncopyable
 
  544     { 
return bs.get_free_internal_block(); }
 
  548     { bs.return_free_internal_block(iblock); }
 
  553           swappable_blocks(bs.swappable_blocks)
 
  558           swappable_blocks(bs.swappable_blocks)
 
  563     virtual bool evictable_blocks_empty() = 0;
 
  564     virtual swappable_block_identifier_type evictable_blocks_pop() = 0;
 
  567     virtual internal_block_type & acquire(
const swappable_block_identifier_type sbid, 
const bool uninitialized = 
false) = 0;
 
  568     virtual void release(swappable_block_identifier_type sbid, 
const bool dirty) = 0;
 
  569     virtual void deinitialize(swappable_block_identifier_type sbid) = 0;
 
  570     virtual void initialize(swappable_block_identifier_type sbid, external_block_type eblock) = 0;
 
  571     virtual external_block_type extract_external_block(swappable_block_identifier_type sbid) = 0;
 
  574     { 
return swappable_blocks[sbid].is_initialized(); }
 
  580     { 
return prediction_sequence; }
 
  584 template <
class SwappableBlockType>
 
  585 class block_scheduler_algorithm_online_lru : 
public block_scheduler_algorithm<SwappableBlockType>
 
  594     using block_scheduler_algorithm_type::bs;
 
  595     using block_scheduler_algorithm_type::swappable_blocks;
 
  596     using block_scheduler_algorithm_type::get_algorithm_from_block_scheduler;
 
  597     using block_scheduler_algorithm_type::get_free_internal_block_from_block_scheduler;
 
  598     using block_scheduler_algorithm_type::return_free_internal_block_to_block_scheduler;
 
  609         assert(! evictable_blocks.empty()); 
 
  610         return swappable_blocks[evictable_blocks.pop()].detach_internal_block();
 
  614     { return_free_internal_block_to_block_scheduler(iblock); }
 
  618         if (get_algorithm_from_block_scheduler())
 
  619             while (! get_algorithm_from_block_scheduler()->evictable_blocks_empty())
 
  620                 evictable_blocks.insert(get_algorithm_from_block_scheduler()->evictable_blocks_pop());
 
  634         if (! evictable_blocks.empty())
 
  635             STXXL_ERRMSG(
"Destructing block_scheduler_algorithm_online that still holds evictable blocks. They get deinitialized.");
 
  636         while (! evictable_blocks.empty())
 
  638             SwappableBlockType& sblock = swappable_blocks[evictable_blocks.pop()];
 
  640                 return_free_internal_block(iblock);
 
  645     { 
return evictable_blocks.empty(); }
 
  648     { 
return evictable_blocks.pop(); }
 
  652         SwappableBlockType& sblock = swappable_blocks[sbid];
 
  658         if (sblock.is_internal())
 
  660             if (! sblock.is_acquired())
 
  662                 evictable_blocks.erase(sbid);
 
  665         else if (sblock.is_initialized())
 
  669             sblock.attach_internal_block(get_free_internal_block());
 
  679             sblock.attach_internal_block(get_free_internal_block());
 
  683                 sblock.fill_default();
 
  685         return sblock.get_internal_block();
 
  690         SwappableBlockType& sblock = swappable_blocks[sbid];
 
  691         sblock.make_dirty_if(dirty);
 
  693         if (! sblock.is_acquired())
 
  695             if (sblock.is_dirty() || sblock.is_external())
 
  697                 evictable_blocks.insert(sbid);
 
  700                 return_free_internal_block(sblock.detach_internal_block());
 
  706         SwappableBlockType& sblock = swappable_blocks[sbid];
 
  707         if (sblock.is_evictable())
 
  708             evictable_blocks.erase(sbid);
 
  710             return_free_internal_block(iblock);
 
  715         SwappableBlockType& sblock = swappable_blocks[sbid];
 
  716         sblock.initialize(eblock);
 
  721         SwappableBlockType& sblock = swappable_blocks[sbid];
 
  722         if (sblock.is_evictable())
 
  723             evictable_blocks.erase(sbid);
 
  724         if (sblock.is_internal())
 
  725             return_free_internal_block(sblock.detach_internal_block());
 
  726         return sblock.extract_external_block();
 
  731 template <
class SwappableBlockType>
 
  743     using block_scheduler_algorithm_type::bs;
 
  744     using block_scheduler_algorithm_type::prediction_sequence;
 
  745     using block_scheduler_algorithm_type::swappable_blocks;
 
  746     using block_scheduler_algorithm_type::get_algorithm_from_block_scheduler;
 
  747     using block_scheduler_algorithm_type::get_free_internal_block_from_block_scheduler;
 
  748     using block_scheduler_algorithm_type::return_free_internal_block_to_block_scheduler;
 
  758     { return_free_internal_block_to_block_scheduler(iblock); }
 
  762         if (get_algorithm_from_block_scheduler())
 
  763             while (! get_algorithm_from_block_scheduler()->evictable_blocks_empty())
 
  764                 evictable_blocks.push(get_algorithm_from_block_scheduler()->evictable_blocks_pop());
 
  766             reference_counts[i] = swappable_blocks[i].is_initialized();
 
  773           last_op_release(false),
 
  774           reference_counts(swappable_blocks.size())
 
  780           last_op_release(false),
 
  781           reference_counts(swappable_blocks.size())
 
  786         if (! evictable_blocks.empty())
 
  787             STXXL_ERRMSG(
"Destructing block_scheduler_algorithm_record_prediction_sequence that still holds evictable blocks. They get deinitialized.");
 
  788         while (! evictable_blocks.empty())
 
  790             SwappableBlockType& sblock = swappable_blocks[evictable_blocks.top()];
 
  792                 return_free_internal_block(iblock);
 
  793             evictable_blocks.pop();
 
  798     { 
return evictable_blocks.empty(); }
 
  803         evictable_blocks.pop();
 
  809         ++reference_counts[sbid];
 
  810         last_op_release = 
false;
 
  812             prediction_sequence.push_back(
 
  816             prediction_sequence.push_back(
 
  824         --reference_counts[sbid] += dirty;
 
  825         time_count += ! last_op_release;
 
  826         last_op_release = 
true;
 
  828             prediction_sequence.push_back(
 
  832             prediction_sequence.push_back(
 
  839         reference_counts[sbid] = 
false;
 
  840         prediction_sequence.push_back(
 
  847         reference_counts[sbid] = 
true;
 
  848         prediction_sequence.push_back(
 
  855         reference_counts[sbid] = 
false;
 
  856         prediction_sequence.push_back(
 
  864         reference_counts.resize(size, 0);
 
  869         return reference_counts[sbid] > 0;
 
  880 template <
class SwappableBlockType>
 
  892     using block_scheduler_algorithm_type::bs;
 
  893     using block_scheduler_algorithm_type::swappable_blocks;
 
  894     using block_scheduler_algorithm_type::get_algorithm_from_block_scheduler;
 
  895     using block_scheduler_algorithm_type::get_free_internal_block_from_block_scheduler;
 
  896     using block_scheduler_algorithm_type::return_free_internal_block_to_block_scheduler;
 
  903         priority(
const SwappableBlockType& sblock, 
const std::pair<bool, time_type>& t)
 
  926         { 
return p > right.
p; }
 
  947         assert(! evictable_blocks.empty()); 
 
  948         return swappable_blocks[evictable_blocks.pop()].detach_internal_block();
 
  952     { return_free_internal_block_to_block_scheduler(iblock); }
 
  956         std::vector<std::pair<bool, time_type> >
 
  957         blocks_next_acquire(swappable_blocks.size(), std::make_pair(
false, 1));
 
  962             for (
typename prediction_sequence_type::const_reverse_iterator it = ps.rbegin(); it != ps.rend(); ++it)
 
  966                 case (block_scheduler_type::op_acquire):
 
  967                 case (block_scheduler_type::op_acquire_uninitialized):
 
  968                     blocks_next_acquire[it->id] = std::make_pair(
true, it->time);
 
  970                 case (block_scheduler_type::op_release):
 
  971                 case (block_scheduler_type::op_release_dirty):
 
  972                     next_use.push_front(blocks_next_acquire[it->id]);
 
  974                 case (block_scheduler_type::op_deinitialize):
 
  975                     blocks_next_acquire[it->id] = std::make_pair(
false, 0);
 
  977                 case (block_scheduler_type::op_initialize):
 
  978                     blocks_next_acquire[it->id] = std::make_pair(
false, 3);
 
  980                 case (block_scheduler_type::op_extract_external_block):
 
  981                     blocks_next_acquire[it->id] = std::make_pair(
false, 2);
 
  986         if (get_algorithm_from_block_scheduler())
 
  988             while (! get_algorithm_from_block_scheduler()->evictable_blocks_empty())
 
  992                 evictable_blocks.insert(sbid, 
priority(swappable_blocks[sbid], blocks_next_acquire[sbid]));
 
 1000     { init(get_algorithm_from_block_scheduler()); }
 
 1009         if (! evictable_blocks.empty())
 
 1010             STXXL_ERRMSG(
"Destructing block_scheduler_algorithm_offline_lfd that still holds evictable blocks. They get deinitialized.");
 
 1011         while (! evictable_blocks.empty())
 
 1013             SwappableBlockType& sblock = swappable_blocks[evictable_blocks.pop()];
 
 1015                 return_free_internal_block(iblock);
 
 1020     { 
return evictable_blocks.empty(); }
 
 1023     { 
return evictable_blocks.pop(); }
 
 1027         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1033         if (sblock.is_internal())
 
 1035             if (! sblock.is_acquired())
 
 1037                 evictable_blocks.erase(sbid);
 
 1040         else if (sblock.is_initialized())
 
 1044             sblock.attach_internal_block(get_free_internal_block());
 
 1045             if (! uninitialized)
 
 1054             sblock.attach_internal_block(get_free_internal_block());
 
 1057             if (! uninitialized)
 
 1058                 sblock.fill_default();
 
 1060         return sblock.get_internal_block();
 
 1065         if (next_use.empty())
 
 1067             STXXL_ERRMSG(
"block_scheduler_algorithm_offline_lfd got release-request but prediction sequence ended. Switching to block_scheduler_algorithm_online.");
 
 1071             old_algo = bs.switch_algorithm_to(new_algo);
 
 1073             new_algo->
release(sbid, dirty);
 
 1078         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1079         sblock.make_dirty_if(dirty);
 
 1081         if (! sblock.is_acquired())
 
 1083             if (sblock.is_dirty() || sblock.is_external())
 
 1085                 evictable_blocks.insert(sbid, 
priority(swappable_blocks[sbid], next_use.front()));
 
 1088                 return_free_internal_block(sblock.detach_internal_block());
 
 1090         next_use.pop_front();
 
 1095         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1096         if (sblock.is_evictable())
 
 1097             evictable_blocks.erase(sbid);
 
 1099             return_free_internal_block(iblock);
 
 1104         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1105         sblock.initialize(eblock);
 
 1110         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1111         if (sblock.is_evictable())
 
 1112             evictable_blocks.erase(sbid);
 
 1113         if (sblock.is_internal())
 
 1114             return_free_internal_block(sblock.detach_internal_block());
 
 1115         return sblock.extract_external_block();
 
 1121 template <
class SwappableBlockType>
 
 1145     using block_scheduler_algorithm_type::bs;
 
 1146     using block_scheduler_algorithm_type::swappable_blocks;
 
 1147     using block_scheduler_algorithm_type::get_algorithm_from_block_scheduler;
 
 1148     using block_scheduler_algorithm_type::get_free_internal_block_from_block_scheduler;
 
 1149     using block_scheduler_algorithm_type::return_free_internal_block_to_block_scheduler;
 
 1150     using block_scheduler_algorithm_type::prediction_sequence;
 
 1161             : write_done_soon(false), shall_read(false), block_to_start_read(), taker(), write_req(0) { }
 
 1169             : wrr(write_read_req) { }
 
 1173             wrr->write_done_soon = 
true;
 
 1174             if (wrr->shall_read)
 
 1175                 wrr->taker->second.read_req = wrr->block_to_start_read->read_async();
 
 1182         std::pair<bool, swappable_block_identifier_type> 
giver;
 
 1187             : reserved_iblock(0),
 
 1191         { operations.push_front(op); }
 
 1212         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1217             bool t = write_scheduled_blocks.insert(std::make_pair(sbid, wrr)).second;
 
 1235         writing_block->second->shall_read = 
false;
 
 1237         if (! writing_block->second->write_done_soon)
 
 1242         wait_on_write(writing_block);
 
 1244         if (taker.second.read_req.valid())
 
 1261         if (it != write_scheduled_blocks.end())
 
 1265             if (it->second->shall_read)
 
 1267                 if (try_interrupt_read(it))
 
 1270                     std::swap(other_block_to_read->second.giver, block_to_read->second.giver);
 
 1271                     if (other_block_to_read->second.giver.first)
 
 1274                         if (it != write_scheduled_blocks.end())
 
 1275                             it->second->taker = other_block_to_read;
 
 1277                             other_block_to_read->second.giver.first = 
false;
 
 1279                     if (block_to_read->second.giver.first)
 
 1282                         if (it != write_scheduled_blocks.end())
 
 1283                             it->second->taker = block_to_read;
 
 1285                             block_to_read->second.giver.first = 
false;
 
 1288                     internal_block_type* tmp_iblock = swappable_blocks[block_to_read->first].detach_internal_block();
 
 1289                     swappable_blocks[block_to_read->first].attach_internal_block(
 
 1290                         swappable_blocks[other_block_to_read->first].detach_internal_block());
 
 1291                     swappable_blocks[other_block_to_read->first].attach_internal_block(tmp_iblock);
 
 1294                     schedule_read(other_block_to_read);
 
 1302                 std::swap(other_block_to_read->second.giver, block_to_read->second.giver);
 
 1303                 if (other_block_to_read->second.giver.first)
 
 1306                     if (it != write_scheduled_blocks.end())
 
 1307                         it->second->taker = other_block_to_read;
 
 1309                         other_block_to_read->second.giver.first = 
false;
 
 1311                 if (block_to_read->second.giver.first)
 
 1314                     if (it != write_scheduled_blocks.end())
 
 1315                         it->second->taker = block_to_read;
 
 1317                         block_to_read->second.giver.first = 
false;
 
 1320                 internal_block_type* tmp_iblock = swappable_blocks[block_to_read->first].detach_internal_block();
 
 1321                 swappable_blocks[block_to_read->first].attach_internal_block(
 
 1322                     other_block_to_read->second.reserved_iblock);
 
 1323                 other_block_to_read->second.reserved_iblock = tmp_iblock;
 
 1330         if (block_to_read->second.giver.first)
 
 1333             if (writing_block != write_scheduled_blocks.end())
 
 1337                 writing_block->second->block_to_start_read = swappable_blocks.begin() + block_to_read->first;
 
 1338                 writing_block->second->taker = block_to_read;
 
 1339                 writing_block->second->shall_read = 
true;
 
 1341                 if (writing_block->second->write_done_soon)
 
 1345                     wait_on_write(writing_block);
 
 1346                     block_to_read->second.giver.first = 
false;
 
 1347                     if (block_to_read->second.read_req.valid())
 
 1356                 block_to_read->second.giver.first = 
false;
 
 1359         block_to_read->second.read_req = swappable_blocks[block_to_read->first].read_async();
 
 1367         writing_block->second->write_req->wait();
 
 1368         delete writing_block->second;
 
 1369         write_scheduled_blocks.erase(writing_block);
 
 1378         if (it != write_scheduled_blocks.end())
 
 1387         if (schedule_meta->second.giver.first)
 
 1389             wait_on_write(schedule_meta->second.giver.second);
 
 1390             schedule_meta->second.giver.first = 
false;
 
 1399         wait_on_write(schedule_meta);
 
 1400         if (schedule_meta->second.read_req.valid())
 
 1402             schedule_meta->second.read_req->wait();
 
 1403             schedule_meta->second.read_req = 0;
 
 1412         wait_on_write(schedule_meta);
 
 1414         schedule_meta->second.reserved_iblock = 0;
 
 1421         for (
typename std::deque<block_scheduler_operation>::reverse_iterator
 
 1422              rit = schedule_meta->second.operations.rbegin() + ignore_first;
 
 1423              rit != schedule_meta->second.operations.rend(); ++rit)
 
 1427             case block_scheduler_type::op_acquire:
 
 1428             case block_scheduler_type::op_acquire_uninitialized:
 
 1431             case block_scheduler_type::op_release:
 
 1432             case block_scheduler_type::op_release_dirty:
 
 1434             case block_scheduler_type::op_deinitialize:
 
 1435                 if (swappable_blocks[schedule_meta->first].is_dirty()) 
return true; 
break;
 
 1436             case block_scheduler_type::op_initialize:
 
 1437             case block_scheduler_type::op_extract_external_block:
 
 1448         for (
typename std::deque<block_scheduler_operation>::reverse_iterator
 
 1449              rit = schedule_meta->second.operations.rbegin() + 1;
 
 1450              rit != schedule_meta->second.operations.rend(); ++rit)
 
 1454             case block_scheduler_type::op_acquire:
 
 1455             case block_scheduler_type::op_acquire_uninitialized:
 
 1456             case block_scheduler_type::op_release:
 
 1458             case block_scheduler_type::op_release_dirty:
 
 1459             case block_scheduler_type::op_deinitialize:
 
 1460             case block_scheduler_type::op_initialize:
 
 1463             case block_scheduler_type::op_extract_external_block:
 
 1474         return swappable_blocks[schedule_meta->first].is_initialized()
 
 1475                && schedule_meta->second.operations.rbegin() + ignore_first != schedule_meta->second.operations.rend()
 
 1476                && *(schedule_meta->second.operations.rbegin() + ignore_first) == block_scheduler_type::op_acquire;
 
 1481         schedule_meta->second.operations.pop_back();
 
 1482         if (schedule_meta->second.operations.empty())
 
 1484             assert(! schedule_meta->second.giver.first);
 
 1485             scheduled_blocks.erase(schedule_meta);
 
 1491         STXXL_ERRMSG(
"block_scheduler_algorithm_offline_lru_prefetching: " << err_msg << 
". Switching to block_scheduler_algorithm_online.");
 
 1496         delete bs.switch_algorithm_to(new_algo);
 
 1501     { return_free_internal_block_to_block_scheduler(iblock); }
 
 1505         while (next_op_to_schedule != prediction_sequence.end())
 
 1508             std::pair<scheduled_blocks_iterator, bool> ins_res = scheduled_blocks.insert(
 
 1509                 std::make_pair(next_op_to_schedule->id, next_op_to_schedule->op));
 
 1511             if (! ins_res.second)
 
 1512                 schedule_meta->second.operations.push_front(next_op_to_schedule->op);
 
 1513             SwappableBlockType& sblock = swappable_blocks[next_op_to_schedule->id];
 
 1516             if (next_op_to_schedule->op == block_scheduler_type::op_acquire
 
 1517                 || next_op_to_schedule->op == block_scheduler_type::op_acquire_uninitialized)
 
 1519                 if (sblock.is_internal())
 
 1521                     if (free_evictable_blocks.erase(next_op_to_schedule->id))
 
 1522                         scheduled_evictable_blocks.insert(next_op_to_schedule->id);
 
 1526                     if (! schedule_meta->second.reserved_iblock)
 
 1530                         schedule_meta->second.reserved_iblock = get_free_internal_block_from_block_scheduler();
 
 1531                         if (! schedule_meta->second.reserved_iblock)
 
 1534                             if (free_evictable_blocks.empty())
 
 1539                                     scheduled_blocks.erase(ins_res.first);
 
 1541                                     schedule_meta->second.operations.pop_front();
 
 1547                                 assert(scheduled_blocks.find(giver) == scheduled_blocks.end() ||
 
 1548                                        !shall_keep_internal_block(scheduled_blocks.find(giver), 
false));
 
 1551                             schedule_meta->second.giver.first = (wrr != NULL);
 
 1552                             schedule_meta->second.giver.second = giver;
 
 1553                             schedule_meta->second.reserved_iblock = swappable_blocks[giver].detach_internal_block();
 
 1555                                 wrr->
taker = schedule_meta;
 
 1558                         if (shall_be_read(schedule_meta, 
false))
 
 1562                             sblock.attach_internal_block(schedule_meta->second.reserved_iblock);
 
 1563                             schedule_meta->second.reserved_iblock = 0;
 
 1564                             scheduled_evictable_blocks.insert(next_op_to_schedule->id);
 
 1565                             schedule_read(schedule_meta);
 
 1570             else if (next_op_to_schedule->op == block_scheduler_type::op_deinitialize)
 
 1572                 if (sblock.is_dirty())
 
 1573                     if (free_evictable_blocks.erase(next_op_to_schedule->id))
 
 1574                         scheduled_evictable_blocks.insert(next_op_to_schedule->id);
 
 1577             ++next_op_to_schedule;
 
 1579         for (
typename std::set<swappable_block_identifier_type>::iterator it = free_evictable_blocks.begin();
 
 1580              it != free_evictable_blocks.end(); ++it)
 
 1582             if (! write_scheduled_blocks.count(*it))
 
 1583                 schedule_write(*it);
 
 1592         next_op_to_schedule = prediction_sequence.begin();
 
 1593         if (get_algorithm_from_block_scheduler())
 
 1594             while (! get_algorithm_from_block_scheduler()->evictable_blocks_empty())
 
 1595                 free_evictable_blocks.insert(get_algorithm_from_block_scheduler()->evictable_blocks_pop());
 
 1596         schedule_next_operations();
 
 1602         if (! scheduled_blocks.empty())
 
 1603             STXXL_MSG(
"deinit while scheduled_blocks not empty");
 
 1604         if (! scheduled_evictable_blocks.empty())
 
 1605             STXXL_MSG(
"deinit while scheduled_evictable_blocks not empty");
 
 1608         free_evictable_blocks.insert(scheduled_evictable_blocks.begin(), scheduled_evictable_blocks.end());
 
 1612         scheduled_evictable_blocks.clear();
 
 1613         while (! scheduled_blocks.empty())
 
 1617             if (it->second.reserved_iblock)
 
 1618                 return_free_internal_block(it->second.reserved_iblock);
 
 1619             scheduled_blocks.erase(it);
 
 1621         while (! write_scheduled_blocks.empty())
 
 1631     { init(get_algorithm_from_block_scheduler()); }
 
 1641         if (! free_evictable_blocks.empty())
 
 1642             STXXL_ERRMSG(
"Destructing block_scheduler_algorithm_offline_lru_prefetching that still holds evictable blocks. They get deinitialized.");
 
 1643         while (! free_evictable_blocks.empty())
 
 1645             SwappableBlockType& sblock = swappable_blocks[
pop_begin(free_evictable_blocks)];
 
 1647                 return_free_internal_block(iblock);
 
 1654         return free_evictable_blocks.empty();
 
 1658     { 
return pop_begin(free_evictable_blocks); }
 
 1662         assert(! prediction_sequence.empty());
 
 1663         assert(prediction_sequence.front().op ==
 
 1664                ((uninitialized) ? block_scheduler_type::op_acquire_uninitialized : block_scheduler_type::op_acquire));
 
 1665         assert(prediction_sequence.front().id == sbid);
 
 1666         prediction_sequence.pop_front();
 
 1668         assert(schedule_meta != scheduled_blocks.end());                                                               
 
 1669         assert(schedule_meta->second.operations.back() ==
 
 1670                ((uninitialized) ? block_scheduler_type::op_acquire_uninitialized : block_scheduler_type::op_acquire)); 
 
 1672         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1678         if (sblock.is_internal())
 
 1680             if (! sblock.is_acquired())
 
 1683                 size_t t = scheduled_evictable_blocks.erase(sbid);
 
 1685                 wait_on_read(schedule_meta);
 
 1691             assert(uninitialized || ! sblock.is_initialized()); 
 
 1693             sblock.attach_internal_block(get_ready_block(schedule_meta));
 
 1696             if (! uninitialized)
 
 1697                 sblock.fill_default();
 
 1700         operation_done(schedule_meta);
 
 1701         return sblock.get_internal_block();
 
 1706         assert(! prediction_sequence.empty());
 
 1707         assert(prediction_sequence.front().op ==
 
 1708                ((dirty) ? block_scheduler_type::op_release_dirty : block_scheduler_type::op_release));
 
 1709         assert(prediction_sequence.front().id == sbid);
 
 1710         prediction_sequence.pop_front();
 
 1712         assert(schedule_meta != scheduled_blocks.end());
 
 1713         assert(schedule_meta->second.operations.back() ==
 
 1714                ((dirty) ? block_scheduler_type::op_release_dirty : block_scheduler_type::op_release));
 
 1716         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1717         sblock.make_dirty_if(dirty);
 
 1719         if (! sblock.is_acquired())
 
 1721             if (sblock.is_dirty() || sblock.is_external())
 
 1724                 if (shall_keep_internal_block(schedule_meta))
 
 1727                     scheduled_evictable_blocks.insert(sbid);
 
 1728                     if (shall_be_cleaned(schedule_meta))
 
 1729                         schedule_write(sbid);
 
 1734                     free_evictable_blocks.insert(sbid);
 
 1735                     if (next_op_to_schedule != prediction_sequence.end())
 
 1736                         schedule_next_operations();
 
 1738                         if (! write_scheduled_blocks.count(sbid))
 
 1739                             schedule_write(sbid);
 
 1746                 if (shall_keep_internal_block(schedule_meta))
 
 1748                     schedule_meta->second.reserved_iblock = sblock.detach_internal_block();
 
 1752                     return_free_internal_block(sblock.detach_internal_block());
 
 1753                     if (next_op_to_schedule != prediction_sequence.end())
 
 1754                         schedule_next_operations();
 
 1758         operation_done(schedule_meta);
 
 1763         assert(! prediction_sequence.empty());
 
 1764         assert(prediction_sequence.front().op == block_scheduler_type::op_deinitialize);
 
 1765         assert(prediction_sequence.front().id == sbid);
 
 1766         prediction_sequence.pop_front();
 
 1768         assert(schedule_meta != scheduled_blocks.end());
 
 1769         assert(schedule_meta->second.operations.back() == block_scheduler_type::op_deinitialize);
 
 1771         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1772         if (sblock.is_evictable())
 
 1775             if (shall_keep_internal_block(schedule_meta, 
false))
 
 1777                 t = scheduled_evictable_blocks.erase(sbid);
 
 1779                     STXXL_ERRMSG(
"dirty block not scheduled on deinitialize");
 
 1780                     t = free_evictable_blocks.erase(sbid);
 
 1784                 t = free_evictable_blocks.erase(sbid);
 
 1789             if (shall_keep_internal_block(schedule_meta))
 
 1791                 schedule_meta->second.reserved_iblock = iblock;
 
 1795                 return_free_internal_block(iblock);
 
 1796                 if (next_op_to_schedule != prediction_sequence.end())
 
 1797                     schedule_next_operations();
 
 1800         operation_done(schedule_meta);
 
 1805         assert(! prediction_sequence.empty());
 
 1806         assert(prediction_sequence.front().op == block_scheduler_type::op_initialize);
 
 1807         assert(prediction_sequence.front().id == sbid);
 
 1808         prediction_sequence.pop_front();
 
 1810         assert(schedule_meta != scheduled_blocks.end());
 
 1811         assert(schedule_meta->second.operations.back() == block_scheduler_type::op_initialize);
 
 1813         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1814         sblock.initialize(eblock);
 
 1815         if (shall_be_read(schedule_meta))
 
 1817             sblock.attach_internal_block(schedule_meta->second.reserved_iblock);
 
 1818             schedule_meta->second.reserved_iblock = 0;
 
 1819             scheduled_evictable_blocks.insert(sbid);
 
 1820             schedule_read(schedule_meta);
 
 1822         operation_done(schedule_meta);
 
 1827         assert(! prediction_sequence.empty());
 
 1828         assert(prediction_sequence.front().op == block_scheduler_type::op_extract_external_block);
 
 1829         assert(prediction_sequence.front().id == sbid);
 
 1830         prediction_sequence.pop_front();
 
 1832         assert(schedule_meta != scheduled_blocks.end());
 
 1833         assert(schedule_meta->second.operations.back() == block_scheduler_type::op_extract_external_block);
 
 1835         SwappableBlockType& sblock = swappable_blocks[sbid];
 
 1836         wait_on_write(sbid);
 
 1837         operation_done(schedule_meta);
 
 1838         return sblock.extract_external_block();
 
 1844 #endif // !STXXL_MNG_BLOCK_SCHEDULER_HEADER 
internal_block_type * detach_internal_block()
Detach the internal_block. Writes to external_block if necessary. Has to be evictable. 
addressable_fifo_queue< swappable_block_identifier_type > evictable_blocks
Holds swappable blocks, whose internal block can be freed, i.e. that are internal but unacquired...
void wait_on_read(const scheduled_blocks_iterator &schedule_meta)
Wait for the read to finish. 
#define STXXL_ASSERT(condition)
block_scheduler_algorithm_type * give_up(std::string err_msg="detected some error in the prediction sequence")
compat::remove_const< Integral >::type div_ceil(Integral n, Integral2 d)
void get_external_block()
bool shall_be_cleaned(const scheduled_blocks_iterator &schedule_meta) const 
const int_type max_internal_blocks
block_scheduler_type::internal_block_type internal_block_type
virtual internal_block_type & acquire(const swappable_block_identifier_type sbid, const bool uninitialized=false)
void schedule_next_operations()
virtual void swappable_blocks_resize(swappable_block_identifier_type size)
internal_block_type & get_internal_block(const swappable_block_identifier_type sbid) const 
Get a const reference to given block's data. Block has to be already acquired. 
bool is_initialized(const swappable_block_identifier_type sbid) const 
check if the swappable_block is initialized. 
void free_swappable_block(const swappable_block_identifier_type sbid)
Free given no longer used temporary swappable_block. 
virtual void initialize(swappable_block_identifier_type sbid, external_block_type eblock)
virtual bool is_initialized(const swappable_block_identifier_type sbid) const 
std::map< swappable_block_identifier_type, write_read_request * > write_scheduled_blocks_type
Completion handler class (Loki-style). 
scheduled_blocks_type scheduled_blocks
Holds not internal swappable_blocks, whose next access has already been scheduled. 
block_scheduler_operation
scheduled_blocks_type::reference scheduled_blocks_reference
swappable_block_identifier_type id
internal_block_type * get_free_internal_block_from_block_scheduler()
Get an internal_block from the block_scheduler. 
void deinitialize(const swappable_block_identifier_type sbid)
Drop all data in the given block, freeing in- and external memory. 
swappable_blocks_iterator block_to_start_read
external_block_type external_data
block_scheduler_algorithm< SwappableBlockType > block_scheduler_algorithm_type
block_scheduler_type::swappable_block_identifier_type swappable_block_identifier_type
virtual void initialize(swappable_block_identifier_type sbid, external_block_type)
SwappableBlockType::internal_block_type internal_block_type
block_scheduler_type::swappable_block_identifier_type swappable_block_identifier_type
virtual bool is_simulating() const 
internal_block_type * get_ready_block(const scheduled_blocks_iterator &schedule_meta)
Wait for the write of the giver to finish and return reserved internal_block. 
std::stack< internal_block_type * > internal_blocks_blocks
Stores pointers to arrays of internal_blocks. Used to deallocate them only. 
block_scheduler_algorithm< SwappableBlockType > block_scheduler_algorithm_type
std::deque< std::pair< bool, time_type > > next_use
Stores for the sequence of releases extracted from the prediction_sequence: (true, timestamp of the blocks next acquire) if it is acquired next (false, 0) if it is deinitialized next (false, 1) if it is not accessed any more (false, 2) if it is extracted next (false, 3) if it is initialized next. 
block_scheduler_algorithm_offline_lru_prefetching(block_scheduler_algorithm_type *old)
Container::value_type pop_begin(Container &c)
void initialize(const swappable_block_identifier_type sbid, external_block_type eblock)
Initialize the swappable_block with the given external_block. 
block_scheduler_algorithm_offline_lfd(block_scheduler_algorithm_type *old)
void read_sync()
Read synchronously from external_block to internal_block. Has to be internal and have an external_blo...
void clean_sync()
Write synchronously from internal_block to external_block if necessary. 
An internal priority queue that allows removing elements addressed with (a copy of) themselves...
internal_block_type * get_free_internal_block()
std::vector< SwappableBlockType > swappable_blocks
temporary blocks that will not be needed after algorithm termination. 
std::vector< int_type > reference_counts
void init(block_scheduler_algorithm_type *old_algo)
virtual bool is_simulating() const 
void explicit_timestep()
Record a timestep in the prediction sequence to seperate consecutive acquire rsp. release-operations...
static uint_pair min()
return an uint_pair instance containing the smallest value possible 
virtual bool evictable_blocks_empty()
request_ptr read_async(completion_handler on_cmpl=completion_handler())
Read asyncronusly from external_block to internal_block. Has to be internal and have an external_bloc...
bool has_external_block() const 
If it has an external_block. 
scheduled_blocks_type::iterator scheduled_blocks_iterator
virtual ~block_scheduler_algorithm_online_lru()
static const int_type max_internal_blocks_alloc_at_once
virtual const prediction_sequence_type & get_prediction_sequence() const 
block_scheduler_algorithm_online_lru(block_scheduler_algorithm_type *old)
internal_block_type * internal_data
external_data.valid if no associated space on disk 
prediction_sequence_type prediction_sequence
block_scheduler_algorithm_offline_lfd(block_scheduler_type &bs)
block_scheduler_type::time_type time_type
block_scheduler_type::prediction_sequence_type prediction_sequence_type
Virtualization of a block of data. Holds information for allocating and swapping. To use in cooperati...
virtual external_block_type extract_external_block(swappable_block_identifier_type sbid)
bool valid() const 
test for a non-NULL pointer 
bool is_simulating() const 
Returns if simulation mode is on, i.e. if a prediction sequence is being recorded. 
block_scheduler< SwappableBlockType > block_scheduler_type
std::stack< swappable_block_identifier_type > evictable_blocks
Holds swappable blocks, whose internal block can be freed, i.e. that are internal but unacquired...
Block scheduling algorithm caching via the least recently used policy (offline), and prefetching in a...
internal_block_type::bid_type external_block_type
virtual void release(swappable_block_identifier_type sbid, const bool dirty)
prediction_sequence_type::iterator next_op_to_schedule
void return_free_internal_block(internal_block_type *iblock)
block_scheduler< SwappableBlockType > block_scheduler_type
internal_block_type * deinitialize()
Bring the block in uninitialized state, freeing external and internal memory. Returns a pointer to th...
void initialize(external_block_type eblock)
Set the external_block that holds the swappable_block's data. The block gets initialized with it...
void free_external_block()
Block scheduling algorithm caching via the least recently used policy (online). 
virtual void deinitialize(swappable_block_identifier_type sbid)
write_scheduled_blocks_type::iterator write_scheduled_blocks_iterator
void init(block_scheduler_algorithm_type *old_algo)
block_scheduler_algorithm * get_algorithm_from_block_scheduler()
block_scheduler_type::external_block_type external_block_type
SwappableBlockType::external_block_type external_block_type
bool is_initialized() const 
If it has some valid data (in- or external). 
block_scheduler_algorithm_type::time_type time_type
virtual ~block_scheduler_algorithm_simulation()
virtual void release(swappable_block_identifier_type sbid, const bool dirty)
block_scheduler_type::prediction_sequence_type prediction_sequence_type
Block containing elements of fixed length. 
counting_ptr< request > request_ptr
A reference counting pointer for request. 
virtual void wait(bool measure_time=true)=0
Suspends calling thread until completion of the request. 
scheduled_blocks_iterator taker
virtual void initialize(swappable_block_identifier_type sbid, external_block_type eblock)
block_scheduler_type::external_block_type external_block_type
internal_block_type & acquire()
Acquire the block, i.e. add a reference. Has to be internal. 
virtual ~block_scheduler_algorithm()
void operation_done(scheduled_blocks_iterator &schedule_meta)
virtual internal_block_type & acquire(const swappable_block_identifier_type sbid, const bool uninitialized=false)
block_scheduler_algorithm_simulation(block_scheduler_algorithm_type *old)
virtual bool is_initialized(const swappable_block_identifier_type sbid) const 
virtual external_block_type extract_external_block(swappable_block_identifier_type sbid)
choose_int_types< my_pointer_size >::int_type int_type
std::priority_queue< swappable_block_identifier_type, std::vector< swappable_block_identifier_type >, std::greater< swappable_block_identifier_type > > free_swappable_blocks
holds indices of free swappable_blocks with attributes reset. 
bool try_interrupt_read(const write_scheduled_blocks_iterator &writing_block)
Try to interrupt a read scheduled in a write_read_request. 
bool shall_be_read(const scheduled_blocks_iterator &schedule_meta, const bool ignore_first=true) const 
block_scheduler_type::external_block_type external_block_type
virtual void initialize(swappable_block_identifier_type sbid, external_block_type eblock)
internal_block_type * get_free_internal_block()
Get an internal_block from the freelist or a newly allocated one if available. 
block_scheduler< SwappableBlockType > block_scheduler_type
virtual void deinitialize(swappable_block_identifier_type sbid)
bool is_acquired() const 
If it is acquired. 
int_type remaining_internal_blocks
addressable_priority_queue< swappable_block_identifier_type, priority > evictable_blocks
Holds swappable blocks, whose internal block can be freed, i.e. that are internal but unacquired...
virtual bool evictable_blocks_empty()
Striping disk allocation scheme functor. 
swappable_block_identifier_type allocate_swappable_block()
Allocate an uninitialized swappable_block. 
std::set< swappable_block_identifier_type > free_evictable_blocks
Holds swappable blocks, whose internal block can be freed, i.e. that are internal but unacquired...
void wait_on_write(const write_scheduled_blocks_iterator &writing_block)
Wait for the write to finish. 
block_scheduler_type::external_block_type external_block_type
Pseudo block scheduling algorithm only recording the request sequence. 
bool operator<(const uint_pair &b) const 
less-than comparison operator 
block_scheduler_algorithm_simulation(block_scheduler_type &bs)
block_scheduler_operation op
#define STXXL_BEGIN_NAMESPACE
write_scheduled_blocks_type::reference write_scheduled_blocks_reference
std::vector< SwappableBlockType >::size_type swappable_block_identifier_type
const internal_block_type & get_internal_block() const 
Get a reference to the data-block. Has to be acquired. 
read_after_write(write_read_request *write_read_req)
block_scheduler(const int_type max_internal_memory)
Create a block_scheduler with empty prediction sequence in simple mode. 
block_scheduler_type::block_scheduler_operation block_scheduler_operation
write_read_request * schedule_write(const swappable_block_identifier_type sbid)
Schedule an internal, possibly dirty swappable_block to write. 
virtual ~block_scheduler_algorithm_offline_lru_prefetching()
std::map< swappable_block_identifier_type, scheduled_block_meta > scheduled_blocks_type
block_scheduler_algorithm(block_scheduler_algorithm *old)
bool shall_keep_internal_block(const scheduled_blocks_iterator &schedule_meta, const bool ignore_first=true) const 
virtual void deinitialize(swappable_block_identifier_type sbid)
virtual swappable_block_identifier_type evictable_blocks_pop()
const prediction_sequence_type & get_prediction_sequence() const 
Get the prediction_sequence. 
request_ptr clean_async(completion_handler on_cmpl=completion_handler())
Write asyncronusly from internal_block to external_block if necessary. 
std::list< prediction_sequence_element > prediction_sequence_type
static uint_pair max()
return an uint_pair instance containing the largest value possible 
virtual swappable_block_identifier_type evictable_blocks_pop()
internal_block_type dummy_block
void return_free_internal_block_to_block_scheduler(internal_block_type *iblock)
Return an internal_block to the block_scheduler. 
block_scheduler_type::prediction_sequence_type prediction_sequence_type
virtual swappable_block_identifier_type evictable_blocks_pop()
typed_block< raw_block_size, ValueType > internal_block_type
block_scheduler_type::internal_block_type internal_block_type
virtual internal_block_type & acquire(const swappable_block_identifier_type sbid, const bool uninitialized=false)
virtual void swappable_blocks_resize(swappable_block_identifier_type)
void fill_default()
Fill block with default data, is supposed to be overwritten by subclass. Has to be internal...
virtual internal_block_type & acquire(const swappable_block_identifier_type sbid, const bool uninitialized=false)
void schedule_read(scheduled_blocks_iterator block_to_read)
Schedule an internal and external block to read. 
virtual void deinitialize(swappable_block_identifier_type sbid)
virtual void explicit_timestep()
virtual void release(swappable_block_identifier_type sbid, const bool dirty)=0
bool is_dirty() const 
If the external_block does not hold valid data. 
swappable_block()
Create in uninitialized state. 
block_scheduler_type::internal_block_type internal_block_type
Block scheduling algorithm caching via the longest forward distance policy (offline). 
block_scheduler_algorithm_online_lru(block_scheduler_type &bs)
void attach_internal_block(internal_block_type *iblock)
Attach an internal_block, making the block internal. Has to be not internal. 
block_scheduler_algorithm< SwappableBlockType > * algo
std::set< swappable_block_identifier_type > scheduled_evictable_blocks
std::vector< SwappableBlockType >::iterator swappable_blocks_iterator
block_scheduler< SwappableBlockType > block_scheduler_type
void wait_on_write(const swappable_block_identifier_type &writing_block)
Wait for the write to finish. 
block_scheduler_type::swappable_block_identifier_type swappable_block_identifier_type
bool is_external() const 
If it has an external_block that holds valid data. 
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
virtual bool evictable_blocks_empty()
priority(const SwappableBlockType &sblock, const std::pair< bool, time_type > &t)
block_scheduler_algorithm(block_scheduler_type &bs)
internal_block_type * get_free_internal_block()
virtual external_block_type extract_external_block(swappable_block_identifier_type sbid)
static unsigned_type disk_allocation_offset
std::vector< SwappableBlockType > & swappable_blocks
void return_free_internal_block(internal_block_type *iblock)
block_scheduler_type::internal_block_type internal_block_type
block_scheduler_type::swappable_block_identifier_type swappable_block_identifier_type
void release()
Release the block, i.e. subduct a reference. Has to be acquired. 
void return_free_internal_block(internal_block_type *iblock)
Return an internal_block to the freelist. 
prediction_sequence_element(block_scheduler_operation op, swappable_block_identifier_type id, int_type time)
void release(const swappable_block_identifier_type sbid, const bool dirty)
Release the given block. Has to be in pairs with acquire. Pairs may be nested and interleaved...
virtual void release(swappable_block_identifier_type sbid, const bool dirty)
virtual external_block_type extract_external_block(swappable_block_identifier_type sbid)
Schedules swapping of blocks and provides blocks for temporary storage. 
block_scheduler_algorithm_type::time_type time_type
write_scheduled_blocks_type write_scheduled_blocks
Holds swappable_blocks, whose internal block has been taken away but the clean did not finish yet...
block_scheduler_type::internal_block_type internal_block_type
void return_free_internal_block(internal_block_type *iblock)
block_scheduler_algorithm< SwappableBlockType > * get_current_algorithm() const 
Return the current algorithm. 
block_scheduler_type::swappable_block_identifier_type swappable_block_identifier_type
block_scheduler_type::prediction_sequence_element prediction_sequence_element_type
block_scheduler_algorithm_offline_lru_prefetching(block_scheduler_type &bs)
virtual swappable_block_identifier_type evictable_blocks_pop()
block_scheduler< SwappableBlockType > block_scheduler_type
virtual void release(swappable_block_identifier_type sbid, const bool dirty)
bool make_dirty_if(const bool make_dirty)
Invalidate external data if true. 
Interface of a block scheduling algorithm. 
block_scheduler_algorithm< SwappableBlockType > block_scheduler_algorithm_type
external_block_type extract_external_block()
Extract the swappable_blocks data in an external_block. The block gets uninitialized. 
block_scheduler_algorithm< SwappableBlockType > * switch_algorithm_to(block_scheduler_algorithm< SwappableBlockType > *new_algo)
Switch the used algorithm, e.g. to simulation etc.. 
virtual ~block_scheduler_algorithm_offline_lfd()
Request object encapsulating basic properties like file and offset. 
virtual void explicit_timestep()
virtual bool evictable_blocks_empty()
block_scheduler_algorithm_type::time_type time_type
block_scheduler_type & bs
std::stack< internal_block_type * > free_internal_blocks
holds free internal_blocks with attributes reset. 
bool is_internal() const 
If it has an internal_block. The internal_block implicitly holds valid data. 
block_scheduler_type::external_block_type external_block_type
block_scheduler_algorithm< SwappableBlockType > block_scheduler_algorithm_type
void wait_on_write(const scheduled_blocks_iterator &schedule_meta)
Wait for the write of the giver to finish. 
void return_free_internal_block(internal_block_type *iblock)
#define STXXL_END_NAMESPACE
internal_block_type & get_internal_block()
Get a reference to the data-block. Has to be acquired. 
internal_block_type & acquire(const swappable_block_identifier_type sbid, const bool uninitialized=false)
Acquire the given block. Has to be in pairs with release. Pairs may be nested and interleaved...
external_block_type extract_external_block(const swappable_block_identifier_type sbid)
Deinitialize the swappable_block and return it's contents in an external_block. 
bool is_evictable() const 
If it holds an internal_block but does not need it.