From a85b9070cb37103c45e0e9b58732b4d92c09288b Mon Sep 17 00:00:00 2001
From: Todd Gamblin <tgamblin@llnl.gov>
Date: Fri, 20 Dec 2019 23:38:23 -0800
Subject: [PATCH] performance: avoid repeated DB locking on view generation

`ViewDescriptor.regenerate()` checks repeatedly whether packages are
installed and also does a lot of DB queries.  Put a read transaction
around the whole thing to avoid repeatedly locking and unlocking the DB.
---
 lib/spack/spack/environment.py | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py
index 4a23c52622..f7a1310459 100644
--- a/lib/spack/spack/environment.py
+++ b/lib/spack/spack/environment.py
@@ -516,20 +516,23 @@ def regenerate(self, all_specs, roots):
             if spec.concrete:  # Do not link unconcretized roots
                 specs_for_view.append(spec.copy(deps=('link', 'run')))
 
-        installed_specs_for_view = set(s for s in specs_for_view
-                                       if s in self and s.package.installed)
+        # regeneration queries the database quite a bit; this read
+        # transaction ensures that we don't repeatedly lock/unlock.
+        with spack.store.db.read_transaction():
+            installed_specs_for_view = set(
+                s for s in specs_for_view if s in self and s.package.installed)
 
-        view = self.view()
+            view = self.view()
 
-        view.clean()
-        specs_in_view = set(view.get_all_specs())
-        tty.msg("Updating view at {0}".format(self.root))
+            view.clean()
+            specs_in_view = set(view.get_all_specs())
+            tty.msg("Updating view at {0}".format(self.root))
 
-        rm_specs = specs_in_view - installed_specs_for_view
-        view.remove_specs(*rm_specs, with_dependents=False)
+            rm_specs = specs_in_view - installed_specs_for_view
+            view.remove_specs(*rm_specs, with_dependents=False)
 
-        add_specs = installed_specs_for_view - specs_in_view
-        view.add_specs(*add_specs, with_dependencies=False)
+            add_specs = installed_specs_for_view - specs_in_view
+            view.add_specs(*add_specs, with_dependencies=False)
 
 
 class Environment(object):
-- 
GitLab