~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/weaverepo.py

  • Committer: Karl Bielefeldt
  • Date: 2010-09-29 19:57:28 UTC
  • mto: (5483.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5484.
  • Revision ID: 7mq3cbbd9q@snkmail.com-20100929195728-nvuqlepsrwcxbziw
Use meliae to dump memory to a file upon MemoryError.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2011 Canonical Ltd
 
1
# Copyright (C) 2007-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
20
20
ghosts.
21
21
"""
22
22
 
23
 
import gzip
24
23
import os
25
24
from cStringIO import StringIO
26
25
import urllib
30
29
from bzrlib import (
31
30
    xml5,
32
31
    graph as _mod_graph,
33
 
    ui,
34
32
    )
35
33
""")
36
34
from bzrlib import (
 
35
    bzrdir,
37
36
    debug,
38
37
    errors,
39
38
    lockable_files,
40
39
    lockdir,
41
40
    osutils,
42
 
    symbol_versioning,
 
41
    revision as _mod_revision,
43
42
    trace,
44
 
    tuned_gzip,
45
43
    urlutils,
46
44
    versionedfile,
47
45
    weave,
50
48
from bzrlib.decorators import needs_read_lock, needs_write_lock
51
49
from bzrlib.repository import (
52
50
    CommitBuilder,
53
 
    InterRepository,
54
 
    InterSameDataRepository,
55
51
    MetaDirVersionedFileRepository,
56
52
    MetaDirRepositoryFormat,
57
53
    Repository,
58
54
    RepositoryFormat,
59
55
    )
60
56
from bzrlib.store.text import TextStore
 
57
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
61
58
from bzrlib.versionedfile import (
62
59
    AbsentContentFactory,
63
60
    FulltextContentFactory,
64
61
    VersionedFiles,
65
62
    )
66
63
 
67
 
from bzrlib.plugins.weave_fmt import bzrdir as weave_bzrdir
68
 
 
69
64
 
70
65
class AllInOneRepository(Repository):
71
66
    """Legacy support - the repository behaviour for all-in-one branches."""
145
140
 
146
141
    def get_commit_builder(self, branch, parents, config, timestamp=None,
147
142
                           timezone=None, committer=None, revprops=None,
148
 
                           revision_id=None, lossy=False):
 
143
                           revision_id=None):
149
144
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
150
145
        result = CommitBuilder(self, parents, config, timestamp, timezone,
151
 
                              committer, revprops, revision_id, lossy=lossy)
 
146
                              committer, revprops, revision_id)
152
147
        self.start_write_group()
153
148
        return result
154
149
 
188
183
        """Returns the policy for making working trees on new branches."""
189
184
        return True
190
185
 
 
186
    def revision_graph_can_have_wrong_parents(self):
 
187
        # XXX: This is an old format that we don't support full checking on, so
 
188
        # just claim that checking for this inconsistency is not required.
 
189
        return False
 
190
 
191
191
 
192
192
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
193
193
    """A subclass of MetaDirRepository to set weave specific policy."""
234
234
 
235
235
    def get_commit_builder(self, branch, parents, config, timestamp=None,
236
236
                           timezone=None, committer=None, revprops=None,
237
 
                           revision_id=None, lossy=False):
 
237
                           revision_id=None):
238
238
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
239
239
        result = CommitBuilder(self, parents, config, timestamp, timezone,
240
 
                              committer, revprops, revision_id, lossy=lossy)
 
240
                              committer, revprops, revision_id)
241
241
        self.start_write_group()
242
242
        return result
243
243
 
258
258
        return self.inventories.add_lines((revision_id,), final_parents, lines,
259
259
            check_content=check_content)[0]
260
260
 
 
261
    def revision_graph_can_have_wrong_parents(self):
 
262
        return False
 
263
 
261
264
 
262
265
class PreSplitOutRepositoryFormat(RepositoryFormat):
263
266
    """Base class for the pre split out repository formats."""
270
273
    _fetch_order = 'topological'
271
274
    _fetch_reconcile = True
272
275
    fast_deltas = False
273
 
    supports_leaving_lock = False
274
 
    supports_full_versioned_files = True
275
 
    # XXX: This is an old format that we don't support full checking on, so
276
 
    # just claim that checking for this inconsistency is not required.
277
 
    revision_graph_can_have_wrong_parents = False
278
276
 
279
277
    def initialize(self, a_bzrdir, shared=False, _internal=False):
280
278
        """Create a weave repository."""
326
324
        result.chk_bytes = None
327
325
        return result
328
326
 
329
 
    def is_deprecated(self):
330
 
        return True
331
 
 
332
327
 
333
328
class RepositoryFormat4(PreSplitOutRepositoryFormat):
334
329
    """Bzr repository format 4.
342
337
    has been removed.
343
338
    """
344
339
 
345
 
    supports_funky_characters = False
346
 
 
347
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat4()
 
340
    _matchingbzrdir = bzrdir.BzrDirFormat4()
348
341
 
349
342
    def get_format_description(self):
350
343
        """See RepositoryFormat.get_format_description()."""
368
361
        return None
369
362
 
370
363
    def _get_revisions(self, repo_transport, repo):
371
 
        from bzrlib.plugins.weave_fmt.xml4 import serializer_v4
 
364
        from bzrlib.xml4 import serializer_v4
372
365
        return RevisionTextStore(repo_transport.clone('revision-store'),
373
366
            serializer_v4, True, versionedfile.PrefixMapper(),
374
367
            repo.is_locked, repo.is_write_locked)
392
385
    """
393
386
 
394
387
    _versionedfile_class = weave.WeaveFile
395
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat5()
396
 
    supports_funky_characters = False
397
 
 
 
388
    _matchingbzrdir = bzrdir.BzrDirFormat5()
398
389
    @property
399
390
    def _serializer(self):
400
391
        return xml5.serializer_v5
428
419
        return versionedfile.ThunkedVersionedFiles(base_transport,
429
420
            weave.WeaveFile, mapper, repo.is_locked)
430
421
 
431
 
    def _get_extra_interrepo_test_combinations(self):
432
 
        from bzrlib.repofmt import knitrepo
433
 
        return [(InterRepository, RepositoryFormat5(),
434
 
            knitrepo.RepositoryFormatKnit3())]
435
 
 
436
422
 
437
423
class RepositoryFormat6(PreSplitOutRepositoryFormat):
438
424
    """Bzr control format 6.
444
430
    """
445
431
 
446
432
    _versionedfile_class = weave.WeaveFile
447
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat6()
448
 
    supports_funky_characters = False
 
433
    _matchingbzrdir = bzrdir.BzrDirFormat6()
449
434
    @property
450
435
    def _serializer(self):
451
436
        return xml5.serializer_v5
495
480
    _versionedfile_class = weave.WeaveFile
496
481
    supports_ghosts = False
497
482
    supports_chks = False
498
 
    supports_funky_characters = False
499
 
    supports_full_versioned_files = True
500
 
    revision_graph_can_have_wrong_parents = False
501
483
 
502
484
    _fetch_order = 'topological'
503
485
    _fetch_reconcile = True
580
562
        result._transport = repo_transport
581
563
        return result
582
564
 
583
 
    def is_deprecated(self):
584
 
        return True
585
 
 
586
565
 
587
566
class TextVersionedFiles(VersionedFiles):
588
567
    """Just-a-bunch-of-files based VersionedFile stores."""
608
587
            raise ValueError('bad idea to put / in %r' % (key,))
609
588
        text = ''.join(lines)
610
589
        if self._compressed:
611
 
            text = tuned_gzip.bytes_to_gzip(text)
 
590
            text = bytes_to_gzip(text)
612
591
        path = self._map(key)
613
592
        self._transport.put_bytes_non_atomic(path, text, create_parent_dir=True)
614
593
 
656
635
            else:
657
636
                return None
658
637
        if compressed:
659
 
            text = gzip.GzipFile(mode='rb', fileobj=StringIO(text)).read()
 
638
            text = GzipFile(mode='rb', fileobj=StringIO(text)).read()
660
639
        return text
661
640
 
662
641
    def _map(self, key):
759
738
        paths = list(relpaths)
760
739
        return set([self._mapper.unmap(path) for path in paths])
761
740
 
762
 
 
763
 
class InterWeaveRepo(InterSameDataRepository):
764
 
    """Optimised code paths between Weave based repositories.
765
 
    """
766
 
 
767
 
    @classmethod
768
 
    def _get_repo_format_to_test(self):
769
 
        return RepositoryFormat7()
770
 
 
771
 
    @staticmethod
772
 
    def is_compatible(source, target):
773
 
        """Be compatible with known Weave formats.
774
 
 
775
 
        We don't test for the stores being of specific types because that
776
 
        could lead to confusing results, and there is no need to be
777
 
        overly general.
778
 
        """
779
 
        try:
780
 
            return (isinstance(source._format, (RepositoryFormat5,
781
 
                                                RepositoryFormat6,
782
 
                                                RepositoryFormat7)) and
783
 
                    isinstance(target._format, (RepositoryFormat5,
784
 
                                                RepositoryFormat6,
785
 
                                                RepositoryFormat7)))
786
 
        except AttributeError:
787
 
            return False
788
 
 
789
 
    @needs_write_lock
790
 
    def copy_content(self, revision_id=None):
791
 
        """See InterRepository.copy_content()."""
792
 
        # weave specific optimised path:
793
 
        try:
794
 
            self.target.set_make_working_trees(self.source.make_working_trees())
795
 
        except (errors.RepositoryUpgradeRequired, NotImplemented):
796
 
            pass
797
 
        # FIXME do not peek!
798
 
        if self.source._transport.listable():
799
 
            pb = ui.ui_factory.nested_progress_bar()
800
 
            try:
801
 
                self.target.texts.insert_record_stream(
802
 
                    self.source.texts.get_record_stream(
803
 
                        self.source.texts.keys(), 'topological', False))
804
 
                pb.update('Copying inventory', 0, 1)
805
 
                self.target.inventories.insert_record_stream(
806
 
                    self.source.inventories.get_record_stream(
807
 
                        self.source.inventories.keys(), 'topological', False))
808
 
                self.target.signatures.insert_record_stream(
809
 
                    self.source.signatures.get_record_stream(
810
 
                        self.source.signatures.keys(),
811
 
                        'unordered', True))
812
 
                self.target.revisions.insert_record_stream(
813
 
                    self.source.revisions.get_record_stream(
814
 
                        self.source.revisions.keys(),
815
 
                        'topological', True))
816
 
            finally:
817
 
                pb.finished()
818
 
        else:
819
 
            self.target.fetch(self.source, revision_id=revision_id)
820
 
 
821
 
    @needs_read_lock
822
 
    def search_missing_revision_ids(self,
823
 
            revision_id=symbol_versioning.DEPRECATED_PARAMETER,
824
 
            find_ghosts=True, revision_ids=None, if_present_ids=None):
825
 
        """See InterRepository.search_missing_revision_ids()."""
826
 
        # we want all revisions to satisfy revision_id in source.
827
 
        # but we don't want to stat every file here and there.
828
 
        # we want then, all revisions other needs to satisfy revision_id
829
 
        # checked, but not those that we have locally.
830
 
        # so the first thing is to get a subset of the revisions to
831
 
        # satisfy revision_id in source, and then eliminate those that
832
 
        # we do already have.
833
 
        # this is slow on high latency connection to self, but as this
834
 
        # disk format scales terribly for push anyway due to rewriting
835
 
        # inventory.weave, this is considered acceptable.
836
 
        # - RBC 20060209
837
 
        if symbol_versioning.deprecated_passed(revision_id):
838
 
            symbol_versioning.warn(
839
 
                'search_missing_revision_ids(revision_id=...) was '
840
 
                'deprecated in 2.4.  Use revision_ids=[...] instead.',
841
 
                DeprecationWarning, stacklevel=2)
842
 
            if revision_ids is not None:
843
 
                raise AssertionError(
844
 
                    'revision_ids is mutually exclusive with revision_id')
845
 
            if revision_id is not None:
846
 
                revision_ids = [revision_id]
847
 
        del revision_id
848
 
        source_ids_set = self._present_source_revisions_for(
849
 
            revision_ids, if_present_ids)
850
 
        # source_ids is the worst possible case we may need to pull.
851
 
        # now we want to filter source_ids against what we actually
852
 
        # have in target, but don't try to check for existence where we know
853
 
        # we do not have a revision as that would be pointless.
854
 
        target_ids = set(self.target._all_possible_ids())
855
 
        possibly_present_revisions = target_ids.intersection(source_ids_set)
856
 
        actually_present_revisions = set(
857
 
            self.target._eliminate_revisions_not_present(possibly_present_revisions))
858
 
        required_revisions = source_ids_set.difference(actually_present_revisions)
859
 
        if revision_ids is not None:
860
 
            # we used get_ancestry to determine source_ids then we are assured all
861
 
            # revisions referenced are present as they are installed in topological order.
862
 
            # and the tip revision was validated by get_ancestry.
863
 
            result_set = required_revisions
864
 
        else:
865
 
            # if we just grabbed the possibly available ids, then
866
 
            # we only have an estimate of whats available and need to validate
867
 
            # that against the revision records.
868
 
            result_set = set(
869
 
                self.source._eliminate_revisions_not_present(required_revisions))
870
 
        return self.source.revision_ids_to_search_result(result_set)
871
 
 
872
 
 
873
 
InterRepository.register_optimiser(InterWeaveRepo)
874
 
 
875
 
 
876
 
def get_extra_interrepo_test_combinations():
877
 
    from bzrlib.repofmt import knitrepo
878
 
    return [(InterRepository, RepositoryFormat5(),
879
 
        knitrepo.RepositoryFormatKnit3())]
 
741
_legacy_formats = [RepositoryFormat4(),
 
742
                   RepositoryFormat5(),
 
743
                   RepositoryFormat6()]