~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

  • Committer: Martin Pool
  • Date: 2010-01-12 06:30:41 UTC
  • mfrom: (4634.119.3 2.0)
  • mto: This revision was merged to the branch mainline in revision 4951.
  • Revision ID: mbp@sourcefrog.net-20100112063041-qp2ei0clx5gh0e9e
merge 2.0 back to trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 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
1545
1545
                self._remove_pack_from_memory(pack)
1546
1546
        # record the newly available packs and stop advertising the old
1547
1547
        # packs
1548
 
        to_be_obsoleted = []
1549
 
        for _, packs in pack_operations:
1550
 
            to_be_obsoleted.extend(packs)
1551
 
        result = self._save_pack_names(clear_obsolete_packs=True,
1552
 
                                       obsolete_packs=to_be_obsoleted)
 
1548
        result = self._save_pack_names(clear_obsolete_packs=True)
 
1549
        # Move the old packs out of the way now they are no longer referenced.
 
1550
        for revision_count, packs in pack_operations:
 
1551
            self._obsolete_packs(packs)
1553
1552
        return result
1554
1553
 
1555
1554
    def _flush_new_pack(self):
1789
1788
        :param return: None.
1790
1789
        """
1791
1790
        for pack in packs:
1792
 
            try:
1793
 
                pack.pack_transport.rename(pack.file_name(),
1794
 
                    '../obsolete_packs/' + pack.file_name())
1795
 
            except (errors.PathError, errors.TransportError), e:
1796
 
                # TODO: Should these be warnings or mutters?
1797
 
                mutter("couldn't rename obsolete pack, skipping it:\n%s"
1798
 
                       % (e,))
 
1791
            pack.pack_transport.rename(pack.file_name(),
 
1792
                '../obsolete_packs/' + pack.file_name())
1799
1793
            # TODO: Probably needs to know all possible indices for this pack
1800
1794
            # - or maybe list the directory and move all indices matching this
1801
1795
            # name whether we recognize it or not?
1803
1797
            if self.chk_index is not None:
1804
1798
                suffixes.append('.cix')
1805
1799
            for suffix in suffixes:
1806
 
                try:
1807
 
                    self._index_transport.rename(pack.name + suffix,
1808
 
                        '../obsolete_packs/' + pack.name + suffix)
1809
 
                except (errors.PathError, errors.TransportError), e:
1810
 
                    mutter("couldn't rename obsolete index, skipping it:\n%s"
1811
 
                           % (e,))
 
1800
                self._index_transport.rename(pack.name + suffix,
 
1801
                    '../obsolete_packs/' + pack.name + suffix)
1812
1802
 
1813
1803
    def pack_distribution(self, total_revisions):
1814
1804
        """Generate a list of the number of revisions to put in each pack.
1886
1876
        disk_nodes = set()
1887
1877
        for index, key, value in self._iter_disk_pack_index():
1888
1878
            disk_nodes.add((key, value))
1889
 
        orig_disk_nodes = set(disk_nodes)
1890
1879
 
1891
1880
        # do a two-way diff against our original content
1892
1881
        current_nodes = set()
1905
1894
        disk_nodes.difference_update(deleted_nodes)
1906
1895
        disk_nodes.update(new_nodes)
1907
1896
 
1908
 
        return disk_nodes, deleted_nodes, new_nodes, orig_disk_nodes
 
1897
        return disk_nodes, deleted_nodes, new_nodes
1909
1898
 
1910
1899
    def _syncronize_pack_names_from_disk_nodes(self, disk_nodes):
1911
1900
        """Given the correct set of pack files, update our saved info.
1951
1940
                added.append(name)
1952
1941
        return removed, added, modified
1953
1942
 
1954
 
    def _save_pack_names(self, clear_obsolete_packs=False, obsolete_packs=None):
 
1943
    def _save_pack_names(self, clear_obsolete_packs=False):
1955
1944
        """Save the list of packs.
1956
1945
 
1957
1946
        This will take out the mutex around the pack names list for the
1961
1950
 
1962
1951
        :param clear_obsolete_packs: If True, clear out the contents of the
1963
1952
            obsolete_packs directory.
1964
 
        :param obsolete_packs: Packs that are obsolete once the new pack-names
1965
 
            file has been written.
1966
1953
        :return: A list of the names saved that were not previously on disk.
1967
1954
        """
1968
 
        already_obsolete = []
1969
1955
        self.lock_names()
1970
1956
        try:
1971
1957
            builder = self._index_builder_class()
1972
 
            (disk_nodes, deleted_nodes, new_nodes,
1973
 
             orig_disk_nodes) = self._diff_pack_names()
 
1958
            disk_nodes, deleted_nodes, new_nodes = self._diff_pack_names()
1974
1959
            # TODO: handle same-name, index-size-changes here -
1975
1960
            # e.g. use the value from disk, not ours, *unless* we're the one
1976
1961
            # changing it.
1978
1963
                builder.add_node(key, value)
1979
1964
            self.transport.put_file('pack-names', builder.finish(),
1980
1965
                mode=self.repo.bzrdir._get_file_mode())
 
1966
            # move the baseline forward
1981
1967
            self._packs_at_load = disk_nodes
1982
1968
            if clear_obsolete_packs:
1983
 
                to_preserve = None
1984
 
                if obsolete_packs:
1985
 
                    to_preserve = set([o.name for o in obsolete_packs])
1986
 
                already_obsolete = self._clear_obsolete_packs(to_preserve)
 
1969
                self._clear_obsolete_packs()
1987
1970
        finally:
1988
1971
            self._unlock_names()
1989
1972
        # synchronise the memory packs list with what we just wrote:
1990
1973
        self._syncronize_pack_names_from_disk_nodes(disk_nodes)
1991
 
        if obsolete_packs:
1992
 
            # TODO: We could add one more condition here. "if o.name not in
1993
 
            #       orig_disk_nodes and o != the new_pack we haven't written to
1994
 
            #       disk yet. However, the new pack object is not easily
1995
 
            #       accessible here (it would have to be passed through the
1996
 
            #       autopacking code, etc.)
1997
 
            obsolete_packs = [o for o in obsolete_packs
1998
 
                              if o.name not in already_obsolete]
1999
 
            self._obsolete_packs(obsolete_packs)
2000
1974
        return [new_node[0][0] for new_node in new_nodes]
2001
1975
 
2002
1976
    def reload_pack_names(self):
2017
1991
        if first_read:
2018
1992
            return True
2019
1993
        # out the new value.
2020
 
        (disk_nodes, deleted_nodes, new_nodes,
2021
 
         orig_disk_nodes) = self._diff_pack_names()
2022
 
        # _packs_at_load is meant to be the explicit list of names in
2023
 
        # 'pack-names' at then start. As such, it should not contain any
2024
 
        # pending names that haven't been written out yet.
2025
 
        self._packs_at_load = orig_disk_nodes
 
1994
        disk_nodes, _, _ = self._diff_pack_names()
 
1995
        self._packs_at_load = disk_nodes
2026
1996
        (removed, added,
2027
1997
         modified) = self._syncronize_pack_names_from_disk_nodes(disk_nodes)
2028
1998
        if removed or added or modified:
2037
2007
            raise
2038
2008
        raise errors.RetryAutopack(self.repo, False, sys.exc_info())
2039
2009
 
2040
 
    def _clear_obsolete_packs(self, preserve=None):
 
2010
    def _clear_obsolete_packs(self):
2041
2011
        """Delete everything from the obsolete-packs directory.
2042
 
 
2043
 
        :return: A list of pack identifiers (the filename without '.pack') that
2044
 
            were found in obsolete_packs.
2045
2012
        """
2046
 
        found = []
2047
2013
        obsolete_pack_transport = self.transport.clone('obsolete_packs')
2048
 
        if preserve is None:
2049
 
            preserve = set()
2050
2014
        for filename in obsolete_pack_transport.list_dir('.'):
2051
 
            name, ext = osutils.splitext(filename)
2052
 
            if ext == '.pack':
2053
 
                found.append(name)
2054
 
            if name in preserve:
2055
 
                continue
2056
2015
            try:
2057
2016
                obsolete_pack_transport.delete(filename)
2058
2017
            except (errors.PathError, errors.TransportError), e:
2059
 
                warning("couldn't delete obsolete pack, skipping it:\n%s"
2060
 
                        % (e,))
2061
 
        return found
 
2018
                warning("couldn't delete obsolete pack, skipping it:\n%s" % (e,))
2062
2019
 
2063
2020
    def _start_write_group(self):
2064
2021
        # Do not permit preparation for writing if we're not in a 'write lock'.