/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/knit.py

  • Committer: Andrew Bennetts
  • Date: 2009-06-17 02:02:44 UTC
  • mfrom: (4449 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4452.
  • Revision ID: andrew.bennetts@canonical.com-20090617020244-50aantdf95aakvjx
Merge bzr.dev, resolving NEWS conflict.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2688
2688
        return key[:-1], key[-1]
2689
2689
 
2690
2690
 
 
2691
class _KeyRefs(object):
 
2692
 
 
2693
    def __init__(self):
 
2694
        # dict mapping 'key' to 'set of keys referring to that key'
 
2695
        self.refs = {}
 
2696
 
 
2697
    def add_references(self, key, refs):
 
2698
        # Record the new references
 
2699
        for referenced in refs:
 
2700
            try:
 
2701
                needed_by = self.refs[referenced]
 
2702
            except KeyError:
 
2703
                needed_by = self.refs[referenced] = set()
 
2704
            needed_by.add(key)
 
2705
        # Discard references satisfied by the new key
 
2706
        self.add_key(key)
 
2707
 
 
2708
    def get_unsatisfied_refs(self):
 
2709
        return self.refs.iterkeys()
 
2710
 
 
2711
    def add_key(self, key):
 
2712
        try:
 
2713
            del self.refs[key]
 
2714
        except KeyError:
 
2715
            # No keys depended on this key.  That's ok.
 
2716
            pass
 
2717
 
 
2718
    def add_keys(self, keys):
 
2719
        for key in keys:
 
2720
            self.add_key(key)
 
2721
 
 
2722
    def get_referrers(self):
 
2723
        result = set()
 
2724
        for referrers in self.refs.itervalues():
 
2725
            result.update(referrers)
 
2726
        return result
 
2727
 
 
2728
 
2691
2729
class _KnitGraphIndex(object):
2692
2730
    """A KnitVersionedFiles index layered on GraphIndex."""
2693
2731
 
2694
2732
    def __init__(self, graph_index, is_locked, deltas=False, parents=True,
2695
 
        add_callback=None):
 
2733
        add_callback=None, track_external_parent_refs=False):
2696
2734
        """Construct a KnitGraphIndex on a graph_index.
2697
2735
 
2698
2736
        :param graph_index: An implementation of bzrlib.index.GraphIndex.
2706
2744
            [(node, value, node_refs), ...]
2707
2745
        :param is_locked: A callback, returns True if the index is locked and
2708
2746
            thus usable.
 
2747
        :param track_external_parent_refs: If True, record all external parent
 
2748
            references parents from added records.  These can be retrieved
 
2749
            later by calling get_missing_parents().
2709
2750
        """
2710
2751
        self._add_callback = add_callback
2711
2752
        self._graph_index = graph_index
2719
2760
        self.has_graph = parents
2720
2761
        self._is_locked = is_locked
2721
2762
        self._missing_compression_parents = set()
 
2763
        if track_external_parent_refs:
 
2764
            self._key_dependencies = _KeyRefs()
 
2765
        else:
 
2766
            self._key_dependencies = None
2722
2767
 
2723
2768
    def __repr__(self):
2724
2769
        return "%s(%r)" % (self.__class__.__name__, self._graph_index)
2748
2793
 
2749
2794
        keys = {}
2750
2795
        compression_parents = set()
 
2796
        key_dependencies = self._key_dependencies
2751
2797
        for (key, options, access_memo, parents) in records:
2752
2798
            if self._parents:
2753
2799
                parents = tuple(parents)
 
2800
                if key_dependencies is not None:
 
2801
                    key_dependencies.add_references(key, parents)
2754
2802
            index, pos, size = access_memo
2755
2803
            if 'no-eol' in options:
2756
2804
                value = 'N'
2818
2866
            new_missing = graph_index.external_references(ref_list_num=1)
2819
2867
            new_missing.difference_update(self.get_parent_map(new_missing))
2820
2868
            self._missing_compression_parents.update(new_missing)
 
2869
        if self._key_dependencies is not None:
 
2870
            # Add parent refs from graph_index (and discard parent refs that
 
2871
            # the graph_index has).
 
2872
            for node in graph_index.iter_all_entries():
 
2873
                self._key_dependencies.add_references(node[1], node[3][0])
2821
2874
 
2822
2875
    def get_missing_compression_parents(self):
2823
2876
        """Return the keys of missing compression parents.
2827
2880
        """
2828
2881
        return frozenset(self._missing_compression_parents)
2829
2882
 
 
2883
    def get_missing_parents(self):
 
2884
        """Return the keys of missing parents."""
 
2885
        # If updating this, you should also update
 
2886
        # groupcompress._GCGraphIndex.get_missing_parents
 
2887
        # We may have false positives, so filter those out.
 
2888
        self._key_dependencies.add_keys(
 
2889
            self.get_parent_map(self._key_dependencies.get_unsatisfied_refs()))
 
2890
        return frozenset(self._key_dependencies.get_unsatisfied_refs())
 
2891
 
2830
2892
    def _check_read(self):
2831
2893
        """raise if reads are not permitted."""
2832
2894
        if not self._is_locked():
3347
3409
        fulltext.)
3348
3410
 
3349
3411
        :return: A list of (key, index_memo) records, suitable for
3350
 
            passing to read_records_iter to start reading in the raw data fro/
 
3412
            passing to read_records_iter to start reading in the raw data from
3351
3413
            the pack file.
3352
3414
        """
3353
3415
        if key in self._annotated_lines:
3490
3552
        """Create a heads provider for resolving ancestry issues."""
3491
3553
        if self._heads_provider is not None:
3492
3554
            return self._heads_provider
3493
 
        parent_provider = _mod_graph.DictParentsProvider(
3494
 
            self._revision_id_graph)
3495
 
        graph_obj = _mod_graph.Graph(parent_provider)
3496
 
        head_cache = _mod_graph.FrozenHeadsCache(graph_obj)
3497
 
        self._heads_provider = head_cache
3498
 
        return head_cache
 
3555
        self._heads_provider = _mod_graph.KnownGraph(self._revision_id_graph)
 
3556
        return self._heads_provider
3499
3557
 
3500
3558
    def annotate(self, key):
3501
3559
        """Return the annotated fulltext at the given key.
3524
3582
        being able to produce line deltas.
3525
3583
        """
3526
3584
        # TODO: this code generates a parent maps of present ancestors; it
3527
 
        # could be split out into a separate method, and probably should use
3528
 
        # iter_ancestry instead. -- mbp and robertc 20080704
 
3585
        #       could be split out into a separate method
 
3586
        #       -- mbp and robertc 20080704
3529
3587
        graph = _mod_graph.Graph(self._knit)
3530
 
        head_cache = _mod_graph.FrozenHeadsCache(graph)
3531
 
        search = graph._make_breadth_first_searcher([key])
3532
 
        keys = set()
3533
 
        while True:
3534
 
            try:
3535
 
                present, ghosts = search.next_with_ghosts()
3536
 
            except StopIteration:
3537
 
                break
3538
 
            keys.update(present)
3539
 
        parent_map = self._knit.get_parent_map(keys)
 
3588
        parent_map = dict((k, v) for k, v in graph.iter_ancestry([key])
 
3589
                          if v is not None)
 
3590
        if not parent_map:
 
3591
            raise errors.RevisionNotPresent(key, self)
 
3592
        keys = parent_map.keys()
 
3593
        heads_provider = _mod_graph.KnownGraph(parent_map)
3540
3594
        parent_cache = {}
3541
3595
        reannotate = annotate.reannotate
3542
3596
        for record in self._knit.get_record_stream(keys, 'topological', True):
3548
3602
            else:
3549
3603
                parent_lines = []
3550
3604
            parent_cache[key] = list(
3551
 
                reannotate(parent_lines, fulltext, key, None, head_cache))
 
3605
                reannotate(parent_lines, fulltext, key, None, heads_provider))
3552
3606
        try:
3553
3607
            return parent_cache[key]
3554
3608
        except KeyError, e: