~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

  • Committer: Robert Collins
  • Date: 2009-02-15 21:47:42 UTC
  • mto: (4022.1.4 fetch.RemoteSink)
  • mto: This revision was merged to the branch mainline in revision 4026.
  • Revision ID: robertc@robertcollins.net-20090215214742-8n251ozbun3ncjsm
First passing NetworkRecordStream test - a fulltext from any record type which isn't a chunked or fulltext can be serialised and deserialised successfully.

Show diffs side-by-side

added added

removed removed

Lines of Context:
152
152
    """An adapter from FT annotated knits to unannotated ones."""
153
153
 
154
154
    def get_bytes(self, factory):
155
 
        annotated_compressed_bytes = factory.get_bytes_as(factory.storage_kind)
 
155
        annotated_compressed_bytes = factory._raw_record
156
156
        rec, contents = \
157
157
            self._data._parse_record_unchecked(annotated_compressed_bytes)
158
158
        content = self._annotate_factory.parse_fulltext(contents, rec[1])
164
164
    """An adapter for deltas from annotated to unannotated."""
165
165
 
166
166
    def get_bytes(self, factory):
167
 
        annotated_compressed_bytes = factory.get_bytes_as(factory.storage_kind)
 
167
        annotated_compressed_bytes = factory._raw_record
168
168
        rec, contents = \
169
169
            self._data._parse_record_unchecked(annotated_compressed_bytes)
170
170
        delta = self._annotate_factory.parse_line_delta(contents, rec[1],
178
178
    """An adapter from FT annotated knits to unannotated ones."""
179
179
 
180
180
    def get_bytes(self, factory):
181
 
        annotated_compressed_bytes = factory.get_bytes_as(factory.storage_kind)
 
181
        annotated_compressed_bytes = factory._raw_record
182
182
        rec, contents = \
183
183
            self._data._parse_record_unchecked(annotated_compressed_bytes)
184
184
        content, delta = self._annotate_factory.parse_record(factory.key[-1],
190
190
    """An adapter for deltas from annotated to unannotated."""
191
191
 
192
192
    def get_bytes(self, factory):
193
 
        annotated_compressed_bytes = factory.get_bytes_as(factory.storage_kind)
 
193
        annotated_compressed_bytes = factory._raw_record
194
194
        rec, contents = \
195
195
            self._data._parse_record_unchecked(annotated_compressed_bytes)
196
196
        delta = self._annotate_factory.parse_line_delta(contents, rec[1],
214
214
    """An adapter from FT plain knits to unannotated ones."""
215
215
 
216
216
    def get_bytes(self, factory):
217
 
        compressed_bytes = factory.get_bytes_as(factory.storage_kind)
 
217
        compressed_bytes = factory._raw_record
218
218
        rec, contents = \
219
219
            self._data._parse_record_unchecked(compressed_bytes)
220
220
        content, delta = self._plain_factory.parse_record(factory.key[-1],
226
226
    """An adapter for deltas from annotated to unannotated."""
227
227
 
228
228
    def get_bytes(self, factory):
229
 
        compressed_bytes = factory.get_bytes_as(factory.storage_kind)
 
229
        compressed_bytes = factory._raw_record
230
230
        rec, contents = \
231
231
            self._data._parse_record_unchecked(compressed_bytes)
232
232
        delta = self._plain_factory.parse_line_delta(contents, rec[1])
253
253
    """
254
254
 
255
255
    def __init__(self, key, parents, build_details, sha1, raw_record,
256
 
        annotated, knit=None):
 
256
        annotated, knit=None, network_bytes=None):
257
257
        """Create a KnitContentFactory for key.
258
258
        
259
259
        :param key: The key.
263
263
        :param sha1: The sha1 expected from the full text of this object.
264
264
        :param raw_record: The bytes of the knit data from disk.
265
265
        :param annotated: True if the raw data is annotated.
 
266
        :param network_bytes: None to calculate the network bytes on demand,
 
267
            not-none if they are already known.
266
268
        """
267
269
        ContentFactory.__init__(self)
268
270
        self.sha1 = sha1
278
280
            annotated_kind = ''
279
281
        self.storage_kind = 'knit-%s%s-gz' % (annotated_kind, kind)
280
282
        self._raw_record = raw_record
 
283
        self._network_bytes = network_bytes
281
284
        self._build_details = build_details
282
285
        self._knit = knit
283
286
 
 
287
    def _create_network_bytes(self):
 
288
        """Create a fully serialised network version for transmission."""
 
289
        # storage_kind, key, parents, Noeol, raw_record
 
290
        key_bytes = '\x00'.join(self.key)
 
291
        if self.parents is None:
 
292
            parent_bytes = 'None:'
 
293
        else:
 
294
            parent_bytes = '\t'.join('\x00'.join(key) for key in self.parents)
 
295
        if self._build_details[1]:
 
296
            noeol = 'N'
 
297
        else:
 
298
            noeol = ' '
 
299
        network_bytes = "%s\n%s\n%s\n%s%s" % (self.storage_kind, key_bytes,
 
300
            parent_bytes, noeol, self._raw_record)
 
301
        self._network_bytes = network_bytes
 
302
 
284
303
    def get_bytes_as(self, storage_kind):
285
304
        if storage_kind == self.storage_kind:
286
 
            return self._raw_record
 
305
            if self._network_bytes is None:
 
306
                self._create_network_bytes()
 
307
            return self._network_bytes
287
308
        if self._knit is not None:
288
309
            if storage_kind == 'chunked':
289
310
                return self._knit.get_lines(self.key[0])
293
314
            self.storage_kind)
294
315
 
295
316
 
 
317
def knit_network_to_record(storage_kind, bytes, line_end):
 
318
    """Convert a network record to a record object.
 
319
 
 
320
    :param storage_kind: The storage kind of the record.
 
321
    :param bytes: The bytes of the record on the network.
 
322
    """
 
323
    start = line_end
 
324
    line_end = bytes.find('\n', start)
 
325
    key = bytes[:line_end].split('\x00')
 
326
    start = line_end + 1
 
327
    line_end = bytes.find('\n', start)
 
328
    parent_line = bytes[start:line_end]
 
329
    if parent_line == 'None:':
 
330
        parents = None
 
331
    else:
 
332
        parents = tuple(
 
333
            [segment.split('\x00') for segment in parent_line.split('\t')
 
334
             if segment])
 
335
    start = line_end + 1
 
336
    noeol = bytes[start] != 'N'
 
337
    if 'ft' in storage_kind:
 
338
        method = 'fulltext'
 
339
    else:
 
340
        method = 'line-delta'
 
341
    build_details = (method, noeol)
 
342
    start = start + 1
 
343
    raw_record = bytes[start:]
 
344
    annotated = 'annotated' in storage_kind
 
345
    return KnitContentFactory(key, parents, build_details, None, raw_record,
 
346
        annotated, network_bytes=bytes)
 
347
 
 
348
 
296
349
class KnitContent(object):
297
350
    """Content of a knit version to which deltas can be applied.
298
351
    
1416
1469
                        adapter = get_adapter(adapter_key)
1417
1470
                    bytes = adapter.get_bytes(record)
1418
1471
                else:
1419
 
                    bytes = record.get_bytes_as(record.storage_kind)
 
1472
                    # It's a knit record, it has a _raw_record field (even if
 
1473
                    # it was reconstituted from a network stream).
 
1474
                    bytes = record._raw_record
1420
1475
                options = [record._build_details[0]]
1421
1476
                if record._build_details[1]:
1422
1477
                    options.append('no-eol')