Hi Julian! On Wed, Mar 31, 2010 at 10:19:10AM +0100, Julian Foad wrote: > On Tue, 2010-03-30, Daniel Näslund wrote: > > Ping! This patch has not been revieved > > [...] > > > [[[ > > > Follow-up to r922176. Fix that tree changes were not considered when > > > determining if the wc has modifications. > > > > > > * subversion/libsvn_wc/revision_status.c > > > (analyze_status): Determine from status if a path has been added or > > > deleted. Do some optimizations to avoid having to do a text > > > comparison for determining if a wc has modifications. > > > > > > Suggested by: gstein > > > rhuijben > > > Approved by: ? > > > ]]] > > > > > Index: subversion/libsvn_wc/revision_status.c > > > =================================================================== > > > --- subversion/libsvn_wc/revision_status.c (revision 922398) > > > +++ subversion/libsvn_wc/revision_status.c (arbetskopia) > > > @@ -41,7 +41,8 @@ > > > }; > > > > > > /* An svn_wc__node_found_func_t callback function for analyzing the > > > status > > > - * of nodes */ > > > + * of nodes. Optimized to avoid text compares and unneccessary checks of > > > + * already set values. */ > > Be more specific: Which nodes does it analyze? How does it return the > result? What kinds of status can it report? (A reference to somewhere > else is fine, if the details are already explained somewhere else.) > Then the "Optimised ..." sentence should make more sense.
I've clarified exactly how the function is optimized and what parameters it takes. A doc comment should say what a func does, rather than how it does it. In that sence, my comment is a bit off. Still, someone reading a static func is surely going to look at the implementation as well. > > > static svn_error_t * > > > analyze_status(const char *local_abspath, > > > void *baton, > > > @@ -50,10 +51,9 @@ > > > struct walk_baton *wb = baton; > > > svn_revnum_t changed_rev; > > > svn_revnum_t revision; > > > + svn_revnum_t item_rev; > > > svn_depth_t depth; > > > svn_wc__db_status_t status; > > > - svn_boolean_t wc_root; > > > - svn_boolean_t switched; > > > > > > SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, > > > NULL, NULL, &changed_rev, > > > @@ -71,24 +71,36 @@ > > > wb->result->sparse_checkout = TRUE; > > > return SVN_NO_ERROR; > > > } > > > + else if (status == svn_wc__db_status_not_present) > > > + { > > > + return SVN_NO_ERROR; > > > + } > > > + else if (status == svn_wc__db_status_added > > > + || status == svn_wc__db_status_obstructed_add > > > + || status == svn_wc__db_status_deleted > > > + || status == svn_wc__db_status_obstructed_delete) > > > + { > > > + wb->result->modified = TRUE; > > > + } > > (Minor nit: "else" is redundant after a "return". I don't particularly > mind, but somebody objected to them the other day.) I'm insisting on my if-else construction. Just a matter of personal preferences. I think the if-else construction ties the function that part together and makes it more readable. Can I get your +1 for this? Daniel
Index: subversion/libsvn_wc/revision_status.c =================================================================== --- subversion/libsvn_wc/revision_status.c (revision 930178) +++ subversion/libsvn_wc/revision_status.c (working copy) @@ -40,8 +40,13 @@ struct walk_baton svn_wc__db_t *db; }; -/* An svn_wc__node_found_func_t callback function for analyzing the status - * of nodes */ +/* An svn_wc__node_found_func_t callback function for analyzing the wc + * status of LOCAL_ABSPATH. Since it can be invoked for a lot of paths in + * a wc but some data , i.e. if the wc is switched or has modifications, is + * expensive to calculate, we optimize by checking if those values are + * already set before runnning the db operations. The found status + * information is stored in BATON. Temporary allocations are made in + * SCRATCH_POOL. */ static svn_error_t * analyze_status(const char *local_abspath, void *baton, @@ -50,10 +55,9 @@ analyze_status(const char *local_abspath, struct walk_baton *wb = baton; svn_revnum_t changed_rev; svn_revnum_t revision; + svn_revnum_t item_rev; svn_depth_t depth; svn_wc__db_status_t status; - svn_boolean_t wc_root; - svn_boolean_t switched; SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, NULL, NULL, &changed_rev, @@ -71,24 +75,36 @@ analyze_status(const char *local_abspath, wb->result->sparse_checkout = TRUE; return SVN_NO_ERROR; } + else if (status == svn_wc__db_status_not_present) + { + return SVN_NO_ERROR; + } + else if (status == svn_wc__db_status_added + || status == svn_wc__db_status_obstructed_add + || status == svn_wc__db_status_deleted + || status == svn_wc__db_status_obstructed_delete) + { + wb->result->modified = TRUE; + } - if (status == svn_wc__db_status_not_present) - return SVN_NO_ERROR; - if (! wb->result->switched) { + svn_boolean_t wc_root; + svn_boolean_t switched; + SVN_ERR(svn_wc__check_wc_root(&wc_root, NULL, &switched, wb->db, local_abspath, scratch_pool)); wb->result->switched |= switched; } + item_rev = (wb->committed + ? changed_rev + : revision); + /* Added files have a revision of no interest */ - if (revision != SVN_INVALID_REVNUM) + if (item_rev != SVN_INVALID_REVNUM) { - svn_revnum_t item_rev = (wb->committed - ? changed_rev - : revision); if (wb->result->min_rev == SVN_INVALID_REVNUM || item_rev < wb->result->min_rev) @@ -101,22 +117,27 @@ analyze_status(const char *local_abspath, if (! wb->result->modified) { - svn_boolean_t text_mod; svn_boolean_t props_mod; SVN_ERR(svn_wc__props_modified(&props_mod, wb->db, local_abspath, scratch_pool)); + wb->result->modified |= props_mod; + } + if (! wb->result->modified) + { + svn_boolean_t text_mod; + SVN_ERR(svn_wc__internal_text_modified_p(&text_mod, wb->db, local_abspath, FALSE, TRUE, scratch_pool)); - wb->result->modified |= (text_mod || props_mod); + wb->result->modified |= text_mod; } - wb->result->sparse_checkout |= ((depth != svn_depth_infinity - && depth != svn_depth_unknown)); + wb->result->sparse_checkout |= (depth != svn_depth_infinity + && depth != svn_depth_unknown); return SVN_NO_ERROR; }