database: maintain in-memory consistency on remove (#15777)

The performance improvements done in #14693 where leaving the DB in an inconsistent state when specs were removed from it. This PR updates the DB internal state whenever the DB is written to a file.

Note that we still cannot properly enumerate installed dependents, so there is a TODO in this code. Fixing that will require the dependents dictionaries in specs to be re-keyed (either by hash, or not keyed at all -- a list would do).  See #11983 for details.
This commit is contained in:
Massimiliano Culpo 2020-04-12 22:14:59 +02:00 committed by GitHub
parent 9209af950a
commit 7e46da73dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 1 deletions

View file

@ -1128,6 +1128,12 @@ def _remove(self, spec):
del self._data[key]
for dep in rec.spec.dependencies(_tracked_deps):
# FIXME: the two lines below needs to be updated once #11983 is
# FIXME: fixed. The "if" statement should be deleted and specs are
# FIXME: to be removed from dependents by hash and not by name.
# FIXME: See https://github.com/spack/spack/pull/15777#issuecomment-607818955
if dep._dependents.get(spec.name):
del dep._dependents[spec.name]
self._decrement_ref_count(dep)
if rec.deprecated_for:

View file

@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import pytest
import llnl.util.tty as tty
import spack.store
from spack.main import SpackCommand, SpackCommandError
@ -30,7 +31,7 @@ def test_multiple_matches(mutable_database):
@pytest.mark.db
def test_installed_dependents(mutable_database):
"""Test can't uninstall when ther are installed dependents."""
"""Test can't uninstall when there are installed dependents."""
with pytest.raises(SpackCommandError):
uninstall('-y', 'libelf')
@ -155,3 +156,16 @@ def db_specs():
assert len(mpileaks_specs) == 3
assert len(callpath_specs) == 3 # back to 3
assert len(mpi_specs) == 3
@pytest.mark.db
@pytest.mark.regression('15773')
def test_in_memory_consistency_when_uninstalling(
mutable_database, monkeypatch
):
"""Test that uninstalling doesn't raise warnings"""
def _warn(*args, **kwargs):
raise RuntimeError('a warning was triggered!')
monkeypatch.setattr(tty, 'warn', _warn)
# Now try to uninstall and check this doesn't trigger warnings
uninstall('-y', '-a')