Rev 4518: Ensure that _KnitAnnotator also supports add_special_text. in http://bazaar.launchpad.net/~jameinel/bzr/1.17-rework-annotate

John Arbash Meinel john at arbash-meinel.com
Mon Jul 6 20:37:36 BST 2009


At http://bazaar.launchpad.net/~jameinel/bzr/1.17-rework-annotate

------------------------------------------------------------
revno: 4518
revision-id: john at arbash-meinel.com-20090706193707-ipgtqgtlkua2pxno
parent: john at arbash-meinel.com-20090706191619-lycpcdwo73j2g1cg
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 1.17-rework-annotate
timestamp: Mon 2009-07-06 14:37:07 -0500
message:
  Ensure that _KnitAnnotator also supports add_special_text.
  
  It already had some support for handling texts that were already present.
-------------- next part --------------
=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py	2009-07-06 16:48:02 +0000
+++ b/bzrlib/knit.py	2009-07-06 19:37:07 +0000
@@ -3376,12 +3376,10 @@
         """
         pending = set([key])
         records = []
-        generation = 0
-        kept_generation = 0
+        ann_keys = set()
         self._num_needed_children[key] = 1
         while pending:
             # get all pending nodes
-            generation += 1
             this_iteration = pending
             build_details = self._vf._index.get_build_details(this_iteration)
             self._all_build_details.update(build_details)
@@ -3394,8 +3392,8 @@
                 self._heads_provider = None
                 records.append((key, index_memo))
                 # Do we actually need to check _annotated_lines?
-                pending.update(p for p in parent_keys
-                                 if p not in self._all_build_details)
+                pending.update([p for p in parent_keys
+                                   if p not in self._all_build_details])
                 if parent_keys:
                     for parent_key in parent_keys:
                         if parent_key in self._num_needed_children:
@@ -3410,11 +3408,25 @@
 
             missing_versions = this_iteration.difference(build_details.keys())
             if missing_versions:
-                raise ValueError('i dont handle ghosts')
+                for key in missing_versions:
+                    if key in self._parent_map and key in self._text_cache:
+                        # We already have this text ready, we just need to
+                        # yield it later so we get it annotated
+                        ann_keys.add(key)
+                        parent_keys = self._parent_map[key]
+                        for parent_key in parent_keys:
+                            if parent_key in self._num_needed_children:
+                                self._num_needed_children[parent_key] += 1
+                            else:
+                                self._num_needed_children[parent_key] = 1
+                        pending.update([p for p in parent_keys
+                                           if p not in self._all_build_details])
+                    else:
+                        raise ValueError('i dont handle ghosts')
         # Generally we will want to read the records in reverse order, because
         # we find the parent nodes after the children
         records.reverse()
-        return records
+        return records, ann_keys
 
     def _get_needed_texts(self, key, pb=None):
         # if True or len(self._vf._fallback_vfs) > 0:
@@ -3425,12 +3437,16 @@
             return
         while True:
             try:
-                records = self._get_build_graph(key)
+                records, ann_keys = self._get_build_graph(key)
                 for idx, (sub_key, text, num_lines) in enumerate(
                                                 self._extract_texts(records)):
                     if pb is not None:
                         pb.update('annotating', idx, len(records))
                     yield sub_key, text, num_lines
+                for sub_key in ann_keys:
+                    text = self._text_cache[sub_key]
+                    num_lines = len(text) # bad assumption
+                    yield sub_key, text, num_lines
                 return
             except errors.RetryWithNewPacks, e:
                 self._vf._access.reload_or_raise(e)

=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py	2009-07-06 16:48:02 +0000
+++ b/bzrlib/tests/test_knit.py	2009-07-06 19:37:07 +0000
@@ -1456,6 +1456,33 @@
                            ['line1\n', 'line2\n'], ('fulltext', False))
         ann._num_compression_children['parent-id'] = 2
 
+    def test_annotate_special_text(self):
+        ann = self.make_annotator()
+        vf = ann._vf
+        rev1_key = ('rev-1',)
+        rev2_key = ('rev-2',)
+        rev3_key = ('rev-3',)
+        spec_key = ('special:',)
+        vf.add_lines(rev1_key, [], ['initial content\n'])
+        vf.add_lines(rev2_key, [rev1_key], ['initial content\n',
+                                            'common content\n',
+                                            'content in 2\n'])
+        vf.add_lines(rev3_key, [rev1_key], ['initial content\n',
+                                            'common content\n',
+                                            'content in 3\n'])
+        spec_text = ('initial content\n'
+                     'common content\n'
+                     'content in 2\n'
+                     'content in 3\n')
+        ann.add_special_text(spec_key, [rev2_key, rev3_key], spec_text)
+        anns, lines = ann.annotate(spec_key)
+        self.assertEqual([(rev1_key,),
+                          (rev2_key, rev3_key),
+                          (rev2_key,),
+                          (rev3_key,),
+                         ], anns)
+        self.assertEqualDiff(spec_text, ''.join(lines))
+
 
 class KnitTests(TestCaseWithTransport):
     """Class containing knit test helper routines."""



More information about the bazaar-commits mailing list