~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

  • Committer: Martin Pool
  • Date: 2010-04-01 04:41:18 UTC
  • mto: This revision was merged to the branch mainline in revision 5128.
  • Revision ID: mbp@sourcefrog.net-20100401044118-shyctqc02ob08ngz
ignore .testrepository

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
69
69
    lru_cache,
70
70
    pack,
71
71
    progress,
 
72
    static_tuple,
72
73
    trace,
73
74
    tsort,
74
75
    tuned_gzip,
 
76
    ui,
75
77
    )
76
78
""")
77
79
from bzrlib import (
1190
1192
        generator = _VFContentMapGenerator(self, [key])
1191
1193
        return generator._get_content(key)
1192
1194
 
 
1195
    def get_known_graph_ancestry(self, keys):
 
1196
        """Get a KnownGraph instance with the ancestry of keys."""
 
1197
        parent_map, missing_keys = self._index.find_ancestry(keys)
 
1198
        for fallback in self._fallback_vfs:
 
1199
            if not missing_keys:
 
1200
                break
 
1201
            (f_parent_map, f_missing_keys) = fallback._index.find_ancestry(
 
1202
                                                missing_keys)
 
1203
            parent_map.update(f_parent_map)
 
1204
            missing_keys = f_missing_keys
 
1205
        kg = _mod_graph.KnownGraph(parent_map)
 
1206
        return kg
 
1207
 
1193
1208
    def get_parent_map(self, keys):
1194
1209
        """Get a map of the graph parents of keys.
1195
1210
 
1505
1520
                if source is parent_maps[0]:
1506
1521
                    # this KnitVersionedFiles
1507
1522
                    records = [(key, positions[key][1]) for key in keys]
1508
 
                    for key, raw_data, sha1 in self._read_records_iter_raw(records):
 
1523
                    for key, raw_data in self._read_records_iter_unchecked(records):
1509
1524
                        (record_details, index_memo, _) = positions[key]
1510
1525
                        yield KnitContentFactory(key, global_map[key],
1511
 
                            record_details, sha1, raw_data, self._factory.annotated, None)
 
1526
                            record_details, None, raw_data, self._factory.annotated, None)
1512
1527
                else:
1513
1528
                    vf = self._fallback_vfs[parent_maps.index(source) - 1]
1514
1529
                    for record in vf.get_record_stream(keys, ordering,
1583
1598
        # key = basis_parent, value = index entry to add
1584
1599
        buffered_index_entries = {}
1585
1600
        for record in stream:
 
1601
            kind = record.storage_kind
 
1602
            if kind.startswith('knit-') and kind.endswith('-gz'):
 
1603
                # Check that the ID in the header of the raw knit bytes matches
 
1604
                # the record metadata.
 
1605
                raw_data = record._raw_record
 
1606
                df, rec = self._parse_record_header(record.key, raw_data)
 
1607
                df.close()
1586
1608
            buffered = False
1587
1609
            parents = record.parents
1588
1610
            if record.storage_kind in delta_types:
1690
1712
            # There were index entries buffered at the end of the stream,
1691
1713
            # So these need to be added (if the index supports holding such
1692
1714
            # entries for later insertion)
 
1715
            all_entries = []
1693
1716
            for key in buffered_index_entries:
1694
1717
                index_entries = buffered_index_entries[key]
1695
 
                self._index.add_records(index_entries,
1696
 
                    missing_compression_parents=True)
 
1718
                all_entries.extend(index_entries)
 
1719
            self._index.add_records(
 
1720
                all_entries, missing_compression_parents=True)
1697
1721
 
1698
1722
    def get_missing_compression_parent_keys(self):
1699
1723
        """Return an iterable of keys of missing compression parents.
1732
1756
        :return: An iterator over (line, key).
1733
1757
        """
1734
1758
        if pb is None:
1735
 
            pb = progress.DummyProgress()
 
1759
            pb = ui.ui_factory.nested_progress_bar()
1736
1760
        keys = set(keys)
1737
1761
        total = len(keys)
1738
1762
        done = False
2345
2369
    FLAGS is a comma separated list of flags about the record. Values include
2346
2370
        no-eol, line-delta, fulltext.
2347
2371
    BYTE_OFFSET is the ascii representation of the byte offset in the data file
2348
 
        that the the compressed data starts at.
 
2372
        that the compressed data starts at.
2349
2373
    LENGTH is the ascii representation of the length of the data file.
2350
2374
    PARENT_ID a utf-8 revision id prefixed by a '.' that is a parent of
2351
2375
        REVISION_ID.
2560
2584
        except KeyError:
2561
2585
            raise RevisionNotPresent(key, self)
2562
2586
 
 
2587
    def find_ancestry(self, keys):
 
2588
        """See CombinedGraphIndex.find_ancestry()"""
 
2589
        prefixes = set(key[:-1] for key in keys)
 
2590
        self._load_prefixes(prefixes)
 
2591
        result = {}
 
2592
        parent_map = {}
 
2593
        missing_keys = set()
 
2594
        pending_keys = list(keys)
 
2595
        # This assumes that keys will not reference parents in a different
 
2596
        # prefix, which is accurate so far.
 
2597
        while pending_keys:
 
2598
            key = pending_keys.pop()
 
2599
            if key in parent_map:
 
2600
                continue
 
2601
            prefix = key[:-1]
 
2602
            try:
 
2603
                suffix_parents = self._kndx_cache[prefix][0][key[-1]][4]
 
2604
            except KeyError:
 
2605
                missing_keys.add(key)
 
2606
            else:
 
2607
                parent_keys = tuple([prefix + (suffix,)
 
2608
                                     for suffix in suffix_parents])
 
2609
                parent_map[key] = parent_keys
 
2610
                pending_keys.extend([p for p in parent_keys
 
2611
                                        if p not in parent_map])
 
2612
        return parent_map, missing_keys
 
2613
 
2563
2614
    def get_parent_map(self, keys):
2564
2615
        """Get a map of the parents of keys.
2565
2616
 
2737
2788
 
2738
2789
class _KeyRefs(object):
2739
2790
 
2740
 
    def __init__(self):
 
2791
    def __init__(self, track_new_keys=False):
2741
2792
        # dict mapping 'key' to 'set of keys referring to that key'
2742
2793
        self.refs = {}
 
2794
        if track_new_keys:
 
2795
            # set remembering all new keys
 
2796
            self.new_keys = set()
 
2797
        else:
 
2798
            self.new_keys = None
 
2799
 
 
2800
    def clear(self):
 
2801
        if self.refs:
 
2802
            self.refs.clear()
 
2803
        if self.new_keys:
 
2804
            self.new_keys.clear()
2743
2805
 
2744
2806
    def add_references(self, key, refs):
2745
2807
        # Record the new references
2752
2814
        # Discard references satisfied by the new key
2753
2815
        self.add_key(key)
2754
2816
 
 
2817
    def get_new_keys(self):
 
2818
        return self.new_keys
 
2819
    
2755
2820
    def get_unsatisfied_refs(self):
2756
2821
        return self.refs.iterkeys()
2757
2822
 
2758
 
    def add_key(self, key):
 
2823
    def _satisfy_refs_for_key(self, key):
2759
2824
        try:
2760
2825
            del self.refs[key]
2761
2826
        except KeyError:
2762
2827
            # No keys depended on this key.  That's ok.
2763
2828
            pass
2764
2829
 
2765
 
    def add_keys(self, keys):
 
2830
    def add_key(self, key):
 
2831
        # satisfy refs for key, and remember that we've seen this key.
 
2832
        self._satisfy_refs_for_key(key)
 
2833
        if self.new_keys is not None:
 
2834
            self.new_keys.add(key)
 
2835
 
 
2836
    def satisfy_refs_for_keys(self, keys):
2766
2837
        for key in keys:
2767
 
            self.add_key(key)
 
2838
            self._satisfy_refs_for_key(key)
2768
2839
 
2769
2840
    def get_referrers(self):
2770
2841
        result = set()
2875
2946
        if not random_id:
2876
2947
            present_nodes = self._get_entries(keys)
2877
2948
            for (index, key, value, node_refs) in present_nodes:
 
2949
                parents = node_refs[:1]
 
2950
                # Sometimes these are passed as a list rather than a tuple
 
2951
                passed = static_tuple.as_tuples(keys[key])
 
2952
                passed_parents = passed[1][:1]
2878
2953
                if (value[0] != keys[key][0][0] or
2879
 
                    node_refs[:1] != keys[key][1][:1]):
 
2954
                    parents != passed_parents):
 
2955
                    node_refs = static_tuple.as_tuples(node_refs)
2880
2956
                    raise KnitCorrupt(self, "inconsistent details in add_records"
2881
 
                        ": %s %s" % ((value, node_refs), keys[key]))
 
2957
                        ": %s %s" % ((value, node_refs), passed))
2882
2958
                del keys[key]
2883
2959
        result = []
2884
2960
        if self._parents:
2932
3008
        # If updating this, you should also update
2933
3009
        # groupcompress._GCGraphIndex.get_missing_parents
2934
3010
        # We may have false positives, so filter those out.
2935
 
        self._key_dependencies.add_keys(
 
3011
        self._key_dependencies.satisfy_refs_for_keys(
2936
3012
            self.get_parent_map(self._key_dependencies.get_unsatisfied_refs()))
2937
3013
        return frozenset(self._key_dependencies.get_unsatisfied_refs())
2938
3014
 
3049
3125
            options.append('no-eol')
3050
3126
        return options
3051
3127
 
 
3128
    def find_ancestry(self, keys):
 
3129
        """See CombinedGraphIndex.find_ancestry()"""
 
3130
        return self._graph_index.find_ancestry(keys, 0)
 
3131
 
3052
3132
    def get_parent_map(self, keys):
3053
3133
        """Get a map of the parents of keys.
3054
3134
 
3629
3709
 
3630
3710
try:
3631
3711
    from bzrlib._knit_load_data_pyx import _load_data_c as _load_data
3632
 
except ImportError:
 
3712
except ImportError, e:
 
3713
    osutils.failed_to_load_extension(e)
3633
3714
    from bzrlib._knit_load_data_py import _load_data_py as _load_data