Beispiel #1
0
struct cigar_t * merge_cigar_t( const struct cigar_t * c )
{
	struct cigar_t * res = NULL;
	if ( c != NULL && c -> length > 0 )
	{
		res = malloc( sizeof * res );
		if ( res != NULL )
		{
			init_cigar_t( res, c->size );
			if ( res->size == c->size )
			{
				int i, last;
				append_to_cigar_t( res, c->op[ 0 ], c->count[ 0 ] );
				for ( i = 1; i < c->length; ++i )
				{
					last = res->length - 1;
					if ( can_merge( c->op[ i ], res->op[ last ] ) )
					{
						res->count[ last ] += c->count[ i ];
						res->op[ last ] = 'M';
					}
					else
						append_to_cigar_t( res, c->op[ i ], c->count[ i ] );	
				}
			}
		}
	}
	return res;
}
Beispiel #2
0
    inline bool
    try_merge(Run& run, Iterator iter, Range const& range)
    {
        // if *iter intersects with, or is adjacent to, 'range'...
        if (can_merge(*iter, range))
        {
            typedef typename Range::value_type value_type;
            typedef integer_traits<value_type> integer_traits;

            // merge range and *iter
            merge(*iter, range);

            // collapse all subsequent ranges that can merge with *iter:
            Iterator i = iter+1;
            // 1. skip subsequent ranges completely included in *iter
            while (i != run.end() && i->last <= iter->last)
                ++i;
            // 2. collapse next range if adjacent or overlapping with *iter
            if (i != run.end() && i->first-1 <= iter->last)
            {
                iter->last = i->last;
                ++i;
            }

            // erase all ranges that were collapsed
            run.erase(iter+1, i);
            return true;
        }
        return false;
    }
Beispiel #3
0
void Header::merge_header(const Header& to_merge_with)
{
    // should have already verified that could merge before performing merge.
    
    //// DEBUG
    if (! can_merge(to_merge_with))
        assert(false);
    //// END DEBUG
    
    // do not currently handle differently-sized headers.
    if (to_merge_with._header_str.size() != _header_str.size())
        assert(false);

    for (int i = 0; i < _header_str.size(); ++i)
    {
        char my_char = _header_str[i];
        // keep match any char
        if (my_char == MATCH_ANY_CHAR)
            continue;
        
        char their_char = to_merge_with._header_str[i];
        if (my_char != their_char)
            _header_str[i] = MATCH_ANY_CHAR;
    }
}
/*
 * Mark a range of blocks as belonging to the "system zone" --- that
 * is, filesystem metadata blocks which should never be used by
 * inodes.
 */
static int add_system_zone(struct ext4_sb_info *sbi,
			   ext4_fsblk_t start_blk,
			   unsigned int count)
{
	struct ext4_system_zone *new_entry = NULL, *entry;
	struct rb_node **n = &sbi->system_blks.rb_node, *node;
	struct rb_node *parent = NULL, *new_node = NULL;

	while (*n) {
		parent = *n;
		entry = rb_entry(parent, struct ext4_system_zone, node);
		if (start_blk < entry->start_blk)
			n = &(*n)->rb_left;
		else if (start_blk >= (entry->start_blk + entry->count))
			n = &(*n)->rb_right;
		else {
			if (start_blk + count > (entry->start_blk + 
						 entry->count))
				entry->count = (start_blk + count - 
						entry->start_blk);
			new_node = *n;
			new_entry = rb_entry(new_node, struct ext4_system_zone,
					     node);
			break;
		}
	}

	if (!new_entry) {
		new_entry = kmem_cache_alloc(ext4_system_zone_cachep,
					     GFP_KERNEL);
		if (!new_entry)
			return -ENOMEM;
		new_entry->start_blk = start_blk;
		new_entry->count = count;
		new_node = &new_entry->node;

		rb_link_node(new_node, parent, n);
		rb_insert_color(new_node, &sbi->system_blks);
	}

	/* Can we merge to the left? */
	node = rb_prev(new_node);
	if (node) {
		entry = rb_entry(node, struct ext4_system_zone, node);
		if (can_merge(entry, new_entry)) {
			new_entry->start_blk = entry->start_blk;
			new_entry->count += entry->count;
			rb_erase(node, &sbi->system_blks);
			kmem_cache_free(ext4_system_zone_cachep, entry);
		}
	}

	/* Can we merge to the right? */
	node = rb_next(new_node);
	if (node) {
		entry = rb_entry(node, struct ext4_system_zone, node);
		if (can_merge(new_entry, entry)) {
			new_entry->count += entry->count;
			rb_erase(node, &sbi->system_blks);
			kmem_cache_free(ext4_system_zone_cachep, entry);
		}
	}
	return 0;
}