288
290
return "%s(%r)" % (self.__class__.__name__,
289
291
self._transport.abspath(self._name))
291
def _buffer_all(self):
293
def _buffer_all(self, stream=None):
292
294
"""Buffer all the index data.
294
296
Mutates self._nodes and self.keys_by_offset.
298
if self._nodes is not None:
299
# We already did this
296
301
if 'index' in debug.debug_flags:
297
302
mutter('Reading entire index %s', self._transport.abspath(self._name))
298
stream = self._transport.get(self._name)
304
stream = self._transport.get(self._name)
299
305
self._read_prefix(stream)
300
306
self._expected_elements = 3 + self._key_length
474
480
if self._size is None and self._nodes is None:
475
481
self._buffer_all()
476
483
# We fit about 20 keys per minimum-read (4K), so if we are looking for
477
484
# more than 1/20th of the index its likely (assuming homogenous key
478
485
# spread) that we'll read the entire index. If we're going to do that,
629
636
if self._bisect_nodes is None:
630
637
readv_ranges.append(_HEADER_READV)
631
638
self._read_and_parse(readv_ranges)
640
if self._nodes is not None:
641
# _read_and_parse triggered a _buffer_all because we requested the
643
for location, key in location_keys:
644
if key not in self._nodes: # not present
645
result.append(((location, key), False))
646
elif self.node_ref_lists:
647
value, refs = self._nodes[key]
648
result.append(((location, key),
649
(self, key, value, refs)))
651
result.append(((location, key),
652
(self, key, self._nodes[key])))
632
654
# generate results:
633
655
# - figure out <, >, missing, present
634
656
# - result present references so we can return them.
636
657
# keys that we cannot answer until we resolve references
637
658
pending_references = []
638
659
pending_locations = set()
689
710
readv_ranges.append((location, length))
690
711
self._read_and_parse(readv_ranges)
712
if self._nodes is not None:
713
# The _read_and_parse triggered a _buffer_all, grab the data and
715
for location, key in pending_references:
716
value, refs = self._nodes[key]
717
result.append(((location, key), (self, key, value, refs)))
691
719
for location, key in pending_references:
692
720
# answer key references we had to look-up-late.
693
index = self._parsed_key_index(key)
694
721
value, refs = self._bisect_nodes[key]
695
722
result.append(((location, key), (self, key,
696
723
value, self._resolve_references(refs))))
967
994
:param readv_ranges: A prepared readv range list.
970
readv_data = self._transport.readv(self._name, readv_ranges, True,
973
for offset, data in readv_data:
974
if self._bisect_nodes is None:
975
# this must be the start
976
if not (offset == 0):
977
raise AssertionError()
978
offset, data = self._parse_header_from_bytes(data)
979
# print readv_ranges, "[%d:%d]" % (offset, offset + len(data))
980
self._parse_region(offset, data)
998
if self._nodes is None and self._bytes_read * 2 >= self._size:
999
# We've already read more than 50% of the file and we are about to
1000
# request more data, just _buffer_all() and be done
1004
readv_data = self._transport.readv(self._name, readv_ranges, True,
1007
for offset, data in readv_data:
1008
self._bytes_read += len(data)
1009
if offset == 0 and len(data) == self._size:
1010
# We read the whole range, most likely because the
1011
# Transport upcast our readv ranges into one long request
1012
# for enough total data to grab the whole index.
1013
self._buffer_all(StringIO(data))
1015
if self._bisect_nodes is None:
1016
# this must be the start
1017
if not (offset == 0):
1018
raise AssertionError()
1019
offset, data = self._parse_header_from_bytes(data)
1020
# print readv_ranges, "[%d:%d]" % (offset, offset + len(data))
1021
self._parse_region(offset, data)
982
1023
def _signature(self):
983
1024
"""The file signature for this index type."""