summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-02-11 11:27:07 (GMT)
committerSteven Knight <knight@baldmt.com>2003-02-11 11:27:07 (GMT)
commit08d5aaf06f5030d59404a586164eb6121c538973 (patch)
tree603b1aa19ce8717891505490845e61bcc77eb0ac /src
parent0f5282ba0d7a5b96c2e5bec6eedb3027aa3fd52a (diff)
downloadSCons-08d5aaf06f5030d59404a586164eb6121c538973.zip
SCons-08d5aaf06f5030d59404a586164eb6121c538973.tar.gz
SCons-08d5aaf06f5030d59404a586164eb6121c538973.tar.bz2
Fix some performance problems with the --implicit-cache option. (Anthony Roach)
Diffstat (limited to 'src')
-rw-r--r--src/CHANGES.txt2
-rw-r--r--src/engine/SCons/Node/FS.py20
-rw-r--r--src/engine/SCons/Node/__init__.py36
-rw-r--r--src/engine/SCons/Sig/__init__.py36
4 files changed, 60 insertions, 34 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 068dc3d..a8c621d 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -96,6 +96,8 @@ RELEASE 0.11 - XXX
- Allow the same object files on Win32 to be linked into either
shared or static libraries.
+ - Cache implicit cache values when using --implicit-cache.
+
RELEASE 0.10 - Thu, 16 Jan 2003 04:11:46 -0600
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 2057797..651d280 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -850,34 +850,26 @@ class File(Entry):
else:
return 0
- def calc_signature(self, calc):
+ def calc_signature(self, calc, cache=None):
"""
Select and calculate the appropriate build signature for a File.
self - the File node
calc - the signature calculation module
+ cache - alternate node to use for the signature cache
returns - the signature
-
- This method does not store the signature in the node or
- in the .sconsign file.
"""
if self.has_builder():
if SCons.Sig.build_signature:
- if not hasattr(self, 'bsig'):
- self.set_bsig(calc.bsig(self.rfile()))
- return self.get_bsig()
+ return calc.bsig(self.rfile(), self)
else:
- if not hasattr(self, 'csig'):
- self.set_csig(calc.csig(self.rfile()))
- return self.get_csig()
+ return calc.csig(self.rfile(), self)
elif not self.rexists():
return None
else:
- if not hasattr(self, 'csig'):
- self.set_csig(calc.csig(self.rfile()))
- return self.get_csig()
-
+ return calc.csig(self.rfile(), self)
+
def store_csig(self):
self.dir.sconsign().set_csig(self.name, self.get_csig())
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index e1bc8f1..600c478 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -255,6 +255,22 @@ class Node:
return deps
+ # cache used to make implicit_factory fast.
+ implicit_factory_cache = {}
+
+ def implicit_factory(self, path):
+ """
+ Turn a cache implicit dependency path into a node.
+ This is called so many times that doing caching
+ here is a significant perforamnce boost.
+ """
+ try:
+ return self.implicit_factory_cache[path]
+ except KeyError:
+ n = self.builder.source_factory(path)
+ self.implicit_factory_cache[path] = n
+ return n
+
def scan(self):
"""Scan this node's dependents for implicit dependencies."""
# Don't bother scanning non-derived files, because we don't
@@ -269,7 +285,7 @@ class Node:
if implicit_cache and not implicit_deps_changed:
implicit = self.get_stored_implicit()
if implicit is not None:
- implicit = map(self.builder.source_factory, implicit)
+ implicit = map(self.implicit_factory, implicit)
self._add_child(self.implicit, implicit)
calc = SCons.Sig.default_calc
if implicit_deps_unchanged or calc.current(self, calc.bsig(self)):
@@ -306,33 +322,25 @@ class Node:
return
self.env = env
- def calc_signature(self, calc):
+ def calc_signature(self, calc, cache=None):
"""
Select and calculate the appropriate build signature for a node.
self - the node
calc - the signature calculation module
+ cache - alternate node to use for the signature cache
returns - the signature
-
- This method does not store the signature in the node or
- in the .sconsign file.
"""
if self.has_builder():
if SCons.Sig.build_signature:
- if not hasattr(self, 'bsig'):
- self.set_bsig(calc.bsig(self))
- return self.get_bsig()
+ return calc.bsig(self, cache)
else:
- if not hasattr(self, 'csig'):
- self.set_csig(calc.csig(self))
- return self.get_csig()
+ return calc.csig(self, cache)
elif not self.exists():
return None
else:
- if not hasattr(self, 'csig'):
- self.set_csig(calc.csig(self))
- return self.get_csig()
+ return calc.csig(self, cache)
def get_bsig(self):
"""Get the node's build signature (based on the signatures
diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py
index 939f36f..196d065 100644
--- a/src/engine/SCons/Sig/__init__.py
+++ b/src/engine/SCons/Sig/__init__.py
@@ -249,12 +249,13 @@ class Calculator:
self.module = module
self.max_drift = max_drift
- def bsig(self, node):
+ def bsig(self, node, cache=None):
"""
Generate a node's build signature, the digested signatures
of its dependency files and build information.
node - the node whose sources will be collected
+ cache - alternate node to use for the signature cache
returns - the build signature
This no longer handles the recursive descent of the
@@ -262,27 +263,50 @@ class Calculator:
already built and updated by someone else, if that's
what's wanted.
"""
- sigs = map(lambda n, c=self: n.calc_signature(c), node.children())
+
+ if cache is None: cache = node
+
+ bsig = cache.get_bsig()
+ if bsig is not None:
+ return bsig
+
+ children = node.children()
+
+ # double check bsig, because the call to childre() above may
+ # have set it:
+ bsig = cache.get_bsig()
+ if bsig is not None:
+ return bsig
+
+ sigs = map(lambda n, c=self: n.calc_signature(c), children)
if node.has_builder():
sigs.append(self.module.signature(node.builder_sig_adapter()))
bsig = self.module.collect(filter(lambda x: not x is None, sigs))
- node.set_bsig(bsig)
+ cache.set_bsig(bsig)
# don't store the bsig here, because it isn't accurate until
# the node is actually built.
return bsig
- def csig(self, node):
+ def csig(self, node, cache=None):
"""
Generate a node's content signature, the digested signature
of its content.
node - the node
+ cache - alternate node to use for the signature cache
returns - the content signature
"""
+
+ if cache is None: cache = node
+
+ csig = cache.get_csig()
+ if csig is not None:
+ return csig
+
if self.max_drift >= 0:
info = node.get_prevsiginfo()
else:
@@ -295,12 +319,12 @@ class Calculator:
csig = info[2]
# Set the csig here so it doesn't get recalculated unnecessarily
# and so it's set when the .sconsign file gets written
- node.set_csig(csig)
+ cache.set_csig(csig)
else:
csig = self.module.signature(node)
# Set the csig here so it doesn't get recalculated unnecessarily
# and so it's set when the .sconsign file gets written
- node.set_csig(csig)
+ cache.set_csig(csig)
if self.max_drift >= 0 and (time.time() - mtime) > self.max_drift:
node.store_csig()