636
636
raise errors.NoSmartMedium(self)
638
def readv(self, relpath, offsets):
638
def readv(self, relpath, offsets, adjust_for_latency=False):
639
"""Get parts of the file at the given relative path.
641
:param relpath: The path to read data from.
642
:param offsets: A list of (offset, size) tuples.
643
:param adjust_for_latency: Adjust the requested offsets to accomdate
644
transport latency. This may re-order the offsets, expand them to
645
grab adjacent data when there is likely a high cost to requesting
646
data relative to delivering it.
647
:return: A list or generator of (offset, data) tuples
649
if adjust_for_latency:
650
offsets = sorted(offsets)
651
# short circuit empty requests
652
if len(offsets) == 0:
654
# Quick thunk to stop this function becoming a generator
655
# itself, rather we return a generator that has nothing to
659
return empty_yielder()
660
# expand by page size at either end
661
expansion = self.recommended_page_size() / 2
663
for offset, length in offsets:
664
new_offset = offset - expansion
665
new_length = length + expansion
667
# don't ask for anything < 0
668
new_length -= new_offset
670
new_offsets.append((new_offset, new_length))
671
# combine the expanded offsets
673
current_offset, current_length = new_offsets[0]
674
current_finish = current_length + current_offset
675
for offset, length in new_offsets[1:]:
676
if offset > current_finish:
677
offsets.append((current_offset, current_length))
678
current_offset = offset
679
current_length = length
681
finish = offset + length
682
if finish > current_finish:
683
current_finish = finish
684
offsets.append((current_offset, current_length))
685
return self._readv(relpath, offsets)
687
def _readv(self, relpath, offsets):
639
688
"""Get parts of the file at the given relative path.
641
690
:offsets: A list of (offset, size) tuples.