~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-10-22 21:25:20 UTC
  • mfrom: (2921.2.2 knits)
  • Revision ID: pqm@pqm.ubuntu.com-20071022212520-al7xlieh3d7ng370
(robertc) Reduce list copying during text construction decreasing the time to extract single texts with many deltas. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
138
138
        """Return a list of (origin, text) tuples."""
139
139
        return list(self.annotate_iter())
140
140
 
 
141
    def apply_delta(self, delta, new_version_id):
 
142
        """Apply delta to this object to become new_version_id."""
 
143
        raise NotImplementedError(self.apply_delta)
 
144
 
141
145
    def line_delta_iter(self, new_lines):
142
146
        """Generate line-based delta from this content to new_lines."""
143
147
        new_texts = new_lines.text()
189
193
        """Yield tuples of (origin, text) for each content line."""
190
194
        return iter(self._lines)
191
195
 
 
196
    def apply_delta(self, delta, new_version_id):
 
197
        """Apply delta to this object to become new_version_id."""
 
198
        offset = 0
 
199
        lines = self._lines
 
200
        for start, end, count, delta_lines in delta:
 
201
            lines[offset+start:offset+end] = delta_lines
 
202
            offset = offset + (start - end) + count
 
203
 
192
204
    def strip_last_line_newline(self):
193
205
        line = self._lines[-1][1].rstrip('\n')
194
206
        self._lines[-1] = (self._lines[-1][0], line)
225
237
        for line in self._lines:
226
238
            yield self._version_id, line
227
239
 
 
240
    def apply_delta(self, delta, new_version_id):
 
241
        """Apply delta to this object to become new_version_id."""
 
242
        offset = 0
 
243
        lines = self._lines
 
244
        for start, end, count, delta_lines in delta:
 
245
            lines[offset+start:offset+end] = delta_lines
 
246
            offset = offset + (start - end) + count
 
247
        self._version_id = new_version_id
 
248
 
228
249
    def copy(self):
229
250
        return PlainKnitContent(self._lines[:], self._version_id)
230
251
 
1004
1025
        the requested versions and content_map contains the KnitContents.
1005
1026
        Both dicts take version_ids as their keys.
1006
1027
        """
 
1028
        # FUTURE: This function could be improved for the 'extract many' case
 
1029
        # by tracking each component and only doing the copy when the number of
 
1030
        # children than need to apply delta's to it is > 1 or it is part of the
 
1031
        # final output.
 
1032
        version_ids = list(version_ids)
 
1033
        multiple_versions = len(version_ids) != 1
1007
1034
        record_map = self._get_record_map(version_ids)
1008
1035
 
1009
1036
        text_map = {}
1029
1056
                        content = self.factory.parse_fulltext(data, version_id)
1030
1057
                    elif method == 'line-delta':
1031
1058
                        delta = self.factory.parse_line_delta(data, version_id)
1032
 
                        content = content.copy()
1033
 
                        content._lines = self._apply_delta(content._lines,
1034
 
                                                           delta)
1035
 
                    content_map[component_id] = content
 
1059
                        if multiple_versions:
 
1060
                            # only doing this when we want multiple versions
 
1061
                            # output avoids list copies - which reference and
 
1062
                            # dereference many strings.
 
1063
                            content = content.copy()
 
1064
                        content.apply_delta(delta, version_id)
 
1065
                    if multiple_versions:
 
1066
                        content_map[component_id] = content
1036
1067
 
1037
1068
            if 'no-eol' in self._index.get_options(version_id):
1038
 
                content = content.copy()
 
1069
                if multiple_versions:
 
1070
                    content = content.copy()
1039
1071
                content.strip_last_line_newline()
1040
1072
            final_content[version_id] = content
1041
1073
 
1052
1084
            text_map[version_id] = text
1053
1085
        return text_map, final_content
1054
1086
 
1055
 
    @staticmethod
1056
 
    def _apply_delta(lines, delta):
1057
 
        """Apply delta to lines."""
1058
 
        lines = list(lines)
1059
 
        offset = 0
1060
 
        for start, end, count, delta_lines in delta:
1061
 
            lines[offset+start:offset+end] = delta_lines
1062
 
            offset = offset + (start - end) + count
1063
 
        return lines
1064
 
 
1065
1087
    def iter_lines_added_or_present_in_versions(self, version_ids=None, 
1066
1088
                                                pb=None):
1067
1089
        """See VersionedFile.iter_lines_added_or_present_in_versions()."""