~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
722
722
        :return: A Pack object, or None if nothing was copied.
723
723
        """
724
724
        # open a pack - using the same name as the last temporary file
725
 
        # - which has already been flushed, so its safe.
 
725
        # - which has already been flushed, so it's safe.
726
726
        # XXX: - duplicate code warning with start_write_group; fix before
727
727
        #      considering 'done'.
728
728
        if self._pack_collection._new_pack is not None:
1222
1222
    def _process_inventory_lines(self, inv_lines):
1223
1223
        """Generate a text key reference map rather for reconciling with."""
1224
1224
        repo = self._pack_collection.repo
1225
 
        refs = repo._find_text_key_references_from_xml_inventory_lines(
1226
 
            inv_lines)
 
1225
        refs = repo._serializer._find_text_key_references(inv_lines)
1227
1226
        self._text_refs = refs
1228
1227
        # during reconcile we:
1229
1228
        #  - convert unreferenced texts to full texts
1292
1291
        # reinserted, and if d3 has incorrect parents it will also be
1293
1292
        # reinserted. If we insert d3 first, d2 is present (as it was bulk
1294
1293
        # copied), so we will try to delta, but d2 is not currently able to be
1295
 
        # extracted because it's basis d1 is not present. Topologically sorting
 
1294
        # extracted because its basis d1 is not present. Topologically sorting
1296
1295
        # addresses this. The following generates a sort for all the texts that
1297
1296
        # are being inserted without having to reference the entire text key
1298
1297
        # space (we only topo sort the revisions, which is smaller).
1573
1572
        mutter('Packing repository %s, which has %d pack files, '
1574
1573
            'containing %d revisions with hint %r.', self, total_packs,
1575
1574
            total_revisions, hint)
 
1575
        while True:
 
1576
            try:
 
1577
                self._try_pack_operations(hint)
 
1578
            except RetryPackOperations:
 
1579
                continue
 
1580
            break
 
1581
 
 
1582
        if clean_obsolete_packs:
 
1583
            self._clear_obsolete_packs()
 
1584
 
 
1585
    def _try_pack_operations(self, hint):
 
1586
        """Calculate the pack operations based on the hint (if any), and
 
1587
        execute them.
 
1588
        """
1576
1589
        # determine which packs need changing
1577
1590
        pack_operations = [[0, []]]
1578
1591
        for pack in self.all_packs():
1581
1594
                # or this pack was included in the hint.
1582
1595
                pack_operations[-1][0] += pack.get_revision_count()
1583
1596
                pack_operations[-1][1].append(pack)
1584
 
        self._execute_pack_operations(pack_operations, OptimisingPacker)
1585
 
 
1586
 
        if clean_obsolete_packs:
1587
 
            self._clear_obsolete_packs()
 
1597
        self._execute_pack_operations(pack_operations, OptimisingPacker,
 
1598
            reload_func=self._restart_pack_operations)
1588
1599
 
1589
1600
    def plan_autopack_combinations(self, existing_packs, pack_distribution):
1590
1601
        """Plan a pack operation.
1600
1611
        pack_operations = [[0, []]]
1601
1612
        # plan out what packs to keep, and what to reorganise
1602
1613
        while len(existing_packs):
1603
 
            # take the largest pack, and if its less than the head of the
 
1614
            # take the largest pack, and if it's less than the head of the
1604
1615
            # distribution chart we will include its contents in the new pack
1605
 
            # for that position. If its larger, we remove its size from the
 
1616
            # for that position. If it's larger, we remove its size from the
1606
1617
            # distribution chart
1607
1618
            next_pack_rev_count, next_pack = existing_packs.pop(0)
1608
1619
            if next_pack_rev_count >= pack_distribution[0]:
1643
1654
 
1644
1655
        :return: True if the disk names had not been previously read.
1645
1656
        """
1646
 
        # NB: if you see an assertion error here, its probably access against
 
1657
        # NB: if you see an assertion error here, it's probably access against
1647
1658
        # an unlocked repo. Naughty.
1648
1659
        if not self.repo.is_locked():
1649
1660
            raise errors.ObjectNotLocked(self.repo)
1946
1957
                    # disk index because the set values are the same, unless
1947
1958
                    # the only index shows up as deleted by the set difference
1948
1959
                    # - which it may. Until there is a specific test for this,
1949
 
                    # assume its broken. RBC 20071017.
 
1960
                    # assume it's broken. RBC 20071017.
1950
1961
                    self._remove_pack_from_memory(self.get_pack_by_name(name))
1951
1962
                    self._names[name] = sizes
1952
1963
                    self.get_pack_by_name(name)
2017
2028
        """
2018
2029
        # The ensure_loaded call is to handle the case where the first call
2019
2030
        # made involving the collection was to reload_pack_names, where we 
2020
 
        # don't have a view of disk contents. Its a bit of a bandaid, and
2021
 
        # causes two reads of pack-names, but its a rare corner case not struck
2022
 
        # with regular push/pull etc.
 
2031
        # don't have a view of disk contents. It's a bit of a bandaid, and
 
2032
        # causes two reads of pack-names, but it's a rare corner case not
 
2033
        # struck with regular push/pull etc.
2023
2034
        first_read = self.ensure_loaded()
2024
2035
        if first_read:
2025
2036
            return True
2044
2055
            raise
2045
2056
        raise errors.RetryAutopack(self.repo, False, sys.exc_info())
2046
2057
 
 
2058
    def _restart_pack_operations(self):
 
2059
        """Reload the pack names list, and restart the autopack code."""
 
2060
        if not self.reload_pack_names():
 
2061
            # Re-raise the original exception, because something went missing
 
2062
            # and a restart didn't find it
 
2063
            raise
 
2064
        raise RetryPackOperations(self.repo, False, sys.exc_info())
 
2065
 
2047
2066
    def _clear_obsolete_packs(self, preserve=None):
2048
2067
        """Delete everything from the obsolete-packs directory.
2049
2068
 
2284
2303
        self._reconcile_fixes_text_parents = True
2285
2304
        self._reconcile_backsup_inventory = False
2286
2305
 
2287
 
    def _warn_if_deprecated(self, branch=None):
2288
 
        # This class isn't deprecated, but one sub-format is
2289
 
        if isinstance(self._format, RepositoryFormatKnitPack5RichRootBroken):
2290
 
            super(KnitPackRepository, self)._warn_if_deprecated(branch)
2291
 
 
2292
2306
    def _abort_write_group(self):
2293
2307
        self.revisions._index._key_dependencies.clear()
2294
2308
        self._pack_collection._abort_write_group()
2456
2470
        from_repo = self.from_repository
2457
2471
        parent_ids = from_repo._find_parent_ids_of_revisions(revision_ids)
2458
2472
        parent_keys = [(p,) for p in parent_ids]
2459
 
        find_text_keys = from_repo._find_text_key_references_from_xml_inventory_lines
 
2473
        find_text_keys = from_repo._serializer._find_text_key_references
2460
2474
        parent_text_keys = set(find_text_keys(
2461
2475
            from_repo._inventory_xml_lines_for_keys(parent_keys)))
2462
2476
        content_text_keys = set()
2544
2558
    index_class = None
2545
2559
    _fetch_uses_deltas = True
2546
2560
    fast_deltas = False
 
2561
    supports_full_versioned_files = True
 
2562
    supports_funky_characters = True
2547
2563
 
2548
2564
    def initialize(self, a_bzrdir, shared=False):
2549
2565
        """Create a pack based repository.
2819
2835
        return ("Packs 5 rich-root (adds stacking support, requires bzr 1.6)"
2820
2836
                " (deprecated)")
2821
2837
 
 
2838
    def is_deprecated(self):
 
2839
        return True
 
2840
 
2822
2841
 
2823
2842
class RepositoryFormatKnitPack6(RepositoryFormatPack):
2824
2843
    """A repository with stacking and btree indexes,
2894
2913
class RepositoryFormatPackDevelopment2Subtree(RepositoryFormatPack):
2895
2914
    """A subtrees development repository.
2896
2915
 
2897
 
    This format should be retained until the second release after bzr 1.7.
 
2916
    This format should be retained in 2.3, to provide an upgrade path from this
 
2917
    to RepositoryFormat2aSubtree.  It can be removed in later releases.
2898
2918
 
2899
2919
    1.6.1-subtree[as it might have been] with B+Tree indices.
2900
 
 
2901
 
    This is [now] retained until we have a CHK based subtree format in
2902
 
    development.
2903
2920
    """
2904
2921
 
2905
2922
    repository_class = KnitPackRepository
2935
2952
        return ("Development repository format, currently the same as "
2936
2953
            "1.6.1-subtree with B+Tree indices.\n")
2937
2954
 
 
2955
 
 
2956
class RetryPackOperations(errors.RetryWithNewPacks):
 
2957
    """Raised when we are packing and we find a missing file.
 
2958
 
 
2959
    Meant as a signaling exception, to tell the RepositoryPackCollection.pack
 
2960
    code it should try again.
 
2961
    """
 
2962
 
 
2963
    internal_error = True
 
2964
 
 
2965
    _fmt = ("Pack files have changed, reload and try pack again."
 
2966
            " context: %(context)s %(orig_error)s")
 
2967
 
 
2968