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
self._unstacked_provider = graph.CachingParentsProvider(
323
get_parent_map=self._get_parent_map_rpc)
324
self._unstacked_provider.disable_cache()
338
326
# These depend on the actual remote format, so force them off for
339
327
# maximum compatibility. XXX: In future these should depend on the
477
465
def get_graph(self, other_repository=None):
478
466
"""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()])
467
parents_provider = self._make_parents_provider(other_repository)
485
468
return graph.Graph(parents_provider)
487
470
def gather_stats(self, revid=None, committers=None):
554
537
if not self._lock_mode:
555
538
self._lock_mode = 'r'
556
539
self._lock_count = 1
557
self._parents_map = {}
558
if 'hpss' in debug.debug_flags:
559
self._requested_parents = set()
540
self._unstacked_provider.enable_cache(cache_misses=False)
560
541
if self._real_repository is not None:
561
542
self._real_repository.lock_read()
596
577
self._leave_lock = False
597
578
self._lock_mode = 'w'
598
579
self._lock_count = 1
599
self._parents_map = {}
600
if 'hpss' in debug.debug_flags:
601
self._requested_parents = set()
580
self._unstacked_provider.enable_cache(cache_misses=False)
602
581
elif self._lock_mode == 'r':
603
582
raise errors.ReadOnlyError(self)
766
743
self._ensure_real()
767
744
return self._real_repository.add_inventory(revid, inv, parents)
746
def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
749
return self._real_repository.add_inventory_by_delta(basis_revision_id,
750
delta, new_revision_id, parents)
769
752
def add_revision(self, rev_id, rev, inv=None, config=None):
770
753
self._ensure_real()
771
754
return self._real_repository.add_revision(
897
880
"""See bzrlib.Graph.get_parent_map()."""
898
881
return self._make_parents_provider().get_parent_map(revision_ids)
900
def _get_parent_map(self, keys):
901
"""Implementation of get_parent_map() that ignores fallbacks."""
902
# Hack to build up the caching logic.
903
ancestry = self._parents_map
905
# Repository is not locked, so there's no cache.
906
missing_revisions = set(keys)
909
missing_revisions = set(key for key in keys if key not in ancestry)
910
if missing_revisions:
911
parent_map = self._get_parent_map_rpc(missing_revisions)
912
if 'hpss' in debug.debug_flags:
913
mutter('retransmitted revisions: %d of %d',
914
len(set(ancestry).intersection(parent_map)),
916
ancestry.update(parent_map)
917
present_keys = [k for k in keys if k in ancestry]
918
if 'hpss' in debug.debug_flags:
919
if self._requested_parents is not None and len(ancestry) != 0:
920
self._requested_parents.update(present_keys)
921
mutter('Current RemoteRepository graph hit rate: %d%%',
922
100.0 * len(self._requested_parents) / len(ancestry))
923
return dict((k, ancestry[k]) for k in present_keys)
925
883
def _get_parent_map_rpc(self, keys):
926
884
"""Helper for get_parent_map that performs the RPC."""
927
885
medium = self._client._medium
970
928
# TODO: Manage this incrementally to avoid covering the same path
971
929
# repeatedly. (The server will have to on each request, but the less
972
930
# work done the better).
973
parents_map = self._parents_map
931
parents_map = self._unstacked_provider.get_cached_map()
974
932
if parents_map is None:
975
933
# Repository is not locked, so there's no cache.
1222
1180
self._ensure_real()
1223
1181
return self._real_repository._check_for_inconsistent_revision_parents()
1225
def _make_parents_provider(self):
1226
providers = [_UnstackedParentsProvider(self)]
1183
def _make_parents_provider(self, other=None):
1184
providers = [self._unstacked_provider]
1185
if other is not None:
1186
providers.insert(0, other)
1227
1187
providers.extend(r._make_parents_provider() for r in
1228
1188
self._fallback_repositories)
1229
1189
return graph._StackedParentsProvider(providers)
1280
1240
class RemoteBranchFormat(branch.BranchFormat):
1243
super(RemoteBranchFormat, self).__init__()
1244
self._matchingbzrdir = RemoteBzrDirFormat()
1245
self._matchingbzrdir.set_branch_format(self)
1282
1247
def __eq__(self, other):
1283
1248
return (isinstance(other, RemoteBranchFormat) and
1284
1249
self.__dict__ == other.__dict__)