Author: cmpilato Date: Fri Jun 24 19:41:26 2011 New Revision: 1139418 URL: http://svn.apache.org/viewvc?rev=1139418&view=rev Log: In anticipation of future improvements, transmit pre-calculated final SHA1 checksums for file contents in the mod_dav_svn update response, and receive them in ra_serf. This should come at negligible cost to both client and server (we are *not* asking the server to calculate any SHA1's not already stored in the repsitory).
(Per discussion at http://svn.haxx.se/dev/archive-2011-05/0894.shtml) * subversion/mod_dav_svn/reports/update.c (add_helper, close_file): Grab the SHA1 checksum for files out of the FS (if readily available), and pass it across the wire. * subversion/libsvn_ra_serf/update.c (report_info_t): Add 'final_sha1_checksum' member. (start_report): Populate new 'final_sha1_checksum' report baton member if we find that information in the REPORT response. Modified: subversion/trunk/subversion/libsvn_ra_serf/update.c subversion/trunk/subversion/mod_dav_svn/reports/update.c Modified: subversion/trunk/subversion/libsvn_ra_serf/update.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/update.c?rev=1139418&r1=1139417&r2=1139418&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_ra_serf/update.c (original) +++ subversion/trunk/subversion/libsvn_ra_serf/update.c Fri Jun 24 19:41:26 2011 @@ -225,6 +225,7 @@ typedef struct report_info_t /* controlling file_baton and textdelta handler */ void *file_baton; const char *base_checksum; + const char *final_sha1_checksum; /* ### currently unused */ svn_txdelta_window_handler_t textdelta; void *textdelta_baton; @@ -1508,6 +1509,12 @@ start_report(svn_ra_serf__xml_parser_t * info->copyfrom_path = cf ? apr_pstrdup(info->pool, cf) : NULL; info->copyfrom_rev = cr ? SVN_STR_TO_REV(cr) : SVN_INVALID_REVNUM; + + info->final_sha1_checksum = + svn_xml_get_attr_value("sha1-checksum", attrs); + if (info->final_sha1_checksum) + info->final_sha1_checksum = apr_pstrdup(info->pool, + info->final_sha1_checksum); } else if ((state == OPEN_DIR || state == ADD_DIR) && strcmp(name.name, "delete-entry") == 0) @@ -1679,8 +1686,13 @@ start_report(svn_ra_serf__xml_parser_t * if (info->base_checksum) info->base_checksum = apr_pstrdup(info->pool, info->base_checksum); - info->fetch_file = TRUE; + info->final_sha1_checksum = + svn_xml_get_attr_value("sha1-checksum", attrs); + if (info->final_sha1_checksum) + info->final_sha1_checksum = apr_pstrdup(info->pool, + info->final_sha1_checksum); + info->fetch_file = TRUE; } else if (strcmp(name.name, "set-prop") == 0 || strcmp(name.name, "remove-prop") == 0) Modified: subversion/trunk/subversion/mod_dav_svn/reports/update.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/reports/update.c?rev=1139418&r1=1139417&r2=1139418&view=diff ============================================================================== --- subversion/trunk/subversion/mod_dav_svn/reports/update.c (original) +++ subversion/trunk/subversion/mod_dav_svn/reports/update.c Fri Jun 24 19:41:26 2011 @@ -295,6 +295,8 @@ add_helper(svn_boolean_t is_dir, const char *qname = apr_xml_quote_string(pool, child->name, 1); const char *elt; const char *real_path = get_real_fs_path(child, pool); + const char *bc_url_str = ""; + const char *sha1_checksum_str = ""; if (is_dir) { @@ -320,36 +322,39 @@ add_helper(svn_boolean_t is_dir, /* make sure that the BC_URL is xml attribute safe. */ bc_url = apr_xml_quote_string(pool, bc_url, 1); } + else + { + svn_checksum_t *sha1_checksum; + SVN_ERR(svn_fs_file_checksum(&sha1_checksum, svn_checksum_sha1, + uc->rev_root, real_path, FALSE, pool)); + if (sha1_checksum) + sha1_checksum_str = + apr_psprintf(pool, " sha1-checksum=\"%s\"", + svn_checksum_to_cstring(sha1_checksum, pool)); + } + + if (bc_url) + bc_url_str = apr_psprintf(pool, " bc-url=\"%s\"", bc_url); if (copyfrom_path == NULL) { - if (bc_url) - elt = apr_psprintf(pool, "<S:add-%s name=\"%s\" " - "bc-url=\"%s\">" DEBUG_CR, - DIR_OR_FILE(is_dir), qname, bc_url); - else - elt = apr_psprintf(pool, "<S:add-%s name=\"%s\">" DEBUG_CR, - DIR_OR_FILE(is_dir), qname); + elt = apr_psprintf(pool, + "<S:add-%s name=\"%s\"%s%s>" DEBUG_CR, + DIR_OR_FILE(is_dir), qname, bc_url_str, + sha1_checksum_str); } else { const char *qcopy = apr_xml_quote_string(pool, copyfrom_path, 1); - if (bc_url) - elt = apr_psprintf(pool, "<S:add-%s name=\"%s\" " - "copyfrom-path=\"%s\" copyfrom-rev=\"%ld\" " - "bc-url=\"%s\">" DEBUG_CR, - DIR_OR_FILE(is_dir), - qname, qcopy, copyfrom_revision, - bc_url); - else - elt = apr_psprintf(pool, "<S:add-%s name=\"%s\" " - "copyfrom-path=\"%s\"" - " copyfrom-rev=\"%ld\">" DEBUG_CR, - DIR_OR_FILE(is_dir), - qname, qcopy, copyfrom_revision); - + elt = apr_psprintf(pool, + "<S:add-%s name=\"%s\"%s%s " + "copyfrom-path=\"%s\" copyfrom-rev=\"%ld\">" + DEBUG_CR, + DIR_OR_FILE(is_dir), + bc_url, sha1_checksum_str, + qname, qcopy, copyfrom_revision); child->copyfrom = TRUE; } @@ -780,12 +785,26 @@ upd_close_file(void *file_baton, const c to fetch it. */ if ((! file->uc->send_all) && (! file->added) && file->text_changed) { + svn_checksum_t *sha1_checksum; + const char *real_path = get_real_fs_path(file, pool); + const char *sha1_digest = NULL; + + /* Try to grab the SHA1 checksum, if it's readily available, and + pump it down to the client, too. */ + SVN_ERR(svn_fs_file_checksum(&sha1_checksum, svn_checksum_sha1, + file->uc->rev_root, real_path, FALSE, pool)); + if (sha1_checksum) + sha1_digest = svn_checksum_to_cstring(sha1_checksum, pool); + SVN_ERR(dav_svn__brigade_printf (file->uc->bb, file->uc->output, - "<S:fetch-file%s%s%s/>" DEBUG_CR, + "<S:fetch-file%s%s%s%s%s%s/>" DEBUG_CR, file->base_checksum ? " base-checksum=\"" : "", file->base_checksum ? file->base_checksum : "", - file->base_checksum ? "\"" : "")); + file->base_checksum ? "\"" : "", + sha1_digest ? " sha1-checksum=\"" : "", + sha1_digest ? sha1_digest : "", + sha1_digest ? "\"" : "")); } if (text_checksum)