13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
60
60
return 'DictParentsProvider(%r)' % self.ancestry
62
62
def get_parent_map(self, keys):
63
"""See _StackedParentsProvider.get_parent_map"""
63
"""See StackedParentsProvider.get_parent_map"""
64
64
ancestry = self.ancestry
65
65
return dict((k, ancestry[k]) for k in keys if k in ancestry)
68
class _StackedParentsProvider(object):
67
@deprecated_function(deprecated_in((1, 16, 0)))
68
def _StackedParentsProvider(*args, **kwargs):
69
return StackedParentsProvider(*args, **kwargs)
71
class StackedParentsProvider(object):
72
"""A parents provider which stacks (or unions) multiple providers.
74
The providers are queries in the order of the provided parent_providers.
70
77
def __init__(self, parent_providers):
71
78
self._parent_providers = parent_providers
73
80
def __repr__(self):
74
return "_StackedParentsProvider(%r)" % self._parent_providers
81
return "%s(%r)" % (self.__class__.__name__, self._parent_providers)
76
83
def get_parent_map(self, keys):
77
84
"""Get a mapping of keys => parents
121
128
self._get_parent_map = self._real_provider.get_parent_map
123
130
self._get_parent_map = get_parent_map
125
self._cache_misses = True
132
self.enable_cache(True)
127
134
def __repr__(self):
128
135
return "%s(%r)" % (self.__class__.__name__, self._real_provider)
133
140
raise AssertionError('Cache enabled when already enabled.')
135
142
self._cache_misses = cache_misses
143
self.missing_keys = set()
137
145
def disable_cache(self):
138
146
"""Disable and clear the cache."""
139
147
self._cache = None
148
self._cache_misses = None
149
self.missing_keys = set()
141
151
def get_cached_map(self):
142
152
"""Return any cached get_parent_map values."""
143
153
if self._cache is None:
145
return dict((k, v) for k, v in self._cache.items()
155
return dict(self._cache)
148
157
def get_parent_map(self, keys):
149
"""See _StackedParentsProvider.get_parent_map."""
150
# Hack to build up the caching logic.
151
ancestry = self._cache
153
# Caching is disabled.
154
missing_revisions = set(keys)
158
"""See StackedParentsProvider.get_parent_map."""
161
cache = self._get_parent_map(keys)
157
missing_revisions = set(key for key in keys if key not in ancestry)
158
if missing_revisions:
159
parent_map = self._get_parent_map(missing_revisions)
160
ancestry.update(parent_map)
161
if self._cache_misses:
162
# None is never a valid parents list, so it can be used to
164
ancestry.update(dict((k, None) for k in missing_revisions
165
if k not in parent_map))
166
present_keys = [k for k in keys if ancestry.get(k) is not None]
167
return dict((k, ancestry[k]) for k in present_keys)
163
needed_revisions = set(key for key in keys if key not in cache)
164
# Do not ask for negatively cached keys
165
needed_revisions.difference_update(self.missing_keys)
167
parent_map = self._get_parent_map(needed_revisions)
168
cache.update(parent_map)
169
if self._cache_misses:
170
for key in needed_revisions:
171
if key not in parent_map:
172
self.note_missing_key(key)
175
value = cache.get(key)
176
if value is not None:
180
def note_missing_key(self, key):
181
"""Note that key is a missing key."""
182
if self._cache_misses:
183
self.missing_keys.add(key)
170
186
class Graph(object):
600
616
all_unique_searcher._iterations)
601
617
unique_tip_searchers = next_unique_searchers
603
@symbol_versioning.deprecated_method(symbol_versioning.one_one)
604
def get_parents(self, revisions):
605
"""Find revision ids of the parents of a list of revisions
607
A list is returned of the same length as the input. Each entry
608
is a list of parent ids for the corresponding input revision.
610
[NULL_REVISION] is used as the parent of the first user-committed
611
revision. Its parent list is empty.
613
If the revision is not present (i.e. a ghost), None is used in place
614
of the list of parents.
616
Deprecated in bzr 1.2 - please see get_parent_map.
618
parents = self.get_parent_map(revisions)
619
return [parents.get(r, None) for r in revisions]
621
619
def get_parent_map(self, revisions):
622
620
"""Get a map of key:parent_list for revisions.
1470
1468
The recipe allows reconstruction of the same results at a later date
1471
1469
without knowing all the found keys. The essential elements are a list
1472
of keys to start and and to stop at. In order to give reproducible
1470
of keys to start and to stop at. In order to give reproducible
1473
1471
results when ghosts are encountered by a search they are automatically
1474
1472
added to the exclude list (or else ghost filling may alter the
1495
1493
return self._keys
1497
1495
def is_empty(self):
1498
"""Return true if the search lists 1 or more revisions."""
1496
"""Return false if the search lists 1 or more revisions."""
1499
1497
return self._recipe[3] == 0
1501
1499
def refine(self, seen, referenced):
1565
1563
def _get_keys(self, graph):
1566
1564
NULL_REVISION = revision.NULL_REVISION
1567
1565
keys = [key for (key, parents) in graph.iter_ancestry(self.heads)
1568
if key != NULL_REVISION]
1566
if key != NULL_REVISION and parents is not None]
1571
1569
def is_empty(self):
1572
"""Return true if the search lists 1 or more revisions."""
1570
"""Return false if the search lists 1 or more revisions."""
1573
1571
if revision.NULL_REVISION in self.heads:
1574
1572
return len(self.heads) == 1