Skip to content

Commit 35befe8

Browse files
scheibelptgamblin
authored andcommitted
experimental refactoring of hash functions
1 parent fd082ee commit 35befe8

File tree

3 files changed

+26
-21
lines changed

3 files changed

+26
-21
lines changed

lib/spack/spack/environment.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ def install(self, user_spec, concrete_spec=None, **install_args):
876876
# spec might be in the user_specs, but not installed.
877877
# TODO: Redo name-based comparison for old style envs
878878
spec = next(s for s in self.user_specs if s.satisfies(user_spec))
879-
concrete = self.specs_by_hash.get(spec.dag_hash(all_deps=True))
879+
concrete = self.specs_by_hash.get(spec.build_hash())
880880
if not concrete:
881881
concrete = spec.concretized()
882882
self._add_concrete_spec(spec, concrete)
@@ -988,7 +988,7 @@ def _add_concrete_spec(self, spec, concrete, new=True):
988988
# update internal lists of specs
989989
self.concretized_user_specs.append(spec)
990990

991-
h = concrete.dag_hash(all_deps=True)
991+
h = concrete.build_hash()
992992
self.concretized_order.append(h)
993993
self.specs_by_hash[h] = concrete
994994

@@ -1103,7 +1103,7 @@ def _to_lockfile_dict(self):
11031103
concrete_specs = {}
11041104
for spec in self.specs_by_hash.values():
11051105
for s in spec.traverse():
1106-
dag_hash_all = s.dag_hash(all_deps=True)
1106+
dag_hash_all = s.build_hash()
11071107
if dag_hash_all not in concrete_specs:
11081108
spec_dict = s.to_node_dict(all_deps=True)
11091109
spec_dict[s.name]['hash'] = s.dag_hash()
@@ -1164,7 +1164,7 @@ def _read_lockfile_dict(self, d):
11641164
self.specs_by_hash = {}
11651165
for _, spec in specs_by_hash.items():
11661166
dag_hash = spec.dag_hash()
1167-
build_hash = spec.dag_hash(all_deps=True)
1167+
build_hash = spec.build_hash()
11681168
if dag_hash in root_hashes:
11691169
old_hash_to_new[dag_hash] = build_hash
11701170

lib/spack/spack/spec.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,34 +1286,41 @@ def prefix(self):
12861286
def prefix(self, value):
12871287
self._prefix = Prefix(value)
12881288

1289-
def dag_hash(self, length=None, all_deps=False):
1289+
def dag_hash(self, length=None):
12901290
"""Return a hash of the entire spec DAG, including connectivity."""
12911291
if not self.concrete:
1292-
h = self._dag_hash(all_deps=all_deps)
1292+
h = self._dag_hash(all_deps=False)
12931293
# An upper bound of None is equivalent to len(h). An upper bound of
12941294
# 0 produces the empty string
12951295
return h[:length]
12961296

12971297
if not self._hash:
12981298
self._hash = self._dag_hash(all_deps=False)
12991299

1300+
return self._hash[:length]
1301+
1302+
def build_hash(self):
1303+
if not self.concrete:
1304+
return self._dag_hash(all_deps=True)
1305+
13001306
if not self._build_hash:
13011307
self._build_hash = self._dag_hash(all_deps=True)
13021308

1303-
h = self._build_hash if all_deps else self._hash
1304-
return h[:length]
1309+
return self._build_hash
13051310

13061311
def _dag_hash(self, all_deps=False):
13071312
yaml_text = syaml.dump(
13081313
self.to_node_dict(all_deps=all_deps),
13091314
default_flow_style=True,
13101315
width=maxint)
1311-
sha = hashlib.sha1(yaml_text.encode('utf-8'))
13121316

1317+
return self._encode_hash_content(yaml_text.encode('utf-8'))
1318+
1319+
def _encode_hash_content(self, bytes):
1320+
sha = hashlib.sha1(bytes)
13131321
b32_hash = base64.b32encode(sha.digest()).lower()
13141322
if sys.version_info[0] >= 3:
13151323
b32_hash = b32_hash.decode('utf-8')
1316-
13171324
return b32_hash
13181325

13191326
def dag_hash_bit_prefix(self, bits):
@@ -1329,13 +1336,8 @@ def full_hash(self, length=None):
13291336
self.to_node_dict(hash_function=lambda s: s.full_hash()),
13301337
default_flow_style=True, width=maxint)
13311338
package_hash = self.package.content_hash()
1332-
sha = hashlib.sha1(yaml_text.encode('utf-8') + package_hash)
1333-
1334-
b32_hash = base64.b32encode(sha.digest()).lower()
1335-
if sys.version_info[0] >= 3:
1336-
b32_hash = b32_hash.decode('utf-8')
1337-
1338-
self._full_hash = b32_hash
1339+
self._full_hash = self._encode_hash_content(
1340+
yaml_text.encode('utf-8') + package_hash)
13391341

13401342
return self._full_hash[:length]
13411343

@@ -1387,7 +1389,10 @@ def to_node_dict(self, hash_function=None, all_deps=False):
13871389
deps = self.dependencies_dict(deptype=deptypes)
13881390
if deps:
13891391
if hash_function is None:
1390-
hash_function = lambda s: s.dag_hash(all_deps=all_deps)
1392+
if all_deps:
1393+
hash_function = lambda s: s.build_hash()
1394+
else:
1395+
hash_function = lambda s: s.dag_hash()
13911396
d['dependencies'] = syaml_dict([
13921397
(name,
13931398
syaml_dict([
@@ -1408,7 +1413,7 @@ def to_dict(self, all_deps=False):
14081413
node = s.to_node_dict(all_deps=all_deps)
14091414
node[s.name]['hash'] = s.dag_hash()
14101415
if all_deps:
1411-
node[s.name]['build_hash'] = s.dag_hash(all_deps=True)
1416+
node[s.name]['build_hash'] = s.build_hash()
14121417
node_list.append(node)
14131418

14141419
return syaml_dict([('spec', node_list)])

lib/spack/spack/test/cmd/env.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,8 +676,8 @@ def test_read_old_lock_and_write_new(tmpdir):
676676
# When the lockfile is rewritten, it should adopt the new hash scheme
677677
# which accounts for all dependencies, including build dependencies
678678
assert hashes == set([
679-
x.dag_hash(all_deps=True),
680-
y.dag_hash(all_deps=True)])
679+
x.build_hash(),
680+
y.build_hash()])
681681

682682

683683
@pytest.mark.usefixtures('config')

0 commit comments

Comments
 (0)