Esempio n. 1
0
def patch_diff_tarfile( base_path, diff_tarfile, restrict_index=() ):
    """Patch given Path object using delta tarfile (as in tarfile.TarFile)

    If restrict_index is set, ignore any deltas in diff_tarfile that
    don't start with restrict_index.

    """
    if base_path.exists():
        path_iter = selection.Select( base_path ).set_iter()
    else:
        path_iter = empty_iter() # probably untarring full backup

    diff_path_iter = difftar2path_iter( diff_tarfile )
    if restrict_index:
        diff_path_iter = filter_path_iter( diff_path_iter, restrict_index )
    collated = diffdir.collate2iters( path_iter, diff_path_iter )

    ITR = IterTreeReducer( PathPatcher, [base_path] )
    for basis_path, diff_ropath in collated:
        if basis_path:
            log.Info( _( "Patching %s" ) % ( basis_path.get_relative_path(), ),
                     log.InfoCode.patch_file_patching,
                     util.escape( basis_path.get_relative_path() ) )
            ITR( basis_path.index, basis_path, diff_ropath )
        else:
            log.Info( _( "Patching %s" ) % ( diff_ropath.get_relative_path(), ),
                     log.InfoCode.patch_file_patching,
                     util.escape( diff_ropath.get_relative_path() ) )
            ITR( diff_ropath.index, basis_path, diff_ropath )
    ITR.Finish()
    base_path.setdata()
Esempio n. 2
0
def collate_iters(iter_list):
    u"""Collate iterators by index

    Input is a list of n iterators each of which must iterate elements
    with an index attribute.  The elements must come out in increasing
    order, and the index should be a tuple itself.

    The output is an iterator which yields tuples where all elements
    in the tuple have the same index, and the tuple has n elements in
    it.  If any iterator lacks an element with that index, the tuple
    will have None in that spot.

    """
    # overflow[i] means that iter_list[i] has been exhausted
    # elems[i] is None means that it is time to replenish it.
    iter_num = len(iter_list)
    if iter_num == 2:
        return diffdir.collate2iters(iter_list[0], iter_list[1])
    overflow = [None] * iter_num
    elems = overflow[:]

    def setrorps(overflow, elems):
        u"""Set the overflow and rorps list"""
        for i in range(iter_num):
            if not overflow[i] and elems[i] is None:
                try:
                    elems[i] = next(iter_list[i])
                except StopIteration:
                    overflow[i] = 1
                    elems[i] = None

    def getleastindex(elems):
        u"""Return the first index in elems, assuming elems isn't empty"""
        return min([elem.index for elem in [x for x in elems if x]])

    def yield_tuples(iter_num, overflow, elems):
        while 1:
            setrorps(overflow, elems)
            if None not in overflow:
                break

            index = getleastindex(elems)
            yieldval = []
            for i in range(iter_num):
                if elems[i] and elems[i].index == index:
                    yieldval.append(elems[i])
                    elems[i] = None
                else:
                    yieldval.append(None)
            yield tuple(yieldval)

    return yield_tuples(iter_num, overflow, elems)
Esempio n. 3
0
def collate_iters( iter_list ):
    """Collate iterators by index

    Input is a list of n iterators each of which must iterate elements
    with an index attribute.  The elements must come out in increasing
    order, and the index should be a tuple itself.

    The output is an iterator which yields tuples where all elements
    in the tuple have the same index, and the tuple has n elements in
    it.  If any iterator lacks an element with that index, the tuple
    will have None in that spot.

    """
    # overflow[i] means that iter_list[i] has been exhausted
    # elems[i] is None means that it is time to replenish it.
    iter_num = len( iter_list )
    if iter_num == 2:
        return diffdir.collate2iters( iter_list[0], iter_list[1] )
    overflow = [None] * iter_num
    elems = overflow[:]

    def setrorps( overflow, elems ):
        """Set the overflow and rorps list"""
        for i in range( iter_num ):
            if not overflow[i] and elems[i] is None:
                try:
                    elems[i] = iter_list[i].next()
                except StopIteration:
                    overflow[i] = 1
                    elems[i] = None

    def getleastindex( elems ):
        """Return the first index in elems, assuming elems isn't empty"""
        return min( map( lambda elem: elem.index, filter( lambda x: x, elems ) ) )

    def yield_tuples( iter_num, overflow, elems ):
        while 1:
            setrorps( overflow, elems )
            if not None in overflow:
                break

            index = getleastindex( elems )
            yieldval = []
            for i in range( iter_num ):
                if elems[i] and elems[i].index == index:
                    yieldval.append( elems[i] )
                    elems[i] = None
                else:
                    yieldval.append( None )
            yield tuple( yieldval )
    return yield_tuples( iter_num, overflow, elems )