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