You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by iv...@apache.org on 2012/06/15 13:40:33 UTC
svn commit: r1350584 - in /subversion/trunk/subversion/libsvn_ra_serf:
ra_serf.h update.c
Author: ivan
Date: Fri Jun 15 11:40:33 2012
New Revision: 1350584
URL: http://svn.apache.org/viewvc?rev=1350584&view=rev
Log:
ra_serf: Do not fetch file from server if we already have the file with
same sha1 checksum in our pristine storage.
* subversion/libsvn_ra_serf/ra_serf.h
(type_and_checksum_props): New.
* subversion/libsvn_ra_serf/update.c
(try_get_wc_contents): New helper for svn_ra_serf__get_file().
(svn_ra_serf__get_file): Fetch sha1 checksum property if caller requested
file contents and try to fetch content from pristine storage using
WC_CONTENTS callback.
Modified:
subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
subversion/trunk/subversion/libsvn_ra_serf/update.c
Modified: subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h?rev=1350584&r1=1350583&r2=1350584&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Fri Jun 15 11:40:33 2012
@@ -286,6 +286,13 @@ static const svn_ra_serf__dav_props_t ch
{ NULL }
};
+static const svn_ra_serf__dav_props_t type_and_checksum_props[] =
+{
+ { "DAV:", "resourcetype" },
+ { SVN_DAV_PROP_NS_DAV, "sha1-checksum" },
+ { NULL }
+};
+
/* WC props compatibility with ra_neon. */
#define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url"
Modified: subversion/trunk/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/update.c?rev=1350584&r1=1350583&r2=1350584&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/update.c Fri Jun 15 11:40:33 2012
@@ -2840,6 +2840,75 @@ svn_ra_serf__do_switch(svn_ra_session_t
switch_editor, switch_baton, pool);
}
+/* Helper svn_ra_serf__get_file(). Attempts to fetch file contents
+ * using SESSION->wc_callbacks->get_wc_contents() if sha1 property is
+ * present in PROPS.
+ *
+ * Sets *FOUND_P to TRUE if file contents was successfuly fetched.
+ *
+ * Performs all temporary allocations in POOL.
+ */
+static svn_error_t *
+try_get_wc_contents(svn_boolean_t *found_p,
+ svn_ra_serf__session_t *session,
+ apr_hash_t *props,
+ svn_stream_t *dst_stream,
+ apr_pool_t *pool)
+{
+ apr_hash_t *svn_props;
+ const char *sha1_checksum_prop;
+ svn_checksum_t *checksum;
+ svn_stream_t *wc_stream;
+ svn_error_t *err;
+
+ /* No contents found by default. */
+ *found_p = FALSE;
+
+ if (!session->wc_callbacks->get_wc_contents)
+ {
+ /* No callback, nothing to do. */
+ return SVN_NO_ERROR;
+ }
+
+
+ svn_props = apr_hash_get(props, SVN_DAV_PROP_NS_DAV, APR_HASH_KEY_STRING);
+ if (!svn_props)
+ {
+ /* No checksum property in response. */
+ return SVN_NO_ERROR;
+ }
+
+ sha1_checksum_prop = svn_prop_get_value(svn_props, "sha1-checksum");
+
+ if (!sha1_checksum_prop)
+ {
+ /* No checksum property in response. */
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1,
+ sha1_checksum_prop, pool));
+
+ err = session->wc_callbacks->get_wc_contents(
+ session->wc_callback_baton, &wc_stream, checksum, pool);
+
+ if (err)
+ {
+ svn_error_clear(err);
+
+ /* Ignore errors for now. */
+ return SVN_NO_ERROR;
+ }
+
+ if (wc_stream)
+ {
+ SVN_ERR(svn_stream_copy3(wc_stream, dst_stream, NULL, NULL, pool));
+ *found_p = TRUE;
+ }
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_ra_serf__get_file(svn_ra_session_t *ra_session,
const char *path,
@@ -2854,6 +2923,7 @@ svn_ra_serf__get_file(svn_ra_session_t *
const char *fetch_url;
apr_hash_t *fetch_props;
svn_kind_t res_kind;
+ const svn_ra_serf__dav_props_t *which_props;
/* What connection should we go on? */
conn = session->conns[session->cur_conn];
@@ -2878,9 +2948,22 @@ svn_ra_serf__get_file(svn_ra_session_t *
/* REVISION is always SVN_INVALID_REVNUM */
SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(revision));
+ if (props)
+ {
+ which_props = all_props;
+ }
+ else if (stream && session->wc_callbacks->get_wc_contents)
+ {
+ which_props = type_and_checksum_props;
+ }
+ else
+ {
+ which_props = check_path_props;
+ }
+
SVN_ERR(svn_ra_serf__fetch_node_props(&fetch_props, conn, fetch_url,
SVN_INVALID_REVNUM,
- props ? all_props : check_path_props,
+ which_props,
pool, pool));
/* Verify that resource type is not collection. */
@@ -2902,39 +2985,46 @@ svn_ra_serf__get_file(svn_ra_session_t *
if (stream)
{
- report_fetch_t *stream_ctx;
- svn_ra_serf__handler_t *handler;
-
- /* Create the fetch context. */
- stream_ctx = apr_pcalloc(pool, sizeof(*stream_ctx));
- stream_ctx->target_stream = stream;
- stream_ctx->sess = session;
- stream_ctx->conn = conn;
- stream_ctx->info = apr_pcalloc(pool, sizeof(*stream_ctx->info));
- stream_ctx->info->name = fetch_url;
-
- handler = apr_pcalloc(pool, sizeof(*handler));
-
- handler->handler_pool = pool;
- handler->method = "GET";
- handler->path = fetch_url;
- handler->conn = conn;
- handler->session = session;
-
- handler->header_delegate = headers_fetch;
- handler->header_delegate_baton = stream_ctx;
-
- handler->response_handler = handle_stream;
- handler->response_baton = stream_ctx;
+ svn_boolean_t found;
+ SVN_ERR(try_get_wc_contents(&found, session, fetch_props, stream, pool));
- handler->response_error = cancel_fetch;
- handler->response_error_baton = stream_ctx;
+ /* No contents found in the WC, let's fetch from server. */
+ if (!found)
+ {
+ report_fetch_t *stream_ctx;
+ svn_ra_serf__handler_t *handler;
+
+ /* Create the fetch context. */
+ stream_ctx = apr_pcalloc(pool, sizeof(*stream_ctx));
+ stream_ctx->target_stream = stream;
+ stream_ctx->sess = session;
+ stream_ctx->conn = conn;
+ stream_ctx->info = apr_pcalloc(pool, sizeof(*stream_ctx->info));
+ stream_ctx->info->name = fetch_url;
+
+ handler = apr_pcalloc(pool, sizeof(*handler));
+
+ handler->handler_pool = pool;
+ handler->method = "GET";
+ handler->path = fetch_url;
+ handler->conn = conn;
+ handler->session = session;
+
+ handler->header_delegate = headers_fetch;
+ handler->header_delegate_baton = stream_ctx;
+
+ handler->response_handler = handle_stream;
+ handler->response_baton = stream_ctx;
+
+ handler->response_error = cancel_fetch;
+ handler->response_error_baton = stream_ctx;
- stream_ctx->handler = handler;
+ stream_ctx->handler = handler;
- svn_ra_serf__request_create(handler);
+ svn_ra_serf__request_create(handler);
- SVN_ERR(svn_ra_serf__context_run_wait(&stream_ctx->done, session, pool));
+ SVN_ERR(svn_ra_serf__context_run_wait(&stream_ctx->done, session, pool));
+ }
}
return SVN_NO_ERROR;