From 2f604b2c8f21ae27eb50c19e084e9ab32acbd2c6 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sun, 21 Nov 2010 00:54:35 -0800 Subject: [PATCH] Don't re-check dependencies in a single run. If a depends on b depends on c, then if when we consider building a, we have to check b and c. If we then are asked about a2 which depends on b, there is no reason to re-check b and its dependencies; we already know it's done. This takes the time to do 'redo t/curse/all' the *second* time down from 1.0s to 0.13s. (make can still do it in 0.07s.) 'redo t/curse/all' the first time is down from 5.4s to to 4.6s. With -j4, from 3.0s to 2.5s. --- redo-ifchange.py | 3 +++ redo.py | 2 ++ state.py | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/redo-ifchange.py b/redo-ifchange.py index a9951b7..a70fc03 100755 --- a/redo-ifchange.py +++ b/redo-ifchange.py @@ -5,6 +5,8 @@ from helpers import debug, err, mkdirp, unlink def _dirty_deps(t, depth, fromdir): + if state.ismarked(t, fromdir): + return False # has already been checked during this session debug('%s?%s\n' % (depth, t)) stamptime = state.stamped(t, fromdir) if stamptime == None: @@ -29,6 +31,7 @@ def _dirty_deps(t, depth, fromdir): if dirty_deps(name, depth + ' ', fromdir=vars.BASE): #debug('%s-- DIRTY (sub)\n' % depth) return True + state.mark(t, fromdir) return False diff --git a/redo.py b/redo.py index b371d24..263e2fb 100755 --- a/redo.py +++ b/redo.py @@ -50,6 +50,8 @@ if is_root: mkdirp('%s/.redo' % base) for f in glob.glob('%s/.redo/lock*' % base): os.unlink(f) + for f in glob.glob('%s/.redo/mark^*' % base): + os.unlink(f) if not vars.DEPTH: diff --git a/state.py b/state.py index 2857c36..3f8591d 100644 --- a/state.py +++ b/state.py @@ -34,6 +34,7 @@ def _stampname(t, fromdir=None): def stamp(t): + mark(t) stampfile = _stampname(t) newstampfile = _sname('stamp' + str(os.getpid()), t) depfile = _sname('dep', t) @@ -65,6 +66,25 @@ def stamped(t, fromdir=None): return stamptime +def mark(t, fromdir=None): + try: + open(_sname('mark', t, fromdir), 'w').close() + except IOError, e: + if e.errno == errno.ENOENT: + pass # may happen if someone deletes our .redo dir + else: + raise + + +_marks = {} +def ismarked(t, fromdir=None): + if _marks.get((t,fromdir)): + return True + if os.path.exists(_sname('mark', t, fromdir)): + _marks[(t,fromdir)] = True + return True + + def is_generated(t): return os.path.exists(_sname('gen', t))