summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2014-11-21 15:58:21 -0600
committerMichael Merickel <michael@merickel.org>2014-12-26 22:49:19 -0600
commita1a5306b89bc652ad089551f0976a8b5f68d6b63 (patch)
tree3b32750487a9d40a15c6b1be3147074990cc88cc
parenta52326b00b843b94b569d35a8d91a2a4c78b56a0 (diff)
downloadpyramid-a1a5306b89bc652ad089551f0976a8b5f68d6b63.tar.gz
pyramid-a1a5306b89bc652ad089551f0976a8b5f68d6b63.tar.bz2
pyramid-a1a5306b89bc652ad089551f0976a8b5f68d6b63.zip
optimize the conflict resolution to occur against only executed actions
-rw-r--r--pyramid/config/__init__.py13
1 files changed, 12 insertions, 1 deletions
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index 740c9c47d..1a9cc3f5a 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -1112,9 +1112,20 @@ class ActionState(object):
# ensures that the previously executed actions have no new
# conflicts.
if self.actions:
+ # Only resolve the new actions against executed_actions
+ # instead of everything to avoid redundant checks.
+ # Assume ``actions = resolveConflicts([A, B, C])`` which
+ # after conflict checks, resulted in ``actions == [A]``
+ # then we know action A won out or a conflict would have
+ # been raised. Thus, when action D is added later, we only
+ # need to check the new action against A.
+ # ``actions = resolveConflicts([A, D]) should drop the
+ # number of redundant checks down from O(n^2) closer to
+ # O(n lg n).
+ pending_actions = resume(resolveConflicts(
+ executed_actions + self.actions))
all_actions.extend(self.actions)
self.actions = []
- pending_actions = resume(resolveConflicts(all_actions))
action = next(pending_actions, None)
if action is None: