You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/02/15 22:20:45 UTC
svn commit: r1730615 - /subversion/trunk/subversion/libsvn_repos/log.c
Author: stefan2
Date: Mon Feb 15 21:20:44 2016
New Revision: 1730615
URL: http://svn.apache.org/viewvc?rev=1730615&view=rev
Log:
Continue work on the svn_repos_get_logs4 to svn_repos_get_logs5 migration:
Finally switch the main log processing to the new FS iterator API.
This finalizes the API work by introducing a repos-layer-specific
path_change_t.
* subversion/libsvn_repos/log.c
(svn_repos__path_change_t): New repos-layer-specific path_change_t.
Keep it identical to the FS one, if feasible.
(svn_repos__path_change_receiver_t): Update signature to use the new type.
(detect_changed): Switch to the iterator-based changes API. No longer
need to convert data here.
(interesting_merge): Update callback.
(path_change_kind_to_char): New utility function.
(log4_path_change_receiver): Update callback. Convert to old data type.
Modified:
subversion/trunk/subversion/libsvn_repos/log.c
Modified: subversion/trunk/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/log.c?rev=1730615&r1=1730614&r2=1730615&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/log.c (original)
+++ subversion/trunk/subversion/libsvn_repos/log.c Mon Feb 15 21:20:44 2016
@@ -47,10 +47,12 @@
/* To become public API. */
+typedef svn_fs_path_change3_t svn_repos__path_change_t;
+
+/* To become public API. */
typedef svn_error_t *(*svn_repos__path_change_receiver_t)(
void *baton,
- const char *path,
- svn_log_changed_path2_t *change,
+ svn_repos__path_change_t *change,
apr_pool_t *scratch_pool);
/* To become public API. */
@@ -258,8 +260,8 @@ detect_changed(svn_repos_revision_access
const log_callbacks_t *callbacks,
apr_pool_t *scratch_pool)
{
- apr_hash_t *changes;
- apr_hash_index_t *hi;
+ svn_fs_path_change_iterator_t *iterator;
+ svn_fs_path_change3_t *change;
apr_pool_t *iterpool;
svn_boolean_t found_readable = FALSE;
svn_boolean_t found_unreadable = FALSE;
@@ -267,9 +269,10 @@ detect_changed(svn_repos_revision_access
/* If we create the CHANGES hash ourselves, we can reuse it as the
* result hash as it contains the exact same keys - but with _all_
* values being replaced by structs of a different type. */
- SVN_ERR(svn_fs_paths_changed2(&changes, root, scratch_pool));
+ SVN_ERR(svn_fs_paths_changed3(&iterator, root, scratch_pool, scratch_pool));
+ SVN_ERR(svn_fs_path_change_get(&change, iterator));
- if (apr_hash_count(changes) == 0)
+ if (!change)
{
/* No paths changed in this revision? Uh, sure, I guess the
revision is readable, then. */
@@ -278,16 +281,12 @@ detect_changed(svn_repos_revision_access
}
iterpool = svn_pool_create(scratch_pool);
- for (hi = apr_hash_first(scratch_pool, changes); hi; hi = apr_hash_next(hi))
+ while (change)
{
/* NOTE: Much of this loop is going to look quite similar to
svn_repos_check_revision_access(), but we have to do more things
here, so we'll live with the duplication. */
- const char *path = apr_hash_this_key(hi);
- svn_fs_path_change2_t *change = apr_hash_this_val(hi);
- char action;
- svn_log_changed_path2_t *item;
-
+ const char *path = change->path.data;
svn_pool_clear(iterpool);
/* Skip path if unreadable. */
@@ -300,6 +299,7 @@ detect_changed(svn_repos_revision_access
if (! readable)
{
found_unreadable = TRUE;
+ SVN_ERR(svn_fs_path_change_get(&change, iterator));
continue;
}
}
@@ -307,41 +307,9 @@ detect_changed(svn_repos_revision_access
/* At least one changed-path was readable. */
found_readable = TRUE;
- switch (change->change_kind)
- {
- case svn_fs_path_change_reset:
- continue;
-
- case svn_fs_path_change_add:
- action = 'A';
- break;
-
- case svn_fs_path_change_replace:
- action = 'R';
- break;
-
- case svn_fs_path_change_delete:
- action = 'D';
- break;
-
- case svn_fs_path_change_modify:
- default:
- action = 'M';
- break;
- }
-
- item = svn_log_changed_path2_create(iterpool);
- item->action = action;
- item->node_kind = change->node_kind;
- item->copyfrom_rev = SVN_INVALID_REVNUM;
- item->text_modified = change->text_mod ? svn_tristate_true
- : svn_tristate_false;
- item->props_modified = change->prop_mod ? svn_tristate_true
- : svn_tristate_false;
-
/* Pre-1.6 revision files don't store the change path kind, so fetch
it manually. */
- if (item->node_kind == svn_node_unknown)
+ if (change->node_kind == svn_node_unknown)
{
svn_fs_root_t *check_root = root;
const char *check_path = path;
@@ -373,12 +341,12 @@ detect_changed(svn_repos_revision_access
check_path = svn_fspath__join(parent_path, name, iterpool);
}
- SVN_ERR(svn_fs_check_path(&item->node_kind, check_root, check_path,
+ SVN_ERR(svn_fs_check_path(&change->node_kind, check_root, check_path,
iterpool));
}
-
- if ((action == 'A') || (action == 'R'))
+ if ( (change->change_kind == svn_fs_path_change_add)
+ || (change->change_kind == svn_fs_path_change_replace))
{
const char *copyfrom_path = change->copyfrom_path;
svn_revnum_t copyfrom_rev = change->copyfrom_rev;
@@ -387,11 +355,8 @@ detect_changed(svn_repos_revision_access
we will follow the DAG from ROOT to PATH and that requires
actually reading the directories along the way. */
if (!change->copyfrom_known)
- {
- SVN_ERR(svn_fs_copied_from(©from_rev, ©from_path,
- root, path, iterpool));
- copyfrom_path = apr_pstrdup(scratch_pool, copyfrom_path);
- }
+ SVN_ERR(svn_fs_copied_from(©from_rev, ©from_path,
+ root, path, iterpool));
if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_rev))
{
@@ -414,8 +379,8 @@ detect_changed(svn_repos_revision_access
if (readable)
{
- item->copyfrom_path = copyfrom_path;
- item->copyfrom_rev = copyfrom_rev;
+ change->copyfrom_path = copyfrom_path;
+ change->copyfrom_rev = copyfrom_rev;
}
}
}
@@ -423,8 +388,11 @@ detect_changed(svn_repos_revision_access
if (callbacks->path_change_receiver)
SVN_ERR(callbacks->path_change_receiver(
callbacks->path_change_receiver_baton,
- path, item,
+ change,
iterpool));
+
+ /* Next changed path. */
+ SVN_ERR(svn_fs_path_change_get(&change, iterator));
}
svn_pool_destroy(iterpool);
@@ -1259,15 +1227,14 @@ typedef struct interesting_merge_baton_t
*/
static svn_error_t *
interesting_merge(void *baton,
- const char *path,
- svn_log_changed_path2_t *change,
+ svn_fs_path_change3_t *change,
apr_pool_t *scratch_pool)
{
interesting_merge_baton_t *b = baton;
apr_hash_index_t *hi;
if (b->inner)
- SVN_ERR(b->inner(b->inner_baton, path, change, scratch_pool));
+ SVN_ERR(b->inner(b->inner_baton, change, scratch_pool));
if (b->found_rev_of_interest)
return SVN_NO_ERROR;
@@ -1282,7 +1249,7 @@ interesting_merge(void *baton,
/* Check whether CHANGED_PATH at revision REV is a child of
a (path, revision) tuple in LOG_TARGET_HISTORY_AS_MERGEINFO. */
- if (svn_fspath__skip_ancestor(mergeinfo_path, path))
+ if (svn_fspath__skip_ancestor(mergeinfo_path, change->path.data))
{
int i;
@@ -2510,31 +2477,53 @@ typedef struct log_entry_receiver_baton_
void *inner_baton;
} log_entry_receiver_baton_t;
+/* Return the action character (see svn_log_changed_path2_t) for KIND.
+ * Returns 0 for invalid KINDs. */
+static char
+path_change_kind_to_char(svn_fs_path_change_kind_t kind)
+{
+ const char symbol[] = "MADR";
+
+ if (kind < svn_fs_path_change_modify || kind > svn_fs_path_change_replace)
+ return 0;
+
+ return symbol[kind];
+}
+
/* Implement svn_repos__path_change_receiver_t.
- * Copy (path, change) to the CHANGES list in *BATON. */
+ * Convert CHANGE and add it to the CHANGES list in *BATON. */
static svn_error_t *
log4_path_change_receiver(void *baton,
- const char *path,
- svn_log_changed_path2_t *change,
+ svn_repos__path_change_t *change,
apr_pool_t *scratch_pool)
{
log_entry_receiver_baton_t *b = baton;
svn_log_changed_path2_t *change_copy;
+ const char *path = apr_pstrmemdup(b->changes_pool, change->path.data,
+ change->path.len);
/* Create a deep copy of the temporary CHANGE struct. */
change_copy = svn_log_changed_path2_create(b->changes_pool);
- *change_copy = *change;
+ change_copy->action = path_change_kind_to_char(change->change_kind);
+
if (change->copyfrom_path)
change_copy->copyfrom_path = apr_pstrdup(b->changes_pool,
change->copyfrom_path);
+ change_copy->copyfrom_rev = change->copyfrom_rev;
+ change_copy->node_kind = change->node_kind;
+ change_copy->text_modified = change->text_mod ? svn_tristate_true
+ : svn_tristate_false;
+ change_copy->props_modified = change->prop_mod ? svn_tristate_true
+ : svn_tristate_false;
+
/* Auto-create the CHANGES container (happens for each first change
* in any revison. */
if (b->changes == NULL)
b->changes = svn_hash__make(b->changes_pool);
/* Add change to per-revision collection. */
- svn_hash_sets(b->changes, apr_pstrdup(b->changes_pool, path), change_copy);
+ apr_hash_set(b->changes, path, change->path.len, change_copy);
return SVN_NO_ERROR;
}