/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

Add RepositoryPackCollection.reload_pack_names()

This refactors the _save_pack_names code into helper functions, and
exposes a public member for outside entities to call to refresh the
list. It updates the internal names and also re-updates the various
indexes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1553
1553
        """Release the mutex around the pack-names index."""
1554
1554
        self.repo.control_files.unlock()
1555
1555
 
1556
 
    def _save_pack_names(self, clear_obsolete_packs=False):
1557
 
        """Save the list of packs.
1558
 
 
1559
 
        This will take out the mutex around the pack names list for the
1560
 
        duration of the method call. If concurrent updates have been made, a
1561
 
        three-way merge between the current list and the current in memory list
1562
 
        is performed.
1563
 
 
1564
 
        :param clear_obsolete_packs: If True, clear out the contents of the
1565
 
            obsolete_packs directory.
1566
 
        """
1567
 
        self.lock_names()
1568
 
        try:
1569
 
            builder = self._index_builder_class()
1570
 
            # load the disk nodes across
1571
 
            disk_nodes = set()
1572
 
            for index, key, value in self._iter_disk_pack_index():
1573
 
                disk_nodes.add((key, value))
1574
 
            # do a two-way diff against our original content
1575
 
            current_nodes = set()
1576
 
            for name, sizes in self._names.iteritems():
1577
 
                current_nodes.add(
1578
 
                    ((name, ), ' '.join(str(size) for size in sizes)))
1579
 
            deleted_nodes = self._packs_at_load - current_nodes
1580
 
            new_nodes = current_nodes - self._packs_at_load
1581
 
            disk_nodes.difference_update(deleted_nodes)
1582
 
            disk_nodes.update(new_nodes)
1583
 
            # TODO: handle same-name, index-size-changes here - 
1584
 
            # e.g. use the value from disk, not ours, *unless* we're the one
1585
 
            # changing it.
1586
 
            for key, value in disk_nodes:
1587
 
                builder.add_node(key, value)
1588
 
            self.transport.put_file('pack-names', builder.finish(),
1589
 
                mode=self.repo.bzrdir._get_file_mode())
1590
 
            # move the baseline forward
1591
 
            self._packs_at_load = disk_nodes
1592
 
            if clear_obsolete_packs:
1593
 
                self._clear_obsolete_packs()
1594
 
        finally:
1595
 
            self._unlock_names()
1596
 
        # synchronise the memory packs list with what we just wrote:
 
1556
    def _diff_pack_names(self):
 
1557
        """Read the pack names from disk, and compare it to the one in memory.
 
1558
 
 
1559
        :return: (disk_nodes, deleted_nodes, new_nodes)
 
1560
            disk_nodes    The final set of nodes that should be referenced
 
1561
            deleted_nodes Nodes which have been removed from when we started
 
1562
            new_nodes     Nodes that are newly introduced
 
1563
        """
 
1564
        # load the disk nodes across
 
1565
        disk_nodes = set()
 
1566
        for index, key, value in self._iter_disk_pack_index():
 
1567
            disk_nodes.add((key, value))
 
1568
 
 
1569
        # do a two-way diff against our original content
 
1570
        current_nodes = set()
 
1571
        for name, sizes in self._names.iteritems():
 
1572
            current_nodes.add(
 
1573
                ((name, ), ' '.join(str(size) for size in sizes)))
 
1574
 
 
1575
        # Packs no longer present in the repository, which were present when we
 
1576
        # locked the repository
 
1577
        deleted_nodes = self._packs_at_load - current_nodes
 
1578
        # Packs which this process is adding
 
1579
        new_nodes = current_nodes - self._packs_at_load
 
1580
 
 
1581
        # Update the disk_nodes set to include the ones we are adding, and
 
1582
        # remove the ones which were removed by someone else
 
1583
        disk_nodes.difference_update(deleted_nodes)
 
1584
        disk_nodes.update(new_nodes)
 
1585
 
 
1586
        return disk_nodes, deleted_nodes, new_nodes
 
1587
 
 
1588
    def _syncronize_pack_names_from_disk_nodes(self, disk_nodes):
 
1589
        """Given the correct set of pack files, update our saved info.
 
1590
 
 
1591
        :return: (removed, added, modified)
 
1592
            removed     pack names removed from self._names
 
1593
            added       pack names added to self._names
 
1594
            modified    pack names that had changed value
 
1595
        """
 
1596
        removed = []
 
1597
        added = []
 
1598
        modified = []
 
1599
        ## self._packs_at_load = disk_nodes
1597
1600
        new_names = dict(disk_nodes)
1598
1601
        # drop no longer present nodes
1599
1602
        for pack in self.all_packs():
1600
1603
            if (pack.name,) not in new_names:
 
1604
                removed.append(pack.name)
1601
1605
                self._remove_pack_from_memory(pack)
1602
1606
        # add new nodes/refresh existing ones
1603
1607
        for key, value in disk_nodes:
1617
1621
                    self._remove_pack_from_memory(self.get_pack_by_name(name))
1618
1622
                    self._names[name] = sizes
1619
1623
                    self.get_pack_by_name(name)
 
1624
                    modified.append(name)
1620
1625
            else:
1621
1626
                # new
1622
1627
                self._names[name] = sizes
1623
1628
                self.get_pack_by_name(name)
 
1629
                added.append(name)
 
1630
        return removed, added, modified
 
1631
 
 
1632
    def _save_pack_names(self, clear_obsolete_packs=False):
 
1633
        """Save the list of packs.
 
1634
 
 
1635
        This will take out the mutex around the pack names list for the
 
1636
        duration of the method call. If concurrent updates have been made, a
 
1637
        three-way merge between the current list and the current in memory list
 
1638
        is performed.
 
1639
 
 
1640
        :param clear_obsolete_packs: If True, clear out the contents of the
 
1641
            obsolete_packs directory.
 
1642
        """
 
1643
        self.lock_names()
 
1644
        try:
 
1645
            builder = self._index_builder_class()
 
1646
            disk_nodes, deleted_nodes, new_nodes = self._diff_pack_names()
 
1647
            # TODO: handle same-name, index-size-changes here - 
 
1648
            # e.g. use the value from disk, not ours, *unless* we're the one
 
1649
            # changing it.
 
1650
            for key, value in disk_nodes:
 
1651
                builder.add_node(key, value)
 
1652
            self.transport.put_file('pack-names', builder.finish(),
 
1653
                mode=self.repo.bzrdir._get_file_mode())
 
1654
            # move the baseline forward
 
1655
            self._packs_at_load = disk_nodes
 
1656
            if clear_obsolete_packs:
 
1657
                self._clear_obsolete_packs()
 
1658
        finally:
 
1659
            self._unlock_names()
 
1660
        # synchronise the memory packs list with what we just wrote:
 
1661
        self._syncronize_pack_names_from_disk_nodes(disk_nodes)
 
1662
 
 
1663
    def reload_pack_names(self):
 
1664
        """Sync our pack listing with what is present in the repository.
 
1665
 
 
1666
        This should be called when we find out that something we thought was
 
1667
        present is now missing. This happens when another process re-packs the
 
1668
        repository, etc.
 
1669
        """
 
1670
        # This is functionally similar to _save_pack_names, but we don't write
 
1671
        # out the new value.
 
1672
        disk_nodes, _, _ = self._diff_pack_names()
 
1673
        self._packs_at_load = disk_nodes
 
1674
        return self._syncronize_pack_names_from_disk_nodes(disk_nodes)
1624
1675
 
1625
1676
    def _clear_obsolete_packs(self):
1626
1677
        """Delete everything from the obsolete-packs directory.