← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:optimize-cleanteamparticipation into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:optimize-cleanteamparticipation into launchpad:master.

Commit message:
Optimize _cleanTeamParticipation

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #2036865 in Launchpad itself: "timeout removing person from team"
  https://bugs.launchpad.net/launchpad/+bug/2036865

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/451899

We did much more work than necessary to update `TeamParticipation` after removing a member from a team, scanning whole branches of the membership tree even when we could prove that they cannot possibly contribute to determining which participations we need to remove.  Prune the search tree more aggressively.  In the test case at hand, this takes the time for the `SELECT` part of this query from on the order of 6-7 seconds to on the order of 100 milliseconds.

The tests in `lp.registry.tests.test_teammembership` already exercise quite a number of scenarios here, and this should not change any observed behaviour other than speed.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:optimize-cleanteamparticipation into launchpad:master.
diff --git a/lib/lp/registry/model/teammembership.py b/lib/lp/registry/model/teammembership.py
index 0532e4a..0d5396b 100644
--- a/lib/lp/registry/model/teammembership.py
+++ b/lib/lp/registry/model/teammembership.py
@@ -499,12 +499,25 @@ def _cleanTeamParticipation(child, parent):
                      * onto the parent.team, since we want the top and
                      * bottom of the hierarchy to calculate the
                      * TeamParticipation. The query above makes sure
-                     * that we do this for all the ancestors.
+                     * that we do this for all the ancestors. We exclude
+                     * direct members that weren't already ancestors or
+                     * descendants of the child from the TeamParticipation
+                     * table, since they can't help us to establish entries
+                     * that we need to keep.
                      */
                     SELECT child.person, parent.team
                     FROM TeamMembership child
                         JOIN parent ON child.team = parent.person
                     WHERE child.status IN %(active_states)s
+                        AND child.person IN (
+                            SELECT team
+                            FROM TeamParticipation
+                            WHERE person = %(child)s
+                            UNION
+                            SELECT person
+                            FROM TeamParticipation
+                            WHERE team = %(child)s
+                        )
                 )
                 SELECT person, team
                 FROM parent