35
36
"""Create a new Annotator from a VersionedFile."""
37
38
self._parent_map = {}
38
self._parent_lines_cache = {}
39
self._parent_annotations_cache = {}
39
self._lines_cache = {}
40
self._annotations_cache = {}
40
41
self._heads_provider = None
42
43
def _get_needed_texts(self, key):
52
53
self._heads_provider = _mod_graph.KnownGraph(self._parent_map)
53
54
return self._heads_provider
56
def _reannotate_one_parent(self, annotations, lines, key, parent_key):
57
"""Reannotate this text relative to its first parent."""
58
parent_lines = self._lines_cache[parent_key]
59
parent_annotations = self._annotations_cache[parent_key]
60
# PatienceSequenceMatcher should probably be part of Policy
61
matcher = patiencediff.PatienceSequenceMatcher(None,
63
matching_blocks = matcher.get_matching_blocks()
65
for parent_idx, lines_idx, match_len in matching_blocks:
66
# For all matching regions we copy across the parent annotations
67
annotations[lines_idx:lines_idx + match_len] = \
68
parent_annotations[parent_idx:parent_idx + match_len]
55
70
def annotate(self, key):
56
71
"""Return annotated fulltext for the given key."""
57
72
keys = self._get_needed_texts(key)
58
reannotate = annotate.reannotate
59
73
heads_provider = self._get_heads_provider
60
74
for record in self._vf.get_record_stream(keys, 'topological', True):
62
76
lines = osutils.chunks_to_lines(record.get_bytes_as('chunked'))
63
parents = self._parent_map[key]
64
if parents is not None:
65
parent_lines = [self._parent_lines_cache[parent]
66
for parent in parents]
69
self._parent_lines_cache[key] = list(reannotate(
70
parent_lines, lines, key, None, heads_provider))
77
annotations = [(this_key,)]*len(lines)
78
self._lines_cache[this_key] = lines
79
self._annotations_cache[this_key] = annotations
81
parents = self._parent_map[this_key]
84
self._reannotate_one_parent(annotations, lines, key, parents[0])
72
annotated = self._parent_lines_cache[key]
86
annotations = self._annotations_cache[key]
74
88
raise errors.RevisionNotPresent(key, self._vf)
75
annotations = [(a,) for a,l in annotated]
76
lines = [l for a,l in annotated]
77
return annotations, lines
89
return annotations, self._lines_cache[key]