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)
|
||||
|
||||
|
||||
@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
|
||||
def providers_for(self, vpkg_spec):
|
||||
if self._provider_index is None:
|
||||
self._provider_index = ProviderIndex(self.all_package_names())
|
||||
|
||||
providers = self._provider_index.providers_for(vpkg_spec)
|
||||
providers = self.provider_index.providers_for(vpkg_spec)
|
||||
if not providers:
|
||||
raise UnknownPackageError(vpkg_spec.name)
|
||||
return providers
|
||||
|
@ -603,12 +611,19 @@ def purge(self):
|
|||
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
|
||||
def providers_for(self, vpkg_spec):
|
||||
if self._provider_index is None:
|
||||
self._provider_index = ProviderIndex(self.all_package_names())
|
||||
|
||||
providers = self._provider_index.providers_for(vpkg_spec)
|
||||
providers = self.provider_index.providers_for(vpkg_spec)
|
||||
if not providers:
|
||||
raise UnknownPackageError(vpkg_spec.name)
|
||||
return providers
|
||||
|
|
|
@ -41,3 +41,9 @@ def test_write_and_read(self):
|
|||
q = ProviderIndex.from_yaml(istream)
|
||||
|
||||
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
|
||||
|
||||
|
||||
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):
|
||||
return self.providers == other.providers
|
||||
|
|
Loading…
Reference in a new issue