Rev 5863: (jelmer) Add Repository.get_file_graph(). (Jelmer Vernooij) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Sat May 14 23:42:33 UTC 2011


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5863 [merge]
revision-id: pqm at pqm.ubuntu.com-20110514234230-f8yy3myzrtp5sxt2
parent: pqm at pqm.ubuntu.com-20110514210206-ez4ltcg5k90tidxe
parent: jelmer at samba.org-20110514224910-v2biqhdh1wb1boii
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Sat 2011-05-14 23:42:30 +0000
message:
  (jelmer) Add Repository.get_file_graph(). (Jelmer Vernooij)
added:
  bzrlib/tests/per_repository/test_file_graph.py test_file_graph.py-20110510103858-p38v5z6ovcss1a8b-1
modified:
  bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/per_repository/__init__.py __init__.py-20060131092037-9564957a7d4a841b
  bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
  bzrlib/tests/per_repository/test_fetch.py test_fetch.py-20070814052151-5cxha9slx4c93uog-1
  bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
  bzrlib/tests/per_repository_vf/test_repository.py test_repository.py-20110224144010-ukgfmlxcgsibq4u4-3
  bzrlib/vf_repository.py        vf_repository.py-20110502151858-yh9nnoxpokg86unk-1
  doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
=== modified file 'bzrlib/log.py'
--- a/bzrlib/log.py	2011-04-08 03:31:54 +0000
+++ b/bzrlib/log.py	2011-05-14 22:49:10 +0000
@@ -1191,6 +1191,8 @@
     """
     # Lookup all possible text keys to determine which ones actually modified
     # the file.
+    graph = branch.repository.get_file_graph()
+    get_parent_map = graph.get_parent_map
     text_keys = [(file_id, rev_id) for rev_id, revno, depth in view_revisions]
     next_keys = None
     # Looking up keys in batches of 1000 can cut the time in half, as well as
@@ -1200,7 +1202,6 @@
     #       indexing layer. We might consider passing in hints as to the known
     #       access pattern (sparse/clustered, high success rate/low success
     #       rate). This particular access is clustered with a low success rate.
-    get_parent_map = branch.repository.texts.get_parent_map
     modified_text_revisions = set()
     chunk_size = 1000
     for start in xrange(0, len(text_keys), chunk_size):

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2011-05-09 12:01:12 +0000
+++ b/bzrlib/remote.py	2011-05-13 09:30:57 +0000
@@ -32,6 +32,7 @@
     static_tuple,
     symbol_versioning,
     urlutils,
+    versionedfile,
     vf_repository,
     )
 from bzrlib.branch import BranchReferenceFormat, BranchWriteLockResult
@@ -1136,6 +1137,10 @@
         return RemoteStreamSource(self, to_format)
 
     @needs_read_lock
+    def get_file_graph(self):
+        return graph.Graph(self.texts)
+
+    @needs_read_lock
     def has_revision(self, revision_id):
         """True if this repository has a copy of the revision."""
         # Copy of bzrlib.repository.Repository.has_revision

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2011-05-13 15:37:47 +0000
+++ b/bzrlib/repository.py	2011-05-14 21:16:04 +0000
@@ -1150,6 +1150,10 @@
         """
         raise NotImplementedError(self.get_known_graph_ancestry)
 
+    def get_file_graph(self):
+        """Return the graph walker for files."""
+        raise NotImplementedError(self.get_file_graph)
+
     def get_graph(self, other_repository=None):
         """Return the graph walker for this repository format"""
         parents_provider = self._make_parents_provider()

=== modified file 'bzrlib/tests/per_repository/__init__.py'
--- a/bzrlib/tests/per_repository/__init__.py	2011-05-13 10:07:00 +0000
+++ b/bzrlib/tests/per_repository/__init__.py	2011-05-14 21:16:04 +0000
@@ -115,6 +115,7 @@
         'test_commit_builder',
         'test_fetch',
         'test_fileid_involved',
+        'test_file_graph',
         'test_get_parent_map',
         'test_has_same_location',
         'test_has_revisions',

=== modified file 'bzrlib/tests/per_repository/test_commit_builder.py'
--- a/bzrlib/tests/per_repository/test_commit_builder.py	2011-05-13 08:36:56 +0000
+++ b/bzrlib/tests/per_repository/test_commit_builder.py	2011-05-14 21:16:04 +0000
@@ -995,7 +995,7 @@
         # (closest to a public per-file graph API we have today)
         tree.lock_read()
         self.addCleanup(tree.unlock)
-        g = dict(graph.Graph(tree.branch.repository.texts).iter_ancestry([tip]))
+        g = dict(tree.branch.repository.get_file_graph().iter_ancestry([tip]))
         self.assertEqual(expected_graph, g)
 
     def test_last_modified_revision_after_content_file_changes(self):

=== modified file 'bzrlib/tests/per_repository/test_fetch.py'
--- a/bzrlib/tests/per_repository/test_fetch.py	2011-05-02 22:44:40 +0000
+++ b/bzrlib/tests/per_repository/test_fetch.py	2011-05-13 12:51:16 +0000
@@ -137,8 +137,9 @@
         repo.lock_write()
         self.addCleanup(repo.unlock)
         repo.fetch(source.repository)
+        graph = repo.get_file_graph()
         self.assertEqual(result,
-            repo.texts.get_parent_map([(root_id, 'tip')])[(root_id, 'tip')])
+            graph.get_parent_map([(root_id, 'tip')])[(root_id, 'tip')])
 
     def test_fetch_to_rich_root_set_parent_no_parents(self):
         # No parents rev -> No parents

=== added file 'bzrlib/tests/per_repository/test_file_graph.py'
--- a/bzrlib/tests/per_repository/test_file_graph.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/per_repository/test_file_graph.py	2011-05-13 09:30:57 +0000
@@ -0,0 +1,37 @@
+# Copyright (C) 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+"""Tests for the per file graph API."""
+
+
+from bzrlib.tests.per_repository import TestCaseWithRepository
+
+
+class TestPerFileGraph(TestCaseWithRepository):
+
+    def test_file_graph(self):
+        tree = self.make_branch_and_tree('.')
+        self.build_tree_contents([("a", "contents")])
+        tree.add(["a"], ["fileid"])
+        revid1 = tree.commit("msg")
+        self.build_tree_contents([("a", "new contents")])
+        revid2 = tree.commit("msg")
+        self.addCleanup(tree.lock_read().unlock)
+        graph = tree.branch.repository.get_file_graph()
+        self.assertEquals({
+            ("fileid", revid2): (("fileid", revid1),), ("fileid", revid1):()},
+            graph.get_parent_map([("fileid", revid2), ("fileid", revid1)]))

=== modified file 'bzrlib/tests/per_repository/test_repository.py'
--- a/bzrlib/tests/per_repository/test_repository.py	2011-05-13 12:51:05 +0000
+++ b/bzrlib/tests/per_repository/test_repository.py	2011-05-14 21:16:04 +0000
@@ -33,8 +33,6 @@
     tests,
     transport,
     upgrade,
-    versionedfile,
-    vf_repository,
     workingtree,
     )
 from bzrlib.repofmt import (
@@ -104,62 +102,6 @@
         repo = self.make_repository('repo')
         self.assertSubset([repo._format.is_supported()], (True, False))
 
-    def test_attribute_text_store_basics(self):
-        """Test the basic behaviour of the text store."""
-        tree = self.make_branch_and_tree('tree')
-        repo = tree.branch.repository
-        file_id = "Foo:Bar"
-        file_key = (file_id,)
-        tree.lock_write()
-        try:
-            self.assertEqual(set(), set(repo.texts.keys()))
-            tree.add(['foo'], [file_id], ['file'])
-            tree.put_file_bytes_non_atomic(file_id, 'content\n')
-            try:
-                rev_key = (tree.commit("foo"),)
-            except errors.IllegalPath:
-                raise tests.TestNotApplicable(
-                    'file_id %r cannot be stored on this'
-                    ' platform for this repo format' % (file_id,))
-            if repo._format.rich_root_data:
-                root_commit = (tree.get_root_id(),) + rev_key
-                keys = set([root_commit])
-                parents = {root_commit:()}
-            else:
-                keys = set()
-                parents = {}
-            keys.add(file_key + rev_key)
-            parents[file_key + rev_key] = ()
-            self.assertEqual(keys, set(repo.texts.keys()))
-            self.assertEqual(parents,
-                repo.texts.get_parent_map(repo.texts.keys()))
-        finally:
-            tree.unlock()
-        tree2 = self.make_branch_and_tree('tree2')
-        tree2.pull(tree.branch)
-        tree2.put_file_bytes_non_atomic('Foo:Bar', 'right\n')
-        right_key = (tree2.commit('right'),)
-        keys.add(file_key + right_key)
-        parents[file_key + right_key] = (file_key + rev_key,)
-        tree.put_file_bytes_non_atomic('Foo:Bar', 'left\n')
-        left_key = (tree.commit('left'),)
-        keys.add(file_key + left_key)
-        parents[file_key + left_key] = (file_key + rev_key,)
-        tree.merge_from_branch(tree2.branch)
-        tree.put_file_bytes_non_atomic('Foo:Bar', 'merged\n')
-        try:
-            tree.auto_resolve()
-        except errors.UnsupportedOperation:
-            pass
-        merge_key = (tree.commit('merged'),)
-        keys.add(file_key + merge_key)
-        parents[file_key + merge_key] = (file_key + left_key,
-                                         file_key + right_key)
-        repo.lock_read()
-        self.addCleanup(repo.unlock)
-        self.assertEqual(keys, set(repo.texts.keys()))
-        self.assertEqual(parents, repo.texts.get_parent_map(repo.texts.keys()))
-
     def test_clone_to_default_format(self):
         #TODO: Test that cloning a repository preserves all the information
         # such as signatures[not tested yet] etc etc.

=== modified file 'bzrlib/tests/per_repository_vf/test_repository.py'
--- a/bzrlib/tests/per_repository_vf/test_repository.py	2011-05-06 17:56:25 +0000
+++ b/bzrlib/tests/per_repository_vf/test_repository.py	2011-05-13 09:35:35 +0000
@@ -258,6 +258,62 @@
 
         self.assertEqual(expected_item_keys, item_keys)
 
+    def test_attribute_text_store_basics(self):
+        """Test the basic behaviour of the text store."""
+        tree = self.make_branch_and_tree('tree')
+        repo = tree.branch.repository
+        file_id = "Foo:Bar"
+        file_key = (file_id,)
+        tree.lock_write()
+        try:
+            self.assertEqual(set(), set(repo.texts.keys()))
+            tree.add(['foo'], [file_id], ['file'])
+            tree.put_file_bytes_non_atomic(file_id, 'content\n')
+            try:
+                rev_key = (tree.commit("foo"),)
+            except errors.IllegalPath:
+                raise tests.TestNotApplicable(
+                    'file_id %r cannot be stored on this'
+                    ' platform for this repo format' % (file_id,))
+            if repo._format.rich_root_data:
+                root_commit = (tree.get_root_id(),) + rev_key
+                keys = set([root_commit])
+                parents = {root_commit:()}
+            else:
+                keys = set()
+                parents = {}
+            keys.add(file_key + rev_key)
+            parents[file_key + rev_key] = ()
+            self.assertEqual(keys, set(repo.texts.keys()))
+            self.assertEqual(parents,
+                repo.texts.get_parent_map(repo.texts.keys()))
+        finally:
+            tree.unlock()
+        tree2 = self.make_branch_and_tree('tree2')
+        tree2.pull(tree.branch)
+        tree2.put_file_bytes_non_atomic('Foo:Bar', 'right\n')
+        right_key = (tree2.commit('right'),)
+        keys.add(file_key + right_key)
+        parents[file_key + right_key] = (file_key + rev_key,)
+        tree.put_file_bytes_non_atomic('Foo:Bar', 'left\n')
+        left_key = (tree.commit('left'),)
+        keys.add(file_key + left_key)
+        parents[file_key + left_key] = (file_key + rev_key,)
+        tree.merge_from_branch(tree2.branch)
+        tree.put_file_bytes_non_atomic('Foo:Bar', 'merged\n')
+        try:
+            tree.auto_resolve()
+        except errors.UnsupportedOperation:
+            pass
+        merge_key = (tree.commit('merged'),)
+        keys.add(file_key + merge_key)
+        parents[file_key + merge_key] = (file_key + left_key,
+                                         file_key + right_key)
+        repo.lock_read()
+        self.addCleanup(repo.unlock)
+        self.assertEqual(keys, set(repo.texts.keys()))
+        self.assertEqual(parents, repo.texts.get_parent_map(repo.texts.keys()))
+
 
 class TestCaseWithComplexRepository(TestCaseWithRepository):
 

=== modified file 'bzrlib/vf_repository.py'
--- a/bzrlib/vf_repository.py	2011-05-14 21:02:06 +0000
+++ b/bzrlib/vf_repository.py	2011-05-14 23:42:30 +0000
@@ -1822,6 +1822,11 @@
         known_graph = self.revisions.get_known_graph_ancestry(revision_keys)
         return graph.GraphThunkIdsToKeys(known_graph)
 
+    @needs_read_lock
+    def get_file_graph(self):
+        """Return the graph walker for text revisions."""
+        return graph.Graph(self.texts)
+
     def _get_versioned_file_checker(self, text_key_references=None,
         ancestors=None):
         """Return an object suitable for checking versioned files.

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-05-13 14:02:14 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-05-14 21:16:04 +0000
@@ -87,6 +87,9 @@
   compatible optimisers rather than an instance of the class it is called
   on. (Jelmer Vernooij)
 
+* New method ``Repository.get_file_graph`` which can return the
+  per-file revision graph. (Jelmer Vernooij, #775578)
+
 * The default implementation of ``Branch`` is now oriented to
   storing the branch tip. Branch implementations which store the full
   history should now subclass ``FullHistoryBzrBranch``.




More information about the bazaar-commits mailing list