~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/versionedfile.py

(gz) Change minimum required testtools version for selftest to 0.9.5 for
 unicode fixes (Martin [gz])

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
 
2
#
 
3
# Authors:
 
4
#   Johan Rydberg <jrydberg@gnu.org>
2
5
#
3
6
# This program is free software; you can redistribute it and/or modify
4
7
# it under the terms of the GNU General Public License as published by
28
31
 
29
32
from bzrlib import (
30
33
    annotate,
31
 
    bencode,
32
34
    errors,
33
35
    graph as _mod_graph,
34
36
    groupcompress,
38
40
    multiparent,
39
41
    tsort,
40
42
    revision,
 
43
    ui,
41
44
    )
 
45
from bzrlib.graph import DictParentsProvider, Graph, StackedParentsProvider
 
46
from bzrlib.transport.memory import MemoryTransport
42
47
""")
43
48
from bzrlib.registry import Registry
44
49
from bzrlib.textmerge import TextMerge
 
50
from bzrlib import bencode
45
51
 
46
52
 
47
53
adapter_registry = Registry()
924
930
 
925
931
    The use of tuples allows a single code base to support several different
926
932
    uses with only the mapping logic changing from instance to instance.
927
 
 
928
 
    :ivar _immediate_fallback_vfs: For subclasses that support stacking,
929
 
        this is a list of other VersionedFiles immediately underneath this
930
 
        one.  They may in turn each have further fallbacks.
931
933
    """
932
934
 
933
935
    def add_lines(self, key, parents, lines, parent_texts=None,
1191
1193
    def _extract_blocks(self, version_id, source, target):
1192
1194
        return None
1193
1195
 
1194
 
    def _transitive_fallbacks(self):
1195
 
        """Return the whole stack of fallback versionedfiles.
1196
 
 
1197
 
        This VersionedFiles may have a list of fallbacks, but it doesn't
1198
 
        necessarily know about the whole stack going down, and it can't know
1199
 
        at open time because they may change after the objects are opened.
1200
 
        """
1201
 
        all_fallbacks = []
1202
 
        for a_vfs in self._immediate_fallback_vfs:
1203
 
            all_fallbacks.append(a_vfs)
1204
 
            all_fallbacks.extend(a_vfs._transitive_fallbacks())
1205
 
        return all_fallbacks
1206
 
 
1207
1196
 
1208
1197
class ThunkedVersionedFiles(VersionedFiles):
1209
1198
    """Storage for many versioned files thunked onto a 'VersionedFile' class.
1448
1437
        # line data for locally held keys.
1449
1438
        self._lines = {}
1450
1439
        # key lookup providers
1451
 
        self._providers = [_mod_graph.DictParentsProvider(self._parents)]
 
1440
        self._providers = [DictParentsProvider(self._parents)]
1452
1441
 
1453
1442
    def plan_merge(self, ver_a, ver_b, base=None):
1454
1443
        """See VersionedFile.plan_merge"""
1461
1450
 
1462
1451
    def plan_lca_merge(self, ver_a, ver_b, base=None):
1463
1452
        from bzrlib.merge import _PlanLCAMerge
1464
 
        graph = _mod_graph.Graph(self)
 
1453
        graph = Graph(self)
1465
1454
        new_plan = _PlanLCAMerge(ver_a, ver_b, self, (self._file_id,), graph).plan_merge()
1466
1455
        if base is None:
1467
1456
            return new_plan
1519
1508
            result[revision.NULL_REVISION] = ()
1520
1509
        self._providers = self._providers[:1] + self.fallback_versionedfiles
1521
1510
        result.update(
1522
 
            _mod_graph.StackedParentsProvider(
1523
 
                self._providers).get_parent_map(keys))
 
1511
            StackedParentsProvider(self._providers).get_parent_map(keys))
1524
1512
        for key, parents in result.iteritems():
1525
1513
            if parents == ():
1526
1514
                result[key] = (revision.NULL_REVISION,)
1872
1860
    for prefix in sorted(per_prefix_map):
1873
1861
        present_keys.extend(reversed(tsort.topo_sort(per_prefix_map[prefix])))
1874
1862
    return present_keys
1875
 
 
1876
 
 
1877
 
class _KeyRefs(object):
1878
 
 
1879
 
    def __init__(self, track_new_keys=False):
1880
 
        # dict mapping 'key' to 'set of keys referring to that key'
1881
 
        self.refs = {}
1882
 
        if track_new_keys:
1883
 
            # set remembering all new keys
1884
 
            self.new_keys = set()
1885
 
        else:
1886
 
            self.new_keys = None
1887
 
 
1888
 
    def clear(self):
1889
 
        if self.refs:
1890
 
            self.refs.clear()
1891
 
        if self.new_keys:
1892
 
            self.new_keys.clear()
1893
 
 
1894
 
    def add_references(self, key, refs):
1895
 
        # Record the new references
1896
 
        for referenced in refs:
1897
 
            try:
1898
 
                needed_by = self.refs[referenced]
1899
 
            except KeyError:
1900
 
                needed_by = self.refs[referenced] = set()
1901
 
            needed_by.add(key)
1902
 
        # Discard references satisfied by the new key
1903
 
        self.add_key(key)
1904
 
 
1905
 
    def get_new_keys(self):
1906
 
        return self.new_keys
1907
 
    
1908
 
    def get_unsatisfied_refs(self):
1909
 
        return self.refs.iterkeys()
1910
 
 
1911
 
    def _satisfy_refs_for_key(self, key):
1912
 
        try:
1913
 
            del self.refs[key]
1914
 
        except KeyError:
1915
 
            # No keys depended on this key.  That's ok.
1916
 
            pass
1917
 
 
1918
 
    def add_key(self, key):
1919
 
        # satisfy refs for key, and remember that we've seen this key.
1920
 
        self._satisfy_refs_for_key(key)
1921
 
        if self.new_keys is not None:
1922
 
            self.new_keys.add(key)
1923
 
 
1924
 
    def satisfy_refs_for_keys(self, keys):
1925
 
        for key in keys:
1926
 
            self._satisfy_refs_for_key(key)
1927
 
 
1928
 
    def get_referrers(self):
1929
 
        result = set()
1930
 
        for referrers in self.refs.itervalues():
1931
 
            result.update(referrers)
1932
 
        return result
1933
 
 
1934
 
 
1935