~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/pack.py

  • Committer: Robert Collins
  • Date: 2007-08-02 03:17:46 UTC
  • mto: (2592.3.65 repository)
  • mto: This revision was merged to the branch mainline in revision 2667.
  • Revision ID: robertc@robertcollins.net-20070802031746-mpnoaxym829719w6
* ``bzrlib.pack.make_readv_reader`` allows readv based access to pack
  files that are stored on a transport. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
"Containers" and "records" are described in doc/developers/container-format.txt.
20
20
"""
21
21
 
 
22
from cStringIO import StringIO
22
23
import re
23
24
 
24
25
from bzrlib import errors
112
113
        return current_offset, self.current_offset - current_offset
113
114
 
114
115
 
 
116
class ReadVFile(object):
 
117
    """Adapt a readv result iterator to a file like protocol."""
 
118
 
 
119
    def __init__(self, readv_result):
 
120
        self.readv_result = readv_result
 
121
        # the most recent readv result block
 
122
        self._string = None
 
123
 
 
124
    def _next(self):
 
125
        if (self._string is None or
 
126
            self._string.tell() == self._string_length):
 
127
            length, data = self.readv_result.next()
 
128
            self._string_length = len(data)
 
129
            self._string = StringIO(data)
 
130
 
 
131
    def read(self, length):
 
132
        self._next()
 
133
        result = self._string.read(length)
 
134
        if len(result) < length:
 
135
            raise errors.BzrError('request for too much data from a readv hunk.')
 
136
        return result
 
137
 
 
138
    def readline(self):
 
139
        """Note that readline will not cross readv segments."""
 
140
        self._next()
 
141
        result = self._string.readline()
 
142
        if self._string.tell() == self._string_length and result[-1] != '\n':
 
143
            raise errors.BzrError('short readline in the readvfile hunk.')
 
144
        return result
 
145
 
 
146
 
 
147
def make_readv_reader(transport, filename, requested_records):
 
148
    """Create a ContainerReader that will read selected records only.
 
149
 
 
150
    :param transport: The transport the pack file is located on.
 
151
    :param filename: The filename of the pack file.
 
152
    :param requested_records: The record offset, length tuples as returned
 
153
        by add_bytes_record for the desired records.
 
154
    """
 
155
    readv_blocks = [(0, len(FORMAT_ONE)+1)]
 
156
    readv_blocks.extend(requested_records)
 
157
    result = ContainerReader(ReadVFile(
 
158
        transport.readv(filename, readv_blocks)))
 
159
    return result
 
160
 
 
161
 
115
162
class BaseReader(object):
116
163
 
117
164
    def __init__(self, source_file):