# # patch "ChangeLog" # from [304f4c134fbf6ec5457ffc731c82a7e031bc7bbc] # to [cc5ee96bf067ff3952cc6bac909501eb17f66ec2] # # patch "change_set.cc" # from [f680797285e20aa2ff83233d95e7d2ac111443bb] # to [bd5f0a03f8512b1319cb9c2323a3aa81f8d67b1c] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,11 @@ +2005-04-21 Nathaniel Smith + + * change_set.cc (apply_path_rearrangement_can_fastpath) + (apply_path_rearrangement_fastpath) + (apply_path_rearrangement_slowpath, apply_path_rearrangement): + Refactor into pieces, so all versions of apply_path_rearrangement + can take a fast-path when possible. + 2005-04-20 Nathaniel Smith * Makefile.am (EXTRA_DIST): Put $(wildcard) around "debian/*", so --- change_set.cc +++ change_set.cc @@ -2464,18 +2464,6 @@ // application stuff void -apply_path_rearrangement(path_set const & old_ps, - change_set::path_rearrangement const & pr, - path_set & new_ps) -{ - pr.check_sane(); - change_set::path_rearrangement a, b, c; - a.added_files = old_ps; - concatenate_rearrangements(a, pr, c); - new_ps = c.added_files; -} - -void build_pure_addition_change_set(manifest_map const & man, change_set & cs) { @@ -2568,30 +2556,70 @@ } } -// quick, optimistic and destructive version +static inline bool +apply_path_rearrangement_can_fastpath(change_set::path_rearrangement const & pr) +{ + return pr.added_files.empty() + && pr.renamed_files.empty() + && pr.renamed_dirs.empty() + && pr.deleted_dirs.empty(); +} + +static inline void +apply_path_rearrangement_fastpath(change_set::path_rearrangement const & pr, + path_set & ps) +{ + pr.check_sane(); + // fast path for simple drop-or-nothing file operations + for (std::set::const_iterator i = pr.deleted_files.begin(); + i != pr.deleted_files.end(); ++i) + { + I(ps.find(*i) != ps.end()); + ps.erase(*i); + } +} + +static inline void +apply_path_rearrangement_slowpath(path_set const & old_ps, + change_set::path_rearrangement const & pr, + path_set & new_ps) +{ + pr.check_sane(); + change_set::path_rearrangement a, b; + a.added_files = old_ps; + concatenate_rearrangements(a, pr, b); + new_ps = b.added_files; +} + void +apply_path_rearrangement(path_set const & old_ps, + change_set::path_rearrangement const & pr, + path_set & new_ps) +{ + if (apply_path_rearrangement_can_fastpath(pr)) + { + new_ps = old_ps; + apply_path_rearrangement_fastpath(pr, new_ps); + } + else + { + apply_path_rearrangement_slowpath(old_ps, pr, new_ps); + } +} + +// destructive version +void apply_path_rearrangement(change_set::path_rearrangement const & pr, path_set & ps) { - pr.check_sane(); - if (pr.added_files.empty() - && pr.renamed_files.empty() - && pr.renamed_dirs.empty() - && pr.deleted_dirs.empty()) + if (apply_path_rearrangement_can_fastpath(pr)) { - // fast path for simple drop-or-nothing file operations - for (std::set::const_iterator i = pr.deleted_files.begin(); - i != pr.deleted_files.end(); ++i) - { - I(ps.find(*i) != ps.end()); - ps.erase(*i); - } + apply_path_rearrangement_fastpath(pr, ps); } else { - // fall back to the slow way - path_set tmp; - apply_path_rearrangement(ps, pr, tmp); + path_set tmp = ps; + apply_path_rearrangement_slowpath(ps, pr, tmp); ps = tmp; } }