From 2db9879e1b4671c412b50a8a3c67eda1c6c95d93 Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Mon, 18 Feb 2002 22:34:59 +0000 Subject: Efficiency: On the Taskmaster's Walker's out-of-date checks, don't return any children if the node itself has already been visited. --- src/CHANGES.txt | 3 +++ src/engine/SCons/Taskmaster.py | 4 ++++ src/engine/SCons/TaskmasterTests.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d3f6aa0..b364ac7 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -65,6 +65,9 @@ RELEASE 0.05 - - Add preliminary support for Unicode strings. + - Efficiency: don't scan dependencies more than once during the + walk of a tree. + From Anthony Roach: - Make the scons script return an error code on failures. diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 558845d..cdee378 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -166,6 +166,10 @@ class Taskmaster: def __init__(self, targets=[], tasker=Task, calc=Calc()): def out_of_date(node): + if node.get_state(): + # The state is set, so someone has already been here + # (finished or currently executing). Find another one. + return [] # Scan the file before fetching its children(). node.scan() return filter(lambda x: x.get_state() != SCons.Node.up_to_date, diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index 0d7a7ad..32a1110 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -32,6 +32,7 @@ import SCons.Errors built = None executed = None +scan_called = 0 class Node: def __init__(self, name, kids = [], scans = []): @@ -58,6 +59,8 @@ class Node: return self.kids def scan(self): + global scan_called + scan_called = scan_called + 1 self.kids = self.kids + self.scans for scan in self.scans: scan.parents.append(self) @@ -240,6 +243,36 @@ class TaskmasterTestCase(unittest.TestCase): assert t.get_target() == n3 t.executed() assert tm.next_task() == None + + n1 = Node("n1") + n2 = Node("n2") + n3 = Node("n3", [n1, n2]) + n4 = Node("n4", [n3]) + n5 = Node("n5", [n3]) + global scan_called + scan_called = 0 + tm = SCons.Taskmaster.Taskmaster([n4]) + t = tm.next_task() + assert t.get_target() == n1 + t.executed() + t = tm.next_task() + assert t.get_target() == n2 + t.executed() + t = tm.next_task() + assert t.get_target() == n3 + t.executed() + t = tm.next_task() + assert t.get_target() == n4 + t.executed() + assert tm.next_task() == None + assert scan_called == 4, scan_called + + tm = SCons.Taskmaster.Taskmaster([n5]) + t = tm.next_task() + assert t.get_target() == n5, t.get_target() + t.executed() + assert tm.next_task() == None + assert scan_called == 5, scan_called def test_cycle_detection(self): n1 = Node("n1") -- cgit v0.12