Пример #1
0
    def _get_copy_parts(self, copy_intent, start_offset, end_offset):
        """ Split copy intent to emerge parts. """
        fragment_length = end_offset - start_offset
        part_count = int(fragment_length / self.max_part_size)
        last_part_length = fragment_length % self.max_part_size
        if last_part_length == 0:
            last_part_length = self.max_part_size
        else:
            part_count += 1

        if part_count == 1:
            part_sizes = [last_part_length]
        else:
            if last_part_length < int(fragment_length / (part_count + 1)):
                part_count += 1
            base_part_size = int(fragment_length / part_count)
            size_remainder = fragment_length % part_count
            part_sizes = [
                base_part_size + (1 if i < size_remainder else 0)
                for i in range(part_count)
            ]

        copy_source = copy_intent.outbound_source
        relative_offset = start_offset - copy_intent.destination_offset
        for part_size in part_sizes:
            yield EmergePart(
                CopyEmergePartDefinition(copy_source, relative_offset,
                                         part_size))
            relative_offset += part_size
Пример #2
0
def part(source_or_def_list, *offset_len):
    """ Helper for building emerge parts from outbound sources defs. Makes planner tests easier to read.

    Possible "def" structures:

        ``outbound_source`` - will build correct emerge part using type introspection with
                              ``0`` for ``offset`` and ``outbound_source.get_content_length()`` for ``length``

        ``outbound_source, offset, length`` - same as above, but given ``offset`` and ``length``

        ``[outbound_source_def,...]``` - will build emerge part using ``UploadSubpartsEmergePartDefinition``
                                         and type introspection for upload subparts; ``outbound_source_def`` is
                                         similar to above, either outbound source or tuple with source, offset, length
    Please notice that ``part([copy_source])`` is a single "small copy" - first download then upload, and
    ``part(copy_source) is "regular copy" - ``length`` is not verified here

    """
    if isinstance(source_or_def_list, list):
        assert not offset_len
        subparts = []
        for sub_part_meta in source_or_def_list:
            if isinstance(sub_part_meta, tuple):
                source, offset, length = sub_part_meta
            else:
                source = sub_part_meta
                offset = 0
                length = source.get_content_length()
            if isinstance(source, UploadSource):
                subparts.append(
                    LocalSourceUploadSubpart(source, offset, length))
            else:
                subparts.append(
                    RemoteSourceUploadSubpart(source, offset, length))
        return UploadSubpartsEmergePartDefinition(subparts)
    else:
        source = source_or_def_list
        if offset_len:
            offset, length = offset_len
        else:
            offset = 0
            length = source.get_content_length()
        if isinstance(source, UploadSource):
            return UploadEmergePartDefinition(source, offset, length)
        else:
            return CopyEmergePartDefinition(source, offset, length)