137
138
% (num_bytes, self._content_length))
138
139
# Expand the content if required
139
140
if self._content is None:
141
if self._content_chunks is not None:
142
self._content = ''.join(self._content_chunks)
143
self._content_chunks = None
144
if self._content is None:
140
145
if self._z_content is None:
141
146
raise AssertionError('No content to decompress')
142
147
if self._z_content == '':
273
278
bytes = apply_delta_to_source(self._content, content_start, end)
281
def set_chunked_content(self, content_chunks, length):
282
"""Set the content of this block to the given chunks."""
283
# If we have lots of short lines, it is may be more efficient to join
284
# the content ahead of time. If the content is <10MiB, we don't really
285
# care about the extra memory consumption, so we can just pack it and
286
# be done. However, timing showed 18s => 17.9s for repacking 1k revs of
287
# mysql, which is below the noise margin
288
self._content_length = length
289
self._content_chunks = content_chunks
291
self._z_content = None
276
293
def set_content(self, content):
277
294
"""Set the content of this block."""
278
295
self._content_length = len(content)
279
296
self._content = content
280
297
self._z_content = None
299
def _create_z_content_using_lzma(self):
300
if self._content_chunks is not None:
301
self._content = ''.join(self._content_chunks)
302
self._content_chunks = None
303
if self._content is None:
304
raise AssertionError('Nothing to compress')
305
self._z_content = pylzma.compress(self._content)
306
self._z_content_length = len(self._z_content)
308
def _create_z_content_from_chunks(self):
309
compressor = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION)
310
compressed_chunks = map(compressor.compress, self._content_chunks)
311
compressed_chunks.append(compressor.flush())
312
self._z_content = ''.join(compressed_chunks)
313
self._z_content_length = len(self._z_content)
315
def _create_z_content(self):
316
if self._z_content is not None:
319
self._create_z_content_using_lzma()
321
if self._content_chunks is not None:
322
self._create_z_content_from_chunks()
324
self._z_content = zlib.compress(self._content)
325
self._z_content_length = len(self._z_content)
282
327
def to_bytes(self):
283
328
"""Encode the information into a byte stream."""
284
compress = zlib.compress
286
compress = pylzma.compress
287
if self._z_content is None:
288
if self._content is None:
289
raise AssertionError('Nothing to compress')
290
self._z_content = compress(self._content)
291
self._z_content_length = len(self._z_content)
329
self._create_z_content()
293
331
header = self.GCB_LZ_HEADER
762
800
# for 'commit' down to ~1x the size of the largest file, at a
763
801
# cost of increased complexity within this code. 2x is still <<
764
802
# 3x the size of the largest file, so we are doing ok.
765
content = ''.join(self.chunks)
803
self._block.set_chunked_content(self.chunks, self.endpoint)
766
804
self.chunks = None
767
805
self._delta_index = None
768
self._block.set_content(content)
769
806
return self._block
771
808
def pop_last(self):
1008
1045
nostore_sha=nostore_sha))[0]
1009
1046
return sha1, length, None
1048
def _add_text(self, key, parents, text, nostore_sha=None, random_id=False):
1049
"""See VersionedFiles._add_text()."""
1050
self._index._check_write_ok()
1051
self._check_add(key, None, random_id, check_content=False)
1052
if text.__class__ is not str:
1053
raise errors.BzrBadParameterUnicode("text")
1055
# The caller might pass None if there is no graph data, but kndx
1056
# indexes can't directly store that, so we give them
1057
# an empty tuple instead.
1059
# double handling for now. Make it work until then.
1061
record = FulltextContentFactory(key, parents, None, text)
1062
sha1 = list(self._insert_record_stream([record], random_id=random_id,
1063
nostore_sha=nostore_sha))[0]
1064
return sha1, length, None
1011
1066
def add_fallback_versioned_files(self, a_versioned_files):
1012
1067
"""Add a source of texts for texts not present in this knit.
1532
1585
'unordered', True)):
1533
1586
# XXX: todo - optimise to use less than full texts.
1534
1587
key = record.key
1535
pb.update('Walking content', key_idx, total)
1589
pb.update('Walking content', key_idx, total)
1536
1590
if record.storage_kind == 'absent':
1537
1591
raise errors.RevisionNotPresent(key, self)
1538
1592
lines = osutils.split_lines(record.get_bytes_as('fulltext'))
1539
1593
for line in lines:
1540
1594
yield line, key
1541
pb.update('Walking content', total, total)
1596
pb.update('Walking content', total, total)
1543
1598
def keys(self):
1544
1599
"""See VersionedFiles.keys."""
1668
1723
if check_present:
1669
1724
missing_keys = keys.difference(found_keys)
1670
1725
if missing_keys:
1671
raise RevisionNotPresent(missing_keys.pop(), self)
1726
raise errors.RevisionNotPresent(missing_keys.pop(), self)
1673
1728
def get_parent_map(self, keys):
1674
1729
"""Get a map of the parents of keys.