~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

(robertc) Pack 2a repositories after fetching from a different format
        (bug 376748) and fix problems with autopacking 2a repositories
        (bug 365615). (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1459
1459
        in synchronisation with certain steps. Otherwise the names collection
1460
1460
        is not flushed.
1461
1461
 
1462
 
        :return: True if packing took place.
 
1462
        :return: Something evaluating true if packing took place.
1463
1463
        """
1464
1464
        while True:
1465
1465
            try:
1466
1466
                return self._do_autopack()
1467
 
            except errors.RetryAutopack, e:
 
1467
            except errors.RetryAutopack:
1468
1468
                # If we get a RetryAutopack exception, we should abort the
1469
1469
                # current action, and retry.
1470
1470
                pass
1474
1474
        total_revisions = self.revision_index.combined_index.key_count()
1475
1475
        total_packs = len(self._names)
1476
1476
        if self._max_pack_count(total_revisions) >= total_packs:
1477
 
            return False
 
1477
            return None
1478
1478
        # determine which packs need changing
1479
1479
        pack_distribution = self.pack_distribution(total_revisions)
1480
1480
        existing_packs = []
1502
1502
            'containing %d revisions. Packing %d files into %d affecting %d'
1503
1503
            ' revisions', self, total_packs, total_revisions, num_old_packs,
1504
1504
            num_new_packs, num_revs_affected)
1505
 
        self._execute_pack_operations(pack_operations,
 
1505
        result = self._execute_pack_operations(pack_operations,
1506
1506
                                      reload_func=self._restart_autopack)
1507
1507
        mutter('Auto-packing repository %s completed', self)
1508
 
        return True
 
1508
        return result
1509
1509
 
1510
1510
    def _execute_pack_operations(self, pack_operations, _packer_class=Packer,
1511
1511
                                 reload_func=None):
1513
1513
 
1514
1514
        :param pack_operations: A list of [revision_count, packs_to_combine].
1515
1515
        :param _packer_class: The class of packer to use (default: Packer).
1516
 
        :return: None.
 
1516
        :return: The new pack names.
1517
1517
        """
1518
1518
        for revision_count, packs in pack_operations:
1519
1519
            # we may have no-ops from the setup logic
1535
1535
                self._remove_pack_from_memory(pack)
1536
1536
        # record the newly available packs and stop advertising the old
1537
1537
        # packs
1538
 
        self._save_pack_names(clear_obsolete_packs=True)
 
1538
        result = self._save_pack_names(clear_obsolete_packs=True)
1539
1539
        # Move the old packs out of the way now they are no longer referenced.
1540
1540
        for revision_count, packs in pack_operations:
1541
1541
            self._obsolete_packs(packs)
 
1542
        return result
1542
1543
 
1543
1544
    def _flush_new_pack(self):
1544
1545
        if self._new_pack is not None:
1554
1555
 
1555
1556
    def _already_packed(self):
1556
1557
        """Is the collection already packed?"""
1557
 
        return len(self._names) < 2
 
1558
        return not (self.repo._format.pack_compresses or (len(self._names) > 1))
1558
1559
 
1559
 
    def pack(self):
 
1560
    def pack(self, hint=None):
1560
1561
        """Pack the pack collection totally."""
1561
1562
        self.ensure_loaded()
1562
1563
        total_packs = len(self._names)
1563
1564
        if self._already_packed():
1564
 
            # This is arguably wrong because we might not be optimal, but for
1565
 
            # now lets leave it in. (e.g. reconcile -> one pack. But not
1566
 
            # optimal.
1567
1565
            return
1568
1566
        total_revisions = self.revision_index.combined_index.key_count()
1569
1567
        # XXX: the following may want to be a class, to pack with a given
1570
1568
        # policy.
1571
1569
        mutter('Packing repository %s, which has %d pack files, '
1572
 
            'containing %d revisions into 1 packs.', self, total_packs,
1573
 
            total_revisions)
 
1570
            'containing %d revisions with hint %r.', self, total_packs,
 
1571
            total_revisions, hint)
1574
1572
        # determine which packs need changing
1575
 
        pack_distribution = [1]
1576
1573
        pack_operations = [[0, []]]
1577
1574
        for pack in self.all_packs():
1578
 
            pack_operations[-1][0] += pack.get_revision_count()
1579
 
            pack_operations[-1][1].append(pack)
 
1575
            if not hint or pack.name in hint:
 
1576
                pack_operations[-1][0] += pack.get_revision_count()
 
1577
                pack_operations[-1][1].append(pack)
1580
1578
        self._execute_pack_operations(pack_operations, OptimisingPacker)
1581
1579
 
1582
1580
    def plan_autopack_combinations(self, existing_packs, pack_distribution):
1938
1936
 
1939
1937
        :param clear_obsolete_packs: If True, clear out the contents of the
1940
1938
            obsolete_packs directory.
 
1939
        :return: A list of the names saved that were not previously on disk.
1941
1940
        """
1942
1941
        self.lock_names()
1943
1942
        try:
1958
1957
            self._unlock_names()
1959
1958
        # synchronise the memory packs list with what we just wrote:
1960
1959
        self._syncronize_pack_names_from_disk_nodes(disk_nodes)
 
1960
        return [new_node[0][0] for new_node in new_nodes]
1961
1961
 
1962
1962
    def reload_pack_names(self):
1963
1963
        """Sync our pack listing with what is present in the repository.
2097
2097
            if not self.autopack():
2098
2098
                # when autopack takes no steps, the names list is still
2099
2099
                # unsaved.
2100
 
                self._save_pack_names()
 
2100
                return self._save_pack_names()
2101
2101
 
2102
2102
    def _suspend_write_group(self):
2103
2103
        tokens = [pack.name for pack in self._resumed_packs]
2348
2348
        raise NotImplementedError(self.dont_leave_lock_in_place)
2349
2349
 
2350
2350
    @needs_write_lock
2351
 
    def pack(self):
 
2351
    def pack(self, hint=None):
2352
2352
        """Compress the data within the repository.
2353
2353
 
2354
2354
        This will pack all the data to a single pack. In future it may
2355
2355
        recompress deltas or do other such expensive operations.
2356
2356
        """
2357
 
        self._pack_collection.pack()
 
2357
        self._pack_collection.pack(hint=hint)
2358
2358
 
2359
2359
    @needs_write_lock
2360
2360
    def reconcile(self, other=None, thorough=False):