/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 breezy/multiparent.py

  • Committer: Jelmer Vernooij
  • Date: 2018-05-06 11:48:54 UTC
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@jelmer.uk-20180506114854-h4qd9ojaqy8wxjsd
Move .mailmap to root.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
lazy_import(globals(), """
25
25
import gzip
26
26
import itertools
27
 
import patiencediff
28
27
 
29
28
from breezy import (
30
29
    bencode,
 
30
    errors,
 
31
    patiencediff,
31
32
    ui,
32
33
    )
33
34
""")
34
 
from . import (
35
 
    errors,
36
 
    )
37
 
from .i18n import gettext
38
35
from .sixish import (
39
36
    BytesIO,
40
37
    range,
47
44
    parents = vf.get_parent_map(keys)
48
45
    return _topo_iter(parents, keys)
49
46
 
50
 
 
51
47
def topo_iter(vf, versions=None):
52
48
    if versions is None:
53
49
        versions = vf.versions()
54
50
    parents = vf.get_parent_map(versions)
55
51
    return _topo_iter(parents, versions)
56
52
 
57
 
 
58
53
def _topo_iter(parents, versions):
59
54
    seen = set()
60
55
    descendants = {}
61
 
 
62
56
    def pending_parents(version):
63
57
        if parents[version] is None:
64
58
            return []
122
116
        parent_text = []
123
117
        block_iter = [iter(i) for i in parent_comparisons]
124
118
        diff = MultiParent([])
125
 
 
126
119
        def next_block(p):
127
120
            try:
128
121
                return next(block_iter[p])
193
186
                yield line
194
187
 
195
188
    def patch_len(self):
196
 
        return len(b''.join(self.to_patch()))
 
189
        return len(''.join(self.to_patch()))
197
190
 
198
191
    def zipped_patch_len(self):
199
192
        return len(gzip_string(self.to_patch()))
209
202
        line_iter = iter(lines)
210
203
        hunks = []
211
204
        cur_line = None
212
 
        while True:
 
205
        while(True):
213
206
            try:
214
207
                cur_line = next(line_iter)
215
208
            except StopIteration:
216
209
                break
217
 
            first_char = cur_line[0:1]
218
 
            if first_char == b'i':
219
 
                num_lines = int(cur_line.split(b' ')[1])
 
210
            if cur_line[0] == 'i':
 
211
                num_lines = int(cur_line.split(' ')[1])
220
212
                hunk_lines = [next(line_iter) for _ in range(num_lines)]
221
213
                hunk_lines[-1] = hunk_lines[-1][:-1]
222
214
                hunks.append(NewText(hunk_lines))
223
 
            elif first_char == b'\n':
224
 
                hunks[-1].lines[-1] += b'\n'
 
215
            elif cur_line[0] == '\n':
 
216
                hunks[-1].lines[-1] += '\n'
225
217
            else:
226
 
                if not (first_char == b'c'):
227
 
                    raise AssertionError(first_char)
 
218
                if not (cur_line[0] == 'c'):
 
219
                    raise AssertionError(cur_line[0])
228
220
                parent, parent_pos, child_pos, num_lines =\
229
 
                    [int(v) for v in cur_line.split(b' ')[1:]]
 
221
                    [int(v) for v in cur_line.split(' ')[1:]]
230
222
                hunks.append(ParentText(parent, parent_pos, child_pos,
231
223
                                        num_lines))
232
224
        return MultiParent(hunks)
259
251
        extra_n = 0
260
252
        for hunk in reversed(self.hunks):
261
253
            if isinstance(hunk, ParentText):
262
 
                return hunk.child_pos + hunk.num_lines + extra_n
 
254
               return hunk.child_pos + hunk.num_lines + extra_n
263
255
            extra_n += len(hunk.lines)
264
256
        return extra_n
265
257
 
287
279
        return 'NewText(%r)' % self.lines
288
280
 
289
281
    def to_patch(self):
290
 
        yield b'i %d\n' % len(self.lines)
 
282
        yield 'i %d\n' % len(self.lines)
291
283
        for line in self.lines:
292
284
            yield line
293
 
        yield b'\n'
 
285
        yield '\n'
294
286
 
295
287
 
296
288
class ParentText(object):
305
297
        self.num_lines = num_lines
306
298
 
307
299
    def _as_dict(self):
308
 
        return {b'parent': self.parent,
309
 
                b'parent_pos': self.parent_pos,
310
 
                b'child_pos': self.child_pos,
311
 
                b'num_lines': self.num_lines}
 
300
        return dict(parent=self.parent, parent_pos=self.parent_pos,
 
301
                    child_pos=self.child_pos, num_lines=self.num_lines)
312
302
 
313
303
    def __repr__(self):
314
304
        return ('ParentText(%(parent)r, %(parent_pos)r, %(child_pos)r,'
320
310
        return self._as_dict() == other._as_dict()
321
311
 
322
312
    def to_patch(self):
323
 
        yield (b'c %(parent)d %(parent_pos)d %(child_pos)d %(num_lines)d\n'
 
313
        yield ('c %(parent)d %(parent_pos)d %(child_pos)d %(num_lines)d\n'
324
314
               % self._as_dict())
325
315
 
326
316
 
345
335
        if self.snapshot_interval is None:
346
336
            return False
347
337
        if self.max_snapshots is not None and\
348
 
                len(self._snapshots) == self.max_snapshots:
 
338
            len(self._snapshots) == self.max_snapshots:
349
339
            return False
350
340
        if len(parent_ids) == 0:
351
341
            return True
420
410
                    parents = vf.get_parents(revision)
421
411
                    if [p for p in parents if p not in self._parents] != []:
422
412
                        continue
423
 
                    lines = [a + b' ' + l for a, l in
 
413
                    lines = [a + ' ' + l for a, l in
424
414
                             vf.annotate(revision)]
425
415
                    if snapshots is None:
426
416
                        force_snapshot = None
443
433
    def select_snapshots(self, vf):
444
434
        """Determine which versions to add as snapshots"""
445
435
        build_ancestors = {}
 
436
        descendants = {}
446
437
        snapshots = set()
447
438
        for version_id in topo_iter(vf):
448
439
            potential_build_ancestors = set(vf.get_parents(version_id))
469
460
    def get_size_ranking(self):
470
461
        """Get versions ranked by size"""
471
462
        versions = []
 
463
        new_snapshots = set()
472
464
        for version_id in self.versions():
473
465
            if version_id in self._snapshots:
474
466
                continue
502
494
        ranking = []
503
495
        while len(available_versions) > 0:
504
496
            available_versions.sort(key=lambda x:
505
 
                                    len(could_avoid[x]) *
506
 
                                    len(referenced_by.get(x, [])))
 
497
                len(could_avoid[x]) *
 
498
                len(referenced_by.get(x, [])))
507
499
            selected = available_versions.pop()
508
500
            ranking.append(selected)
509
501
            for version_id in referenced_by[selected]:
565
557
 
566
558
    def get_diff(self, version_id):
567
559
        start, count = self._diff_offset[version_id]
568
 
        with open(self._filename + '.mpknit', 'rb') as infile:
 
560
        infile = open(self._filename + '.mpknit', 'rb')
 
561
        try:
569
562
            infile.seek(start)
570
563
            sio = BytesIO(infile.read(count))
571
 
        with gzip.GzipFile(None, mode='rb', fileobj=sio) as zip_file:
 
564
        finally:
 
565
            infile.close()
 
566
        zip_file = gzip.GzipFile(None, mode='rb', fileobj=sio)
 
567
        try:
572
568
            file_version_id = zip_file.readline()
573
569
            content = zip_file.read()
574
570
            return MultiParent.from_patch(content)
 
571
        finally:
 
572
            zip_file.close()
575
573
 
576
574
    def add_diff(self, diff, version_id, parent_ids):
577
 
        with open(self._filename + '.mpknit', 'ab') as outfile:
 
575
        outfile = open(self._filename + '.mpknit', 'ab')
 
576
        try:
578
577
            outfile.seek(0, 2)      # workaround for windows bug:
579
 
            # .tell() for files opened in 'ab' mode
580
 
            # before any write returns 0
 
578
                                    # .tell() for files opened in 'ab' mode
 
579
                                    # before any write returns 0
581
580
            start = outfile.tell()
582
 
            with gzip.GzipFile(None, mode='ab', fileobj=outfile) as zipfile:
 
581
            try:
 
582
                zipfile = gzip.GzipFile(None, mode='ab', fileobj=outfile)
583
583
                zipfile.writelines(itertools.chain(
584
 
                    [b'version %s\n' % version_id], diff.to_patch()))
 
584
                    ['version %s\n' % version_id], diff.to_patch()))
 
585
            finally:
 
586
                zipfile.close()
585
587
            end = outfile.tell()
586
 
        self._diff_offset[version_id] = (start, end - start)
 
588
        finally:
 
589
            outfile.close()
 
590
        self._diff_offset[version_id] = (start, end-start)
587
591
        self._parents[version_id] = parent_ids
588
592
 
589
593
    def destroy(self):
672
676
 
673
677
def gzip_string(lines):
674
678
    sio = BytesIO()
675
 
    with gzip.GzipFile(None, mode='wb', fileobj=sio) as data_file:
676
 
        data_file.writelines(lines)
 
679
    data_file = gzip.GzipFile(None, mode='wb', fileobj=sio)
 
680
    data_file.writelines(lines)
 
681
    data_file.close()
677
682
    return sio.getvalue()