~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-04-07 07:52:50 UTC
  • mfrom: (3340.1.1 208418-1.4)
  • Revision ID: pqm@pqm.ubuntu.com-20080407075250-phs53xnslo8boaeo
Return the correct knit serialisation method in _StreamAccess.
        (Andrew Bennetts, Martin Pool, Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2225
2225
    def get_raw_records(self, memos_for_retrieval):
2226
2226
        """Get the raw bytes for a records.
2227
2227
 
2228
 
        :param memos_for_retrieval: An iterable containing the (thunk_flag,
2229
 
            index, start, end) memo for retrieving the bytes.
2230
 
        :return: An iterator over the bytes of the records.
 
2228
        :param memos_for_retrieval: An iterable of memos from the
 
2229
            _StreamIndex object identifying bytes to read; for these classes
 
2230
            they are (from_backing_knit, index, start, end) and can point to
 
2231
            either the backing knit or streamed data.
 
2232
        :return: An iterator yielding a byte string for each record in 
 
2233
            memos_for_retrieval.
2231
2234
        """
2232
2235
        # use a generator for memory friendliness
2233
 
        for thunk_flag, version_id, start, end in memos_for_retrieval:
2234
 
            if version_id is self.stream_index:
 
2236
        for from_backing_knit, version_id, start, end in memos_for_retrieval:
 
2237
            if not from_backing_knit:
 
2238
                assert version_id is self.stream_index
2235
2239
                yield self.data[start:end]
2236
2240
                continue
2237
2241
            # we have been asked to thunk. This thunking only occurs when
2242
2246
            # as desired. However, for now, this is sufficient.
2243
2247
            if self.orig_factory.__class__ != KnitPlainFactory:
2244
2248
                raise errors.KnitCorrupt(
2245
 
                    self, 'Bad thunk request %r' % version_id)
 
2249
                    self, 'Bad thunk request %r cannot be backed by %r' %
 
2250
                        (version_id, self.orig_factory))
2246
2251
            lines = self.backing_knit.get_lines(version_id)
2247
2252
            line_bytes = ''.join(lines)
2248
2253
            digest = sha_string(line_bytes)
 
2254
            # the packed form of the fulltext always has a trailing newline,
 
2255
            # even if the actual text does not, unless the file is empty.  the
 
2256
            # record options including the noeol flag are passed through by
 
2257
            # _StreamIndex, so this is safe.
2249
2258
            if lines:
2250
2259
                if lines[-1][-1] != '\n':
2251
2260
                    lines[-1] = lines[-1] + '\n'
2252
2261
                    line_bytes += '\n'
2253
 
            orig_options = list(self.backing_knit._index.get_options(version_id))
2254
 
            if 'fulltext' not in orig_options:
2255
 
                if 'line-delta' not in orig_options:
2256
 
                    raise errors.KnitCorrupt(self,
2257
 
                        'Unknown compression method %r' % orig_options)
2258
 
                orig_options.remove('line-delta')
2259
 
                orig_options.append('fulltext')
2260
2262
            # We want plain data, because we expect to thunk only to allow text
2261
2263
            # extraction.
2262
2264
            size, bytes = self.backing_knit._data._record_to_data(version_id,
2314
2316
        :return: A dict of version_id:(index_memo, compression_parent,
2315
2317
                                       parents, record_details).
2316
2318
            index_memo
2317
 
                opaque structure to pass to read_records to extract the raw
2318
 
                data
 
2319
                opaque memo that can be passed to _StreamAccess.read_records
 
2320
                to extract the raw data; for these classes it is
 
2321
                (from_backing_knit, index, start, end) 
2319
2322
            compression_parent
2320
2323
                Content that this record is built upon, may be None
2321
2324
            parents
2333
2336
                continue
2334
2337
            parent_ids = self.get_parents_with_ghosts(version_id)
2335
2338
            noeol = ('no-eol' in self.get_options(version_id))
 
2339
            index_memo = self.get_position(version_id)
 
2340
            from_backing_knit = index_memo[0]
 
2341
            if from_backing_knit:
 
2342
                # texts retrieved from the backing knit are always full texts
 
2343
                method = 'fulltext'
2336
2344
            if method == 'fulltext':
2337
2345
                compression_parent = None
2338
2346
            else:
2339
2347
                compression_parent = parent_ids[0]
2340
 
            index_memo = self.get_position(version_id)
2341
2348
            result[version_id] = (index_memo, compression_parent,
2342
2349
                                  parent_ids, (method, noeol))
2343
2350
        return result
2344
2351
 
2345
2352
    def get_method(self, version_id):
2346
2353
        """Return compression method of specified version."""
2347
 
        try:
2348
 
            options = self._by_version[version_id][0]
2349
 
        except KeyError:
2350
 
            # Strictly speaking this should check in the backing knit, but
2351
 
            # until we have a test to discriminate, this will do.
2352
 
            return self.backing_index.get_method(version_id)
 
2354
        options = self.get_options(version_id)
2353
2355
        if 'fulltext' in options:
2354
2356
            return 'fulltext'
2355
2357
        elif 'line-delta' in options:
2365
2367
        try:
2366
2368
            return self._by_version[version_id][0]
2367
2369
        except KeyError:
2368
 
            return self.backing_index.get_options(version_id)
 
2370
            options = list(self.backing_index.get_options(version_id))
 
2371
            if 'fulltext' in options:
 
2372
                pass
 
2373
            elif 'line-delta' in options:
 
2374
                # Texts from the backing knit are always returned from the stream
 
2375
                # as full texts
 
2376
                options.remove('line-delta')
 
2377
                options.append('fulltext')
 
2378
            else:
 
2379
                raise errors.KnitIndexUnknownMethod(self, options)
 
2380
            return tuple(options)
2369
2381
 
2370
2382
    def get_parent_map(self, version_ids):
2371
2383
        """Passed through to by KnitVersionedFile.get_parent_map."""
2393
2405
        coordinates into that (as index_memo's are opaque outside the
2394
2406
        index and matching access class).
2395
2407
 
2396
 
        :return: a tuple (thunk_flag, index, start, end).  If thunk_flag is
2397
 
            False, index will be self, otherwise it will be a version id.
 
2408
        :return: a tuple (from_backing_knit, index, start, end) that can 
 
2409
            be passed e.g. to get_raw_records.  
 
2410
            If from_backing_knit is False, index will be self, otherwise it
 
2411
            will be a version id.
2398
2412
        """
2399
2413
        try:
2400
2414
            start, end = self._by_version[version_id][1]