758
758
into a single large request, while retaining the original
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
762
767
:param offsets: A list of (start, length) pairs
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.
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'
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.
778
:return: yield _CoalescedOffset objects, which have members for where
779
to start, how much to read, and how to split those
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
783
784
cur = _CoalescedOffset(None, None, [])
785
coalesced_offsets = []
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)):
795
raise ValueError('Overlapping range not allowed:'
796
' last range ended at %s, new one starts at %s'
792
798
cur.length = end - cur.start
793
799
cur.ranges.append((start-cur.start, size))
795
801
if cur.start is not None:
802
coalesced_offsets.append(cur)
797
803
cur = _CoalescedOffset(start, size, [(0, size)])
800
806
if cur.start is not None:
807
coalesced_offsets.append(cur)
808
return coalesced_offsets
805
810
def get_multi(self, relpaths, pb=None):
806
811
"""Get a list of file-like objects, one for each entry in relpaths.