Make ProviderIndexes mergeable, so we can cache them per-repo.
This commit is contained in:
parent
bf028990e7
commit
cf2f902b82
3 changed files with 57 additions and 8 deletions
|
@ -224,12 +224,20 @@ def all_packages(self):
|
||||||
yield self.get(name)
|
yield self.get(name)
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def provider_index(self):
|
||||||
|
"""Merged ProviderIndex from all Repos in the RepoPath."""
|
||||||
|
if self._provider_index is None:
|
||||||
|
self._provider_index = ProviderIndex()
|
||||||
|
for repo in reversed(self.repos):
|
||||||
|
self._provider_index.merge(repo.provider_index)
|
||||||
|
|
||||||
|
return self._provider_index
|
||||||
|
|
||||||
|
|
||||||
@_autospec
|
@_autospec
|
||||||
def providers_for(self, vpkg_spec):
|
def providers_for(self, vpkg_spec):
|
||||||
if self._provider_index is None:
|
providers = self.provider_index.providers_for(vpkg_spec)
|
||||||
self._provider_index = ProviderIndex(self.all_package_names())
|
|
||||||
|
|
||||||
providers = self._provider_index.providers_for(vpkg_spec)
|
|
||||||
if not providers:
|
if not providers:
|
||||||
raise UnknownPackageError(vpkg_spec.name)
|
raise UnknownPackageError(vpkg_spec.name)
|
||||||
return providers
|
return providers
|
||||||
|
@ -603,12 +611,19 @@ def purge(self):
|
||||||
self._instances.clear()
|
self._instances.clear()
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def provider_index(self):
|
||||||
|
"""A provider index with names *specific* to this repo."""
|
||||||
|
if self._provider_index is None:
|
||||||
|
namespaced_names = ['%s.%s' % (self.namespace, n)
|
||||||
|
for n in self.all_package_names()]
|
||||||
|
self._provider_index = ProviderIndex(namespaced_names)
|
||||||
|
return self._provider_index
|
||||||
|
|
||||||
|
|
||||||
@_autospec
|
@_autospec
|
||||||
def providers_for(self, vpkg_spec):
|
def providers_for(self, vpkg_spec):
|
||||||
if self._provider_index is None:
|
providers = self.provider_index.providers_for(vpkg_spec)
|
||||||
self._provider_index = ProviderIndex(self.all_package_names())
|
|
||||||
|
|
||||||
providers = self._provider_index.providers_for(vpkg_spec)
|
|
||||||
if not providers:
|
if not providers:
|
||||||
raise UnknownPackageError(vpkg_spec.name)
|
raise UnknownPackageError(vpkg_spec.name)
|
||||||
return providers
|
return providers
|
||||||
|
|
|
@ -41,3 +41,9 @@ def test_write_and_read(self):
|
||||||
q = ProviderIndex.from_yaml(istream)
|
q = ProviderIndex.from_yaml(istream)
|
||||||
|
|
||||||
self.assertTrue(p == q)
|
self.assertTrue(p == q)
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy(self):
|
||||||
|
p = ProviderIndex(spack.repo.all_package_names())
|
||||||
|
q = p.copy()
|
||||||
|
self.assertTrue(p == q)
|
||||||
|
|
|
@ -209,5 +209,33 @@ def from_yaml(stream):
|
||||||
return index
|
return index
|
||||||
|
|
||||||
|
|
||||||
|
def merge(self, other):
|
||||||
|
"""Merge `other` ProviderIndex into this one."""
|
||||||
|
other = other.copy() # defensive copy.
|
||||||
|
|
||||||
|
for pkg in other.providers:
|
||||||
|
if pkg not in self.providers:
|
||||||
|
self.providers[pkg] = other.providers[pkg]
|
||||||
|
continue
|
||||||
|
|
||||||
|
spdict, opdict = self.providers[pkg], other.providers[pkg]
|
||||||
|
for provided_spec in opdict:
|
||||||
|
if provided_spec not in spdict:
|
||||||
|
spdict[provided_spec] = opdict[provided_spec]
|
||||||
|
continue
|
||||||
|
|
||||||
|
spdict[provided_spec] += opdict[provided_spec]
|
||||||
|
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
"""Deep copy of this ProviderIndex."""
|
||||||
|
clone = ProviderIndex()
|
||||||
|
clone.providers = dict(
|
||||||
|
(name, dict((vpkg, set((p.copy() for p in pset)))
|
||||||
|
for vpkg, pset in pdict.items()))
|
||||||
|
for name, pdict in self.providers.items())
|
||||||
|
return clone
|
||||||
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.providers == other.providers
|
return self.providers == other.providers
|
||||||
|
|
Loading…
Reference in a new issue