コード例 #1
0
//returns the number of doubles actually freed
size_t DiskBackedBlockMap::backup_and_free_doubles(size_t requested_doubles_to_free) {
	size_t freed_count = 0;
	try {
		while (freed_count < requested_doubles_to_free) { //if requested_doubles_to_free <= 0, no iterations performed.
			ServerBlock* block;
			BlockId bid = policy_.get_next_block_for_removal(block);
			block->wait();
			ServerBlock* blk = block_map_.block(bid);
			check(blk == block, "bug in free_doubles");
			SIP_LOG(
					std::cout << "S " << sip_mpi_attr_.company_rank() << " : Freeing block " << bid << " and writing to disk to make space for new block" << std::endl);
			if (!blk->disk_state_.is_valid_on_disk()) {
				write_block_to_disk(bid, blk);
				blocks_to_disk_.inc();
				blk->disk_state_.set_valid_on_disk();
			}
			double* data_to_free = blk->get_data();
			free_data(data_to_free, blk->size()); //this method updates remaining_doubles_
			blk->disk_state_.unset_in_memory();
			blk->data_ = NULL;
			freed_count += blk->size();
		}
	} catch (const std::out_of_range& oor) {
		//ran out of blocks, just return what was freed.
	}
	return freed_count;
}
コード例 #2
0
/** Template specialization for ServerBlock.
 *
 * Regular LRU Array policy is to evict the
 * "first" block from the least recently used array.
 * For ServerBlocks however, since they are not
 * removed from the BlockMap, but are "emptied out",
 * the regular array policy won't work.
 *
 * This methods first chooses an array whose block
 * is to be evicted. It then finds one, skipping
 * over those blocks which have been "emptied" out.
 */
template<> BlockId LRUArrayPolicy<ServerBlock>::get_next_block_for_removal(){
	/** Return an arbitrary block from the least recently used array
	 */
	if(lru_list_.empty())
		throw std::out_of_range("No blocks have been touched, yet block requested for flushing");
	while (!lru_list_.empty()) {
		int to_remove_array = lru_list_.back();
		IdBlockMap<ServerBlock>::PerArrayMap* array_map = block_map_.per_array_map(to_remove_array);
		IdBlockMap<ServerBlock>::PerArrayMap::iterator it = array_map->begin();
		for (; it != array_map->end(); it ++) {
			ServerBlock *blk = it->second;
			if (blk !=NULL && blk->get_data() != NULL) {
				return it->first;
			}
		}
		lru_list_.pop_back();
	}
	throw std::out_of_range("No server blocks to remove - all empty or none present !");
}