Beispiel #1
0
inline typename ListType::Iterator randomFragment(const ListType& src)
{
    if( src.empty() ) return src.end();
    typename ListType::ConstIterator result = src.begin();
    ::std::advance( result, ::std::rand() % src.size() );
    return result;
}
typename ListType::FragmentType
selectBlock(const ListType& src, typename ListType::FSizeType blockSize,
    const AvailableType* available )
{
    typedef typename ListType::FragmentType FragmentType;
    typedef typename ListType::FSizeType FSizeType;
    typedef typename ListType::ConstIterator ConstIterator;
    
    if( src.empty() ) return FragmentType( 0,
        ::std::numeric_limits< FSizeType >::max() );

    ::std::deque< FSizeType > blocks;

    for( ConstIterator selectIterator = src.begin();
        selectIterator != src.end(); ++selectIterator )
    {
        FSizeType blockBegin = selectIterator->begin() / blockSize;
        FSizeType blockEnd = ( selectIterator->end() - 1 ) / blockSize;
		if ( selectIterator->begin() % blockSize )
		{
			// the start of a block is complete, but part is missing
			
			if ( !available || available[ blockBegin ] )
			{
                return FragmentType( selectIterator->begin(),
                    ::std::min( selectIterator->end(),
                    blockSize * ( blockBegin + 1 ) ) );
			}
            ++blockBegin;
		}
		if ( blockBegin <= blockEnd && selectIterator->end() % blockSize
            && selectIterator->end() < src.limit() )
		{
			// the end of a block is complete, but part is missing
			
			if ( !available || available[ blockEnd ] )
			{
                return FragmentType( blockEnd * blockSize,
                    selectIterator->end() );
			}
            --blockEnd;
		}
		// this fragment contains one or more aligned empty blocks
        if( blockEnd != ~0ULL ) for( ; blockBegin <= blockEnd; ++blockBegin )
        {
            if( !available || available[ blockBegin ] )
            {
                blocks.push_back( blockBegin );
            }
        }
	}
	
    if( blocks.empty() )  return FragmentType( 0,
        ::std::numeric_limits< FSizeType >::max() );

    FSizeType blockBegin = blocks[ ::std::rand() % blocks.size() ] * blockSize;

    return FragmentType( blockBegin, ::std::min( blockBegin + blockSize, src.limit() ) );
}