Author: hwright
Date: Wed Oct 24 22:06:33 2012
New Revision: 1401901
URL: http://svn.apache.org/viewvc?rev=1401901&view=rev
Log:
First cut at an RA-layer function which returns an Ev2-capable editor for use
in replay range consumers, such as svnrdump and svnsync.
Note: This code isn't yet called anywhere or tested, so use at own risk!
* subversion/libsvn_ra/editor.c
(fb_baton, fetch_base, wrapped_replay_baton, revstart_func_wrapper,
revstart_end_wrapper, svn_ra__use_replay_range_shim): New.
* subversion/libsvn_ra/ra_loader.c
(svn_ra__replay_range_ev2): Implement.
* subversion/libsvn_ra/ra_loader.h
(svn_ra__vtable_t): Add entry for replay_range_ev2. No implementors
currently set it.
(svn_ra__use_replay_range_shim): New.
* subversion/include/private/svn_ra_private.h
(svn_ra__replay_range_ev2): Add required Ev2 callbacks to parameter list.
Modified:
subversion/trunk/subversion/include/private/svn_ra_private.h
subversion/trunk/subversion/libsvn_ra/editor.c
subversion/trunk/subversion/libsvn_ra/ra_loader.c
subversion/trunk/subversion/libsvn_ra/ra_loader.h
Modified: subversion/trunk/subversion/include/private/svn_ra_private.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_ra_private.h?rev=1401901&r1=1401900&r2=1401901&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_ra_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_ra_private.h Wed Oct 24
22:06:33 2012
@@ -257,6 +257,10 @@ svn_ra__replay_range_ev2(svn_ra_session_
svn_ra__replay_revstart_ev2_callback_t revstart_func,
svn_ra__replay_revfinish_ev2_callback_t
revfinish_func,
void *replay_baton,
+ svn_ra__provide_base_cb_t provide_base_cb,
+ svn_ra__provide_props_cb_t provide_props_cb,
+ svn_ra__get_copysrc_kind_cb_t get_copysrc_kind_cb,
+ void *cb_baton,
apr_pool_t *scratch_pool);
/* Similar to svn_ra_replay(), but with an Ev2 editor. */
Modified: subversion/trunk/subversion/libsvn_ra/editor.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra/editor.c?rev=1401901&r1=1401900&r2=1401901&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra/editor.c (original)
+++ subversion/trunk/subversion/libsvn_ra/editor.c Wed Oct 24 22:06:33 2012
@@ -42,6 +42,11 @@ struct fp_baton {
void *cb_baton;
};
+struct fb_baton {
+ svn_ra__provide_base_cb_t provide_base_cb;
+ void *cb_baton;
+};
+
/* The shims currently want a callback that provides props for a given
REPOS_RELPATH at a given BASE_REVISION. However, the RA Ev2 interface
has a callback that provides properties for the REPOS_RELPATH from any
@@ -72,6 +77,42 @@ fetch_props(apr_hash_t **props,
result_pool, scratch_pool));
}
+/* See note above regarding BASE_REVISION.
+ This also pulls down the entire contents of the file stream from the
+ RA layer and stores them in a local file, returning the path.
+*/
+static svn_error_t *
+fetch_base(const char **filename,
+ void *baton,
+ const char *repos_relpath,
+ svn_revnum_t base_revision,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ struct fb_baton *fbb = baton;
+ svn_revnum_t unused_revision;
+ svn_stream_t *contents;
+ svn_stream_t *file_stream;
+ const char *tmp_filename;
+
+ /* Ignored: BASE_REVISION. */
+
+ SVN_ERR(fbb->provide_base_cb(&contents, &unused_revision, fbb->cb_baton,
+ repos_relpath, result_pool, scratch_pool));
+
+ SVN_ERR(svn_stream_open_unique(&file_stream, &tmp_filename, NULL,
+ svn_io_file_del_on_pool_cleanup,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_stream_copy3(contents, file_stream, NULL, NULL, scratch_pool));
+
+ *filename = apr_pstrdup(result_pool, tmp_filename);
+
+
+
+ return SVN_NO_ERROR;
+}
+
+
svn_error_t *
svn_ra__use_commit_shim(svn_editor_t **editor,
@@ -173,3 +214,126 @@ svn_ra__use_commit_shim(svn_editor_t **e
return SVN_NO_ERROR;
}
+
+
+struct wrapped_replay_baton_t {
+ svn_ra__replay_revstart_ev2_callback_t revstart_func;
+ svn_ra__replay_revfinish_ev2_callback_t revfinish_func;
+ void *replay_baton;
+
+ svn_ra_session_t *session;
+
+ svn_ra__provide_base_cb_t provide_base_cb;
+ svn_ra__provide_props_cb_t provide_props_cb;
+ void *cb_baton;
+
+ /* This will be populated by the revstart wrapper. */
+ svn_editor_t *editor;
+};
+
+static svn_error_t *
+revstart_func_wrapper(svn_revnum_t revision,
+ void *replay_baton,
+ const svn_delta_editor_t **deditor,
+ void **dedit_baton,
+ apr_hash_t *rev_props,
+ apr_pool_t *result_pool)
+{
+ struct wrapped_replay_baton_t *wrb = replay_baton;
+ const char *repos_root;
+ const char *session_url;
+ const char *base_relpath;
+ svn_boolean_t *found_abs_paths;
+ struct fp_baton *fpb;
+ struct svn_delta__extra_baton *exb;
+
+ /* Get the Ev2 editor from the original revstart func. */
+ SVN_ERR(wrb->revstart_func(revision, wrb->replay_baton, &wrb->editor,
+ rev_props, result_pool));
+
+ /* Get or calculate the appropriate repos root and base relpath. */
+ SVN_ERR(svn_ra_get_repos_root2(wrb->session, &repos_root, result_pool));
+ SVN_ERR(svn_ra_get_session_url(wrb->session, &session_url, result_pool));
+ base_relpath = svn_uri_skip_ancestor(repos_root, session_url, result_pool);
+
+ /* We will assume that when the underlying Ev1 editor is finally driven
+ by the shim, that we will not need to prepend "/" to the paths. Place
+ this on the heap because it is examined much later. Set to FALSE. */
+ found_abs_paths = apr_pcalloc(result_pool, sizeof(*found_abs_paths));
+
+ /* The PROVIDE_PROPS_CB callback does not match what the shims want.
+ Let's jigger things around a little bit here. */
+ fpb = apr_palloc(result_pool, sizeof(*fpb));
+ fpb->provide_props_cb = wrb->provide_props_cb;
+ fpb->cb_baton = wrb->cb_baton;
+
+ /* Create the extra baton. */
+ exb = apr_pcalloc(result_pool, sizeof(*exb));
+
+ /* Create the Ev1 editor from the Ev2 editor provided by the RA layer.
+
+ Note: GET_COPYSRC_KIND_CB is compatible in type/semantics with the
+ shim's FETCH_KIND_FUNC parameter. */
+ SVN_ERR(svn_delta__delta_from_editor(deditor, dedit_baton, wrb->editor,
+ NULL, NULL,
+ found_abs_paths,
+ repos_root, base_relpath,
+ fetch_props, wrb->cb_baton,
+ fetch_base, wrb->cb_baton,
+ exb, result_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+revfinish_func_wrapper(svn_revnum_t revision,
+ void *replay_baton,
+ const svn_delta_editor_t *editor,
+ void *edit_baton,
+ apr_hash_t *rev_props,
+ apr_pool_t *pool)
+{
+ struct wrapped_replay_baton_t *wrb = replay_baton;
+
+ SVN_ERR(wrb->revfinish_func(revision, replay_baton, wrb->editor, rev_props,
+ pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra__use_replay_range_shim(svn_ra_session_t *session,
+ svn_revnum_t start_revision,
+ svn_revnum_t end_revision,
+ svn_revnum_t low_water_mark,
+ svn_boolean_t send_deltas,
+ svn_ra__replay_revstart_ev2_callback_t
revstart_func,
+ svn_ra__replay_revfinish_ev2_callback_t
revfinish_func,
+ void *replay_baton,
+ svn_ra__provide_base_cb_t provide_base_cb,
+ svn_ra__provide_props_cb_t provide_props_cb,
+ void *cb_baton,
+ apr_pool_t *scratch_pool)
+{
+ /* The basic strategy here is to wrap the callback start and finish
+ functions to appropriately return an Ev1 editor which is itself wrapped
+ from the Ev2 one the provided callbacks will give us. */
+
+ struct wrapped_replay_baton_t *wrb = apr_pcalloc(scratch_pool, sizeof(*wrb));
+
+ wrb->revstart_func = revstart_func;
+ wrb->revfinish_func = revfinish_func;
+ wrb->replay_baton = replay_baton;
+ wrb->session = session;
+
+ wrb->provide_base_cb = provide_base_cb;
+ wrb->provide_props_cb = provide_props_cb;
+ wrb->cb_baton = cb_baton;
+
+ return svn_error_trace(svn_ra_replay_range(session, start_revision,
+ end_revision, low_water_mark,
+ send_deltas,
+ revstart_func_wrapper,
+ revfinish_func_wrapper,
+ wrb, scratch_pool));
+}
Modified: subversion/trunk/subversion/libsvn_ra/ra_loader.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra/ra_loader.c?rev=1401901&r1=1401900&r2=1401901&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/trunk/subversion/libsvn_ra/ra_loader.c Wed Oct 24 22:06:33 2012
@@ -1211,9 +1211,38 @@ svn_ra__replay_range_ev2(svn_ra_session_
svn_ra__replay_revstart_ev2_callback_t revstart_func,
svn_ra__replay_revfinish_ev2_callback_t
revfinish_func,
void *replay_baton,
+ svn_ra__provide_base_cb_t provide_base_cb,
+ svn_ra__provide_props_cb_t provide_props_cb,
+ svn_ra__get_copysrc_kind_cb_t get_copysrc_kind_cb,
+ void *cb_baton,
apr_pool_t *scratch_pool)
{
- SVN__NOT_IMPLEMENTED();
+ if (session->vtable->replay_range_ev2 == NULL)
+ {
+ /* The specific RA layer does not have an implementation. Use our
+ default shim over the normal replay editor. */
+
+ /* This will call the Ev1 replay range handler with modified
+ callbacks. */
+ return svn_error_trace(svn_ra__use_replay_range_shim(
+ session,
+ start_revision,
+ end_revision,
+ low_water_mark,
+ send_deltas,
+ revstart_func,
+ revfinish_func,
+ replay_baton,
+ provide_base_cb,
+ provide_props_cb,
+ cb_baton,
+ scratch_pool));
+ }
+
+ return svn_error_trace(session->vtable->replay_range_ev2(
+ session, start_revision, end_revision,
+ low_water_mark, send_deltas, revstart_func,
+ revfinish_func, replay_baton, scratch_pool));
}
svn_error_t *svn_ra_has_capability(svn_ra_session_t *session,
Modified: subversion/trunk/subversion/libsvn_ra/ra_loader.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra/ra_loader.h?rev=1401901&r1=1401900&r2=1401901&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/trunk/subversion/libsvn_ra/ra_loader.h Wed Oct 24 22:06:33 2012
@@ -324,6 +324,18 @@ typedef struct svn_ra__vtable_t {
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+ /* See svn_ra__replay_range_ev2() */
+ svn_error_t *(*replay_range_ev2)(
+ svn_ra_session_t *session,
+ svn_revnum_t start_revision,
+ svn_revnum_t end_revision,
+ svn_revnum_t low_water_mark,
+ svn_boolean_t send_deltas,
+ svn_ra__replay_revstart_ev2_callback_t revstart_func,
+ svn_ra__replay_revfinish_ev2_callback_t revfinish_func,
+ void *replay_baton,
+ apr_pool_t *scratch_pool);
+
} svn_ra__vtable_t;
/* The RA session object. */
@@ -519,6 +531,24 @@ svn_ra__use_commit_shim(svn_editor_t **e
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Utility function to provide a shim between a returned Ev2 and an RA
+ provider's Ev1-based commit editor.
+
+ See svn_ra__replay_range_ev2() for parameter semantics. */
+svn_error_t *
+svn_ra__use_replay_range_shim(svn_ra_session_t *session,
+ svn_revnum_t start_revision,
+ svn_revnum_t end_revision,
+ svn_revnum_t low_water_mark,
+ svn_boolean_t send_deltas,
+ svn_ra__replay_revstart_ev2_callback_t
revstart_func,
+ svn_ra__replay_revfinish_ev2_callback_t
revfinish_func,
+ void *replay_baton,
+ svn_ra__provide_base_cb_t provide_base_cb,
+ svn_ra__provide_props_cb_t provide_props_cb,
+ void *cb_baton,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}