You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ko...@apache.org on 2022/11/25 17:13:55 UTC
svn commit: r1905528 - in /subversion/branches/pristines-on-demand-on-mwf/subversion: include/ libsvn_client/ libsvn_ra/ libsvn_ra_local/ libsvn_ra_serf/ libsvn_ra_svn/
Author: kotkov
Date: Fri Nov 25 17:13:55 2022
New Revision: 1905528
URL: http://svn.apache.org/viewvc?rev=1905528&view=rev
Log:
On the 'pristines-on-demand-on-mwf' branch: Rework the RA part of the
text-base fetching.
This changeset solves a performance issue where fetching a single text-base
over ra_serf required two requests (PROPFIND + GET) instead of one (GET).
It also lays the groundwork for reusing RA sessions. Such reuse was partly
blocked by having to open a session that is not associated with a specific
working copy, because otherwise a content fetch would first try the local
pristine cache — which is a waste of resources for the case when we are
fetching the pristines ourselves.
* subversion/include/svn_ra.h
(svn_ra_fetch_file_contents): New.
* subversion/libsvn_ra/ra_loader.h
(svn_ra__vtable_t.fetch_file_contents): New
* subversion/libsvn_ra/ra_loader.c
(svn_ra_fetch_file_contents): Call the new vtable member.
* subversion/libsvn_ra_local/ra_plugin.c
(get_file): Factor out this helper function. Always close the stream.
(svn_ra_local__get_file): Call the helper function, disowning the stream
to keep the current behavior.
(svn_ra_local__fetch_file_contents): New, implemented with a call to the
new helper function.
(ra_local_vtable): Add new function to vtable.
* subversion/libsvn_ra_svn/client.c
(get_file): Factor out this helper function. Always close the stream.
(ra_svn_get_file): Call the helper function, disowning the stream
to keep the current behavior.
(ra_svn_fetch_file_contents): New, implemented with a call to the
new helper function.
(ra_svn_vtable): Add new function to vtable.
* subversion/libsvn_ra_serf/ra_serf.h
(svn_ra_serf__fetch_file_contents): New.
* subversion/libsvn_ra_serf/get_file.c
(svn_ra_serf__fetch_file_contents): New.
* subversion/libsvn_ra_serf/serf.c
(serf_vtable): Add new function to vtable.
* subversion/libsvn_client/textbase.c
(textbase_hydrate_cb): Use the new RA function to fetch the contents.
Modified:
subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_ra.h
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/textbase.c
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.c
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.h
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_local/ra_plugin.c
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/get_file.c
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/ra_serf.h
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/serf.c
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_svn/client.c
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_ra.h?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_ra.h (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/include/svn_ra.h Fri Nov 25 17:13:55 2022
@@ -2164,6 +2164,29 @@ svn_ra_get_inherited_props(svn_ra_sessio
apr_pool_t *scratch_pool);
/**
+ * Fetch the contents of file @a path at @a revision. Interpret @a path
+ * relative to the URL in @a session. @a revision must be a valid revision
+ * number. Use @a scratch_pool for scratch allocations.
+ *
+ * The contents of the file will be pushed to @a stream, and the stream will
+ * be closed when finished. If the closure is not desired, then you can use
+ * svn_stream_disown() to protect the stream from being closed. The stream
+ * handlers for @a stream may not perform any RA operations using @a session.
+ *
+ * The contents may be expected to be fetched directly from the remote
+ * endpoint, rather from any local caches such as the one provided by
+ * #svn_ra_get_wc_contents_func_t.
+ *
+ * @since New in 1.15.
+ */
+svn_error_t *
+svn_ra_fetch_file_contents(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ svn_stream_t *stream,
+ apr_pool_t *scratch_pool);
+
+/**
* @defgroup Capabilities Dynamically query the server's capabilities.
*
* @{
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/textbase.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/textbase.c?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/textbase.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_client/textbase.c Fri Nov 25 17:13:55 2022
@@ -49,7 +49,6 @@ textbase_hydrate_cb(void *baton,
struct textbase_hydrate_baton_t *b = baton;
const char *url;
const char *old_url;
- svn_error_t *err;
url = svn_path_url_add_component2(repos_root_url, repos_relpath,
scratch_pool);
@@ -87,11 +86,10 @@ textbase_hydrate_cb(void *baton,
SVN_ERR(svn_client__ensure_ra_session_url(&old_url, b->ra_session, url,
scratch_pool));
- err = svn_ra_get_file(b->ra_session, "", revision, contents,
- NULL, NULL, scratch_pool);
- err = svn_error_compose_create(err, svn_stream_close(contents));
+ SVN_ERR(svn_ra_fetch_file_contents(b->ra_session, "", revision, contents,
+ scratch_pool));
- return svn_error_trace(err);
+ return SVN_NO_ERROR;
}
svn_error_t *
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.c?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.c Fri Nov 25 17:13:55 2022
@@ -1369,6 +1369,18 @@ svn_ra_get_inherited_props(svn_ra_sessio
}
svn_error_t *
+svn_ra_fetch_file_contents(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ svn_stream_t *stream,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR_ASSERT(svn_relpath_is_canonical(path));
+ return session->vtable->fetch_file_contents(session, path, revision, stream,
+ scratch_pool);
+}
+
+svn_error_t *
svn_ra__get_commit_ev2(svn_editor_t **editor,
svn_ra_session_t *session,
apr_hash_t *revprop_table,
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.h?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra/ra_loader.h Fri Nov 25 17:13:55 2022
@@ -345,6 +345,13 @@ typedef struct svn_ra__vtable_t {
void *receiver_baton,
apr_pool_t *scratch_pool);
+ /* See svn_ra_fetch_file_contents(). */
+ svn_error_t *(*fetch_file_contents)(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ svn_stream_t *stream,
+ apr_pool_t *scratch_pool);
+
/* Experimental support below here */
/* See svn_ra__register_editor_shim_callbacks() */
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_local/ra_plugin.c?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_local/ra_plugin.c Fri Nov 25 17:13:55 2022
@@ -1255,13 +1255,13 @@ get_node_props(apr_hash_t **props,
/* Getting just one file. */
static svn_error_t *
-svn_ra_local__get_file(svn_ra_session_t *session,
- const char *path,
- svn_revnum_t revision,
- svn_stream_t *stream,
- svn_revnum_t *fetched_rev,
- apr_hash_t **props,
- apr_pool_t *pool)
+get_file(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ svn_stream_t *stream,
+ svn_revnum_t *fetched_rev,
+ apr_hash_t **props,
+ apr_pool_t *pool)
{
svn_fs_root_t *root;
svn_stream_t *contents;
@@ -1306,11 +1306,8 @@ svn_ra_local__get_file(svn_ra_session_t
stored checksum, and all we're doing here is writing bytes in
a loop. Truly, Nothing Can Go Wrong :-). But RA layers that
go over a network should confirm the checksum.
-
- Note: we are not supposed to close the passed-in stream, so
- disown the thing.
*/
- SVN_ERR(svn_stream_copy3(contents, svn_stream_disown(stream, pool),
+ SVN_ERR(svn_stream_copy3(contents, stream,
sess->callbacks
? sess->callbacks->cancel_func : NULL,
sess->callback_baton,
@@ -1866,6 +1863,38 @@ svn_ra_local__list(svn_ra_session_t *ses
sess->callback_baton, pool));
}
+static svn_error_t *
+svn_ra_local__get_file(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ svn_stream_t *stream,
+ svn_revnum_t *fetched_rev,
+ apr_hash_t **props,
+ apr_pool_t *pool)
+{
+ /* We are not supposed to close the passed-in stream, so disown it. */
+ if (stream)
+ stream = svn_stream_disown(stream, pool);
+
+ SVN_ERR(get_file(session, path, revision, stream, fetched_rev,
+ props, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+svn_ra_local__fetch_file_contents(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ svn_stream_t *stream,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR(get_file(session, path, revision, stream, NULL,
+ NULL, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
/*----------------------------------------------------------------*/
static const svn_version_t *
@@ -1917,6 +1946,7 @@ static const svn_ra__vtable_t ra_local_v
svn_ra_local__get_inherited_props,
NULL /* set_svn_ra_open */,
svn_ra_local__list ,
+ svn_ra_local__fetch_file_contents,
svn_ra_local__register_editor_shim_callbacks,
svn_ra_local__get_commit_ev2,
NULL /* replay_range_ev2 */
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/get_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/get_file.c?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/get_file.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/get_file.c Fri Nov 25 17:13:55 2022
@@ -428,3 +428,59 @@ svn_ra_serf__get_file(svn_ra_session_t *
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_ra_serf__fetch_file_contents(svn_ra_session_t *ra_session,
+ const char *path,
+ svn_revnum_t revision,
+ svn_stream_t *stream,
+ apr_pool_t *scratch_pool)
+{
+ svn_ra_serf__session_t *session = ra_session->priv;
+ const char *fetch_url;
+ stream_ctx_t *stream_ctx;
+ svn_ra_serf__handler_t *handler;
+ svn_error_t *err;
+
+ fetch_url = svn_path_url_add_component2(session->session_url.path, path,
+ scratch_pool);
+
+ SVN_ERR(svn_ra_serf__get_stable_url(&fetch_url, NULL, session,
+ fetch_url, revision,
+ scratch_pool, scratch_pool));
+
+ /* Create the fetch context. */
+ stream_ctx = apr_pcalloc(scratch_pool, sizeof(*stream_ctx));
+ stream_ctx->result_stream = stream;
+ stream_ctx->session = session;
+
+ handler = svn_ra_serf__create_handler(session, scratch_pool);
+
+ handler->method = "GET";
+ handler->path = fetch_url;
+
+ handler->custom_accept_encoding = TRUE;
+ handler->no_dav_headers = TRUE;
+
+ 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;
+
+ err = svn_ra_serf__context_run_one(handler, scratch_pool);
+
+ err = svn_error_compose_create(err, svn_stream_close(stream));
+
+ if (err)
+ return svn_error_trace(err);
+ else if (handler->sline.code != 200)
+ return svn_error_trace(svn_ra_serf__unexpected_status(handler));
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/ra_serf.h?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/ra_serf.h Fri Nov 25 17:13:55 2022
@@ -1511,6 +1511,14 @@ svn_error_t *
svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
svn_delta_shim_callbacks_t *callbacks);
+/* Implements svn_ra__vtable_t.fetch_file_contents(). */
+svn_error_t *
+svn_ra_serf__fetch_file_contents(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ svn_stream_t *stream,
+ apr_pool_t *scratch_pool);
+
/*** Authentication handler declarations ***/
/**
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/serf.c?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_serf/serf.c Fri Nov 25 17:13:55 2022
@@ -1068,6 +1068,7 @@ static const svn_ra__vtable_t serf_vtabl
svn_ra_serf__get_inherited_props,
NULL /* set_svn_ra_open */,
svn_ra_serf__list,
+ svn_ra_serf__fetch_file_contents,
svn_ra_serf__register_editor_shim_callbacks,
NULL /* commit_ev2 */,
NULL /* replay_range_ev2 */
Modified: subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_svn/client.c?rev=1905528&r1=1905527&r2=1905528&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_ra_svn/client.c Fri Nov 25 17:13:55 2022
@@ -1436,11 +1436,11 @@ parse_iproplist(apr_array_header_t **inh
return SVN_NO_ERROR;
}
-static svn_error_t *ra_svn_get_file(svn_ra_session_t *session, const char *path,
- svn_revnum_t rev, svn_stream_t *stream,
- svn_revnum_t *fetched_rev,
- apr_hash_t **props,
- apr_pool_t *pool)
+static svn_error_t *get_file(svn_ra_session_t *session, const char *path,
+ svn_revnum_t rev, svn_stream_t *stream,
+ svn_revnum_t *fetched_rev,
+ apr_hash_t **props,
+ apr_pool_t *pool)
{
svn_ra_svn__session_baton_t *sess_baton = session->priv;
svn_ra_svn_conn_t *conn = sess_baton->conn;
@@ -1497,6 +1497,8 @@ static svn_error_t *ra_svn_get_file(svn_
}
svn_pool_destroy(iterpool);
+ SVN_ERR(svn_stream_close(stream));
+
SVN_ERR(svn_ra_svn__read_cmd_response(conn, pool, ""));
if (expected_checksum)
@@ -3258,6 +3260,34 @@ ra_svn_list(svn_ra_session_t *session,
return SVN_NO_ERROR;
}
+static svn_error_t *ra_svn_get_file(svn_ra_session_t *session, const char *path,
+ svn_revnum_t rev, svn_stream_t *stream,
+ svn_revnum_t *fetched_rev,
+ apr_hash_t **props,
+ apr_pool_t *pool)
+{
+ /* We are not supposed to close the passed-in stream, so disown it. */
+ if (stream)
+ stream = svn_stream_disown(stream, pool);
+
+ SVN_ERR(get_file(session, path, rev, stream, fetched_rev,
+ props, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *ra_svn_fetch_file_contents(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t rev,
+ svn_stream_t *stream,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR(get_file(session, path, rev, stream, NULL,
+ NULL, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
static const svn_ra__vtable_t ra_svn_vtable = {
svn_ra_svn_version,
ra_svn_get_description,
@@ -3298,6 +3328,7 @@ static const svn_ra__vtable_t ra_svn_vta
ra_svn_get_inherited_props,
NULL /* ra_set_svn_ra_open */,
ra_svn_list,
+ ra_svn_fetch_file_contents,
ra_svn_register_editor_shim_callbacks,
NULL /* commit_ev2 */,
NULL /* replay_range_ev2 */