~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/weaverepo.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-08-27 02:27:19 UTC
  • mfrom: (4634.3.19 gc-batching)
  • Revision ID: pqm@pqm.ubuntu.com-20090827022719-bl2yoqhpj3fcfczu
(andrew) Fix #402657: 2a fetch over dumb transport reads one group at
        a time.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Deprecated weave-based repository formats.
18
18
 
24
24
from cStringIO import StringIO
25
25
import urllib
26
26
 
 
27
from bzrlib.lazy_import import lazy_import
 
28
lazy_import(globals(), """
 
29
from bzrlib import (
 
30
    xml5,
 
31
    graph as _mod_graph,
 
32
    )
 
33
""")
27
34
from bzrlib import (
28
35
    bzrdir,
29
36
    debug,
32
39
    lockdir,
33
40
    osutils,
34
41
    revision as _mod_revision,
 
42
    urlutils,
35
43
    versionedfile,
36
44
    weave,
37
45
    weavefile,
38
 
    xml5,
39
46
    )
40
47
from bzrlib.decorators import needs_read_lock, needs_write_lock
41
48
from bzrlib.repository import (
58
65
class AllInOneRepository(Repository):
59
66
    """Legacy support - the repository behaviour for all-in-one branches."""
60
67
 
61
 
    _serializer = xml5.serializer_v5
 
68
    @property
 
69
    def _serializer(self):
 
70
        return xml5.serializer_v5
 
71
 
 
72
    def _escape(self, file_or_path):
 
73
        if not isinstance(file_or_path, basestring):
 
74
            file_or_path = '/'.join(file_or_path)
 
75
        if file_or_path == '':
 
76
            return u''
 
77
        return urlutils.escape(osutils.safe_unicode(file_or_path))
62
78
 
63
79
    def __init__(self, _format, a_bzrdir):
64
80
        # we reuse one control files instance.
67
83
 
68
84
        def get_store(name, compressed=True, prefixed=False):
69
85
            # FIXME: This approach of assuming stores are all entirely compressed
70
 
            # or entirely uncompressed is tidy, but breaks upgrade from 
71
 
            # some existing branches where there's a mixture; we probably 
 
86
            # or entirely uncompressed is tidy, but breaks upgrade from
 
87
            # some existing branches where there's a mixture; we probably
72
88
            # still want the option to look for both.
73
 
            relpath = a_bzrdir._control_files._escape(name)
 
89
            relpath = self._escape(name)
74
90
            store = TextStore(a_bzrdir.transport.clone(relpath),
75
91
                              prefixed=prefixed, compressed=compressed,
76
92
                              dir_mode=dir_mode,
80
96
        # not broken out yet because the controlweaves|inventory_store
81
97
        # and texts bits are still different.
82
98
        if isinstance(_format, RepositoryFormat4):
83
 
            # cannot remove these - there is still no consistent api 
 
99
            # cannot remove these - there is still no consistent api
84
100
            # which allows access to this old info.
85
101
            self.inventory_store = get_store('inventory-store')
86
102
            self._text_store = get_store('text-store')
87
103
        super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files)
88
 
        self._fetch_order = 'topological'
89
 
        self._fetch_reconcile = True
90
104
 
91
105
    @needs_read_lock
92
106
    def _all_possible_ids(self):
97
111
 
98
112
    @needs_read_lock
99
113
    def _all_revision_ids(self):
100
 
        """Returns a list of all the revision ids in the repository. 
 
114
        """Returns a list of all the revision ids in the repository.
101
115
 
102
 
        These are in as much topological order as the underlying store can 
 
116
        These are in as much topological order as the underlying store can
103
117
        present: for weaves ghosts may lead to a lack of correctness until
104
118
        the reweave updates the parents list.
105
119
        """
177
191
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
178
192
    """A subclass of MetaDirRepository to set weave specific policy."""
179
193
 
180
 
    _serializer = xml5.serializer_v5
181
 
 
182
194
    def __init__(self, _format, a_bzrdir, control_files):
183
195
        super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
184
 
        self._fetch_order = 'topological'
185
 
        self._fetch_reconcile = True
 
196
        self._serializer = _format._serializer
186
197
 
187
198
    @needs_read_lock
188
199
    def _all_possible_ids(self):
193
204
 
194
205
    @needs_read_lock
195
206
    def _all_revision_ids(self):
196
 
        """Returns a list of all the revision ids in the repository. 
 
207
        """Returns a list of all the revision ids in the repository.
197
208
 
198
 
        These are in as much topological order as the underlying store can 
 
209
        These are in as much topological order as the underlying store can
199
210
        present: for weaves ghosts may lead to a lack of correctness until
200
211
        the reweave updates the parents list.
201
212
        """
256
267
    supports_tree_reference = False
257
268
    supports_ghosts = False
258
269
    supports_external_lookups = False
 
270
    supports_chks = False
 
271
    _fetch_order = 'topological'
 
272
    _fetch_reconcile = True
 
273
    fast_deltas = False
259
274
 
260
275
    def initialize(self, a_bzrdir, shared=False, _internal=False):
261
276
        """Create a weave repository."""
265
280
        if not _internal:
266
281
            # always initialized when the bzrdir is.
267
282
            return self.open(a_bzrdir, _found=True)
268
 
        
 
283
 
269
284
        # Create an empty weave
270
285
        sio = StringIO()
271
286
        weavefile.write_weave_v5(weave.Weave(), sio)
272
287
        empty_weave = sio.getvalue()
273
288
 
274
289
        mutter('creating repository in %s.', a_bzrdir.transport.base)
275
 
        
 
290
 
276
291
        # FIXME: RBC 20060125 don't peek under the covers
277
292
        # NB: no need to escape relative paths that are url safe.
278
293
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
283
298
        try:
284
299
            transport.mkdir_multi(['revision-store', 'weaves'],
285
300
                mode=a_bzrdir._get_dir_mode())
286
 
            transport.put_bytes_non_atomic('inventory.weave', empty_weave)
 
301
            transport.put_bytes_non_atomic('inventory.weave', empty_weave,
 
302
                mode=a_bzrdir._get_file_mode())
287
303
        finally:
288
304
            control_files.unlock()
289
305
        return self.open(a_bzrdir, _found=True)
301
317
        result.signatures = self._get_signatures(repo_transport, result)
302
318
        result.inventories = self._get_inventories(repo_transport, result)
303
319
        result.texts = self._get_texts(repo_transport, result)
 
320
        result.chk_bytes = None
304
321
        return result
305
322
 
306
 
    def check_conversion_target(self, target_format):
307
 
        pass
308
 
 
309
323
 
310
324
class RepositoryFormat4(PreSplitOutRepositoryFormat):
311
325
    """Bzr repository format 4.
321
335
 
322
336
    _matchingbzrdir = bzrdir.BzrDirFormat4()
323
337
 
324
 
    def __init__(self):
325
 
        super(RepositoryFormat4, self).__init__()
326
 
        self._fetch_order = 'topological'
327
 
        self._fetch_reconcile = True
328
 
 
329
338
    def get_format_description(self):
330
339
        """See RepositoryFormat.get_format_description()."""
331
340
        return "Repository format 4"
338
347
        """Format 4 is not supported.
339
348
 
340
349
        It is not supported because the model changed from 4 to 5 and the
341
 
        conversion logic is expensive - so doing it on the fly was not 
 
350
        conversion logic is expensive - so doing it on the fly was not
342
351
        feasible.
343
352
        """
344
353
        return False
373
382
 
374
383
    _versionedfile_class = weave.WeaveFile
375
384
    _matchingbzrdir = bzrdir.BzrDirFormat5()
376
 
 
377
 
    def __init__(self):
378
 
        super(RepositoryFormat5, self).__init__()
379
 
        self._fetch_order = 'topological'
380
 
        self._fetch_reconcile = True
 
385
    @property
 
386
    def _serializer(self):
 
387
        return xml5.serializer_v5
381
388
 
382
389
    def get_format_description(self):
383
390
        """See RepositoryFormat.get_format_description()."""
384
391
        return "Weave repository format 5"
385
392
 
 
393
    def network_name(self):
 
394
        """The network name for this format is the control dirs disk label."""
 
395
        return self._matchingbzrdir.get_format_string()
 
396
 
386
397
    def _get_inventories(self, repo_transport, repo, name='inventory'):
387
398
        mapper = versionedfile.ConstantMapper(name)
388
399
        return versionedfile.ThunkedVersionedFiles(repo_transport,
389
400
            weave.WeaveFile, mapper, repo.is_locked)
390
401
 
391
402
    def _get_revisions(self, repo_transport, repo):
392
 
        from bzrlib.xml5 import serializer_v5
393
403
        return RevisionTextStore(repo_transport.clone('revision-store'),
394
 
            serializer_v5, False, versionedfile.PrefixMapper(),
 
404
            xml5.serializer_v5, False, versionedfile.PrefixMapper(),
395
405
            repo.is_locked, repo.is_write_locked)
396
406
 
397
407
    def _get_signatures(self, repo_transport, repo):
417
427
 
418
428
    _versionedfile_class = weave.WeaveFile
419
429
    _matchingbzrdir = bzrdir.BzrDirFormat6()
420
 
 
421
 
    def __init__(self):
422
 
        super(RepositoryFormat6, self).__init__()
423
 
        self._fetch_order = 'topological'
424
 
        self._fetch_reconcile = True
 
430
    @property
 
431
    def _serializer(self):
 
432
        return xml5.serializer_v5
425
433
 
426
434
    def get_format_description(self):
427
435
        """See RepositoryFormat.get_format_description()."""
428
436
        return "Weave repository format 6"
429
437
 
 
438
    def network_name(self):
 
439
        """The network name for this format is the control dirs disk label."""
 
440
        return self._matchingbzrdir.get_format_string()
 
441
 
430
442
    def _get_inventories(self, repo_transport, repo, name='inventory'):
431
443
        mapper = versionedfile.ConstantMapper(name)
432
444
        return versionedfile.ThunkedVersionedFiles(repo_transport,
433
445
            weave.WeaveFile, mapper, repo.is_locked)
434
446
 
435
447
    def _get_revisions(self, repo_transport, repo):
436
 
        from bzrlib.xml5 import serializer_v5
437
448
        return RevisionTextStore(repo_transport.clone('revision-store'),
438
 
            serializer_v5, False, versionedfile.HashPrefixMapper(),
 
449
            xml5.serializer_v5, False, versionedfile.HashPrefixMapper(),
439
450
            repo.is_locked, repo.is_write_locked)
440
451
 
441
452
    def _get_signatures(self, repo_transport, repo):
464
475
 
465
476
    _versionedfile_class = weave.WeaveFile
466
477
    supports_ghosts = False
 
478
    supports_chks = False
 
479
 
 
480
    _fetch_order = 'topological'
 
481
    _fetch_reconcile = True
 
482
    fast_deltas = False
 
483
    @property
 
484
    def _serializer(self):
 
485
        return xml5.serializer_v5
467
486
 
468
487
    def get_format_string(self):
469
488
        """See RepositoryFormat.get_format_string()."""
473
492
        """See RepositoryFormat.get_format_description()."""
474
493
        return "Weave repository format 7"
475
494
 
476
 
    def check_conversion_target(self, target_format):
477
 
        pass
478
 
 
479
495
    def _get_inventories(self, repo_transport, repo, name='inventory'):
480
496
        mapper = versionedfile.ConstantMapper(name)
481
497
        return versionedfile.ThunkedVersionedFiles(repo_transport,
482
498
            weave.WeaveFile, mapper, repo.is_locked)
483
499
 
484
500
    def _get_revisions(self, repo_transport, repo):
485
 
        from bzrlib.xml5 import serializer_v5
486
501
        return RevisionTextStore(repo_transport.clone('revision-store'),
487
 
            serializer_v5, True, versionedfile.HashPrefixMapper(),
 
502
            xml5.serializer_v5, True, versionedfile.HashPrefixMapper(),
488
503
            repo.is_locked, repo.is_write_locked)
489
504
 
490
505
    def _get_signatures(self, repo_transport, repo):
511
526
 
512
527
        mutter('creating repository in %s.', a_bzrdir.transport.base)
513
528
        dirs = ['revision-store', 'weaves']
514
 
        files = [('inventory.weave', StringIO(empty_weave)), 
 
529
        files = [('inventory.weave', StringIO(empty_weave)),
515
530
                 ]
516
531
        utf8_files = [('format', self.get_format_string())]
517
 
 
 
532
 
518
533
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
519
534
        return self.open(a_bzrdir=a_bzrdir, _found=True)
520
535
 
521
536
    def open(self, a_bzrdir, _found=False, _override_transport=None):
522
537
        """See RepositoryFormat.open().
523
 
        
 
538
 
524
539
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
525
540
                                    repository at a slightly different url
526
541
                                    than normal. I.e. during 'upgrade'.
539
554
        result.signatures = self._get_signatures(repo_transport, result)
540
555
        result.inventories = self._get_inventories(repo_transport, result)
541
556
        result.texts = self._get_texts(repo_transport, result)
 
557
        result.chk_bytes = None
542
558
        result._transport = repo_transport
543
559
        return result
544
560
 
647
663
                continue
648
664
            result[key] = parents
649
665
        return result
650
 
    
 
666
 
 
667
    def get_known_graph_ancestry(self, keys):
 
668
        """Get a KnownGraph instance with the ancestry of keys."""
 
669
        keys = self.keys()
 
670
        parent_map = self.get_parent_map(keys)
 
671
        kg = _mod_graph.KnownGraph(parent_map)
 
672
        return kg
 
673
 
651
674
    def get_record_stream(self, keys, sort_order, include_delta_closure):
652
675
        for key in keys:
653
676
            text, parents = self._load_text_parents(key)
687
710
                continue
688
711
            result[key] = None
689
712
        return result
690
 
    
 
713
 
691
714
    def get_record_stream(self, keys, sort_order, include_delta_closure):
692
715
        for key in keys:
693
716
            text = self._load_text(key)