Rev 2777: Support annotating knits with no annotation cache in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Mon Sep 3 00:36:09 BST 2007
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 2777
revision-id: pqm at pqm.ubuntu.com-20070902233606-wb062d366w5c83uc
parent: pqm at pqm.ubuntu.com-20070901160444-hcr66zejwyy0jezc
parent: aaron.bentley at utoronto.ca-20070902223854-vh6jc4c19w94htsm
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2007-09-03 00:36:06 +0100
message:
Support annotating knits with no annotation cache
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/annotate.py annotate.py-20050922133147-7c60541d2614f022
bzrlib/knit.py knit.py-20051212171256-f056ac8f0fbe1bd9
bzrlib/tests/test_annotate.py test_annotate.py-20061213215015-sttc9agsxomls7q0-1
bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
------------------------------------------------------------
revno: 2770.1.10
merged: aaron.bentley at utoronto.ca-20070902223854-vh6jc4c19w94htsm
parent: aaron.bentley at utoronto.ca-20070902223333-e0g232qwy63mj4qm
parent: pqm at pqm.ubuntu.com-20070901160444-hcr66zejwyy0jezc
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: pack-annotate
timestamp: Sun 2007-09-02 18:38:54 -0400
message:
Merge bzr.dev
------------------------------------------------------------
revno: 2770.1.9
merged: aaron.bentley at utoronto.ca-20070902223333-e0g232qwy63mj4qm
parent: aaron.bentley at utoronto.ca-20070902222950-s810wxdatgaap7by
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: pack-annotate
timestamp: Sun 2007-09-02 18:33:33 -0400
message:
Simplify annotate iterator
------------------------------------------------------------
revno: 2770.1.8
merged: aaron.bentley at utoronto.ca-20070902222950-s810wxdatgaap7by
parent: abentley at panoramicfeedback.com-20070831200932-cce1tz9ft6bdfjw5
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: pack-annotate
timestamp: Sun 2007-09-02 18:29:50 -0400
message:
Use topo-sorted ancestry for generating annotations
------------------------------------------------------------
revno: 2770.1.7
merged: abentley at panoramicfeedback.com-20070831200932-cce1tz9ft6bdfjw5
parent: abentley at panoramicfeedback.com-20070831194044-1328krhsdc795cbc
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: pack-annotate
timestamp: Fri 2007-08-31 16:09:32 -0400
message:
Update NEWS
------------------------------------------------------------
revno: 2770.1.6
merged: abentley at panoramicfeedback.com-20070831194044-1328krhsdc795cbc
parent: abentley at panoramicfeedback.com-20070831193852-6ip22sbw058yib5u
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: pack-annotate
timestamp: Fri 2007-08-31 15:40:44 -0400
message:
Remove annotate override for normal knits
------------------------------------------------------------
revno: 2770.1.5
merged: abentley at panoramicfeedback.com-20070831193852-6ip22sbw058yib5u
parent: aaron.bentley at utoronto.ca-20070831121426-rh5lo64rygkpy3xs
committer: Aaron Bentley <abentley at panoramicfeedback.com>
branch nick: pack-annotate
timestamp: Fri 2007-08-31 15:38:52 -0400
message:
Clean up docs, test matching blocks for reannotate
------------------------------------------------------------
revno: 2770.1.4
merged: aaron.bentley at utoronto.ca-20070831121426-rh5lo64rygkpy3xs
parent: aaron.bentley at utoronto.ca-20070831035850-9ap3s1a6m0qc03zg
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: pack-annotate
timestamp: Fri 2007-08-31 08:14:26 -0400
message:
Further optimize annotation, using existing matching blocks
------------------------------------------------------------
revno: 2770.1.3
merged: aaron.bentley at utoronto.ca-20070831035850-9ap3s1a6m0qc03zg
parent: aaron.bentley at utoronto.ca-20070831031243-c87mp74f7xvdymi1
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: pack-annotate
timestamp: Thu 2007-08-30 23:58:50 -0400
message:
Rework knit annotation as stack-based
------------------------------------------------------------
revno: 2770.1.2
merged: aaron.bentley at utoronto.ca-20070831031243-c87mp74f7xvdymi1
parent: aaron.bentley at utoronto.ca-20070831025954-bs1ngof5pa3kejrs
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: pack-annotate
timestamp: Thu 2007-08-30 23:12:43 -0400
message:
Convert to knit-only annotation
------------------------------------------------------------
revno: 2770.1.1
merged: aaron.bentley at utoronto.ca-20070831025954-bs1ngof5pa3kejrs
parent: pqm at pqm.ubuntu.com-20070830171447-t9j1u709q4yw63lh
committer: Aaron Bentley <aaron.bentley at utoronto.ca>
branch nick: pack-annotate
timestamp: Thu 2007-08-30 22:59:54 -0400
message:
Initial implmentation of plain knit annotation
=== modified file 'NEWS'
--- a/NEWS 2007-09-01 16:04:44 +0000
+++ b/NEWS 2007-09-02 22:38:54 +0000
@@ -171,6 +171,9 @@
efficiently streaming the knit data for a set of versions over the smart
protocol.
+ * Knits with no annotation cache still produce correct annotations.
+ (Aaron Bentley)
+
TESTING:
* Use UTF-8 encoded StringIO for log tests to avoid failures on
=== modified file 'bzrlib/annotate.py'
--- a/bzrlib/annotate.py 2007-08-16 18:50:22 +0000
+++ b/bzrlib/annotate.py 2007-08-31 19:38:52 +0000
@@ -137,20 +137,29 @@
yield (revno_str, author, date_str, origin, text)
-def reannotate(parents_lines, new_lines, new_revision_id):
+def reannotate(parents_lines, new_lines, new_revision_id,
+ _left_matching_blocks=None):
"""Create a new annotated version from new lines and parent annotations.
:param parents_lines: List of annotated lines for all parents
:param new_lines: The un-annotated new lines
:param new_revision_id: The revision-id to associate with new lines
(will often be CURRENT_REVISION)
+ :param left_matching_blocks: a hint about which areas are common
+ between the text and its left-hand-parent. The format is
+ the SequenceMatcher.get_matching_blocks format.
"""
- if len(parents_lines) == 1:
- for data in _reannotate(parents_lines[0], new_lines, new_revision_id):
+ if len(parents_lines) == 0:
+ for line in new_lines:
+ yield new_revision_id, line
+ elif len(parents_lines) == 1:
+ for data in _reannotate(parents_lines[0], new_lines, new_revision_id,
+ _left_matching_blocks):
yield data
else:
- reannotations = [list(_reannotate(p, new_lines, new_revision_id)) for
- p in parents_lines]
+ block_list = [_left_matching_blocks] + [None] * len(parents_lines)
+ reannotations = [list(_reannotate(p, new_lines, new_revision_id, b))
+ for p, b in zip(parents_lines, block_list)]
for annos in zip(*reannotations):
origins = set(a for a, l in annos)
line = annos[0][1]
@@ -162,12 +171,15 @@
yield new_revision_id, line
-def _reannotate(parent_lines, new_lines, new_revision_id):
+def _reannotate(parent_lines, new_lines, new_revision_id,
+ matching_blocks=None):
plain_parent_lines = [l for r, l in parent_lines]
matcher = patiencediff.PatienceSequenceMatcher(None, plain_parent_lines,
new_lines)
new_cur = 0
- for i, j, n in matcher.get_matching_blocks():
+ if matching_blocks is None:
+ matching_blocks = matcher.get_matching_blocks()
+ for i, j, n in matching_blocks:
for line in new_lines[new_cur:j]:
yield new_revision_id, line
for data in parent_lines[i:i+n]:
=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py 2007-08-31 02:05:10 +0000
+++ b/bzrlib/knit.py 2007-09-02 22:38:54 +0000
@@ -74,6 +74,7 @@
from bzrlib.lazy_import import lazy_import
lazy_import(globals(), """
from bzrlib import (
+ annotate,
pack,
trace,
)
@@ -290,6 +291,10 @@
for origin, text in lines)
return out
+ def annotate_iter(self, knit, version_id):
+ content = knit._get_content(version_id)
+ return content.annotate_iter()
+
class KnitPlainFactory(_KnitFactory):
"""Factory for creating plain Content objects."""
@@ -345,6 +350,9 @@
out.extend([text for origin, text in lines])
return out
+ def annotate_iter(self, knit, version_id):
+ return annotate_knit(knit, version_id)
+
def make_empty_knit(transport, relpath):
"""Construct a empty knit at the specified location."""
@@ -1107,9 +1115,7 @@
def annotate_iter(self, version_id):
"""See VersionedFile.annotate_iter."""
version_id = osutils.safe_revision_id(version_id)
- content = self._get_content(version_id)
- for origin, text in content.annotate_iter():
- yield origin, text
+ return self.factory.annotate_iter(self, version_id)
def get_parents(self, version_id):
"""See VersionedFile.get_parents."""
@@ -2522,6 +2528,33 @@
return besti, bestj, bestsize
+def annotate_knit(knit, revision_id):
+ """Annotate a knit with no cached annotations.
+
+ This implementation is for knits with no cached annotations.
+ It will work for knits with cached annotations, but this is not
+ recommended.
+ """
+ ancestry = knit.get_ancestry(revision_id)
+ fulltext = dict(zip(ancestry, knit.get_line_list(ancestry)))
+ annotations = {}
+ for candidate in ancestry:
+ if candidate in annotations:
+ continue
+ parents = knit.get_parents(candidate)
+ if len(parents) == 0:
+ blocks = None
+ elif knit._index.get_method(candidate) != 'line-delta':
+ blocks = None
+ else:
+ parent, sha1, noeol, delta = knit.get_delta(candidate)
+ blocks = KnitContent.get_line_delta_blocks(delta,
+ fulltext[parents[0]], fulltext[candidate])
+ annotations[candidate] = list(annotate.reannotate([annotations[p]
+ for p in parents], fulltext[candidate], candidate, blocks))
+ return iter(annotations[revision_id])
+
+
try:
from bzrlib._knit_load_data_c import _load_data_c as _load_data
except ImportError:
=== modified file 'bzrlib/tests/test_annotate.py'
--- a/bzrlib/tests/test_annotate.py 2007-08-15 14:11:32 +0000
+++ b/bzrlib/tests/test_annotate.py 2007-08-31 19:38:52 +0000
@@ -87,6 +87,14 @@
e
""".splitlines(True)
+expected_1 = annotation("""\
+blahblah a
+blahblah b
+blahblah c
+blahblah d
+blahblah e
+""")
+
new_2 = """\
a
@@ -365,9 +373,10 @@
class TestReannotate(tests.TestCase):
- def annotateEqual(self, expected, parents, newlines, revision_id):
+ def annotateEqual(self, expected, parents, newlines, revision_id,
+ blocks=None):
annotate_list = list(annotate.reannotate(parents, newlines,
- revision_id))
+ revision_id, blocks))
self.assertEqual(len(expected), len(annotate_list))
for e, a in zip(expected, annotate_list):
self.assertEqual(e, a)
@@ -377,3 +386,21 @@
self.annotateEqual(expected_2_1, [parent_2], new_1, 'blahblah')
self.annotateEqual(expected_1_2_2, [parent_1, parent_2], new_2,
'blahblah')
+
+ def test_reannotate_no_parents(self):
+ self.annotateEqual(expected_1, [], new_1, 'blahblah')
+
+ def test_reannotate_left_matching_blocks(self):
+ """Ensure that left_matching_blocks has an impact.
+
+ In this case, the annotation is ambiguous, so the hint isn't actually
+ lying.
+ """
+ parent = [('rev1', 'a\n')]
+ new_text = ['a\n', 'a\n']
+ blocks = [(0, 0, 1), (1, 2, 0)]
+ self.annotateEqual([('rev1', 'a\n'), ('rev2', 'a\n')], [parent],
+ new_text, 'rev2', blocks)
+ blocks = [(0, 1, 1), (1, 2, 0)]
+ self.annotateEqual([('rev2', 'a\n'), ('rev1', 'a\n')], [parent],
+ new_text, 'rev2', blocks)
=== modified file 'bzrlib/tests/test_versionedfile.py'
--- a/bzrlib/tests/test_versionedfile.py 2007-08-30 08:11:54 +0000
+++ b/bzrlib/tests/test_versionedfile.py 2007-09-02 22:38:54 +0000
@@ -34,8 +34,11 @@
RevisionAlreadyPresent,
WeaveParentMismatch
)
-from bzrlib.knit import KnitVersionedFile, \
- KnitAnnotateFactory, KnitPlainFactory
+from bzrlib.knit import (
+ KnitVersionedFile,
+ KnitAnnotateFactory,
+ KnitPlainFactory,
+ )
from bzrlib.tests import TestCaseWithMemoryTransport, TestSkipped
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
from bzrlib.trace import mutter
@@ -881,8 +884,8 @@
class TestKnit(TestCaseWithMemoryTransport, VersionedFileTestMixIn):
def get_file(self, name='foo'):
- return KnitVersionedFile(name, get_transport(self.get_url('.')),
- delta=True, create=True)
+ return self.get_factory()(name, get_transport(self.get_url('.')),
+ delta=True, create=True)
def get_factory(self):
return KnitVersionedFile
@@ -894,7 +897,7 @@
return knit
def reopen_file(self, name='foo', create=False):
- return KnitVersionedFile(name, get_transport(self.get_url('.')),
+ return self.get_factory()(name, get_transport(self.get_url('.')),
delta=True,
create=create)
@@ -909,6 +912,19 @@
get_transport(self.get_url('.')))
+class TestPlaintextKnit(TestKnit):
+ """Test a knit with no cached annotations"""
+
+ def _factory(self, name, transport, file_mode=None, access_mode=None,
+ delta=True, create=False):
+ return KnitVersionedFile(name, transport, file_mode, access_mode,
+ KnitPlainFactory(), delta=delta,
+ create=create)
+
+ def get_factory(self):
+ return self._factory
+
+
class InterString(versionedfile.InterVersionedFile):
"""An inter-versionedfile optimised code path for strings.
More information about the bazaar-commits
mailing list