Rev 2851: Move various weave specific code out of the base Repository class to weaverepo.py. in http://people.ubuntu.com/~robertc/baz2.0/pack-support

Robert Collins robertc at robertcollins.net
Sun Sep 23 23:22:26 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/pack-support

------------------------------------------------------------
revno: 2851
revision-id: robertc at robertcollins.net-20070923222217-n7494b41iceeik08
parent: pqm at pqm.ubuntu.com-20070923210826-t3ymvo1l68z96in1
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack-support
timestamp: Mon 2007-09-24 08:22:17 +1000
message:
  Move various weave specific code out of the base Repository class to weaverepo.py.
modified:
  bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
  bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
=== modified file 'bzrlib/repofmt/knitrepo.py'
--- a/bzrlib/repofmt/knitrepo.py	2007-09-16 23:48:15 +0000
+++ b/bzrlib/repofmt/knitrepo.py	2007-09-23 22:22:17 +0000
@@ -129,12 +129,6 @@
             raise errors.NoSuchRevision(self, revision_id)
 
     @needs_read_lock
-    def get_revision(self, revision_id):
-        """Return the Revision object for a named revision"""
-        revision_id = osutils.safe_revision_id(revision_id)
-        return self.get_revision_reconcile(revision_id)
-
-    @needs_read_lock
     def get_revision_graph(self, revision_id=None):
         """Return a dictionary containing the revision graph.
 

=== modified file 'bzrlib/repofmt/weaverepo.py'
--- a/bzrlib/repofmt/weaverepo.py	2007-09-09 22:01:56 +0000
+++ b/bzrlib/repofmt/weaverepo.py	2007-09-23 22:22:17 +0000
@@ -24,9 +24,12 @@
 
 from bzrlib import (
     bzrdir,
+    debug,
+    errors,
     lockable_files,
     lockdir,
     osutils,
+    revision as _mod_revision,
     weave,
     weavefile,
     xml5,
@@ -74,6 +77,45 @@
             text_store = get_store('text-store')
         super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
 
+    @needs_read_lock
+    def _all_possible_ids(self):
+        """Return all the possible revisions that we could find."""
+        if 'evil' in debug.debug_flags:
+            mutter_callsite(3, "_all_possible_ids scales with size of history.")
+        return self.get_inventory_weave().versions()
+
+    @needs_read_lock
+    def _all_revision_ids(self):
+        """Returns a list of all the revision ids in the repository. 
+
+        These are in as much topological order as the underlying store can 
+        present: for weaves ghosts may lead to a lack of correctness until
+        the reweave updates the parents list.
+        """
+        if self._revision_store.text_store.listable():
+            return self._revision_store.all_revision_ids(self.get_transaction())
+        result = self._all_possible_ids()
+        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
+        #       ids. (It should, since _revision_store's API should change to
+        #       return utf8 revision_ids)
+        return self._eliminate_revisions_not_present(result)
+
+    def _check_revision_parents(self, revision, inventory):
+        """Private to Repository and Fetch.
+        
+        This checks the parentage of revision in an inventory weave for 
+        consistency and is only applicable to inventory-weave-for-ancestry
+        using repository formats & fetchers.
+        """
+        weave_parents = inventory.get_parents(revision.revision_id)
+        weave_names = inventory.versions()
+        for parent_id in revision.parent_ids:
+            if parent_id in weave_names:
+                # this parent must not be a ghost.
+                if not parent_id in weave_parents:
+                    # but it is a ghost
+                    raise errors.CorruptRepository(self)
+
     def get_commit_builder(self, branch, parents, config, timestamp=None,
                            timezone=None, committer=None, revprops=None,
                            revision_id=None):
@@ -85,6 +127,58 @@
         return result
 
     @needs_read_lock
+    def get_revisions(self, revision_ids):
+        revs = self._get_revisions(revision_ids)
+        # weave corruption can lead to absent revision markers that should be
+        # present.
+        # the following test is reasonably cheap (it needs a single weave read)
+        # and the weave is cached in read transactions. In write transactions
+        # it is not cached but typically we only read a small number of
+        # revisions. For knits when they are introduced we will probably want
+        # to ensure that caching write transactions are in use.
+        inv = self.get_inventory_weave()
+        for rev in revs:
+            self._check_revision_parents(rev, inv)
+        return revs
+
+    @needs_read_lock
+    def get_revision_graph(self, revision_id=None):
+        """Return a dictionary containing the revision graph.
+        
+        :param revision_id: The revision_id to get a graph from. If None, then
+        the entire revision graph is returned. This is a deprecated mode of
+        operation and will be removed in the future.
+        :return: a dictionary of revision_id->revision_parents_list.
+        """
+        if 'evil' in debug.debug_flags:
+            mutter_callsite(2,
+                "get_revision_graph scales with size of history.")
+        # special case NULL_REVISION
+        if revision_id == _mod_revision.NULL_REVISION:
+            return {}
+        revision_id = osutils.safe_revision_id(revision_id)
+        a_weave = self.get_inventory_weave()
+        all_revisions = self._eliminate_revisions_not_present(
+                                a_weave.versions())
+        entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for 
+                             node in all_revisions])
+        if revision_id is None:
+            return entire_graph
+        elif revision_id not in entire_graph:
+            raise errors.NoSuchRevision(self, revision_id)
+        else:
+            # add what can be reached from revision_id
+            result = {}
+            pending = set([revision_id])
+            while len(pending) > 0:
+                node = pending.pop()
+                result[node] = entire_graph[node]
+                for revision_id in result[node]:
+                    if revision_id not in result:
+                        pending.add(revision_id)
+            return result
+
+    @needs_read_lock
     def is_shared(self):
         """AllInOne repositories cannot be shared."""
         return False
@@ -111,6 +205,45 @@
 
     _serializer = xml5.serializer_v5
 
+    @needs_read_lock
+    def _all_possible_ids(self):
+        """Return all the possible revisions that we could find."""
+        if 'evil' in debug.debug_flags:
+            mutter_callsite(3, "_all_possible_ids scales with size of history.")
+        return self.get_inventory_weave().versions()
+
+    @needs_read_lock
+    def _all_revision_ids(self):
+        """Returns a list of all the revision ids in the repository. 
+
+        These are in as much topological order as the underlying store can 
+        present: for weaves ghosts may lead to a lack of correctness until
+        the reweave updates the parents list.
+        """
+        if self._revision_store.text_store.listable():
+            return self._revision_store.all_revision_ids(self.get_transaction())
+        result = self._all_possible_ids()
+        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
+        #       ids. (It should, since _revision_store's API should change to
+        #       return utf8 revision_ids)
+        return self._eliminate_revisions_not_present(result)
+
+    def _check_revision_parents(self, revision, inventory):
+        """Private to Repository and Fetch.
+        
+        This checks the parentage of revision in an inventory weave for 
+        consistency and is only applicable to inventory-weave-for-ancestry
+        using repository formats & fetchers.
+        """
+        weave_parents = inventory.get_parents(revision.revision_id)
+        weave_names = inventory.versions()
+        for parent_id in revision.parent_ids:
+            if parent_id in weave_names:
+                # this parent must not be a ghost.
+                if not parent_id in weave_parents:
+                    # but it is a ghost
+                    raise errors.CorruptRepository(self)
+
     def get_commit_builder(self, branch, parents, config, timestamp=None,
                            timezone=None, committer=None, revprops=None,
                            revision_id=None):
@@ -121,6 +254,60 @@
         self.start_write_group()
         return result
 
+    @needs_read_lock
+    def get_revision(self, revision_id):
+        """Return the Revision object for a named revision"""
+        # TODO: jam 20070210 get_revision_reconcile should do this for us
+        revision_id = osutils.safe_revision_id(revision_id)
+        r = self.get_revision_reconcile(revision_id)
+        # weave corruption can lead to absent revision markers that should be
+        # present.
+        # the following test is reasonably cheap (it needs a single weave read)
+        # and the weave is cached in read transactions. In write transactions
+        # it is not cached but typically we only read a small number of
+        # revisions. For knits when they are introduced we will probably want
+        # to ensure that caching write transactions are in use.
+        inv = self.get_inventory_weave()
+        self._check_revision_parents(r, inv)
+        return r
+
+    @needs_read_lock
+    def get_revision_graph(self, revision_id=None):
+        """Return a dictionary containing the revision graph.
+        
+        :param revision_id: The revision_id to get a graph from. If None, then
+        the entire revision graph is returned. This is a deprecated mode of
+        operation and will be removed in the future.
+        :return: a dictionary of revision_id->revision_parents_list.
+        """
+        if 'evil' in debug.debug_flags:
+            mutter_callsite(3,
+                "get_revision_graph scales with size of history.")
+        # special case NULL_REVISION
+        if revision_id == _mod_revision.NULL_REVISION:
+            return {}
+        revision_id = osutils.safe_revision_id(revision_id)
+        a_weave = self.get_inventory_weave()
+        all_revisions = self._eliminate_revisions_not_present(
+                                a_weave.versions())
+        entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for 
+                             node in all_revisions])
+        if revision_id is None:
+            return entire_graph
+        elif revision_id not in entire_graph:
+            raise errors.NoSuchRevision(self, revision_id)
+        else:
+            # add what can be reached from revision_id
+            result = {}
+            pending = set([revision_id])
+            while len(pending) > 0:
+                node = pending.pop()
+                result[node] = entire_graph[node]
+                for revision_id in result[node]:
+                    if revision_id not in result:
+                        pending.add(revision_id)
+            return result
+
 
 class PreSplitOutRepositoryFormat(RepositoryFormat):
     """Base class for the pre split out repository formats."""

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2007-09-21 00:22:35 +0000
+++ b/bzrlib/repository.py	2007-09-23 22:22:17 +0000
@@ -453,11 +453,6 @@
         self._revision_store._add_revision(revision, StringIO(text),
                                            self.get_transaction())
 
-    @needs_read_lock
-    def _all_possible_ids(self):
-        """Return all the possible revisions that we could find."""
-        return self.get_inventory_weave().versions()
-
     def all_revision_ids(self):
         """Returns a list of all the revision ids in the repository. 
 
@@ -465,23 +460,17 @@
         reachable from a particular revision, and ignore any other revisions
         that might be present.  There is no direct replacement method.
         """
+        if 'evil' in debug.debug_flags:
+            mutter_callsite(2, "all_revision_ids is linear with history.")
         return self._all_revision_ids()
 
-    @needs_read_lock
     def _all_revision_ids(self):
         """Returns a list of all the revision ids in the repository. 
 
         These are in as much topological order as the underlying store can 
-        present: for weaves ghosts may lead to a lack of correctness until
-        the reweave updates the parents list.
+        present.
         """
-        if self._revision_store.text_store.listable():
-            return self._revision_store.all_revision_ids(self.get_transaction())
-        result = self._all_possible_ids()
-        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
-        #       ids. (It should, since _revision_store's API should change to
-        #       return utf8 revision_ids)
-        return self._eliminate_revisions_not_present(result)
+        raise NotImplementedError(self._all_revision_ids)
 
     def break_lock(self):
         """Break a lock if one is present from another instance.
@@ -832,6 +821,11 @@
                                                     self.get_transaction())
 
     @needs_read_lock
+    def get_revision(self, revision_id):
+        """Return the Revision object for a named revision."""
+        return self.get_revisions([revision_id])[0]
+
+    @needs_read_lock
     def get_revision_reconcile(self, revision_id):
         """'reconcile' helper routine that allows access to a revision always.
         
@@ -840,14 +834,20 @@
         be used by reconcile, or reconcile-alike commands that are correcting
         or testing the revision graph.
         """
-        if not revision_id or not isinstance(revision_id, basestring):
-            raise errors.InvalidRevisionId(revision_id=revision_id,
-                                           branch=self)
-        return self.get_revisions([revision_id])[0]
+        return self._get_revisions([revision_id])[0]
 
     @needs_read_lock
     def get_revisions(self, revision_ids):
+        """Get many revisions at once."""
+        return self._get_revisions(revision_ids)
+
+    @needs_read_lock
+    def _get_revisions(self, revision_ids):
+        """Core work logic to get many revisions without sanity checks."""
         revision_ids = [osutils.safe_revision_id(r) for r in revision_ids]
+        for rev_id in revision_ids:
+            if not rev_id or not isinstance(rev_id, basestring):
+                raise errors.InvalidRevisionId(revision_id=rev_id, branch=self)
         revs = self._revision_store.get_revisions(revision_ids,
                                                   self.get_transaction())
         for rev in revs:
@@ -870,23 +870,6 @@
         return rev_tmp.getvalue()
 
     @needs_read_lock
-    def get_revision(self, revision_id):
-        """Return the Revision object for a named revision"""
-        # TODO: jam 20070210 get_revision_reconcile should do this for us
-        revision_id = osutils.safe_revision_id(revision_id)
-        r = self.get_revision_reconcile(revision_id)
-        # weave corruption can lead to absent revision markers that should be
-        # present.
-        # the following test is reasonably cheap (it needs a single weave read)
-        # and the weave is cached in read transactions. In write transactions
-        # it is not cached but typically we only read a small number of
-        # revisions. For knits when they are introduced we will probably want
-        # to ensure that caching write transactions are in use.
-        inv = self.get_inventory_weave()
-        self._check_revision_parents(r, inv)
-        return r
-
-    @needs_read_lock
     def get_deltas_for_revisions(self, revisions):
         """Produce a generator of revision deltas.
         
@@ -917,22 +900,6 @@
         r = self.get_revision(revision_id)
         return list(self.get_deltas_for_revisions([r]))[0]
 
-    def _check_revision_parents(self, revision, inventory):
-        """Private to Repository and Fetch.
-        
-        This checks the parentage of revision in an inventory weave for 
-        consistency and is only applicable to inventory-weave-for-ancestry
-        using repository formats & fetchers.
-        """
-        weave_parents = inventory.get_parents(revision.revision_id)
-        weave_names = inventory.versions()
-        for parent_id in revision.parent_ids:
-            if parent_id in weave_names:
-                # this parent must not be a ghost.
-                if not parent_id in weave_parents:
-                    # but it is a ghost
-                    raise errors.CorruptRepository(self)
-
     @needs_write_lock
     def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
         revision_id = osutils.safe_revision_id(revision_id)
@@ -1147,43 +1114,6 @@
         return self.get_revision(revision_id).inventory_sha1
 
     @needs_read_lock
-    def get_revision_graph(self, revision_id=None):
-        """Return a dictionary containing the revision graph.
-        
-        :param revision_id: The revision_id to get a graph from. If None, then
-        the entire revision graph is returned. This is a deprecated mode of
-        operation and will be removed in the future.
-        :return: a dictionary of revision_id->revision_parents_list.
-        """
-        if 'evil' in debug.debug_flags:
-            mutter_callsite(2,
-                "get_revision_graph scales with size of history.")
-        # special case NULL_REVISION
-        if revision_id == _mod_revision.NULL_REVISION:
-            return {}
-        revision_id = osutils.safe_revision_id(revision_id)
-        a_weave = self.get_inventory_weave()
-        all_revisions = self._eliminate_revisions_not_present(
-                                a_weave.versions())
-        entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for 
-                             node in all_revisions])
-        if revision_id is None:
-            return entire_graph
-        elif revision_id not in entire_graph:
-            raise errors.NoSuchRevision(self, revision_id)
-        else:
-            # add what can be reached from revision_id
-            result = {}
-            pending = set([revision_id])
-            while len(pending) > 0:
-                node = pending.pop()
-                result[node] = entire_graph[node]
-                for revision_id in result[node]:
-                    if revision_id not in result:
-                        pending.add(revision_id)
-            return result
-
-    @needs_read_lock
     def get_revision_graph_with_ghosts(self, revision_ids=None):
         """Return a graph of the revisions with ghosts marked as applicable.
 
@@ -1987,7 +1917,11 @@
 
 
 class InterWeaveRepo(InterSameDataRepository):
-    """Optimised code paths between Weave based repositories."""
+    """Optimised code paths between Weave based repositories.
+    
+    This should be in bzrlib/repofmt/weaverepo.py but we have not yet
+    implemented lazy inter-object optimisation.
+    """
 
     @classmethod
     def _get_repo_format_to_test(self):
@@ -2150,13 +2084,13 @@
             assert source_ids[0] is None
             source_ids.pop(0)
         else:
-            source_ids = self.source._all_possible_ids()
+            source_ids = self.source.all_revision_ids()
         source_ids_set = set(source_ids)
         # source_ids is the worst possible case we may need to pull.
         # now we want to filter source_ids against what we actually
         # have in target, but don't try to check for existence where we know
         # we do not have a revision as that would be pointless.
-        target_ids = set(self.target._all_possible_ids())
+        target_ids = set(self.target.all_revision_ids())
         possibly_present_revisions = target_ids.intersection(source_ids_set)
         actually_present_revisions = set(self.target._eliminate_revisions_not_present(possibly_present_revisions))
         required_revisions = source_ids_set.difference(actually_present_revisions)



More information about the bazaar-commits mailing list