diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2022-03-08 10:57:52 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2022-03-08 10:59:20 +0200 |
commit | 2ede341d59b4ab259caf808dfa65c0ac380ba347 (patch) | |
tree | a69e7b9f6a943692cc81b22cd98c8df97c1e9e19 /libbuild2/algorithm.cxx | |
parent | c5022fa04b64a9b572cd468837b934eaf5999e1a (diff) |
Improve performance of update during match for multiple targets
Diffstat (limited to 'libbuild2/algorithm.cxx')
-rw-r--r-- | libbuild2/algorithm.cxx | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index cbf0495..d72e95e 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -2119,6 +2119,75 @@ namespace build2 } } + bool + update_during_match (tracer& trace, + action a, + prerequisite_targets& pts, + uintptr_t mask) + { + // On the first pass detect and handle unchanged tragets. Note that we + // have to do it in a separate pass since we cannot call matched_state() + // once we've switched the phase. + // + context* ctx (nullptr); + + for (prerequisite_target& p: pts) + { + if ((p.include & mask) != 0) + { + if (p.target != nullptr) + { + const target& pt (*p.target); + + target_state os (pt.matched_state (a)); + + if (os != target_state::unchanged) + { + if (ctx == nullptr) + ctx = &pt.ctx; + + p.data = static_cast<uintptr_t> (os); + continue; + } + } + + p.data = 0; + } + } + + // If all unchanged, we are done. + // + if (ctx == nullptr) + return false; + + phase_switch ps (*ctx, run_phase::execute); + + bool r (false); + + for (prerequisite_target& p: pts) + { + if ((p.include & mask) != 0 && p.data != 0) + { + const target& pt (*p.target); + + target_state os (static_cast<target_state> (p.data)); + target_state ns (execute_direct (a, pt)); + + if (ns != os && ns != target_state::unchanged) + { + l6 ([&]{trace << "updated " << pt + << "; old state " << os + << "; new state " << ns;}); + r = true; + } + + p.data = 0; + } + } + + return r; + } + static inline void blank_adhoc_member (const target*&) { |