~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/pack.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-08-17 18:13:57 UTC
  • mfrom: (5268.7.29 transport-segments)
  • Revision ID: pqm@pqm.ubuntu.com-20110817181357-y5q5eth1hk8bl3om
(jelmer) Allow specifying the colocated branch to use in the branch URL,
 and retrieving the branch name using ControlDir._get_selected_branch.
 (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
doc/developers/container-format.txt.
21
21
"""
22
22
 
23
 
from __future__ import absolute_import
24
 
 
25
23
from cStringIO import StringIO
26
24
import re
27
25
 
77
75
        """Return the bytes to finish a container."""
78
76
        return "E"
79
77
 
80
 
    def bytes_header(self, length, names):
81
 
        """Return the header for a Bytes record."""
 
78
    def bytes_record(self, bytes, names):
 
79
        """Return the bytes for a Bytes record with the given name and
 
80
        contents.
 
81
        """
82
82
        # Kind marker
83
83
        byte_sections = ["B"]
84
84
        # Length
85
 
        byte_sections.append(str(length) + "\n")
 
85
        byte_sections.append(str(len(bytes)) + "\n")
86
86
        # Names
87
87
        for name_tuple in names:
88
88
            # Make sure we're writing valid names.  Note that we will leave a
92
92
            byte_sections.append('\x00'.join(name_tuple) + "\n")
93
93
        # End of headers
94
94
        byte_sections.append("\n")
 
95
        # Finally, the contents.
 
96
        byte_sections.append(bytes)
 
97
        # XXX: This causes a memory copy of bytes in size, but is usually
 
98
        # faster than two write calls (12 vs 13 seconds to output a gig of
 
99
        # 1k records.) - results may differ on significantly larger records
 
100
        # like .iso's but as they should be rare in any case and thus not
 
101
        # likely to be the common case. The biggest issue is causing extreme
 
102
        # memory pressure in that case. One possibly improvement here is to
 
103
        # check the size of the content before deciding to join here vs call
 
104
        # write twice.
95
105
        return ''.join(byte_sections)
96
106
 
97
 
    def bytes_record(self, bytes, names):
98
 
        """Return the bytes for a Bytes record with the given name and
99
 
        contents.
100
 
 
101
 
        If the content may be large, construct the header separately and then
102
 
        stream out the contents.
103
 
        """
104
 
        return self.bytes_header(len(bytes), names) + bytes
105
 
 
106
107
 
107
108
class ContainerWriter(object):
108
109
    """A class for writing containers to a file.
112
113
        introduced by the begin() and end() methods.
113
114
    """
114
115
 
115
 
    # Join up headers with the body if writing fewer than this many bytes:
116
 
    # trades off memory usage and copying to do less IO ops.
117
 
    _JOIN_WRITES_THRESHOLD = 100000
118
 
 
119
116
    def __init__(self, write_func):
120
117
        """Constructor.
121
118
 
154
151
            and thus are only suitable for use by a ContainerReader.
155
152
        """
156
153
        current_offset = self.current_offset
157
 
        length = len(bytes)
158
 
        if length < self._JOIN_WRITES_THRESHOLD:
159
 
            self.write_func(self._serialiser.bytes_header(length, names)
160
 
                + bytes)
161
 
        else:
162
 
            self.write_func(self._serialiser.bytes_header(length, names))
163
 
            self.write_func(bytes)
 
154
        serialised_record = self._serialiser.bytes_record(bytes, names)
 
155
        self.write_func(serialised_record)
164
156
        self.records_written += 1
165
157
        # return a memo of where we wrote data to allow random access.
166
158
        return current_offset, self.current_offset - current_offset
341
333
                # risk that the same unicode string has been encoded two
342
334
                # different ways.
343
335
                if name_tuple in all_names:
344
 
                    raise errors.DuplicateRecordNameError(name_tuple[0])
 
336
                    raise errors.DuplicateRecordNameError(name_tuple)
345
337
                all_names.add(name_tuple)
346
338
        excess_bytes = self.reader_func(1)
347
339
        if excess_bytes != '':