Author: cmpilato
Date: Fri Jun 8 16:01:00 2012
New Revision: 1348131
URL: http://svn.apache.org/viewvc?rev=1348131&view=rev
Log:
Finish issue #4179 by eliminating no-op HEAD requests from ra_serf's
checkout/update logic.
* subversion/libsvn_ra_serf/update.c
(handle_local_contents): Was local_fetch(). Callers updated. Also,
decrement the directory reference count.
(handle_local_fetch): Remove as unused.
(fetch_file): Avoid HEAD requests where locally cached file contents
are available. Instead, either immediately handle the contents,
or squirrel away some state so we remember to do so...
(finish_report): ...here.
Modified:
subversion/trunk/subversion/libsvn_ra_serf/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=1348131&r1=1348130&r2=1348131&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/update.c Fri Jun 8 16:01:00 2012
@@ -1189,8 +1189,8 @@ handle_propchange_only(report_info_t *in
editor. In editor-speak, this will add/open the file, transmit any
property changes, handle the contents, and then close the file. */
static svn_error_t *
-local_fetch(report_info_t *info,
- apr_pool_t *scratch_pool)
+handle_local_content(report_info_t *info,
+ apr_pool_t *scratch_pool)
{
SVN_ERR(open_updated_file(info, TRUE, scratch_pool));
SVN_ERR(svn_txdelta_send_stream(info->cached_contents, info->textdelta,
@@ -1202,63 +1202,9 @@ local_fetch(report_info_t *info,
/* We're done with our pool. */
svn_pool_destroy(info->pool);
- return SVN_NO_ERROR;
-}
-
-/* Implements svn_ra_serf__response_handler_t */
-static svn_error_t *
-handle_local_fetch(serf_request_t *request,
- serf_bucket_t *response,
- void *handler_baton,
- apr_pool_t *pool)
-{
- report_fetch_t *fetch_ctx = handler_baton;
- apr_status_t status;
- svn_error_t *err;
- const char *data;
- apr_size_t len;
-
- /* ### new field. make sure we didn't miss some initialization. */
- SVN_ERR_ASSERT(fetch_ctx->handler != NULL);
+ info->dir->ref_count--;
- /* If the error code wasn't 200, something went wrong. Don't use the returned
- data as its probably an error message. Just bail out instead. */
- if (fetch_ctx->handler->sline.code != 200)
- {
- err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
- _("HEAD request failed: %d %s"),
- fetch_ctx->handler->sline.code,
- fetch_ctx->handler->sline.reason);
- return error_fetch(request, fetch_ctx, err);
- }
-
- while (1)
- {
- status = serf_bucket_read(response, 8000, &data, &len);
- if (SERF_BUCKET_READ_ERROR(status))
- {
- return svn_error_wrap_apr(status, NULL);
- }
- if (APR_STATUS_IS_EOF(status))
- {
- err = local_fetch(fetch_ctx->info, fetch_ctx->info->pool);
- if (err)
- {
- return error_fetch(request, fetch_ctx, err);
- }
-
- fetch_ctx->done = TRUE;
- fetch_ctx->done_item.data = fetch_ctx;
- fetch_ctx->done_item.next = *fetch_ctx->done_list;
- *fetch_ctx->done_list = &fetch_ctx->done_item;
- return svn_error_wrap_apr(status, NULL);
- }
- if (APR_STATUS_IS_EAGAIN(status))
- {
- return svn_error_wrap_apr(status, NULL);
- }
- }
- /* not reached */
+ return SVN_NO_ERROR;
}
/* --------------------------------------------------------- */
@@ -1331,43 +1277,35 @@ fetch_file(report_context_t *ctx, report
}
}
- /* If the working copy can provided cached contents for this
- file, we'll send a simple HEAD request (which I'll claim is
- to verify readability, but really is just so I can provide a
- Serf-queued-request-compliant way of processing the contents
- after the PROPFIND for the file's properties ... ugh).
-
- Otherwise, we use a GET request for the file's contents. */
+ /* If the working copy can provide cached contents for this
+ file, we don't have to fetch them from the server. */
if (info->cached_contents)
{
- report_fetch_t *fetch_ctx;
-
- fetch_ctx = apr_pcalloc(info->dir->pool, sizeof(*fetch_ctx));
- fetch_ctx->info = info;
- fetch_ctx->done_list = &ctx->done_fetches;
- fetch_ctx->sess = ctx->sess;
- fetch_ctx->conn = conn;
-
- handler = apr_pcalloc(info->dir->pool, sizeof(*handler));
-
- handler->handler_pool = info->dir->pool;
- handler->method = "HEAD";
- handler->path = fetch_ctx->info->url;
-
- handler->conn = conn;
- handler->session = ctx->sess;
-
- handler->response_handler = handle_local_fetch;
- handler->response_baton = fetch_ctx;
-
- fetch_ctx->handler = handler;
-
- svn_ra_serf__request_create(handler);
-
- ctx->active_fetches++;
+ /* If we'll be doing a PROPFIND for this file... */
+ if (info->propfind)
+ {
+ /* ... then we'll just leave ourselves a little "todo"
+ about that fact (and we'll deal with the file content
+ stuff later, after we've handled that PROPFIND
+ response. */
+ svn_ra_serf__list_t *list_item;
+
+ list_item = apr_pcalloc(info->dir->pool, sizeof(*list_item));
+ list_item->data = info;
+ list_item->next = ctx->file_propchanges_only;
+ ctx->file_propchanges_only = list_item;
+ }
+ else
+ {
+ /* Otherwise, if we've no PROPFIND to do, we might as
+ well take care of those locally accessible file
+ contents now. */
+ SVN_ERR(handle_local_content(info, info->pool));
+ }
}
else
{
+ /* Otherwise, we use a GET request for the file's contents. */
report_fetch_t *fetch_ctx;
fetch_ctx = apr_pcalloc(info->dir->pool, sizeof(*fetch_ctx));
@@ -2544,7 +2482,20 @@ finish_report(void *report_baton,
*/
if (cur)
{
- SVN_ERR(handle_propchange_only(cur->data, iterpool_inner));
+ report_info_t *info = cur->data;
+
+ /* If we've got cached file content for this file,
+ take care of the locally collected properties and
+ file content at once. Otherwise, just deal with
+ the collected properties. */
+ if (info->cached_contents)
+ {
+ SVN_ERR(handle_local_content(info, iterpool_inner));
+ }
+ else
+ {
+ SVN_ERR(handle_propchange_only(info, iterpool_inner));
+ }
if (!prev)
{