~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bundle/serializer/v10.py

  • Committer: Aaron Bentley
  • Date: 2007-06-11 14:59:52 UTC
  • mto: (2520.5.2 bzr.mpbundle)
  • mto: This revision was merged to the branch mainline in revision 2631.
  • Revision ID: abentley@panoramicfeedback.com-20070611145952-cwt4480gphdhen6l
Get installation started

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from bzrlib import multiparent
1
2
from bzrlib.bundle import serializer
2
3
from bzrlib.util import bencode
3
4
 
6
7
    def write(self, repository, revision_ids, forced_bases, fileobj):
7
8
        container = _PseudoContainer(fileobj)
8
9
        transaction = repository.get_transaction()
9
 
        for file_id, file_revision_ids in \
10
 
            repository.fileids_altered_by_revision_ids(revision_ids).iteritems():
 
10
        altered = repository.fileids_altered_by_revision_ids(revision_ids)
 
11
        for file_id, file_revision_ids in altered.iteritems():
11
12
            vf = repository.weave_store.get_weave(file_id, transaction)
12
13
            file_revision_ids = [r for r in revision_ids if r in
13
14
                                 file_revision_ids]
14
15
            for file_revision_id in file_revision_ids:
15
16
                text = ''.join(vf.make_mpdiff(file_revision_id).to_patch())
16
 
                container.add_record('M', len(text), ['file:%s/%s' %
17
 
                                     (file_id, file_revision_id)], text)
 
17
                container_name = self.encode_name('file', file_revision_id,
 
18
                                                  file_id)
 
19
                container.add_record('M', len(text), [container_name], text)
18
20
        container.finish()
19
21
 
20
 
    def read(self, file)
21
 
        
 
22
    def read(self, file):
 
23
        container = _RecordReader(file, self)
 
24
        return container
 
25
 
 
26
    @staticmethod
 
27
    def encode_name(name_kind, revision_id, file_id=None):
 
28
        assert name_kind in ('revision', 'file')
 
29
        if name_kind in ('revision',):
 
30
            assert file_id is None
 
31
        else:
 
32
            assert file_id is not None
 
33
        if file_id is not None:
 
34
            file_tail = '/' + file_id
 
35
        else:
 
36
            file_tail = ''
 
37
        return name_kind + ':' + revision_id + file_tail
 
38
 
 
39
    @staticmethod
 
40
    def decode_name(name):
 
41
        kind, revisionfile_id = name.split(':', 1)
 
42
        revisionfile_id = revisionfile_id.split('/')
 
43
        if len(revisionfile_id) == 1:
 
44
            revision_id = revisionfile_id[0]
 
45
            file_id = None
 
46
        else:
 
47
            revision_id, file_id = revisionfile_id
 
48
        return kind, revision_id, file_id
 
49
 
22
50
 
23
51
class _PseudoContainer(object):
24
52
    
31
59
 
32
60
    def finish(self):
33
61
        self._fileobj.write(bencode.bencode([list(e) for e in self._records]))
 
62
 
 
63
 
 
64
class _RecordReader(object):
 
65
 
 
66
    def __init__(self, fileobj, serializer):
 
67
        self._records = [tuple(e) for e in bencode.bdecode(fileobj.read())]
 
68
        self._record_iter = iter(self._records)
 
69
        self._current_text = None
 
70
        self._serializer = serializer
 
71
 
 
72
    def iter_records(self):
 
73
        for type, size, names, text in self._records:
 
74
            self._current_text = text
 
75
            yield type, size, names
 
76
        yield 'E', None, None
 
77
 
 
78
    def read_record(self):
 
79
        return self._current_text
 
80
 
 
81
    def install(self, repository):
 
82
        current_file = None
 
83
        current_versionedfile = None
 
84
        pending_file_records = []
 
85
        for type_, size, names  in self.iter_records():
 
86
            if type_ == 'E':
 
87
                self._install_file_records(current_versionedfile,
 
88
                    pending_file_records)
 
89
                break
 
90
            (name,) = names
 
91
            kind, revision_id, file_id = self._serializer.decode_name(name)
 
92
            if  kind != 'file':
 
93
                self._install_file_records(current_versionedfile,
 
94
                    pending_file_records)
 
95
            if kind == 'file':
 
96
                if file_id != current_file:
 
97
                    self._install_file_records(current_versionedfile,
 
98
                        pending_file_records)
 
99
                    current_file = file_id
 
100
                    current_versionedfile = \
 
101
                        repository.weave_store.get_weave_or_empty(file_id,
 
102
                        repository.get_transaction())
 
103
                    pending_file_records = []
 
104
                if revision_id in current_versionedfile:
 
105
                    continue
 
106
                pending_file_records.append((type_, revision_id, [],
 
107
                                            self.read_record()))
 
108
 
 
109
 
 
110
    def _install_file_records(self, current_versionedfile,
 
111
                              pending_file_records):
 
112
        for type_, revision, parents, text in pending_file_records:
 
113
            assert type_ == 'M'
 
114
            mpdiff = multiparent.MultiParent.from_lines(text)
 
115
            current_versionedfile.add_mpdiff(revision, parents, mpdiff)