~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/graph.py

  • Committer: Aaron Bentley
  • Date: 2008-11-23 16:27:08 UTC
  • mto: This revision was merged to the branch mainline in revision 3892.
  • Revision ID: aaron@aaronbentley.com-20081123162708-17093o7m3obv7czs
Unify CachingExtraParentsProvider and CachingParentsProvider.

Show diffs side-by-side

added added

removed removed

Lines of Context:
99
99
 
100
100
 
101
101
class CachingParentsProvider(object):
102
 
    """A parents provider which will cache the revision => parents in a dict.
103
 
 
104
 
    This is useful for providers that have an expensive lookup.
105
 
    """
106
 
 
107
 
    def __init__(self, parent_provider):
108
 
        self._real_provider = parent_provider
109
 
        # Theoretically we could use an LRUCache here
110
 
        self._cache = {}
111
 
 
112
 
    def __repr__(self):
113
 
        return "%s(%r)" % (self.__class__.__name__, self._real_provider)
114
 
 
115
 
    def get_parent_map(self, keys):
116
 
        """See _StackedParentsProvider.get_parent_map"""
117
 
        needed = set()
118
 
        # If the _real_provider doesn't have a key, we cache a value of None,
119
 
        # which we then later use to realize we cannot provide a value for that
120
 
        # key.
121
 
        parent_map = {}
122
 
        cache = self._cache
123
 
        for key in keys:
124
 
            if key in cache:
125
 
                value = cache[key]
126
 
                if value is not None:
127
 
                    parent_map[key] = value
128
 
            else:
129
 
                needed.add(key)
130
 
 
131
 
        if needed:
132
 
            new_parents = self._real_provider.get_parent_map(needed)
133
 
            cache.update(new_parents)
134
 
            parent_map.update(new_parents)
135
 
            needed.difference_update(new_parents)
136
 
            cache.update(dict.fromkeys(needed, None))
137
 
        return parent_map
138
 
 
139
 
 
140
 
class CachingExtraParentsProvider(object):
141
102
    """ParentsProvider that allows extra parents.
142
103
 
143
104
    This class takes a callback that acts like get_parent_map, except that it
144
105
    may return un-asked-for parents.  These extras are cached, but filtered
145
106
    out of get_parent_map.
146
107
    """
147
 
    def __init__(self, get_parent_map, debug=False):
148
 
        self._get_parent_map = get_parent_map
149
 
        self._parents_map = None
 
108
    def __init__(self, parent_provider=None, get_parent_map=None, debug=False):
 
109
        self._real_provider = parent_provider
 
110
        if get_parent_map is None:
 
111
            self._get_parent_map = self._real_provider.get_parent_map
 
112
        else:
 
113
            self._get_parent_map = get_parent_map
 
114
        self._parents_map = {}
150
115
        self._debug = debug
151
116
        if self._debug:
152
117
            self._requested_parents = None
153
118
 
 
119
    def __repr__(self):
 
120
        return "%s(%r)" % (self.__class__.__name__, self._real_provider)
 
121
 
154
122
    def enable_cache(self):
155
123
        """Enable cache."""
156
124
        self._parents_map = {}
165
133
 
166
134
    def get_cached_map(self):
167
135
        """Return any cached get_parent_map values."""
168
 
        return self._parents_map
 
136
        if self._parents_map is None:
 
137
            return None
 
138
        return dict((k, v) for k, v in self._parents_map.items()
 
139
                    if v is not None)
169
140
 
170
141
    def get_parent_map(self, keys):
171
142
        """See RemoteRepository.get_parent_map."""
184
155
                        len(set(ancestry).intersection(parent_map)),
185
156
                        len(parent_map))
186
157
            ancestry.update(parent_map)
187
 
        present_keys = [k for k in keys if k in ancestry]
 
158
            ancestry.update(dict((k, None) for k in missing_revisions
 
159
                                 if k not in parent_map))
 
160
        present_keys = [k for k in keys if ancestry.get(k) is not None]
188
161
        if self._debug:
189
162
            if self._requested_parents is not None and len(ancestry) != 0:
190
163
                self._requested_parents.update(present_keys)