/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: 2008-04-07 08:20:13 UTC
  • mfrom: (3340 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3344.
  • Revision ID: andrew.bennetts@canonical.com-20080407082013-ca1n1tqqon7ugxiy
Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
101
101
    RevisionNotPresent,
102
102
    RevisionAlreadyPresent,
103
103
    )
104
 
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
 
104
from bzrlib.graph import Graph
105
105
from bzrlib.osutils import (
106
106
    contains_whitespace,
107
107
    contains_linebreaks,
108
108
    sha_string,
109
109
    sha_strings,
110
110
    )
111
 
from bzrlib.symbol_versioning import DEPRECATED_PARAMETER, deprecated_passed
 
111
from bzrlib.symbol_versioning import (
 
112
    DEPRECATED_PARAMETER,
 
113
    deprecated_method,
 
114
    deprecated_passed,
 
115
    one_four,
 
116
    )
112
117
from bzrlib.tsort import topo_sort
 
118
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
113
119
import bzrlib.ui
 
120
from bzrlib.versionedfile import VersionedFile, InterVersionedFile
114
121
import bzrlib.weave
115
 
from bzrlib.versionedfile import VersionedFile, InterVersionedFile
116
122
 
117
123
 
118
124
# TODO: Split out code specific to this format into an associated object.
575
581
                fulltext_size = size
576
582
                break
577
583
            delta_size += size
578
 
            delta_parents = self._index.get_parents(parent)
 
584
            delta_parents = self._index.get_parent_map([parent])[parent]
579
585
        else:
580
586
            # We couldn't find a fulltext, so we must create a new one
581
587
            return False
626
632
        # move the copied index into place
627
633
        transport.move(name + INDEX_SUFFIX + '.tmp', name + INDEX_SUFFIX)
628
634
 
629
 
    def create_empty(self, name, transport, mode=None):
630
 
        return KnitVersionedFile(name, transport, factory=self.factory,
631
 
                                 delta=self.delta, create=True)
632
 
    
633
635
    def get_data_stream(self, required_versions):
634
636
        """Get a data stream for the specified versions.
635
637
 
720
722
    def get_delta(self, version_id):
721
723
        """Get a delta for constructing version from some other version."""
722
724
        self.check_not_reserved_id(version_id)
723
 
        parents = self.get_parents(version_id)
 
725
        parents = self.get_parent_map([version_id])[version_id]
724
726
        if len(parents):
725
727
            parent = parents[0]
726
728
        else:
751
753
            annotated_part = "plain"
752
754
        return "knit-%s" % (annotated_part,)
753
755
        
 
756
    @deprecated_method(one_four)
754
757
    def get_graph_with_ghosts(self):
755
758
        """See VersionedFile.get_graph_with_ghosts()."""
756
 
        graph_items = self._index.get_graph()
757
 
        return dict(graph_items)
 
759
        return self.get_parent_map(self.versions())
758
760
 
759
761
    def get_sha1(self, version_id):
760
762
        return self.get_sha1s([version_id])[0]
770
772
        """See VersionedFile.get_suffixes()."""
771
773
        return [DATA_SUFFIX, INDEX_SUFFIX]
772
774
 
 
775
    @deprecated_method(one_four)
773
776
    def has_ghost(self, version_id):
774
777
        """True if there is a ghost reference in the file to version_id."""
775
778
        # maybe we have it
776
779
        if self.has_version(version_id):
777
780
            return False
778
781
        # optimisable if needed by memoising the _ghosts set.
779
 
        items = self._index.get_graph()
780
 
        for node, parents in items:
 
782
        items = self.get_parent_map(self.versions())
 
783
        for parents in items.itervalues():
781
784
            for parent in parents:
782
 
                if parent not in self._index._cache:
783
 
                    if parent == version_id:
784
 
                        return True
 
785
                if parent == version_id and parent not in items:
 
786
                    return True
785
787
        return False
786
788
 
787
789
    def insert_data_stream(self, (format, data_list, reader_callable)):
977
979
        self._index.check_versions_present(version_ids)
978
980
 
979
981
    def _add_lines_with_ghosts(self, version_id, parents, lines, parent_texts,
980
 
        nostore_sha, random_id, check_content):
 
982
        nostore_sha, random_id, check_content, left_matching_blocks):
981
983
        """See VersionedFile.add_lines_with_ghosts()."""
982
984
        self._check_add(version_id, lines, random_id, check_content)
983
985
        return self._add(version_id, lines, parents, self.delta,
984
 
            parent_texts, None, nostore_sha, random_id)
 
986
            parent_texts, left_matching_blocks, nostore_sha, random_id)
985
987
 
986
988
    def _add_lines(self, version_id, parents, lines, parent_texts,
987
989
        left_matching_blocks, nostore_sha, random_id, check_content):
1258
1260
        """See VersionedFile.annotate_iter."""
1259
1261
        return self.factory.annotate_iter(self, version_id)
1260
1262
 
1261
 
    def get_parents(self, version_id):
1262
 
        """See VersionedFile.get_parents."""
1263
 
        # perf notes:
1264
 
        # optimism counts!
1265
 
        # 52554 calls in 1264 872 internal down from 3674
1266
 
        try:
1267
 
            return self._index.get_parents(version_id)
1268
 
        except KeyError:
1269
 
            raise RevisionNotPresent(version_id, self.filename)
1270
 
 
1271
 
    def get_parents_with_ghosts(self, version_id):
1272
 
        """See VersionedFile.get_parents."""
1273
 
        try:
1274
 
            return self._index.get_parents_with_ghosts(version_id)
1275
 
        except KeyError:
1276
 
            raise RevisionNotPresent(version_id, self.filename)
 
1263
    def get_parent_map(self, version_ids):
 
1264
        """See VersionedFile.get_parent_map."""
 
1265
        return self._index.get_parent_map(version_ids)
1277
1266
 
1278
1267
    def get_ancestry(self, versions, topo_sorted=True):
1279
1268
        """See VersionedFile.get_ancestry."""
1440
1429
                self._transport.put_bytes_non_atomic(
1441
1430
                    self._filename, self.HEADER, mode=self._file_mode)
1442
1431
 
1443
 
    def get_graph(self):
1444
 
        """Return a list of the node:parents lists from this knit index."""
1445
 
        return [(vid, idx[4]) for vid, idx in self._cache.iteritems()]
1446
 
 
1447
1432
    def get_ancestry(self, versions, topo_sorted=True):
1448
1433
        """See VersionedFile.get_ancestry."""
1449
1434
        # get a graph of all the mentioned versions:
1529
1514
            The order is undefined, allowing for different optimisations in
1530
1515
            the underlying implementation.
1531
1516
        """
1532
 
        for version_id in version_ids:
1533
 
            try:
1534
 
                yield version_id, tuple(self.get_parents(version_id))
1535
 
            except KeyError:
1536
 
                pass
 
1517
        parent_map = self.get_parent_map(version_ids)
 
1518
        parent_map_set = set(parent_map)
 
1519
        unknown_existence = set()
 
1520
        for parents in parent_map.itervalues():
 
1521
            unknown_existence.update(parents)
 
1522
        unknown_existence.difference_update(parent_map_set)
 
1523
        present_parents = set(self.get_parent_map(unknown_existence))
 
1524
        present_parents.update(parent_map_set)
 
1525
        for version_id, parents in parent_map.iteritems():
 
1526
            parents = tuple(parent for parent in parents
 
1527
                if parent in present_parents)
 
1528
            yield version_id, parents
1537
1529
 
1538
1530
    def num_versions(self):
1539
1531
        return len(self._history)
1582
1574
                assert isinstance(line, str), \
1583
1575
                    'content must be utf-8 encoded: %r' % (line,)
1584
1576
                lines.append(line)
1585
 
                self._cache_version(version_id, options, pos, size, parents)
 
1577
                self._cache_version(version_id, options, pos, size, tuple(parents))
1586
1578
            if not self._need_to_create:
1587
1579
                self._transport.append_bytes(self._filename, ''.join(lines))
1588
1580
            else:
1637
1629
        """
1638
1630
        return self._cache[version_id][1]
1639
1631
 
1640
 
    def get_parents(self, version_id):
1641
 
        """Return parents of specified version ignoring ghosts."""
1642
 
        return [parent for parent in self._cache[version_id][4] 
1643
 
                if parent in self._cache]
 
1632
    def get_parent_map(self, version_ids):
 
1633
        """Passed through to by KnitVersionedFile.get_parent_map."""
 
1634
        result = {}
 
1635
        for version_id in version_ids:
 
1636
            try:
 
1637
                result[version_id] = tuple(self._cache[version_id][4])
 
1638
            except KeyError:
 
1639
                pass
 
1640
        return result
1644
1641
 
1645
1642
    def get_parents_with_ghosts(self, version_id):
1646
1643
        """Return parents of specified version with ghosts."""
1647
 
        return self._cache[version_id][4] 
 
1644
        try:
 
1645
            return self.get_parent_map([version_id])[version_id]
 
1646
        except KeyError:
 
1647
            raise RevisionNotPresent(version_id, self)
1648
1648
 
1649
1649
    def check_versions_present(self, version_ids):
1650
1650
        """Check that all specified versions are present."""
1846
1846
        else:
1847
1847
            return 'fulltext'
1848
1848
 
1849
 
    def get_graph(self):
1850
 
        """Return a list of the node:parents lists from this knit index."""
1851
 
        if not self._parents:
1852
 
            return [(key, ()) for key in self.get_versions()]
1853
 
        result = []
1854
 
        for index, key, value, refs in self._graph_index.iter_all_entries():
1855
 
            result.append((key[0], tuple([ref[0] for ref in refs[0]])))
1856
 
        return result
1857
 
 
1858
1849
    def iter_parents(self, version_ids):
1859
1850
        """Iterate through the parents for many version ids.
1860
1851
 
1935
1926
            options.append('no-eol')
1936
1927
        return options
1937
1928
 
1938
 
    def get_parents(self, version_id):
1939
 
        """Return parents of specified version ignoring ghosts."""
1940
 
        parents = list(self.iter_parents([version_id]))
1941
 
        if not parents:
1942
 
            # missing key
1943
 
            raise errors.RevisionNotPresent(version_id, self)
1944
 
        return parents[0][1]
 
1929
    def get_parent_map(self, version_ids):
 
1930
        """Passed through to by KnitVersionedFile.get_parent_map."""
 
1931
        nodes = self._get_entries(self._version_ids_to_keys(version_ids))
 
1932
        result = {}
 
1933
        if self._parents:
 
1934
            for node in nodes:
 
1935
                result[node[1][0]] = self._keys_to_version_ids(node[3][0])
 
1936
        else:
 
1937
            for node in nodes:
 
1938
                result[node[1][0]] = ()
 
1939
        return result
1945
1940
 
1946
1941
    def get_parents_with_ghosts(self, version_id):
1947
1942
        """Return parents of specified version with ghosts."""
1948
 
        nodes = list(self._get_entries(self._version_ids_to_keys([version_id]),
1949
 
            check_present=True))
1950
 
        if not self._parents:
1951
 
            return ()
1952
 
        return self._keys_to_version_ids(nodes[0][3][0])
 
1943
        try:
 
1944
            return self.get_parent_map([version_id])[version_id]
 
1945
        except KeyError:
 
1946
            raise RevisionNotPresent(version_id, self)
1953
1947
 
1954
1948
    def check_versions_present(self, version_ids):
1955
1949
        """Check that all specified versions are present."""
2373
2367
        except KeyError:
2374
2368
            return self.backing_index.get_options(version_id)
2375
2369
 
 
2370
    def get_parent_map(self, version_ids):
 
2371
        """Passed through to by KnitVersionedFile.get_parent_map."""
 
2372
        result = {}
 
2373
        pending_ids = set()
 
2374
        for version_id in version_ids:
 
2375
            try:
 
2376
                result[version_id] = self._by_version[version_id][2]
 
2377
            except KeyError:
 
2378
                pending_ids.add(version_id)
 
2379
        result.update(self.backing_index.get_parent_map(pending_ids))
 
2380
        return result
 
2381
 
2376
2382
    def get_parents_with_ghosts(self, version_id):
2377
2383
        """Return parents of specified version with ghosts."""
2378
2384
        try:
2379
 
            return self._by_version[version_id][2]
 
2385
            return self.get_parent_map([version_id])[version_id]
2380
2386
        except KeyError:
2381
 
            return self.backing_index.get_parents_with_ghosts(version_id)
 
2387
            raise RevisionNotPresent(version_id, self)
2382
2388
 
2383
2389
    def get_position(self, version_id):
2384
2390
        """Return details needed to access the version.
2656
2662
        see join() for the parameter definitions.
2657
2663
        """
2658
2664
        version_ids = self._get_source_version_ids(version_ids, ignore_missing)
2659
 
        graph = self.source.get_graph(version_ids)
2660
 
        order = topo_sort(graph.items())
 
2665
        # --- the below is factorable out with VersionedFile.join, but wait for
 
2666
        # VersionedFiles, it may all be simpler then.
 
2667
        graph = Graph(self.source)
 
2668
        search = graph._make_breadth_first_searcher(version_ids)
 
2669
        transitive_ids = set()
 
2670
        map(transitive_ids.update, list(search))
 
2671
        parent_map = self.source.get_parent_map(transitive_ids)
 
2672
        order = topo_sort(parent_map.items())
2661
2673
 
2662
2674
        def size_of_content(content):
2663
2675
            return sum(len(line) for line in content.text())
2724
2736
    
2725
2737
            if not needed_versions:
2726
2738
                return 0
2727
 
            full_list = topo_sort(self.source.get_graph())
 
2739
            full_list = topo_sort(
 
2740
                self.source.get_parent_map(self.source.versions()))
2728
2741
    
2729
2742
            version_list = [i for i in full_list if (not self.target.has_version(i)
2730
2743
                            and i in needed_versions)]
2826
2839
    
2827
2840
            if not needed_versions:
2828
2841
                return 0
2829
 
            full_list = topo_sort(self.source.get_graph())
 
2842
            full_list = topo_sort(
 
2843
                self.source.get_parent_map(self.source.versions()))
2830
2844
    
2831
2845
            version_list = [i for i in full_list if (not self.target.has_version(i)
2832
2846
                            and i in needed_versions)]
2834
2848
            # do the join:
2835
2849
            count = 0
2836
2850
            total = len(version_list)
 
2851
            parent_map = self.source.get_parent_map(version_list)
2837
2852
            for version_id in version_list:
2838
2853
                pb.update("Converting to knit", count, total)
2839
 
                parents = self.source.get_parents(version_id)
 
2854
                parents = parent_map[version_id]
2840
2855
                # check that its will be a consistent copy:
2841
2856
                for parent in parents:
2842
2857
                    # if source has the parent, we must already have it