2225
2225
def get_raw_records(self, memos_for_retrieval):
2226
2226
"""Get the raw bytes for a records.
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.
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]
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.
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
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).
2317
opaque structure to pass to read_records to extract the raw
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
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
2336
2344
if method == 'fulltext':
2337
2345
compression_parent = None
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))
2345
2352
def get_method(self, version_id):
2346
2353
"""Return compression method of specified version."""
2348
options = self._by_version[version_id][0]
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:
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:
2373
elif 'line-delta' in options:
2374
# Texts from the backing knit are always returned from the stream
2376
options.remove('line-delta')
2377
options.append('fulltext')
2379
raise errors.KnitIndexUnknownMethod(self, options)
2380
return tuple(options)
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).
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.
2400
2414
start, end = self._by_version[version_id][1]