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() ) );
}
Beispiel #2
0
inline ListType inverse(const ListType& src)
{
    typedef typename ListType::FragmentType FragmentType;
    typedef typename ListType::PayloadType PayloadType;
    ListType result( src.limit() );
    typename ListType::FSizeType last = 0;
    for( typename ListType::ConstIterator i = src.begin(); i != src.end();
        ++i )
    {
        if( last < i->begin() )
        {
            result.insert( FragmentType( last, i->begin(),
                PayloadType() ) );
        }
        last = i->end();
    }
    if( last < src.limit() )
    {
        result.insert( FragmentType( last, src.limit(), PayloadType() ) );
    }
    return result;
}