~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to equivalence_table.py

  • Committer: Jelmer Vernooij
  • Date: 2012-01-18 10:42:07 UTC
  • mfrom: (6437.3.6 2.5)
  • mto: (6437.3.7 2.5)
  • mto: This revision was merged to the branch mainline in revision 6441.
  • Revision ID: jelmer@vernstok.nl-20120118104207-yc5fhsaz4mupjcam
Merge 2.5 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008 Canonical Limited.
2
 
#
3
 
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License version 2 as published
5
 
# by the Free Software Foundation.
6
 
#
7
 
# This program is distributed in the hope that it will be useful,
8
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
# GNU General Public License for more details.
11
 
#
12
 
# You should have received a copy of the GNU General Public License
13
 
# along with this program; if not, write to the Free Software
14
 
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
15
 
#
16
 
 
17
 
"""Functions for dealing with a persistent equivalency table."""
18
 
 
19
 
 
20
 
SENTINEL = -1
21
 
 
22
 
 
23
 
class EquivalenceTable(object):
24
 
    """This class tracks equivalencies between lists of hashable objects.
25
 
 
26
 
    :ivar lines: The 'static' lines that will be preserved between runs.
27
 
    :ival _matching_lines: A dict of {line:[matching offsets]}
28
 
    """
29
 
 
30
 
    def __init__(self, lines):
31
 
        self.lines = lines
32
 
        self._right_lines = None
33
 
        # For each line in 'left' give the offset to the other lines which
34
 
        # match it.
35
 
        self._generate_matching_lines()
36
 
 
37
 
    def _generate_matching_lines(self):
38
 
        matches = {}
39
 
        for idx, line in enumerate(self.lines):
40
 
            matches.setdefault(line, []).append(idx)
41
 
        self._matching_lines = matches
42
 
 
43
 
    def _update_matching_lines(self, new_lines, index):
44
 
        matches = self._matching_lines
45
 
        start_idx = len(self.lines)
46
 
        for idx, do_index in enumerate(index):
47
 
            if not do_index:
48
 
                continue
49
 
            matches.setdefault(new_lines[idx], []).append(start_idx + idx)
50
 
 
51
 
    def get_matches(self, line):
52
 
        """Return the lines which match the line in right."""
53
 
        try:
54
 
            return self._matching_lines[line]
55
 
        except KeyError:
56
 
            return None
57
 
 
58
 
    def _get_matching_lines(self):
59
 
        """Return a dictionary showing matching lines."""
60
 
        matching = {}
61
 
        for line in self.lines:
62
 
            matching[line] = self.get_matches(line)
63
 
        return matching
64
 
 
65
 
    def get_idx_matches(self, right_idx):
66
 
        """Return the left lines matching the right line at the given offset."""
67
 
        line = self._right_lines[right_idx]
68
 
        try:
69
 
            return self._matching_lines[line]
70
 
        except KeyError:
71
 
            return None
72
 
 
73
 
    def extend_lines(self, lines, index):
74
 
        """Add more lines to the left-lines list.
75
 
 
76
 
        :param lines: A list of lines to add
77
 
        :param index: A True/False for each node to define if it should be
78
 
            indexed.
79
 
        """
80
 
        self._update_matching_lines(lines, index)
81
 
        self.lines.extend(lines)
82
 
 
83
 
    def set_right_lines(self, lines):
84
 
        """Set the lines we will be matching against."""
85
 
        self._right_lines = lines