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()
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)
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 )