~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/groupcompress.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-05-18 13:02:52 UTC
  • mfrom: (5830.3.6 i18n-msgfmt)
  • Revision ID: pqm@pqm.ubuntu.com-20110518130252-ky96qcvzt6o0zg3f
(mbp) add build_mo command to setup.py (INADA Naoki)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Core compression logic for compressing streams of related files."""
18
18
 
19
 
from __future__ import absolute_import
20
 
 
21
19
import time
22
20
import zlib
 
21
try:
 
22
    import pylzma
 
23
except ImportError:
 
24
    pylzma = None
23
25
 
24
26
from bzrlib.lazy_import import lazy_import
25
27
lazy_import(globals(), """
37
39
    )
38
40
 
39
41
from bzrlib.repofmt import pack_repo
40
 
from bzrlib.i18n import gettext
41
42
""")
42
43
 
43
44
from bzrlib.btree_index import BTreeBuilder
55
56
# groupcompress blocks.
56
57
BATCH_SIZE = 2**16
57
58
 
 
59
_USE_LZMA = False and (pylzma is not None)
 
60
 
58
61
# osutils.sha_string('')
59
62
_null_sha1 = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
60
63
 
149
152
                self._content = ''
150
153
            elif self._compressor_name == 'lzma':
151
154
                # We don't do partial lzma decomp yet
152
 
                import pylzma
153
155
                self._content = pylzma.decompress(z_content)
154
156
            elif self._compressor_name == 'zlib':
155
157
                # Start a zlib decompressor
296
298
        self._content = content
297
299
        self._z_content_chunks = None
298
300
 
 
301
    def _create_z_content_using_lzma(self):
 
302
        if self._content_chunks is not None:
 
303
            self._content = ''.join(self._content_chunks)
 
304
            self._content_chunks = None
 
305
        if self._content is None:
 
306
            raise AssertionError('Nothing to compress')
 
307
        z_content = pylzma.compress(self._content)
 
308
        self._z_content_chunks = (z_content,)
 
309
        self._z_content_length = len(z_content)
 
310
 
299
311
    def _create_z_content_from_chunks(self, chunks):
300
312
        compressor = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION)
301
313
        # Peak in this point is 1 fulltext, 1 compressed text, + zlib overhead
309
321
    def _create_z_content(self):
310
322
        if self._z_content_chunks is not None:
311
323
            return
 
324
        if _USE_LZMA:
 
325
            self._create_z_content_using_lzma()
 
326
            return
312
327
        if self._content_chunks is not None:
313
328
            chunks = self._content_chunks
314
329
        else:
318
333
    def to_chunks(self):
319
334
        """Create the byte stream as a series of 'chunks'"""
320
335
        self._create_z_content()
321
 
        header = self.GCB_HEADER
 
336
        if _USE_LZMA:
 
337
            header = self.GCB_LZ_HEADER
 
338
        else:
 
339
            header = self.GCB_HEADER
322
340
        chunks = ['%s%d\n%d\n'
323
341
                  % (header, self._z_content_length, self._content_length),
324
342
                 ]
448
466
                # Grab and cache the raw bytes for this entry
449
467
                # and break the ref-cycle with _manager since we don't need it
450
468
                # anymore
451
 
                try:
452
 
                    self._manager._prepare_for_extract()
453
 
                except zlib.error as value:
454
 
                    raise errors.DecompressCorruption("zlib: " + str(value))
 
469
                self._manager._prepare_for_extract()
455
470
                block = self._manager._block
456
471
                self._bytes = block.extract(self.key, self._start, self._end)
457
472
                # There are code paths that first extract as fulltext, and then
970
985
 
971
986
    It contains code very similar to SequenceMatcher because of having a similar
972
987
    task. However some key differences apply:
973
 
 
974
 
    * there is no junk, we want a minimal edit not a human readable diff.
975
 
    * we don't filter very common lines (because we don't know where a good
976
 
      range will start, and after the first text we want to be emitting minmal
977
 
      edits only.
978
 
    * we chain the left side, not the right side
979
 
    * we incrementally update the adjacency matrix as new lines are provided.
980
 
    * we look for matches in all of the left side, so the routine which does
981
 
      the analagous task of find_longest_match does not need to filter on the
982
 
      left side.
 
988
     - there is no junk, we want a minimal edit not a human readable diff.
 
989
     - we don't filter very common lines (because we don't know where a good
 
990
       range will start, and after the first text we want to be emitting minmal
 
991
       edits only.
 
992
     - we chain the left side, not the right side
 
993
     - we incrementally update the adjacency matrix as new lines are provided.
 
994
     - we look for matches in all of the left side, so the routine which does
 
995
       the analagous task of find_longest_match does not need to filter on the
 
996
       left side.
983
997
    """
984
998
 
985
999
    def __init__(self, settings=None):
1241
1255
        :param key: The key tuple of the text to add.
1242
1256
        :param parents: The parents key tuples of the text to add.
1243
1257
        :param lines: A list of lines. Each line must be a bytestring. And all
1244
 
            of them except the last must be terminated with \\n and contain no
1245
 
            other \\n's. The last line may either contain no \\n's or a single
1246
 
            terminating \\n. If the lines list does meet this constraint the
1247
 
            add routine may error or may succeed - but you will be unable to
1248
 
            read the data back accurately. (Checking the lines have been split
 
1258
            of them except the last must be terminated with \n and contain no
 
1259
            other \n's. The last line may either contain no \n's or a single
 
1260
            terminating \n. If the lines list does meet this constraint the add
 
1261
            routine may error or may succeed - but you will be unable to read
 
1262
            the data back accurately. (Checking the lines have been split
1249
1263
            correctly is expensive and extremely unlikely to catch bugs so it
1250
1264
            is not done at runtime unless check_content is True.)
1251
1265
        :param parent_texts: An optional dictionary containing the opaque
1489
1503
 
1490
1504
        The returned objects should be in the order defined by 'ordering',
1491
1505
        which can weave between different sources.
1492
 
 
1493
1506
        :param ordering: Must be one of 'topological' or 'groupcompress'
1494
1507
        :return: List of [(source, [keys])] tuples, such that all keys are in
1495
1508
            the defined order, regardless of source.
1736
1749
                raise errors.RevisionNotPresent(record.key, self)
1737
1750
            if random_id:
1738
1751
                if record.key in inserted_keys:
1739
 
                    trace.note(gettext('Insert claimed random_id=True,'
1740
 
                               ' but then inserted %r two times'), record.key)
 
1752
                    trace.note('Insert claimed random_id=True,'
 
1753
                               ' but then inserted %r two times', record.key)
1741
1754
                    continue
1742
1755
                inserted_keys.add(record.key)
1743
1756
            if reuse_blocks:
2117
2130
        :param keys: An iterable of keys.
2118
2131
        :return: A dict of key:
2119
2132
            (index_memo, compression_parent, parents, record_details).
2120
 
 
2121
 
            * index_memo: opaque structure to pass to read_records to extract
2122
 
              the raw data
2123
 
            * compression_parent: Content that this record is built upon, may
2124
 
              be None
2125
 
            * parents: Logical parents of this node
2126
 
            * record_details: extra information about the content which needs
2127
 
              to be passed to Factory.parse_record
 
2133
            index_memo
 
2134
                opaque structure to pass to read_records to extract the raw
 
2135
                data
 
2136
            compression_parent
 
2137
                Content that this record is built upon, may be None
 
2138
            parents
 
2139
                Logical parents of this node
 
2140
            record_details
 
2141
                extra information about the content which needs to be passed to
 
2142
                Factory.parse_record
2128
2143
        """
2129
2144
        self._check_read()
2130
2145
        result = {}