~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-12-10 21:06:38 UTC
  • mfrom: (3835.1.18 remote-stacking-graph)
  • Revision ID: pqm@pqm.ubuntu.com-20081210210638-e569azc2bomqq5qx
(abentley) Move RemoteRepository caching to CachingParentsProvider

Show diffs side-by-side

added added

removed removed

Lines of Context:
287
287
                'Does not support nested trees', target_format)
288
288
 
289
289
 
290
 
class _UnstackedParentsProvider(object):
291
 
    """ParentsProvider for RemoteRepository that ignores stacking."""
292
 
 
293
 
    def __init__(self, remote_repository):
294
 
        self._remote_repository = remote_repository
295
 
 
296
 
    def get_parent_map(self, revision_ids):
297
 
        """See RemoteRepository.get_parent_map."""
298
 
        return self._remote_repository._get_parent_map(revision_ids)
299
 
 
300
 
 
301
290
class RemoteRepository(_RpcHelper):
302
291
    """Repository accessed over rpc.
303
292
 
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()
337
326
        # For tests:
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
476
465
 
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)
486
470
 
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()
562
544
        else:
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)
604
584
        else:
663
643
        self._lock_count -= 1
664
644
        if self._lock_count > 0:
665
645
            return
666
 
        self._parents_map = None
667
 
        if 'hpss' in debug.debug_flags:
668
 
            self._requested_parents = None
 
646
        self._unstacked_provider.disable_cache()
669
647
        old_mode = self._lock_mode
670
648
        self._lock_mode = None
671
649
        try:
903
881
        """See bzrlib.Graph.get_parent_map()."""
904
882
        return self._make_parents_provider().get_parent_map(revision_ids)
905
883
 
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
910
 
        if ancestry is None:
911
 
            # Repository is not locked, so there's no cache.
912
 
            missing_revisions = set(keys)
913
 
            ancestry = {}
914
 
        else:
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)),
921
 
                        len(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)
930
 
 
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.
982
935
            parents_map = {}
1228
1181
        self._ensure_real()
1229
1182
        return self._real_repository._check_for_inconsistent_revision_parents()
1230
1183
 
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)