Merge pull request #3536 from Zweedeend/ticket_23837

Fixes #23837: Replace list with deque in migration-planner for improved performance.
This commit is contained in:
Carl Meyer 2014-11-15 18:56:52 +01:00
commit 1ed9b9e2e2
1 changed files with 10 additions and 7 deletions

View File

@ -1,4 +1,5 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from collections import deque
from django.db.migrations.state import ProjectState from django.db.migrations.state import ProjectState
from django.utils.datastructures import OrderedSet from django.utils.datastructures import OrderedSet
@ -100,26 +101,28 @@ class MigrationGraph(object):
def dfs(self, start, get_children): def dfs(self, start, get_children):
""" """
Dynamic programming based depth first search, for finding dependencies. Iterative depth first search, for finding dependencies.
""" """
visited = [] visited = deque()
visited.append(start) visited.append(start)
path = [start] path = [start]
stack = sorted(get_children(start)) stack = deque(sorted(get_children(start)))
while stack: while stack:
node = stack.pop(0) node = stack.popleft()
if node in path: if node in path:
raise CircularDependencyError() raise CircularDependencyError()
path.append(node) path.append(node)
visited.insert(0, node) visited.appendleft(node)
children = sorted(get_children(node)) children = sorted(get_children(node), reverse=True)
# reverse sorting is needed because prepending using deque.extendleft
# also effectively reverses values
if path[-1] == node: if path[-1] == node:
path.pop() path.pop()
stack = children + stack stack.extendleft(children)
return list(OrderedSet(visited)) return list(OrderedSet(visited))