~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/__init__.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
758
758
        into a single large request, while retaining the original
759
759
        offsets.
760
760
        Turns  [(15, 10), (25, 10)] => [(15, 20, [(0, 10), (10, 10)])]
 
761
        Note that overlapping requests are not permitted. (So [(15, 10), (20,
 
762
        10)] will raise a ValueError.) This is because the data we access never
 
763
        overlaps, and it allows callers to trust that we only need any byte of
 
764
        data for 1 request (so nothing needs to be buffered to fulfill a second
 
765
        request.)
761
766
 
762
767
        :param offsets: A list of (start, length) pairs
763
 
 
764
768
        :param limit: Only combine a maximum of this many pairs Some transports
765
769
                penalize multiple reads more than others, and sometimes it is
766
770
                better to return early.
767
771
                0 means no limit
768
 
 
769
772
        :param fudge_factor: All transports have some level of 'it is
770
 
                better to read some more data and throw it away rather 
 
773
                better to read some more data and throw it away rather
771
774
                than seek', so collapse if we are 'close enough'
772
 
 
773
775
        :param max_size: Create coalesced offsets no bigger than this size.
774
776
                When a single offset is bigger than 'max_size', it will keep
775
777
                its size and be alone in the coalesced offset.
776
778
                0 means no maximum size.
777
 
 
778
 
        :return: yield _CoalescedOffset objects, which have members for where
779
 
                to start, how much to read, and how to split those 
780
 
                chunks back up
 
779
        :return: return a list of _CoalescedOffset objects, which have members
 
780
            for where to start, how much to read, and how to split those chunks
 
781
            back up
781
782
        """
782
783
        last_end = None
783
784
        cur = _CoalescedOffset(None, None, [])
 
785
        coalesced_offsets = []
784
786
 
785
787
        for start, size in offsets:
786
788
            end = start + size
789
791
                and start >= cur.start
790
792
                and (limit <= 0 or len(cur.ranges) < limit)
791
793
                and (max_size <= 0 or end - cur.start <= max_size)):
 
794
                if start < last_end:
 
795
                    raise ValueError('Overlapping range not allowed:'
 
796
                        ' last range ended at %s, new one starts at %s'
 
797
                        % (last_end, start))
792
798
                cur.length = end - cur.start
793
799
                cur.ranges.append((start-cur.start, size))
794
800
            else:
795
801
                if cur.start is not None:
796
 
                    yield cur
 
802
                    coalesced_offsets.append(cur)
797
803
                cur = _CoalescedOffset(start, size, [(0, size)])
798
804
            last_end = end
799
805
 
800
806
        if cur.start is not None:
801
 
            yield cur
802
 
 
803
 
        return
 
807
            coalesced_offsets.append(cur)
 
808
        return coalesced_offsets
804
809
 
805
810
    def get_multi(self, relpaths, pb=None):
806
811
        """Get a list of file-like objects, one for each entry in relpaths.