/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
89
89
     sha_strings
90
90
from bzrlib.symbol_versioning import DEPRECATED_PARAMETER, deprecated_passed
91
91
from bzrlib.tsort import topo_sort
 
92
import bzrlib.ui
92
93
import bzrlib.weave
93
94
from bzrlib.versionedfile import VersionedFile, InterVersionedFile
94
95
 
118
119
 
119
120
    def annotate_iter(self):
120
121
        """Yield tuples of (origin, text) for each content line."""
121
 
        for origin, text in self._lines:
122
 
            yield origin, text
 
122
        return iter(self._lines)
123
123
 
124
124
    def annotate(self):
125
125
        """Return a list of (origin, text) tuples."""
127
127
 
128
128
    def line_delta_iter(self, new_lines):
129
129
        """Generate line-based delta from this content to new_lines."""
130
 
        new_texts = [text for origin, text in new_lines._lines]
131
 
        old_texts = [text for origin, text in self._lines]
 
130
        new_texts = new_lines.text()
 
131
        old_texts = self.text()
132
132
        s = KnitSequenceMatcher(None, old_texts, new_texts)
133
 
        for op in s.get_opcodes():
134
 
            if op[0] == 'equal':
 
133
        for tag, i1, i2, j1, j2 in s.get_opcodes():
 
134
            if tag == 'equal':
135
135
                continue
136
 
            #     ofrom   oto   length        data
137
 
            yield (op[1], op[2], op[4]-op[3], new_lines._lines[op[3]:op[4]])
 
136
            # ofrom, oto, length, data
 
137
            yield i1, i2, j2 - j1, new_lines._lines[j1:j2]
138
138
 
139
139
    def line_delta(self, new_lines):
140
140
        return list(self.line_delta_iter(new_lines))
175
175
        return KnitContent(lines)
176
176
 
177
177
    def parse_line_delta_iter(self, lines):
178
 
        for result_item in self.parse_line_delta[lines]:
179
 
            yield result_item
 
178
        return iter(self.parse_line_delta(lines))
180
179
 
181
180
    def parse_line_delta(self, lines, version):
182
181
        """Convert a line based delta into internal representation.
204
203
            result.append((start, end, count, contents))
205
204
        return result
206
205
 
 
206
    def get_fulltext_content(self, lines):
 
207
        """Extract just the content lines from a fulltext."""
 
208
        return (line.split(' ', 1)[1] for line in lines)
 
209
 
 
210
    def get_linedelta_content(self, lines):
 
211
        """Extract just the content from a line delta.
 
212
 
 
213
        This doesn't return all of the extra information stored in a delta.
 
214
        Only the actual content lines.
 
215
        """
 
216
        lines = iter(lines)
 
217
        next = lines.next
 
218
        for header in lines:
 
219
            header = header.split(',')
 
220
            count = int(header[2])
 
221
            for i in xrange(count):
 
222
                origin, text = next().split(' ', 1)
 
223
                yield text
 
224
 
207
225
    def lower_fulltext(self, content):
208
226
        """convert a fulltext content record into a serializable form.
209
227
 
240
258
        return self.make(content, version)
241
259
 
242
260
    def parse_line_delta_iter(self, lines, version):
243
 
        while lines:
244
 
            header = lines.pop(0)
 
261
        cur = 0
 
262
        num_lines = len(lines)
 
263
        while cur < num_lines:
 
264
            header = lines[cur]
 
265
            cur += 1
245
266
            start, end, c = [int(n) for n in header.split(',')]
246
 
            yield start, end, c, zip([version] * c, lines[:c])
247
 
            del lines[:c]
 
267
            yield start, end, c, zip([version] * c, lines[cur:cur+c])
 
268
            cur += c
248
269
 
249
270
    def parse_line_delta(self, lines, version):
250
271
        return list(self.parse_line_delta_iter(lines, version))
251
 
    
 
272
 
 
273
    def get_fulltext_content(self, lines):
 
274
        """Extract just the content lines from a fulltext."""
 
275
        return iter(lines)
 
276
 
 
277
    def get_linedelta_content(self, lines):
 
278
        """Extract just the content from a line delta.
 
279
 
 
280
        This doesn't return all of the extra information stored in a delta.
 
281
        Only the actual content lines.
 
282
        """
 
283
        lines = iter(lines)
 
284
        next = lines.next
 
285
        for header in lines:
 
286
            header = header.split(',')
 
287
            count = int(header[2])
 
288
            for i in xrange(count):
 
289
                yield next()
 
290
 
252
291
    def lower_fulltext(self, content):
253
292
        return content.text()
254
293
 
794
833
                        assert content is None
795
834
                        content = self.factory.parse_fulltext(data, version_idx)
796
835
                    elif method == 'line-delta':
797
 
                        delta = self.factory.parse_line_delta(data[:], 
798
 
                                                              version_idx)
 
836
                        delta = self.factory.parse_line_delta(data, version_idx)
799
837
                        content = content.copy()
800
838
                        content._lines = self._apply_delta(content._lines, 
801
839
                                                           delta)
827
865
        # but we need to setup a list of records to visit.
828
866
        # we need version_id, position, length
829
867
        version_id_records = []
830
 
        requested_versions = list(version_ids)
 
868
        requested_versions = set(version_ids)
831
869
        # filter for available versions
832
870
        for version_id in requested_versions:
833
871
            if not self.has_version(version_id):
834
872
                raise RevisionNotPresent(version_id, self.filename)
835
873
        # get a in-component-order queue:
836
 
        version_ids = []
837
874
        for version_id in self.versions():
838
875
            if version_id in requested_versions:
839
 
                version_ids.append(version_id)
840
876
                data_pos, length = self._index.get_position(version_id)
841
877
                version_id_records.append((version_id, data_pos, length))
842
878
 
846
882
            pb.update('Walking content.', version_idx, total)
847
883
            method = self._index.get_method(version_id)
848
884
            version_idx = self._index.lookup(version_id)
 
885
 
849
886
            assert method in ('fulltext', 'line-delta')
850
887
            if method == 'fulltext':
851
 
                content = self.factory.parse_fulltext(data, version_idx)
852
 
                for line in content.text():
853
 
                    yield line
 
888
                line_iterator = self.factory.get_fulltext_content(data)
854
889
            else:
855
 
                delta = self.factory.parse_line_delta(data, version_idx)
856
 
                for start, end, count, lines in delta:
857
 
                    for origin, line in lines:
858
 
                        yield line
 
890
                line_iterator = self.factory.get_linedelta_content(data)
 
891
            for line in line_iterator:
 
892
                yield line
 
893
 
859
894
        pb.update('Walking content.', total, total)
860
895
        
861
896
    def num_versions(self):
981
1016
 
982
1017
    def check_header(self, fp):
983
1018
        line = fp.readline()
 
1019
        if line == '':
 
1020
            # An empty file can actually be treated as though the file doesn't
 
1021
            # exist yet.
 
1022
            raise errors.NoSuchFile(self._transport.base + self._filename)
984
1023
        if line != self.HEADER:
985
 
            raise KnitHeaderError(badline=line)
 
1024
            raise KnitHeaderError(badline=line,
 
1025
                              filename=self._transport.abspath(self._filename))
986
1026
 
987
1027
    def commit(self):
988
1028
        """Commit is a nop."""