~lifeless/bzr/index.range_map

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

  • Committer: Robert Collins
  • Date: 2008-06-19 01:17:19 UTC
  • mfrom: (3218.1.277 +trunk)
  • Revision ID: robertc@robertcollins.net-20080619011719-1c4g4uxzzhdls2wf
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008 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
42
42
""")
43
43
from bzrlib import (
44
44
    bzrdir,
45
 
    deprecated_graph,
46
45
    errors,
47
46
    knit,
48
47
    lockable_files,
61
60
    CommitBuilder,
62
61
    MetaDirRepository,
63
62
    MetaDirRepositoryFormat,
 
63
    RepositoryFormat,
64
64
    RootCommitBuilder,
65
65
    )
66
66
import bzrlib.revision as _mod_revision
67
67
from bzrlib.store.revision.knit import KnitRevisionStore
68
68
from bzrlib.store.versioned import VersionedFileStore
69
 
from bzrlib.trace import mutter, note, warning
 
69
from bzrlib.trace import (
 
70
    mutter,
 
71
    mutter_callsite,
 
72
    note,
 
73
    warning,
 
74
    )
70
75
 
71
76
 
72
77
class PackCommitBuilder(CommitBuilder):
198
203
            signature_index)
199
204
        self.name = name
200
205
        self.pack_transport = pack_transport
201
 
        assert None not in (revision_index, inventory_index, text_index,
202
 
            signature_index, name, pack_transport)
 
206
        if None in (revision_index, inventory_index, text_index,
 
207
                signature_index, name, pack_transport):
 
208
            raise AssertionError()
203
209
 
204
210
    def __eq__(self, other):
205
211
        return self.__dict__ == other.__dict__
322
328
 
323
329
    def access_tuple(self):
324
330
        """Return a tuple (transport, name) for the pack content."""
325
 
        assert self._state in ('open', 'finished')
326
331
        if self._state == 'finished':
327
332
            return Pack.access_tuple(self)
328
 
        else:
 
333
        elif self._state == 'open':
329
334
            return self.upload_transport, self.random_name
 
335
        else:
 
336
            raise AssertionError(self._state)
330
337
 
331
338
    def data_inserted(self):
332
339
        """True if data has been added to this pack."""
495
502
        :param index: An index from the pack parameter.
496
503
        :param pack: A Pack instance.
497
504
        """
498
 
        assert self.add_callback is None, \
499
 
            "%s already has a writable index through %s" % \
500
 
            (self, self.add_callback)
 
505
        if self.add_callback is not None:
 
506
            raise AssertionError(
 
507
                "%s already has a writable index through %s" % \
 
508
                (self, self.add_callback))
501
509
        # allow writing: queue writes to a new index
502
510
        self.add_index(index, pack)
503
511
        # Updates the index to packs mapping as a side effect,
596
604
        return NewPack(self._pack_collection._upload_transport,
597
605
            self._pack_collection._index_transport,
598
606
            self._pack_collection._pack_transport, upload_suffix=self.suffix,
599
 
            file_mode=self._pack_collection.repo.control_files._file_mode)
 
607
            file_mode=self._pack_collection.repo.bzrdir._get_file_mode())
600
608
 
601
609
    def _copy_revision_texts(self):
602
610
        """Copy revision data to the new pack."""
642
650
        # at this point.
643
651
        self.pb.update("Copying inventory texts", 2)
644
652
        total_items, readv_group_iter = self._least_readv_node_readv(inv_nodes)
 
653
        # Only grab the output lines if we will be processing them
 
654
        output_lines = bool(self.revision_ids)
645
655
        inv_lines = self._copy_nodes_graph(inventory_index_map,
646
656
            self.new_pack._writer, self.new_pack.inventory_index,
647
 
            readv_group_iter, total_items, output_lines=True)
 
657
            readv_group_iter, total_items, output_lines=output_lines)
648
658
        if self.revision_ids:
649
659
            self._process_inventory_lines(inv_lines)
650
660
        else:
656
666
                time.ctime(), self._pack_collection._upload_transport.base,
657
667
                self.new_pack.random_name,
658
668
                self.new_pack.inventory_index.key_count(),
659
 
                time.time() - new_pack.start_time)
 
669
                time.time() - self.new_pack.start_time)
660
670
 
661
671
    def _copy_text_texts(self):
662
672
        # select text keys
1059
1069
            deltas=True, parents=True)
1060
1070
        output_knit = knit.KnitVersionedFile('reconcile-texts',
1061
1071
            self._pack_collection.transport,
1062
 
            None,
1063
1072
            index=knit_index,
1064
1073
            access_method=_PackAccess(
1065
1074
                {self.new_pack.text_index:self.new_pack.access_tuple()},
1092
1101
        missing_text_keys = self.new_pack._external_compression_parents_of_texts()
1093
1102
        if missing_text_keys:
1094
1103
            raise errors.BzrError('Reference to missing compression parents %r'
1095
 
                % (refs - keys,))
 
1104
                % (missing_text_keys,))
1096
1105
        self._log_copied_texts()
1097
1106
 
1098
1107
    def _use_pack(self, new_pack):
1148
1157
        
1149
1158
        :param pack: A Pack object.
1150
1159
        """
1151
 
        assert pack.name not in self._packs_by_name
 
1160
        if pack.name in self._packs_by_name:
 
1161
            raise AssertionError()
1152
1162
        self.packs.append(pack)
1153
1163
        self._packs_by_name[pack.name] = pack
1154
1164
        self.revision_index.add_index(pack.revision_index, pack)
1576
1586
            for key, value in disk_nodes:
1577
1587
                builder.add_node(key, value)
1578
1588
            self.transport.put_file('pack-names', builder.finish(),
1579
 
                mode=self.repo.control_files._file_mode)
 
1589
                mode=self.repo.bzrdir._get_file_mode())
1580
1590
            # move the baseline forward
1581
1591
            self._packs_at_load = disk_nodes
1582
 
            # now clear out the obsolete packs directory
1583
1592
            if clear_obsolete_packs:
1584
 
                self.transport.clone('obsolete_packs').delete_multi(
1585
 
                    self.transport.list_dir('obsolete_packs'))
 
1593
                self._clear_obsolete_packs()
1586
1594
        finally:
1587
1595
            self._unlock_names()
1588
1596
        # synchronise the memory packs list with what we just wrote:
1614
1622
                self._names[name] = sizes
1615
1623
                self.get_pack_by_name(name)
1616
1624
 
 
1625
    def _clear_obsolete_packs(self):
 
1626
        """Delete everything from the obsolete-packs directory.
 
1627
        """
 
1628
        obsolete_pack_transport = self.transport.clone('obsolete_packs')
 
1629
        for filename in obsolete_pack_transport.list_dir('.'):
 
1630
            try:
 
1631
                obsolete_pack_transport.delete(filename)
 
1632
            except (errors.PathError, errors.TransportError), e:
 
1633
                warning("couldn't delete obsolete pack, skipping it:\n%s" % (e,))
 
1634
 
1617
1635
    def _start_write_group(self):
1618
1636
        # Do not permit preparation for writing if we're not in a 'write lock'.
1619
1637
        if not self.repo.is_write_locked():
1620
1638
            raise errors.NotWriteLocked(self)
1621
1639
        self._new_pack = NewPack(self._upload_transport, self._index_transport,
1622
1640
            self._pack_transport, upload_suffix='.pack',
1623
 
            file_mode=self.repo.control_files._file_mode)
 
1641
            file_mode=self.repo.bzrdir._get_file_mode())
1624
1642
        # allow writing: queue writes to a new index
1625
1643
        self.revision_index.add_writable_index(self._new_pack.revision_index,
1626
1644
            self._new_pack)
1703
1721
            add_callback=add_callback)
1704
1722
        self.repo._revision_knit = knit.KnitVersionedFile(
1705
1723
            'revisions', self.transport.clone('..'),
1706
 
            self.repo.control_files._file_mode,
1707
 
            create=False, access_mode=self.repo._access_mode(),
 
1724
            self.repo.bzrdir._get_file_mode(),
 
1725
            create=False,
1708
1726
            index=knit_index, delta=False, factory=knit.KnitPlainFactory(),
1709
1727
            access_method=self.repo._pack_collection.revision_index.knit_access)
1710
1728
        return self.repo._revision_knit
1721
1739
            add_callback=add_callback, parents=False)
1722
1740
        self.repo._signature_knit = knit.KnitVersionedFile(
1723
1741
            'signatures', self.transport.clone('..'),
1724
 
            self.repo.control_files._file_mode,
1725
 
            create=False, access_mode=self.repo._access_mode(),
 
1742
            self.repo.bzrdir._get_file_mode(),
 
1743
            create=False,
1726
1744
            index=knit_index, delta=False, factory=knit.KnitPlainFactory(),
1727
1745
            access_method=self.repo._pack_collection.signature_index.knit_access)
1728
1746
        return self.repo._signature_knit
1810
1828
            add_callback=add_callback, deltas=True, parents=True)
1811
1829
        return knit.KnitVersionedFile(
1812
1830
            'inventory', self.transport.clone('..'),
1813
 
            self.repo.control_files._file_mode,
1814
 
            create=False, access_mode=self.repo._access_mode(),
 
1831
            self.repo.bzrdir._get_file_mode(),
 
1832
            create=False,
1815
1833
            index=knit_index, delta=True, factory=knit.KnitPlainFactory(),
1816
1834
            access_method=self.repo._pack_collection.inventory_index.knit_access)
1817
1835
 
1818
1836
 
1819
1837
class KnitPackRepository(KnitRepository):
1820
 
    """Experimental graph-knit using repository."""
 
1838
    """Repository with knit objects stored inside pack containers."""
1821
1839
 
1822
1840
    def __init__(self, _format, a_bzrdir, control_files, _revision_store,
1823
1841
        control_store, text_store, _commit_builder_class, _serializer):
1824
1842
        KnitRepository.__init__(self, _format, a_bzrdir, control_files,
1825
1843
            _revision_store, control_store, text_store, _commit_builder_class,
1826
1844
            _serializer)
1827
 
        index_transport = control_files._transport.clone('indices')
1828
 
        self._pack_collection = RepositoryPackCollection(self, control_files._transport,
 
1845
        index_transport = self._transport.clone('indices')
 
1846
        self._pack_collection = RepositoryPackCollection(self,
 
1847
            self._transport,
1829
1848
            index_transport,
1830
 
            control_files._transport.clone('upload'),
1831
 
            control_files._transport.clone('packs'))
 
1849
            self._transport.clone('upload'),
 
1850
            self._transport.clone('packs'))
1832
1851
        self._revision_store = KnitPackRevisionStore(self, index_transport, self._revision_store)
1833
1852
        self.weave_store = KnitPackTextStore(self, index_transport, self.weave_store)
1834
1853
        self._inv_thunk = InventoryKnitThunk(self, index_transport)
1847
1866
    def _abort_write_group(self):
1848
1867
        self._pack_collection._abort_write_group()
1849
1868
 
1850
 
    def _access_mode(self):
1851
 
        """Return 'w' or 'r' for depending on whether a write lock is active.
1852
 
        
1853
 
        This method is a helper for the Knit-thunking support objects.
1854
 
        """
1855
 
        if self.is_write_locked():
1856
 
            return 'w'
1857
 
        return 'r'
1858
 
 
1859
1869
    def _find_inconsistent_revision_parents(self):
1860
1870
        """Find revisions with incorrectly cached parents.
1861
1871
 
1911
1921
        self._pack_collection.ensure_loaded()
1912
1922
        index = self._pack_collection.revision_index.combined_index
1913
1923
        keys = set(keys)
 
1924
        if None in keys:
 
1925
            raise ValueError('get_parent_map(None) is not valid')
1914
1926
        if _mod_revision.NULL_REVISION in keys:
1915
1927
            keys.discard(_mod_revision.NULL_REVISION)
1916
1928
            found_parents = {_mod_revision.NULL_REVISION:()}
2055
2067
    # Set this attribute in derived clases to control the _serializer that the
2056
2068
    # repository objects will have passed to their constructor.
2057
2069
    _serializer = None
 
2070
    # External references are not supported in pack repositories yet.
 
2071
    supports_external_lookups = False
2058
2072
 
2059
2073
    def _get_control_store(self, repo_transport, control_files):
2060
2074
        """Return the control store for this repository."""
2062
2076
            repo_transport,
2063
2077
            prefixed=False,
2064
2078
            file_mode=control_files._file_mode,
2065
 
            versionedfile_class=knit.KnitVersionedFile,
 
2079
            versionedfile_class=knit.make_file_knit,
2066
2080
            versionedfile_kwargs={'factory': knit.KnitPlainFactory()},
2067
2081
            )
2068
2082
 
2073
2087
            file_mode=control_files._file_mode,
2074
2088
            prefixed=False,
2075
2089
            precious=True,
2076
 
            versionedfile_class=knit.KnitVersionedFile,
 
2090
            versionedfile_class=knit.make_file_knit,
2077
2091
            versionedfile_kwargs={'delta': False,
2078
2092
                                  'factory': knit.KnitPlainFactory(),
2079
2093
                                 },
2086
2100
        return self._get_versioned_file_store('knits',
2087
2101
                                  transport,
2088
2102
                                  control_files,
2089
 
                                  versionedfile_class=knit.KnitVersionedFile,
 
2103
                                  versionedfile_class=knit.make_file_knit,
2090
2104
                                  versionedfile_kwargs={
2091
2105
                                      'create_parent_dir': True,
2092
2106
                                      'delay_create': True,
2120
2134
        """
2121
2135
        if not _found:
2122
2136
            format = RepositoryFormat.find_format(a_bzrdir)
2123
 
            assert format.__class__ ==  self.__class__
2124
2137
        if _override_transport is not None:
2125
2138
            repo_transport = _override_transport
2126
2139
        else:
2127
2140
            repo_transport = a_bzrdir.get_repository_transport(None)
2128
2141
        control_files = lockable_files.LockableFiles(repo_transport,
2129
 
                                'lock', lockdir.LockDir)
 
2142
            'lock', lockdir.LockDir)
2130
2143
        text_store = self._get_text_store(repo_transport, control_files)
2131
2144
        control_store = self._get_control_store(repo_transport, control_files)
2132
2145
        _revision_store = self._get_revision_store(repo_transport, control_files)
2249
2262
    def get_format_description(self):
2250
2263
        """See RepositoryFormat.get_format_description()."""
2251
2264
        return "Packs containing knits with rich root support\n"
 
2265
 
 
2266
 
 
2267
class RepositoryFormatPackDevelopment0(RepositoryFormatPack):
 
2268
    """A no-subtrees development repository.
 
2269
 
 
2270
    This format should be retained until the second release after bzr 1.0.
 
2271
 
 
2272
    No changes to the disk behaviour from pack-0.92.
 
2273
    """
 
2274
 
 
2275
    repository_class = KnitPackRepository
 
2276
    _commit_builder_class = PackCommitBuilder
 
2277
    _serializer = xml5.serializer_v5
 
2278
 
 
2279
    def _get_matching_bzrdir(self):
 
2280
        return bzrdir.format_registry.make_bzrdir('development0')
 
2281
 
 
2282
    def _ignore_setting_bzrdir(self, format):
 
2283
        pass
 
2284
 
 
2285
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
 
2286
 
 
2287
    def get_format_string(self):
 
2288
        """See RepositoryFormat.get_format_string()."""
 
2289
        return "Bazaar development format 0 (needs bzr.dev from before 1.3)\n"
 
2290
 
 
2291
    def get_format_description(self):
 
2292
        """See RepositoryFormat.get_format_description()."""
 
2293
        return ("Development repository format, currently the same as "
 
2294
            "pack-0.92\n")
 
2295
 
 
2296
    def check_conversion_target(self, target_format):
 
2297
        pass
 
2298
 
 
2299
 
 
2300
class RepositoryFormatPackDevelopment0Subtree(RepositoryFormatPack):
 
2301
    """A subtrees development repository.
 
2302
 
 
2303
    This format should be retained until the second release after bzr 1.0.
 
2304
 
 
2305
    No changes to the disk behaviour from pack-0.92-subtree.
 
2306
    """
 
2307
 
 
2308
    repository_class = KnitPackRepository
 
2309
    _commit_builder_class = PackRootCommitBuilder
 
2310
    rich_root_data = True
 
2311
    supports_tree_reference = True
 
2312
    _serializer = xml7.serializer_v7
 
2313
 
 
2314
    def _get_matching_bzrdir(self):
 
2315
        return bzrdir.format_registry.make_bzrdir(
 
2316
            'development0-subtree')
 
2317
 
 
2318
    def _ignore_setting_bzrdir(self, format):
 
2319
        pass
 
2320
 
 
2321
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
 
2322
 
 
2323
    def check_conversion_target(self, target_format):
 
2324
        if not target_format.rich_root_data:
 
2325
            raise errors.BadConversionTarget(
 
2326
                'Does not support rich root data.', target_format)
 
2327
        if not getattr(target_format, 'supports_tree_reference', False):
 
2328
            raise errors.BadConversionTarget(
 
2329
                'Does not support nested trees', target_format)
 
2330
            
 
2331
    def get_format_string(self):
 
2332
        """See RepositoryFormat.get_format_string()."""
 
2333
        return ("Bazaar development format 0 with subtree support "
 
2334
            "(needs bzr.dev from before 1.3)\n")
 
2335
 
 
2336
    def get_format_description(self):
 
2337
        """See RepositoryFormat.get_format_description()."""
 
2338
        return ("Development repository format, currently the same as "
 
2339
            "pack-0.92-subtree\n")
 
2340
 
 
2341