[pypy-commit] pypy taskengine-sorted-optionals: Use toposort + lattice
william_ml_leslie
pypy.commits at gmail.com
Mon May 9 13:09:06 EDT 2016
Author: William ML Leslie <william.leslie.ttg at gmail.com>
Branch: taskengine-sorted-optionals
Changeset: r84338:76a012472eda
Date: 2016-05-10 03:08 +1000
http://bitbucket.org/pypy/pypy/changeset/76a012472eda/
Log: Use toposort + lattice
diff --git a/rpython/translator/tool/taskengine.py b/rpython/translator/tool/taskengine.py
--- a/rpython/translator/tool/taskengine.py
+++ b/rpython/translator/tool/taskengine.py
@@ -22,44 +22,57 @@
except KeyError:
pass
- plan = []
- goal_walker = goals[::-1]
- flattened_goals = []
- for base_goal in goals[::-1]:
- goal_walker = [base_goal]
- dep_walker = [iter(self.tasks[base_goal.lstrip('?')][1])]
- while goal_walker:
- for subgoal in dep_walker[-1]:
- break
- else:
- # all dependencies are in flattened_goals. record
- # this goal.
- dep_walker.pop()
- goal = goal_walker.pop()
- if goal not in flattened_goals:
- flattened_goals.append(goal)
- continue
- if subgoal in goal_walker:
- raise RuntimeException('circular dependency')
+ optionality = dict((goal.lstrip('?'), goal.count('?'))
+ for goal in goals)
+ task_deps = {}
- # subgoal must be at least as optional as its parent
- qs = goal_walker[-1].count('?')
- if subgoal.count('?') < qs:
- subgoal = '?' * qs + subgoal.lstrip('?')
+ def will_do(task):
+ priority = optionality[task]
+ if priority < 1:
+ return True
+ return priority == 1 and task not in skip
- # we'll add this goal once we have its dependencies.
- goal_walker.append(subgoal)
- dep_walker.append(iter(self.tasks[subgoal.lstrip('?')][1]))
+ goal_walker = list(goals[::-1])
+ while goal_walker:
+ goal = goal_walker.pop()
+ qs = optionality.get(goal, 0)
+ if goal not in task_deps:
+ task_deps[goal] = deps = set()
+ for dep in self.tasks[goal][1]:
+ deps.add(dep.lstrip('?'))
+ for dep in self.tasks[goal][1]:
+ depname = dep.lstrip('?')
+ def_optionality = optionality.get(depname, 5)
+ dep_qs = max(qs, dep.count('?'))
+ if dep_qs < def_optionality:
+ optionality[depname] = dep_qs
+ goal_walker.append(depname)
+
+ for task, deps in list(task_deps.iteritems()):
+ if not will_do(task):
+ del task_deps[task]
+ else:
+ if task in deps:
+ deps.remove(task)
+ for dep in list(deps):
+ if not will_do(dep):
+ deps.remove(dep)
plan = []
- for name in flattened_goals:
- name = name.lstrip('?')
- if name in plan:
- continue
- will_run = name in flattened_goals or (
- '?' + name in flattened_goals and name not in skip)
- if will_run:
- plan.append(name)
+ seen = set()
+ tasks = list(task_deps)
+ while tasks:
+ remaining = []
+ for task in tasks:
+ if task_deps[task] - seen:
+ remaining.append(task)
+ else:
+ plan.append(task)
+ seen.add(task)
+ if len(remaining) == len(tasks):
+ raise RuntimeException('circular dependency')
+ tasks = remaining
+
self._plan_cache[key] = plan
return plan
More information about the pypy-commit
mailing list