287
287
'Does not support nested trees', target_format)
290
class _UnstackedParentsProvider(object):
291
"""ParentsProvider for RemoteRepository that ignores stacking."""
293
def __init__(self, remote_repository):
294
self._remote_repository = remote_repository
296
def get_parent_map(self, revision_ids):
297
"""See RemoteRepository.get_parent_map."""
298
return self._remote_repository._get_parent_map(revision_ids)
301
290
class RemoteRepository(_RpcHelper):
302
291
"""Repository accessed over rpc.
330
319
self._lock_token = None
331
320
self._lock_count = 0
332
321
self._leave_lock = False
333
# A cache of looked up revision parent data; reset at unlock time.
334
self._parents_map = None
335
if 'hpss' in debug.debug_flags:
336
self._requested_parents = None
322
debug_cache = ('hpss' in debug.debug_flags)
323
self._unstacked_provider = graph.CachingParentsProvider(
324
get_parent_map=self._get_parent_map_rpc, debug=debug_cache)
325
self._unstacked_provider.disable_cache()
338
327
# These depend on the actual remote format, so force them off for
339
328
# maximum compatibility. XXX: In future these should depend on the
477
466
def get_graph(self, other_repository=None):
478
467
"""Return the graph for this repository format"""
479
parents_provider = self._make_parents_provider()
480
if (other_repository is not None and
481
other_repository.bzrdir.transport.base !=
482
self.bzrdir.transport.base):
483
parents_provider = graph._StackedParentsProvider(
484
[parents_provider, other_repository._make_parents_provider()])
468
parents_provider = self._make_parents_provider(other_repository)
485
469
return graph.Graph(parents_provider)
487
471
def gather_stats(self, revid=None, committers=None):
554
538
if not self._lock_mode:
555
539
self._lock_mode = 'r'
556
540
self._lock_count = 1
557
self._parents_map = {}
558
if 'hpss' in debug.debug_flags:
559
self._requested_parents = set()
541
self._unstacked_provider.enable_cache(cache_misses=False)
560
542
if self._real_repository is not None:
561
543
self._real_repository.lock_read()
596
578
self._leave_lock = False
597
579
self._lock_mode = 'w'
598
580
self._lock_count = 1
599
self._parents_map = {}
600
if 'hpss' in debug.debug_flags:
601
self._requested_parents = set()
581
self._unstacked_provider.enable_cache(cache_misses=False)
602
582
elif self._lock_mode == 'r':
603
583
raise errors.ReadOnlyError(self)
903
881
"""See bzrlib.Graph.get_parent_map()."""
904
882
return self._make_parents_provider().get_parent_map(revision_ids)
906
def _get_parent_map(self, keys):
907
"""Implementation of get_parent_map() that ignores fallbacks."""
908
# Hack to build up the caching logic.
909
ancestry = self._parents_map
911
# Repository is not locked, so there's no cache.
912
missing_revisions = set(keys)
915
missing_revisions = set(key for key in keys if key not in ancestry)
916
if missing_revisions:
917
parent_map = self._get_parent_map_rpc(missing_revisions)
918
if 'hpss' in debug.debug_flags:
919
mutter('retransmitted revisions: %d of %d',
920
len(set(ancestry).intersection(parent_map)),
922
ancestry.update(parent_map)
923
present_keys = [k for k in keys if k in ancestry]
924
if 'hpss' in debug.debug_flags:
925
if self._requested_parents is not None and len(ancestry) != 0:
926
self._requested_parents.update(present_keys)
927
mutter('Current RemoteRepository graph hit rate: %d%%',
928
100.0 * len(self._requested_parents) / len(ancestry))
929
return dict((k, ancestry[k]) for k in present_keys)
931
884
def _get_parent_map_rpc(self, keys):
932
885
"""Helper for get_parent_map that performs the RPC."""
933
886
medium = self._client._medium
976
929
# TODO: Manage this incrementally to avoid covering the same path
977
930
# repeatedly. (The server will have to on each request, but the less
978
931
# work done the better).
979
parents_map = self._parents_map
932
parents_map = self._unstacked_provider.get_cached_map()
980
933
if parents_map is None:
981
934
# Repository is not locked, so there's no cache.
1228
1181
self._ensure_real()
1229
1182
return self._real_repository._check_for_inconsistent_revision_parents()
1231
def _make_parents_provider(self):
1232
providers = [_UnstackedParentsProvider(self)]
1184
def _make_parents_provider(self, other=None):
1185
providers = [self._unstacked_provider]
1186
if other is not None:
1187
providers.insert(0, other)
1233
1188
providers.extend(r._make_parents_provider() for r in
1234
1189
self._fallback_repositories)
1235
1190
return graph._StackedParentsProvider(providers)