You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/09/07 21:36:01 UTC
svn commit: r1166332 - in /subversion/trunk/subversion:
libsvn_delta/compat.c tests/libsvn_delta/editor-test.c
Author: hwright
Date: Wed Sep 7 19:36:01 2011
New Revision: 1166332
URL: http://svn.apache.org/viewvc?rev=1166332&view=rev
Log:
A checkpoint commit of work on the Ev2 compat code. This extends the tests and
compat code a bit.
* subversion/tests/libsvn_delta/editor-test.c
(SET_STR): New.
(editor_from_delta_editor_test): Extend this test with some prop editing.
* subversion/libsvn_delta/compat.c
(edit_baton, file_baton): Add a few members.
(action, path_action, prop_args): New.
(add_action): New.
(ev2_add_directory, ev2_add_file, ev2_open_file, ev2_change_file_prop):
Queue up a few actions for processing.
(ev2_close_edit): Implement post-pass processing.
(svn_delta_from_editor): Populate a few baton members.
Modified:
subversion/trunk/subversion/libsvn_delta/compat.c
subversion/trunk/subversion/tests/libsvn_delta/editor-test.c
Modified: subversion/trunk/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/compat.c?rev=1166332&r1=1166331&r2=1166332&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/compat.c (original)
+++ subversion/trunk/subversion/libsvn_delta/compat.c Wed Sep 7 19:36:01 2011
@@ -21,11 +21,11 @@
* ====================================================================
*/
-#include <apr_pools.h>
-
#include "svn_types.h"
#include "svn_error.h"
#include "svn_delta.h"
+#include "svn_sorts.h"
+#include "svn_pools.h"
struct file_rev_handler_wrapper_baton {
@@ -92,6 +92,8 @@ svn_compat_wrap_file_rev_handler(svn_fil
struct ev2_edit_baton
{
svn_editor_t *editor;
+ apr_hash_t *paths;
+ apr_pool_t *edit_pool;
};
struct ev2_dir_baton
@@ -102,9 +104,56 @@ struct ev2_dir_baton
struct ev2_file_baton
{
struct ev2_edit_baton *eb;
+ const char *path;
+};
+
+enum action
+{
+ add,
+ delete,
+ set_prop
+};
+
+struct path_action
+{
+ enum action action;
+ void *args;
+};
+
+struct prop_args
+{
+ const char *name;
+ const svn_string_t *value;
};
static svn_error_t *
+add_action(struct ev2_edit_baton *eb,
+ const char *path,
+ enum action action,
+ void *args)
+{
+ struct path_action *p_action;
+ apr_array_header_t *action_list = apr_hash_get(eb->paths, path,
+ APR_HASH_KEY_STRING);
+
+ p_action = apr_palloc(eb->edit_pool, sizeof(*p_action));
+ p_action->action = action;
+ p_action->args = args;
+
+ if (action_list == NULL)
+ {
+ action_list = apr_array_make(eb->edit_pool, 1,
+ sizeof(struct path_action *));
+ apr_hash_set(eb->paths, apr_pstrdup(eb->edit_pool, path),
+ APR_HASH_KEY_STRING, action_list);
+ }
+
+ APR_ARRAY_PUSH(action_list, struct path_action *) = p_action;
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
ev2_set_target_revision(void *edit_baton,
svn_revnum_t target_revision,
apr_pool_t *scratch_pool)
@@ -148,6 +197,11 @@ ev2_add_directory(const char *path,
void **child_baton)
{
struct ev2_dir_baton *pb = parent_baton;
+ svn_node_kind_t *kind;
+
+ kind = apr_palloc(pb->eb->edit_pool, sizeof(*kind));
+ *kind = svn_node_dir;
+ SVN_ERR(add_action(pb->eb, path, add, kind));
return SVN_NO_ERROR;
}
@@ -183,6 +237,7 @@ ev2_close_directory(void *dir_baton,
apr_pool_t *scratch_pool)
{
struct ev2_dir_baton *db = dir_baton;
+
return SVN_NO_ERROR;
}
@@ -205,10 +260,16 @@ ev2_add_file(const char *path,
{
struct ev2_file_baton *fb = apr_palloc(result_pool, sizeof(*fb));
struct ev2_dir_baton *pb = parent_baton;
+ svn_node_kind_t *kind;
fb->eb = pb->eb;
-
+ fb->path = apr_pstrdup(result_pool, path);
*file_baton = fb;
+
+ kind = apr_palloc(pb->eb->edit_pool, sizeof(*kind));
+ *kind = svn_node_file;
+ SVN_ERR(add_action(pb->eb, path, add, kind));
+
return SVN_NO_ERROR;
}
@@ -223,6 +284,7 @@ ev2_open_file(const char *path,
struct ev2_dir_baton *pb = parent_baton;
fb->eb = pb->eb;
+ fb->path = apr_pstrdup(result_pool, path);
*file_baton = fb;
return SVN_NO_ERROR;
@@ -250,6 +312,13 @@ ev2_change_file_prop(void *file_baton,
apr_pool_t *scratch_pool)
{
struct ev2_file_baton *fb = file_baton;
+ struct prop_args *p_args = apr_palloc(fb->eb->edit_pool, sizeof(*p_args));
+
+ p_args->name = apr_pstrdup(fb->eb->edit_pool, name);
+ p_args->value = svn_string_dup(value, fb->eb->edit_pool);
+
+ SVN_ERR(add_action(fb->eb, fb->path, set_prop, p_args));
+
return SVN_NO_ERROR;
}
@@ -276,6 +345,60 @@ ev2_close_edit(void *edit_baton,
apr_pool_t *scratch_pool)
{
struct ev2_edit_baton *eb = edit_baton;
+ apr_array_header_t *sorted_hash;
+ apr_pool_t *iterpool;
+ int i;
+
+ /* Sort the paths touched by this edit.
+ * Ev2 doesn't really have any particular need for depth-first-ness, but
+ * we want to ensure all parent directories are handled before children in
+ * the case of adds (which does introduce an element of depth-first-ness). */
+ sorted_hash = svn_sort__hash(eb->paths, svn_sort_compare_items_as_paths,
+ scratch_pool);
+
+ iterpool = svn_pool_create(scratch_pool);
+ for (i = 0; i < sorted_hash->nelts; i++)
+ {
+ svn_sort__item_t *item = &APR_ARRAY_IDX(sorted_hash, i, svn_sort__item_t);
+ apr_array_header_t *actions = item->value;
+ const char *path = item->key;
+ apr_hash_t *props;
+ int j;
+
+ svn_pool_clear(iterpool);
+
+ props = apr_hash_make(iterpool);
+
+ /* Go through all of our actions, populating various datastructures
+ * dependent on them. */
+ for (j = 0; j < actions->nelts; j++)
+ {
+ struct path_action *action = APR_ARRAY_IDX(actions, j,
+ struct path_action *);
+
+ switch (action->action)
+ {
+ case set_prop:
+ {
+ struct prop_args *p_args = action->args;
+
+ apr_hash_set(props, p_args->name, APR_HASH_KEY_STRING,
+ p_args->value);
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ /* We've now got a wholistic view of what has happened to this node,
+ * so we can call our own editor APIs on it. */
+ if (apr_hash_count(props) > 0)
+ SVN_ERR(svn_editor_set_props(eb->editor, path, SVN_INVALID_REVNUM,
+ props, TRUE));
+ }
+ svn_pool_destroy(iterpool);
return svn_error_trace(svn_editor_complete(eb->editor));
}
@@ -317,6 +440,8 @@ svn_delta_from_editor(svn_delta_editor_t
struct ev2_edit_baton *eb = apr_palloc(pool, sizeof(*eb));
eb->editor = editor;
+ eb->paths = apr_hash_make(pool);
+ eb->edit_pool = pool;
*dedit_baton = eb;
*deditor = &delta_editor;
Modified: subversion/trunk/subversion/tests/libsvn_delta/editor-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_delta/editor-test.c?rev=1166332&r1=1166331&r2=1166332&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_delta/editor-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_delta/editor-test.c Wed Sep 7 19:36:01 2011
@@ -27,10 +27,13 @@
#include "svn_types.h"
#include "svn_error.h"
+#include "svn_pools.h"
#include "svn_editor.h"
#include "../svn_test_fs.h"
+#define SET_STR(ps, s) ((ps)->data = (s), (ps)->len = strlen(s))
+
/* We use svn_repos APIs in some of these tests simply for convenience. */
/* This implements svn_editor_cb_add_directory_t */
@@ -201,38 +204,78 @@ editor_from_delta_editor_test(const svn_
svn_repos_t *repos;
svn_fs_t *fs;
svn_fs_txn_t *txn;
- svn_fs_root_t *revision_root, *txn_root, *base_root;
+ svn_fs_root_t *txn_root;
svn_revnum_t youngest_rev;
- void *dedit_baton;
- svn_delta_editor_t *deditor;
- svn_editor_t *editor;
+ apr_pool_t *iterpool;
+ svn_string_t s1;
+ int i;
/* Create a filesystem and repository. */
SVN_ERR(svn_test__create_repos(&repos, "ev2-from-delta-editor-test",
opts, pool));
fs = svn_repos_fs(repos);
- /* Prepare a txn to receive the greek tree. */
- SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
- SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-
- /* Create and commit the greek tree. */
- SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
- SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
- SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
-
- SVN_ERR(svn_fs_revision_root(&revision_root, fs, youngest_rev, pool));
- SVN_ERR(svn_fs_revision_root(&base_root, fs, 0, pool));
-
- /* Construct our editor, and from it a delta editor. */
- SVN_ERR(get_noop_editor(&editor, NULL, NULL, NULL, pool, pool));
- SVN_ERR(svn_delta_from_editor(&deditor, &dedit_baton, editor, pool));
-
- SVN_ERR(svn_repos_replay2(revision_root, "", SVN_INVALID_REVNUM, TRUE,
- deditor, dedit_baton, NULL, NULL, pool));
+ {
+ /* Prepare a txn to receive the greek tree. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+ /* Create and commit the greek tree. */
+ SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+ SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+ }
- /* Close the edit. */
- SVN_ERR(deditor->close_edit(dedit_baton, pool));
+ {
+ /* Now chuck in some prop changes. */
+ const char *props[4][2] = {
+ { "If you change to meet a frown,", "Do not let it stay." },
+ { "Quickly turn it upside down,", "And smile that frown away." },
+ { "No one likes a frowny face,", "Change it for a smile," },
+ { "Make the world a better place,", "By smiling all the while!" }
+ };
+
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, 1, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+
+ for (i = 0; i < 4; i++)
+ {
+ SET_STR(&s1, props[i][1]);
+ SVN_ERR(svn_fs_change_node_prop(txn_root, "iota",
+ props[i][0], &s1, pool));
+ }
+
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+ SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
+ }
+
+ /* Now, let's look at each revision. */
+ iterpool = svn_pool_create(pool);
+ for (i = 0; i < youngest_rev; i++)
+ {
+ svn_fs_root_t *revision_root;
+ void *dedit_baton;
+ svn_delta_editor_t *deditor;
+ svn_editor_t *editor;
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_fs_revision_root(&revision_root, fs, i, iterpool));
+
+ /* Construct our editor, and from it a delta editor. */
+ SVN_ERR(get_noop_editor(&editor, NULL, NULL, NULL, iterpool, iterpool));
+ SVN_ERR(svn_delta_from_editor(&deditor, &dedit_baton, editor, iterpool));
+
+ SVN_ERR(svn_repos_replay2(revision_root, "", SVN_INVALID_REVNUM, TRUE,
+ deditor, dedit_baton, NULL, NULL, iterpool));
+
+ /* Close the edit. */
+ SVN_ERR(deditor->close_edit(dedit_baton, iterpool));
+
+ /* ### This is the point at which we should probably verify something,
+ * ### but right now, we're just pleased if the tests don't crash. */
+ }
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
Re: svn commit: r1166332 - in /subversion/trunk/subversion:
libsvn_delta/compat.c tests/libsvn_delta/editor-test.c
Posted by Hyrum K Wright <hy...@wandisco.com>.
On Wed, Sep 7, 2011 at 10:52 PM, Daniel Shahaf <d....@daniel.shahaf.name> wrote:
> hwright@apache.org wrote on Wed, Sep 07, 2011 at 19:36:01 -0000:
>> @@ -276,6 +345,60 @@ ev2_close_edit(void *edit_baton,
>> apr_pool_t *scratch_pool)
>> {
>> struct ev2_edit_baton *eb = edit_baton;
>> + apr_array_header_t *sorted_hash;
>> + apr_pool_t *iterpool;
>> + int i;
>> +
>> + /* Sort the paths touched by this edit.
>> + * Ev2 doesn't really have any particular need for depth-first-ness, but
>> + * we want to ensure all parent directories are handled before children in
>> + * the case of adds (which does introduce an element of depth-first-ness). */
>> + sorted_hash = svn_sort__hash(eb->paths, svn_sort_compare_items_as_paths,
>> + scratch_pool);
>> +
>> + iterpool = svn_pool_create(scratch_pool);
>> + for (i = 0; i < sorted_hash->nelts; i++)
>> + {
>> + svn_sort__item_t *item = &APR_ARRAY_IDX(sorted_hash, i, svn_sort__item_t);
>> + apr_array_header_t *actions = item->value;
>> + const char *path = item->key;
>> + apr_hash_t *props;
>> + int j;
>> +
>> + svn_pool_clear(iterpool);
>> +
>> + props = apr_hash_make(iterpool);
>> +
>> + /* Go through all of our actions, populating various datastructures
>> + * dependent on them. */
>> + for (j = 0; j < actions->nelts; j++)
>> + {
>> + struct path_action *action = APR_ARRAY_IDX(actions, j,
>> + struct path_action *);
>> +
>> + switch (action->action)
>> + {
>> + case set_prop:
>> + {
>> + struct prop_args *p_args = action->args;
>> +
>> + apr_hash_set(props, p_args->name, APR_HASH_KEY_STRING,
>> + p_args->value);
>> + break;
>> + }
>> +
>> + default:
>> + break;
>> + }
>> + }
>> +
>> + /* We've now got a wholistic view of what has happened to this node,
>> + * so we can call our own editor APIs on it. */
>> + if (apr_hash_count(props) > 0)
>
> What if ACTIONS contains only property deletions?
I *think* I addressed this in subsequent commits, but it did raise a
question which I added to svn_editor.h.
-Hyrum
>> + SVN_ERR(svn_editor_set_props(eb->editor, path, SVN_INVALID_REVNUM,
>> + props, TRUE));
>> + }
>> + svn_pool_destroy(iterpool);
>>
>> return svn_error_trace(svn_editor_complete(eb->editor));
>> }
>
--
uberSVN: Apache Subversion Made Easy
http://www.uberSVN.com/
Re: svn commit: r1166332 - in /subversion/trunk/subversion:
libsvn_delta/compat.c tests/libsvn_delta/editor-test.c
Posted by Hyrum K Wright <hy...@wandisco.com>.
On Wed, Sep 7, 2011 at 10:52 PM, Daniel Shahaf <d....@daniel.shahaf.name> wrote:
> hwright@apache.org wrote on Wed, Sep 07, 2011 at 19:36:01 -0000:
>> @@ -276,6 +345,60 @@ ev2_close_edit(void *edit_baton,
>> apr_pool_t *scratch_pool)
>> {
>> struct ev2_edit_baton *eb = edit_baton;
>> + apr_array_header_t *sorted_hash;
>> + apr_pool_t *iterpool;
>> + int i;
>> +
>> + /* Sort the paths touched by this edit.
>> + * Ev2 doesn't really have any particular need for depth-first-ness, but
>> + * we want to ensure all parent directories are handled before children in
>> + * the case of adds (which does introduce an element of depth-first-ness). */
>> + sorted_hash = svn_sort__hash(eb->paths, svn_sort_compare_items_as_paths,
>> + scratch_pool);
>> +
>> + iterpool = svn_pool_create(scratch_pool);
>> + for (i = 0; i < sorted_hash->nelts; i++)
>> + {
>> + svn_sort__item_t *item = &APR_ARRAY_IDX(sorted_hash, i, svn_sort__item_t);
>> + apr_array_header_t *actions = item->value;
>> + const char *path = item->key;
>> + apr_hash_t *props;
>> + int j;
>> +
>> + svn_pool_clear(iterpool);
>> +
>> + props = apr_hash_make(iterpool);
>> +
>> + /* Go through all of our actions, populating various datastructures
>> + * dependent on them. */
>> + for (j = 0; j < actions->nelts; j++)
>> + {
>> + struct path_action *action = APR_ARRAY_IDX(actions, j,
>> + struct path_action *);
>> +
>> + switch (action->action)
>> + {
>> + case set_prop:
>> + {
>> + struct prop_args *p_args = action->args;
>> +
>> + apr_hash_set(props, p_args->name, APR_HASH_KEY_STRING,
>> + p_args->value);
>> + break;
>> + }
>> +
>> + default:
>> + break;
>> + }
>> + }
>> +
>> + /* We've now got a wholistic view of what has happened to this node,
>> + * so we can call our own editor APIs on it. */
>> + if (apr_hash_count(props) > 0)
>
> What if ACTIONS contains only property deletions?
I *think* I addressed this in subsequent commits, but it did raise a
question which I added to svn_editor.h.
-Hyrum
>> + SVN_ERR(svn_editor_set_props(eb->editor, path, SVN_INVALID_REVNUM,
>> + props, TRUE));
>> + }
>> + svn_pool_destroy(iterpool);
>>
>> return svn_error_trace(svn_editor_complete(eb->editor));
>> }
>
--
uberSVN: Apache Subversion Made Easy
http://www.uberSVN.com/
Re: svn commit: r1166332 - in /subversion/trunk/subversion:
libsvn_delta/compat.c tests/libsvn_delta/editor-test.c
Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
hwright@apache.org wrote on Wed, Sep 07, 2011 at 19:36:01 -0000:
> @@ -276,6 +345,60 @@ ev2_close_edit(void *edit_baton,
> apr_pool_t *scratch_pool)
> {
> struct ev2_edit_baton *eb = edit_baton;
> + apr_array_header_t *sorted_hash;
> + apr_pool_t *iterpool;
> + int i;
> +
> + /* Sort the paths touched by this edit.
> + * Ev2 doesn't really have any particular need for depth-first-ness, but
> + * we want to ensure all parent directories are handled before children in
> + * the case of adds (which does introduce an element of depth-first-ness). */
> + sorted_hash = svn_sort__hash(eb->paths, svn_sort_compare_items_as_paths,
> + scratch_pool);
> +
> + iterpool = svn_pool_create(scratch_pool);
> + for (i = 0; i < sorted_hash->nelts; i++)
> + {
> + svn_sort__item_t *item = &APR_ARRAY_IDX(sorted_hash, i, svn_sort__item_t);
> + apr_array_header_t *actions = item->value;
> + const char *path = item->key;
> + apr_hash_t *props;
> + int j;
> +
> + svn_pool_clear(iterpool);
> +
> + props = apr_hash_make(iterpool);
> +
> + /* Go through all of our actions, populating various datastructures
> + * dependent on them. */
> + for (j = 0; j < actions->nelts; j++)
> + {
> + struct path_action *action = APR_ARRAY_IDX(actions, j,
> + struct path_action *);
> +
> + switch (action->action)
> + {
> + case set_prop:
> + {
> + struct prop_args *p_args = action->args;
> +
> + apr_hash_set(props, p_args->name, APR_HASH_KEY_STRING,
> + p_args->value);
> + break;
> + }
> +
> + default:
> + break;
> + }
> + }
> +
> + /* We've now got a wholistic view of what has happened to this node,
> + * so we can call our own editor APIs on it. */
> + if (apr_hash_count(props) > 0)
What if ACTIONS contains only property deletions?
> + SVN_ERR(svn_editor_set_props(eb->editor, path, SVN_INVALID_REVNUM,
> + props, TRUE));
> + }
> + svn_pool_destroy(iterpool);
>
> return svn_error_trace(svn_editor_complete(eb->editor));
> }
Re: svn commit: r1166332 - in /subversion/trunk/subversion:
libsvn_delta/compat.c tests/libsvn_delta/editor-test.c
Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
hwright@apache.org wrote on Wed, Sep 07, 2011 at 19:36:01 -0000:
> @@ -276,6 +345,60 @@ ev2_close_edit(void *edit_baton,
> apr_pool_t *scratch_pool)
> {
> struct ev2_edit_baton *eb = edit_baton;
> + apr_array_header_t *sorted_hash;
> + apr_pool_t *iterpool;
> + int i;
> +
> + /* Sort the paths touched by this edit.
> + * Ev2 doesn't really have any particular need for depth-first-ness, but
> + * we want to ensure all parent directories are handled before children in
> + * the case of adds (which does introduce an element of depth-first-ness). */
> + sorted_hash = svn_sort__hash(eb->paths, svn_sort_compare_items_as_paths,
> + scratch_pool);
> +
> + iterpool = svn_pool_create(scratch_pool);
> + for (i = 0; i < sorted_hash->nelts; i++)
> + {
> + svn_sort__item_t *item = &APR_ARRAY_IDX(sorted_hash, i, svn_sort__item_t);
> + apr_array_header_t *actions = item->value;
> + const char *path = item->key;
> + apr_hash_t *props;
> + int j;
> +
> + svn_pool_clear(iterpool);
> +
> + props = apr_hash_make(iterpool);
> +
> + /* Go through all of our actions, populating various datastructures
> + * dependent on them. */
> + for (j = 0; j < actions->nelts; j++)
> + {
> + struct path_action *action = APR_ARRAY_IDX(actions, j,
> + struct path_action *);
> +
> + switch (action->action)
> + {
> + case set_prop:
> + {
> + struct prop_args *p_args = action->args;
> +
> + apr_hash_set(props, p_args->name, APR_HASH_KEY_STRING,
> + p_args->value);
> + break;
> + }
> +
> + default:
> + break;
> + }
> + }
> +
> + /* We've now got a wholistic view of what has happened to this node,
> + * so we can call our own editor APIs on it. */
> + if (apr_hash_count(props) > 0)
What if ACTIONS contains only property deletions?
> + SVN_ERR(svn_editor_set_props(eb->editor, path, SVN_INVALID_REVNUM,
> + props, TRUE));
> + }
> + svn_pool_destroy(iterpool);
>
> return svn_error_trace(svn_editor_complete(eb->editor));
> }