hashing: fix caching of dependency hashes in to_node_dict

This commit is contained in:
Gregory Becker 2019-07-23 09:37:48 -05:00 committed by Todd Gamblin
parent 4ff2773704
commit a086dda82f
2 changed files with 17 additions and 11 deletions

View file

@ -18,19 +18,22 @@ class SpecHashDescriptor(object):
We currently use different hashes for different use cases.
"""
def __init__(self, deptype=('link', 'run'), package_hash=False):
def __init__(self, deptype=('link', 'run'), package_hash=False, attr=None):
self.deptype = dp.canonical_deptype(deptype)
self.package_hash = package_hash
self.attr = attr
#: Default Hash descriptor, used by Spec.dag_hash() and stored in the DB.
dag_hash = SpecHashDescriptor(deptype=('link', 'run'), package_hash=False)
dag_hash = SpecHashDescriptor(deptype=('link', 'run'), package_hash=False,
attr='_hash')
#: Hash descriptor that includes build dependencies.
build_hash = SpecHashDescriptor(
deptype=('build', 'link', 'run'), package_hash=False)
deptype=('build', 'link', 'run'), package_hash=False, attr='_build_hash')
#: Full hash used in build pipelines to determine when to rebuild packages.
full_hash = SpecHashDescriptor(deptype=('link', 'run'), package_hash=True)
full_hash = SpecHashDescriptor(deptype=('link', 'run'), package_hash=True,
attr='_full_hash')

View file

@ -1305,7 +1305,7 @@ def _spec_hash(self, hash):
return b32_hash
def _cached_hash(self, length, attr, hash):
def _cached_hash(self, hash, length=None):
"""Helper function for storing a cached hash on the spec.
This will run _spec_hash() with the deptype and package_hash
@ -1315,13 +1315,16 @@ def _cached_hash(self, length, attr, hash):
Arguments:
hash (SpecHashDescriptor): type of hash to generate.
"""
hash_string = getattr(self, attr, None)
if not hash.attr:
return self._spec_hash(hash)[:length]
hash_string = getattr(self, hash.attr, None)
if hash_string:
return hash_string[:length]
else:
hash_string = self._spec_hash(hash)
if self.concrete:
setattr(self, attr, hash_string)
setattr(self, hash.attr, hash_string)
return hash_string[:length]
@ -1333,7 +1336,7 @@ def dag_hash(self, length=None):
revise this to include more detailed provenance when the
concretizer can more aggressievly reuse installed dependencies.
"""
return self._cached_hash(length, '_hash', ht.dag_hash)
return self._cached_hash(ht.dag_hash, length)
def build_hash(self, length=None):
"""Hash used to store specs in environments.
@ -1341,7 +1344,7 @@ def build_hash(self, length=None):
This hash includes build dependencies, and we need to preserve
them to be able to rebuild an entire environment for a user.
"""
return self._cached_hash(length, '_build_hash', ht.build_hash)
return self._cached_hash(ht.build_hash, length)
def full_hash(self, length=None):
"""Hash to determine when to rebuild packages in the build pipeline.
@ -1352,7 +1355,7 @@ def full_hash(self, length=None):
TODO: investigate whether to include build deps here.
"""
return self._cached_hash(length, '_full_hash', ht.full_hash)
return self._cached_hash(ht.full_hash, length)
def dag_hash_bit_prefix(self, bits):
"""Get the first <bits> bits of the DAG hash as an integer type."""
@ -1456,7 +1459,7 @@ def to_node_dict(self, hash=ht.dag_hash):
d['dependencies'] = syaml_dict([
(name,
syaml_dict([
('hash', dspec.spec._spec_hash(hash)),
('hash', dspec.spec._cached_hash(hash)),
('type', sorted(str(s) for s in dspec.deptypes))])
) for name, dspec in sorted(deps.items())
])