~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/pack_repo.py

  • Committer: Martin Pool
  • Date: 2009-09-14 01:48:28 UTC
  • mfrom: (4685 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4688.
  • Revision ID: mbp@sourcefrog.net-20090914014828-ydr9rlkdfq2sv57z
Merge news

Show diffs side-by-side

added added

removed removed

Lines of Context:
422
422
        self._writer.begin()
423
423
        # what state is the pack in? (open, finished, aborted)
424
424
        self._state = 'open'
 
425
        # no name until we finish writing the content
 
426
        self.name = None
425
427
 
426
428
    def abort(self):
427
429
        """Cancel creating this pack."""
448
450
            self.signature_index.key_count() or
449
451
            (self.chk_index is not None and self.chk_index.key_count()))
450
452
 
 
453
    def finish_content(self):
 
454
        if self.name is not None:
 
455
            return
 
456
        self._writer.end()
 
457
        if self._buffer[1]:
 
458
            self._write_data('', flush=True)
 
459
        self.name = self._hash.hexdigest()
 
460
 
451
461
    def finish(self, suspend=False):
452
462
        """Finish the new pack.
453
463
 
459
469
         - stores the index size tuple for the pack in the index_sizes
460
470
           attribute.
461
471
        """
462
 
        self._writer.end()
463
 
        if self._buffer[1]:
464
 
            self._write_data('', flush=True)
465
 
        self.name = self._hash.hexdigest()
 
472
        self.finish_content()
466
473
        if not suspend:
467
474
            self._check_references()
468
475
        # write indices
1567
1574
        # determine which packs need changing
1568
1575
        pack_operations = [[0, []]]
1569
1576
        for pack in self.all_packs():
1570
 
            if not hint or pack.name in hint:
 
1577
            if hint is None or pack.name in hint:
 
1578
                # Either no hint was provided (so we are packing everything),
 
1579
                # or this pack was included in the hint.
1571
1580
                pack_operations[-1][0] += pack.get_revision_count()
1572
1581
                pack_operations[-1][1].append(pack)
1573
1582
        self._execute_pack_operations(pack_operations, OptimisingPacker)
2054
2063
            self._remove_pack_indices(resumed_pack)
2055
2064
        del self._resumed_packs[:]
2056
2065
 
 
2066
    def _check_new_inventories(self):
 
2067
        """Detect missing inventories in this write group.
 
2068
 
 
2069
        :returns: list of strs, summarising any problems found.  If the list is
 
2070
            empty no problems were found.
 
2071
        """
 
2072
        # The base implementation does no checks.  GCRepositoryPackCollection
 
2073
        # overrides this.
 
2074
        return []
 
2075
        
2057
2076
    def _commit_write_group(self):
2058
2077
        all_missing = set()
2059
2078
        for prefix, versioned_file in (
2068
2087
            raise errors.BzrCheckError(
2069
2088
                "Repository %s has missing compression parent(s) %r "
2070
2089
                 % (self.repo, sorted(all_missing)))
 
2090
        problems = self._check_new_inventories()
 
2091
        if problems:
 
2092
            problems_summary = '\n'.join(problems)
 
2093
            raise errors.BzrCheckError(
 
2094
                "Cannot add revision(s) to repository: " + problems_summary)
2071
2095
        self._remove_pack_indices(self._new_pack)
2072
 
        should_autopack = False
 
2096
        any_new_content = False
2073
2097
        if self._new_pack.data_inserted():
2074
2098
            # get all the data to disk and read to use
2075
2099
            self._new_pack.finish()
2076
2100
            self.allocate(self._new_pack)
2077
2101
            self._new_pack = None
2078
 
            should_autopack = True
 
2102
            any_new_content = True
2079
2103
        else:
2080
2104
            self._new_pack.abort()
2081
2105
            self._new_pack = None
2086
2110
            self._remove_pack_from_memory(resumed_pack)
2087
2111
            resumed_pack.finish()
2088
2112
            self.allocate(resumed_pack)
2089
 
            should_autopack = True
 
2113
            any_new_content = True
2090
2114
        del self._resumed_packs[:]
2091
 
        if should_autopack:
2092
 
            if not self.autopack():
 
2115
        if any_new_content:
 
2116
            result = self.autopack()
 
2117
            if not result:
2093
2118
                # when autopack takes no steps, the names list is still
2094
2119
                # unsaved.
2095
2120
                return self._save_pack_names()
 
2121
            return result
 
2122
        return []
2096
2123
 
2097
2124
    def _suspend_write_group(self):
2098
2125
        tokens = [pack.name for pack in self._resumed_packs]
2212
2239
                    % (self._format, self.bzrdir.transport.base))
2213
2240
 
2214
2241
    def _abort_write_group(self):
2215
 
        self.revisions._index._key_dependencies.refs.clear()
 
2242
        self.revisions._index._key_dependencies.clear()
2216
2243
        self._pack_collection._abort_write_group()
2217
2244
 
2218
 
    def _find_inconsistent_revision_parents(self):
2219
 
        """Find revisions with incorrectly cached parents.
2220
 
 
2221
 
        :returns: an iterator yielding tuples of (revison-id, parents-in-index,
2222
 
            parents-in-revision).
2223
 
        """
2224
 
        if not self.is_locked():
2225
 
            raise errors.ObjectNotLocked(self)
2226
 
        pb = ui.ui_factory.nested_progress_bar()
2227
 
        result = []
2228
 
        try:
2229
 
            revision_nodes = self._pack_collection.revision_index \
2230
 
                .combined_index.iter_all_entries()
2231
 
            index_positions = []
2232
 
            # Get the cached index values for all revisions, and also the
2233
 
            # location in each index of the revision text so we can perform
2234
 
            # linear IO.
2235
 
            for index, key, value, refs in revision_nodes:
2236
 
                node = (index, key, value, refs)
2237
 
                index_memo = self.revisions._index._node_to_position(node)
2238
 
                if index_memo[0] != index:
2239
 
                    raise AssertionError('%r != %r' % (index_memo[0], index))
2240
 
                index_positions.append((index_memo, key[0],
2241
 
                                       tuple(parent[0] for parent in refs[0])))
2242
 
                pb.update("Reading revision index", 0, 0)
2243
 
            index_positions.sort()
2244
 
            batch_size = 1000
2245
 
            pb.update("Checking cached revision graph", 0,
2246
 
                      len(index_positions))
2247
 
            for offset in xrange(0, len(index_positions), 1000):
2248
 
                pb.update("Checking cached revision graph", offset)
2249
 
                to_query = index_positions[offset:offset + batch_size]
2250
 
                if not to_query:
2251
 
                    break
2252
 
                rev_ids = [item[1] for item in to_query]
2253
 
                revs = self.get_revisions(rev_ids)
2254
 
                for revision, item in zip(revs, to_query):
2255
 
                    index_parents = item[2]
2256
 
                    rev_parents = tuple(revision.parent_ids)
2257
 
                    if index_parents != rev_parents:
2258
 
                        result.append((revision.revision_id, index_parents,
2259
 
                                       rev_parents))
2260
 
        finally:
2261
 
            pb.finished()
2262
 
        return result
2263
 
 
2264
2245
    def _get_source(self, to_format):
2265
2246
        if to_format.network_name() == self._format.network_name():
2266
2247
            return KnitPackStreamSource(self, to_format)
2278
2259
        self._pack_collection._start_write_group()
2279
2260
 
2280
2261
    def _commit_write_group(self):
2281
 
        self.revisions._index._key_dependencies.refs.clear()
2282
 
        return self._pack_collection._commit_write_group()
 
2262
        hint = self._pack_collection._commit_write_group()
 
2263
        self.revisions._index._key_dependencies.clear()
 
2264
        return hint
2283
2265
 
2284
2266
    def suspend_write_group(self):
2285
2267
        # XXX check self._write_group is self.get_transaction()?
2286
2268
        tokens = self._pack_collection._suspend_write_group()
2287
 
        self.revisions._index._key_dependencies.refs.clear()
 
2269
        self.revisions._index._key_dependencies.clear()
2288
2270
        self._write_group = None
2289
2271
        return tokens
2290
2272
 
2565
2547
        """See RepositoryFormat.get_format_description()."""
2566
2548
        return "Packs containing knits without subtree support"
2567
2549
 
2568
 
    def check_conversion_target(self, target_format):
2569
 
        pass
2570
 
 
2571
2550
 
2572
2551
class RepositoryFormatKnitPack3(RepositoryFormatPack):
2573
2552
    """A subtrees parameterized Pack repository.
2599
2578
 
2600
2579
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
2601
2580
 
2602
 
    def check_conversion_target(self, target_format):
2603
 
        if not target_format.rich_root_data:
2604
 
            raise errors.BadConversionTarget(
2605
 
                'Does not support rich root data.', target_format)
2606
 
        if not getattr(target_format, 'supports_tree_reference', False):
2607
 
            raise errors.BadConversionTarget(
2608
 
                'Does not support nested trees', target_format)
2609
 
 
2610
2581
    def get_format_string(self):
2611
2582
        """See RepositoryFormat.get_format_string()."""
2612
2583
        return "Bazaar pack repository format 1 with subtree support (needs bzr 0.92)\n"
2645
2616
 
2646
2617
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
2647
2618
 
2648
 
    def check_conversion_target(self, target_format):
2649
 
        if not target_format.rich_root_data:
2650
 
            raise errors.BadConversionTarget(
2651
 
                'Does not support rich root data.', target_format)
2652
 
 
2653
2619
    def get_format_string(self):
2654
2620
        """See RepositoryFormat.get_format_string()."""
2655
2621
        return ("Bazaar pack repository format 1 with rich root"
2696
2662
        """See RepositoryFormat.get_format_description()."""
2697
2663
        return "Packs 5 (adds stacking support, requires bzr 1.6)"
2698
2664
 
2699
 
    def check_conversion_target(self, target_format):
2700
 
        pass
2701
 
 
2702
2665
 
2703
2666
class RepositoryFormatKnitPack5RichRoot(RepositoryFormatPack):
2704
2667
    """A repository with rich roots and stacking.
2731
2694
 
2732
2695
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
2733
2696
 
2734
 
    def check_conversion_target(self, target_format):
2735
 
        if not target_format.rich_root_data:
2736
 
            raise errors.BadConversionTarget(
2737
 
                'Does not support rich root data.', target_format)
2738
 
 
2739
2697
    def get_format_string(self):
2740
2698
        """See RepositoryFormat.get_format_string()."""
2741
2699
        return "Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6.1)\n"
2782
2740
 
2783
2741
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
2784
2742
 
2785
 
    def check_conversion_target(self, target_format):
2786
 
        if not target_format.rich_root_data:
2787
 
            raise errors.BadConversionTarget(
2788
 
                'Does not support rich root data.', target_format)
2789
 
 
2790
2743
    def get_format_string(self):
2791
2744
        """See RepositoryFormat.get_format_string()."""
2792
2745
        return "Bazaar RepositoryFormatKnitPack5RichRoot (bzr 1.6)\n"
2830
2783
        """See RepositoryFormat.get_format_description()."""
2831
2784
        return "Packs 6 (uses btree indexes, requires bzr 1.9)"
2832
2785
 
2833
 
    def check_conversion_target(self, target_format):
2834
 
        pass
2835
 
 
2836
2786
 
2837
2787
class RepositoryFormatKnitPack6RichRoot(RepositoryFormatPack):
2838
2788
    """A repository with rich roots, no subtrees, stacking and btree indexes.
2862
2812
 
2863
2813
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
2864
2814
 
2865
 
    def check_conversion_target(self, target_format):
2866
 
        if not target_format.rich_root_data:
2867
 
            raise errors.BadConversionTarget(
2868
 
                'Does not support rich root data.', target_format)
2869
 
 
2870
2815
    def get_format_string(self):
2871
2816
        """See RepositoryFormat.get_format_string()."""
2872
2817
        return "Bazaar RepositoryFormatKnitPack6RichRoot (bzr 1.9)\n"
2908
2853
 
2909
2854
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
2910
2855
 
2911
 
    def check_conversion_target(self, target_format):
2912
 
        if not target_format.rich_root_data:
2913
 
            raise errors.BadConversionTarget(
2914
 
                'Does not support rich root data.', target_format)
2915
 
        if not getattr(target_format, 'supports_tree_reference', False):
2916
 
            raise errors.BadConversionTarget(
2917
 
                'Does not support nested trees', target_format)
2918
 
 
2919
2856
    def get_format_string(self):
2920
2857
        """See RepositoryFormat.get_format_string()."""
2921
2858
        return ("Bazaar development format 2 with subtree support "