53
53
self._heads_provider = _mod_graph.KnownGraph(self._parent_map)
54
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."""
56
def _get_parent_annotations_and_matches(self, lines, parent_key):
58
57
parent_lines = self._lines_cache[parent_key]
59
58
parent_annotations = self._annotations_cache[parent_key]
60
59
# PatienceSequenceMatcher should probably be part of Policy
61
60
matcher = patiencediff.PatienceSequenceMatcher(None,
62
61
parent_lines, lines)
63
62
matching_blocks = matcher.get_matching_blocks()
63
return parent_annotations, matching_blocks
65
def _reannotate_one_parent(self, annotations, lines, key, parent_key):
66
"""Reannotate this text relative to its first parent."""
67
parent_annotations, matching_blocks = self._get_parent_annotations_and_matches(
65
70
for parent_idx, lines_idx, match_len in matching_blocks:
66
71
# For all matching regions we copy across the parent annotations
67
72
annotations[lines_idx:lines_idx + match_len] = \
68
73
parent_annotations[parent_idx:parent_idx + match_len]
75
def _reannotate_other_parents(self, annotations, lines, key, parent_key):
76
"""Reannotate this text relative to a second (or more) parent."""
77
parent_annotations, matching_blocks = self._get_parent_annotations_and_matches(
80
simple_key_ann = (key,)
81
for parent_idx, lines_idx, match_len in matching_blocks:
82
# For lines which match this parent, we will now resolve whether
83
# this parent wins over the current annotation
84
for idx in xrange(match_len):
85
ann_idx = lines_idx + idx
86
ann = annotations[ann_idx]
87
par_ann = parent_annotations[parent_idx + idx]
91
if ann == simple_key_ann:
92
# Originally claimed 'this', but it was really in this
94
annotations[ann_idx] = par_ann
96
# Now we have a conflict, both sides claim to have introduced
99
assert key not in new_ann
100
# new_ann.discard(key)
101
new_ann.update(par_ann)
102
new_ann = tuple(sorted(new_ann))
103
annotations[ann_idx] = new_ann
70
105
def annotate(self, key):
71
106
"""Return annotated fulltext for the given key."""
72
107
keys = self._get_needed_texts(key)
84
119
self._reannotate_one_parent(annotations, lines, key, parents[0])
120
for parent in parents[1:]:
121
self._reannotate_other_parents(annotations, lines, key, parent)
86
123
annotations = self._annotations_cache[key]