~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

  • Committer: Mark Hammond
  • Date: 2008-12-28 05:21:23 UTC
  • mfrom: (3920 +trunk)
  • mto: (3932.1.1 prepare-1.11)
  • mto: This revision was merged to the branch mainline in revision 3937.
  • Revision ID: mhammond@skippinet.com.au-20081228052123-f78xs5sbdkotshwf
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
 
17
import sys
 
18
 
17
19
from bzrlib.lazy_import import lazy_import
18
20
lazy_import(globals(), """
19
21
from itertools import izip
555
557
class Packer(object):
556
558
    """Create a pack from packs."""
557
559
 
558
 
    def __init__(self, pack_collection, packs, suffix, revision_ids=None):
 
560
    def __init__(self, pack_collection, packs, suffix, revision_ids=None,
 
561
                 reload_func=None):
559
562
        """Create a Packer.
560
563
 
561
564
        :param pack_collection: A RepositoryPackCollection object where the
563
566
        :param packs: The packs to combine.
564
567
        :param suffix: The suffix to use on the temporary files for the pack.
565
568
        :param revision_ids: Revision ids to limit the pack to.
 
569
        :param reload_func: A function to call if a pack file/index goes
 
570
            missing. The side effect of calling this function should be to
 
571
            update self.packs. See also AggregateIndex
566
572
        """
567
573
        self.packs = packs
568
574
        self.suffix = suffix
570
576
        # The pack object we are creating.
571
577
        self.new_pack = None
572
578
        self._pack_collection = pack_collection
 
579
        self._reload_func = reload_func
573
580
        # The index layer keys for the revisions being copied. None for 'all
574
581
        # objects'.
575
582
        self._revision_keys = None
629
636
        # XXX: - duplicate code warning with start_write_group; fix before
630
637
        #      considering 'done'.
631
638
        if self._pack_collection._new_pack is not None:
632
 
            raise errors.BzrError('call to create_pack_from_packs while '
633
 
                'another pack is being written.')
 
639
            raise errors.BzrError('call to %s.pack() while another pack is'
 
640
                                  ' being written.'
 
641
                                  % (self.__class__.__name__,))
634
642
        if self.revision_ids is not None:
635
643
            if len(self.revision_ids) == 0:
636
644
                # silly fetch request.
861
869
            # copy the data
862
870
            pack_obj = index_map[index]
863
871
            transport, path = pack_obj.access_tuple()
864
 
            reader = pack.make_readv_reader(transport, path,
865
 
                [offset[0:2] for offset in pack_readv_requests])
 
872
            try:
 
873
                reader = pack.make_readv_reader(transport, path,
 
874
                    [offset[0:2] for offset in pack_readv_requests])
 
875
            except errors.NoSuchFile:
 
876
                if self._reload_func is not None:
 
877
                    self._reload_func()
 
878
                raise
866
879
            for (names, read_func), (_1, _2, (key, eol_flag)) in \
867
880
                izip(reader.iter_records(), pack_readv_requests):
868
881
                raw_data = read_func(None)
906
919
            # copy the data
907
920
            pack_obj = index_map[index]
908
921
            transport, path = pack_obj.access_tuple()
909
 
            reader = pack.make_readv_reader(transport, path, readv_vector)
 
922
            try:
 
923
                reader = pack.make_readv_reader(transport, path, readv_vector)
 
924
            except errors.NoSuchFile:
 
925
                if self._reload_func is not None:
 
926
                    self._reload_func()
 
927
                raise
910
928
            for (names, read_func), (key, eol_flag, references) in \
911
929
                izip(reader.iter_records(), node_vector):
912
930
                raw_data = read_func(None)
1275
1293
 
1276
1294
        :return: True if packing took place.
1277
1295
        """
 
1296
        while True:
 
1297
            try:
 
1298
                return self._do_autopack()
 
1299
            except errors.RetryAutopack, e:
 
1300
                # If we get a RetryAutopack exception, we should abort the
 
1301
                # current action, and retry.
 
1302
                pass
 
1303
 
 
1304
    def _do_autopack(self):
1278
1305
        # XXX: Should not be needed when the management of indices is sane.
1279
1306
        total_revisions = self.revision_index.combined_index.key_count()
1280
1307
        total_packs = len(self._names)
1309
1336
            'containing %d revisions. Packing %d files into %d affecting %d'
1310
1337
            ' revisions', self, total_packs, total_revisions, num_old_packs,
1311
1338
            num_new_packs, num_revs_affected)
1312
 
        self._execute_pack_operations(pack_operations)
 
1339
        self._execute_pack_operations(pack_operations,
 
1340
                                      reload_func=self._restart_autopack)
1313
1341
        return True
1314
1342
 
1315
 
    def _execute_pack_operations(self, pack_operations, _packer_class=Packer):
 
1343
    def _execute_pack_operations(self, pack_operations, _packer_class=Packer,
 
1344
                                 reload_func=None):
1316
1345
        """Execute a series of pack operations.
1317
1346
 
1318
1347
        :param pack_operations: A list of [revision_count, packs_to_combine].
1323
1352
            # we may have no-ops from the setup logic
1324
1353
            if len(packs) == 0:
1325
1354
                continue
1326
 
            _packer_class(self, packs, '.autopack').pack()
 
1355
            packer = _packer_class(self, packs, '.autopack',
 
1356
                                   reload_func=reload_func)
 
1357
            try:
 
1358
                packer.pack()
 
1359
            except errors.RetryWithNewPacks:
 
1360
                # An exception is propagating out of this context, make sure
 
1361
                # this packer has cleaned up. Packer() doesn't set its new_pack
 
1362
                # state into the RepositoryPackCollection object, so we only
 
1363
                # have access to it directly here.
 
1364
                if packer.new_pack is not None:
 
1365
                    packer.new_pack.abort()
 
1366
                raise
1327
1367
            for pack in packs:
1328
1368
                self._remove_pack_from_memory(pack)
1329
1369
        # record the newly available packs and stop advertising the old
1710
1750
            return True
1711
1751
        return False
1712
1752
 
 
1753
    def _restart_autopack(self):
 
1754
        """Reload the pack names list, and restart the autopack code."""
 
1755
        if not self.reload_pack_names():
 
1756
            # Re-raise the original exception, because something went missing
 
1757
            # and a restart didn't find it
 
1758
            raise
 
1759
        raise errors.RetryAutopack(self.repo, False, sys.exc_info())
 
1760
 
1713
1761
    def _clear_obsolete_packs(self):
1714
1762
        """Delete everything from the obsolete-packs directory.
1715
1763
        """
2313
2361
        return xml7.serializer_v7
2314
2362
 
2315
2363
    def _get_matching_bzrdir(self):
2316
 
        return bzrdir.format_registry.make_bzrdir(
 
2364
        matching = bzrdir.format_registry.make_bzrdir(
2317
2365
            '1.6.1-rich-root')
 
2366
        matching.repository_format = self
 
2367
        return matching
2318
2368
 
2319
2369
    def _ignore_setting_bzrdir(self, format):
2320
2370
        pass