Author: stefan2
Date: Thu May 16 15:57:11 2013
New Revision: 1483422
URL: http://svn.apache.org/r1483422
Log:
On the fsfs-format7 branch: Modify the change_t structure to be easier
to use with loggy functions.
The path member will be a proper svn_string_t to allow for efficient
hashing, duplicating data etc. The remainder now uses an instance of
the svn_fs_path_change2_t which we have to hand our to the API anyway.
Callers / users usually only need one extra syntactic indirection.
Operations that need to copy and / or "fold" changes can now be simplified,
require fewer temporary copies and will become much faster as a result.
* subversion/libsvn_fs_fs/fs.h
(change_t): change the definition but leave contents almost unchanged
* subversion/libsvn_fs_fs/changes.c
(append_change,
svn_fs_fs__changes_get_list,
svn_fs_fs__changes_get_list_func): update
* subversion/libsvn_fs_fs/low_level.c
(read_change): ditto
* subversion/libsvn_fs_fs/temp_serializer.c
(serialize_change,
deserialize_change): ditto
* subversion/libsvn_fs_fs/transaction.c
(fold_change): update and simplify
(process_changes): update; no longer use this for pre-folded lists at all
(svn_fs_fs__txn_changes_fetch): update caller
(svn_fs_fs__paths_changed): build result hash directly
Modified:
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c?rev=1483422&r1=1483421&r2=1483422&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/changes.c Thu May
16 15:57:11 2013
@@ -138,30 +138,34 @@ append_change(svn_fs_fs__changes_t *chan
{
binary_change_t binary_change = { 0 };
svn_boolean_t is_txn_id;
+ svn_fs_path_change2_t *info;
/* CHANGE must be sufficiently complete */
SVN_ERR_ASSERT(change);
- SVN_ERR_ASSERT(change->path);
+ SVN_ERR_ASSERT(change->path.data);
/* define the kind of change and what specific information is present */
- is_txn_id = change->noderev_id && svn_fs_fs__id_is_txn(change->noderev_id);
- binary_change.flags = (change->text_mod ? CHANGE_TEXT_MOD : 0)
- | (change->prop_mod ? CHANGE_PROP_MOD : 0)
+ info = &change->info;
+ is_txn_id = info->node_rev_id && svn_fs_fs__id_is_txn(info->node_rev_id);
+ binary_change.flags = (info->text_mod ? CHANGE_TEXT_MOD : 0)
+ | (info->prop_mod ? CHANGE_PROP_MOD : 0)
| (is_txn_id ? CHANGE_TXN_NODE : 0)
- | ((int)change->kind << CHANGE_KIND_SHIFT)
- | ((int)change->node_kind << CHANGE_NODE_SHIFT);
+ | ((int)info->change_kind << CHANGE_KIND_SHIFT)
+ | ((int)info->node_kind << CHANGE_NODE_SHIFT);
/* Path of the change. */
binary_change.path
- = svn_fs_fs__string_table_builder_add(changes->builder, change->path, 0);
+ = svn_fs_fs__string_table_builder_add(changes->builder,
+ change->path.data,
+ change->path.len);
/* copy-from information, if presence is indicated by FLAGS */
- if (SVN_IS_VALID_REVNUM(change->copyfrom_rev))
+ if (SVN_IS_VALID_REVNUM(info->copyfrom_rev))
{
- binary_change.copyfrom_rev = change->copyfrom_rev;
+ binary_change.copyfrom_rev = info->copyfrom_rev;
binary_change.copyfrom_path
= svn_fs_fs__string_table_builder_add(changes->builder,
- change->copyfrom_path,
+ info->copyfrom_path,
0);
}
else
@@ -171,13 +175,13 @@ append_change(svn_fs_fs__changes_t *chan
}
/* Relevant parts of the revision ID of the change. */
- if (change->noderev_id)
+ if (info->node_rev_id)
{
- binary_change.node_id = *svn_fs_fs__id_node_id(change->noderev_id);
- binary_change.copy_id = *svn_fs_fs__id_copy_id(change->noderev_id);
+ binary_change.node_id = *svn_fs_fs__id_node_id(info->node_rev_id);
+ binary_change.copy_id = *svn_fs_fs__id_copy_id(info->node_rev_id);
binary_change.rev_id = is_txn_id
- ? *svn_fs_fs__id_txn_id(change->noderev_id)
- : *svn_fs_fs__id_rev_item(change->noderev_id);
+ ? *svn_fs_fs__id_txn_id(info->node_rev_id)
+ : *svn_fs_fs__id_rev_item(info->node_rev_id);
}
else
{
@@ -260,13 +264,14 @@ svn_fs_fs__changes_get_list(apr_array_he
/* convert BINARY_CHANGE into a standard FSFS change_t */
change_t *change = apr_pcalloc(pool, sizeof(*change));
- change->path = svn_fs_fs__string_table_get(changes->paths,
- binary_change->path,
- NULL,
- pool);
+ svn_fs_path_change2_t *info = &change->info;
+ change->path.data = svn_fs_fs__string_table_get(changes->paths,
+ binary_change->path,
+ &change->path.len,
+ pool);
if (svn_fs_fs__id_txn_used(&binary_change->rev_id))
- change->noderev_id
+ info->node_rev_id
= (binary_change->flags & CHANGE_TXN_NODE)
? svn_fs_fs__id_txn_create(&binary_change->node_id,
&binary_change->copy_id,
@@ -277,16 +282,17 @@ svn_fs_fs__changes_get_list(apr_array_he
&binary_change->rev_id,
pool);
- change->kind = (svn_fs_path_change_kind_t)
+ info->change_kind = (svn_fs_path_change_kind_t)
((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT);
- change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
- change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
- change->node_kind = (svn_node_kind_t)
+ info->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
+ info->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
+ info->node_kind = (svn_node_kind_t)
((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT);
- change->copyfrom_rev = binary_change->copyfrom_rev;
+ info->copyfrom_rev = binary_change->copyfrom_rev;
+ info->copyfrom_known = TRUE;
if (SVN_IS_VALID_REVNUM(binary_change->copyfrom_rev))
- change->copyfrom_path
+ info->copyfrom_path
= svn_fs_fs__string_table_get(changes->paths,
binary_change->copyfrom_path,
NULL,
@@ -530,13 +536,13 @@ svn_fs_fs__changes_get_list_func(void **
/* convert BINARY_CHANGE into a standard FSFS change_t */
change_t *change = apr_pcalloc(pool, sizeof(*change));
- change->path = svn_fs_fs__string_table_get_func(paths,
- binary_change->path,
- NULL,
- pool);
+ svn_fs_path_change2_t *info = &change->info;
+ change->path.data
+ = svn_fs_fs__string_table_get_func(paths, binary_change->path,
+ &change->path.len, pool);
if (svn_fs_fs__id_txn_used(&binary_change->rev_id))
- change->noderev_id
+ info->node_rev_id
= (binary_change->flags & CHANGE_TXN_NODE)
? svn_fs_fs__id_txn_create(&binary_change->node_id,
&binary_change->copy_id,
@@ -547,16 +553,17 @@ svn_fs_fs__changes_get_list_func(void **
&binary_change->rev_id,
pool);
- change->kind = (svn_fs_path_change_kind_t)
+ info->change_kind = (svn_fs_path_change_kind_t)
((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT);
- change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
- change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
- change->node_kind = (svn_node_kind_t)
+ info->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0;
+ info->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0;
+ info->node_kind = (svn_node_kind_t)
((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT);
- change->copyfrom_rev = binary_change->copyfrom_rev;
+ info->copyfrom_rev = binary_change->copyfrom_rev;
+ info->copyfrom_known = TRUE;
if (SVN_IS_VALID_REVNUM(binary_change->copyfrom_rev))
- change->copyfrom_path
+ info->copyfrom_path
= svn_fs_fs__string_table_get_func(paths,
binary_change->copyfrom_path,
NULL,
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h?rev=1483422&r1=1483421&r2=1483422&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.h Thu May 16
15:57:11 2013
@@ -561,25 +561,10 @@ typedef struct node_revision_t
typedef struct change_t
{
/* Path of the change. */
- const char *path;
-
- /* Node revision ID of the change. */
- const svn_fs_id_t *noderev_id;
-
- /* The kind of change. */
- svn_fs_path_change_kind_t kind;
-
- /* Text or property mods? */
- svn_boolean_t text_mod;
- svn_boolean_t prop_mod;
-
- /* Node kind (possibly svn_node_unknown). */
- svn_node_kind_t node_kind;
-
- /* Copyfrom revision and path. */
- svn_revnum_t copyfrom_rev;
- const char * copyfrom_path;
+ svn_string_t path;
+ /* API compatible change description */
+ svn_fs_path_change2_t info;
} change_t;
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c?rev=1483422&r1=1483421&r2=1483422&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c Thu
May 16 15:57:11 2013
@@ -721,6 +721,7 @@ read_change(change_t **change_p,
svn_boolean_t eof = TRUE;
change_t *change;
char *str, *last_str, *kind_str;
+ svn_fs_path_change2_t *info;
/* Default return value. */
*change_p = NULL;
@@ -732,6 +733,7 @@ read_change(change_t **change_p,
return SVN_NO_ERROR;
change = apr_pcalloc(pool, sizeof(*change));
+ info = &change->info;
last_str = line->data;
/* Get the node-id of the change. */
@@ -740,8 +742,8 @@ read_change(change_t **change_p,
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Invalid changes line in rev-file"));
- change->noderev_id = svn_fs_fs__id_parse(str, strlen(str), pool);
- if (change->noderev_id == NULL)
+ info->node_rev_id = svn_fs_fs__id_parse(str, strlen(str), pool);
+ if (info->node_rev_id == NULL)
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Invalid changes line in rev-file"));
@@ -753,7 +755,7 @@ read_change(change_t **change_p,
/* Don't bother to check the format number before looking for
* node-kinds: just read them if you find them. */
- change->node_kind = svn_node_unknown;
+ info->node_kind = svn_node_unknown;
kind_str = strchr(str, '-');
if (kind_str)
{
@@ -761,9 +763,9 @@ read_change(change_t **change_p,
*kind_str = '\0';
kind_str++;
if (strcmp(kind_str, SVN_FS_FS__KIND_FILE) == 0)
- change->node_kind = svn_node_file;
+ info->node_kind = svn_node_file;
else if (strcmp(kind_str, SVN_FS_FS__KIND_DIR) == 0)
- change->node_kind = svn_node_dir;
+ info->node_kind = svn_node_dir;
else
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Invalid changes line in rev-file"));
@@ -771,23 +773,23 @@ read_change(change_t **change_p,
if (strcmp(str, ACTION_MODIFY) == 0)
{
- change->kind = svn_fs_path_change_modify;
+ info->change_kind = svn_fs_path_change_modify;
}
else if (strcmp(str, ACTION_ADD) == 0)
{
- change->kind = svn_fs_path_change_add;
+ info->change_kind = svn_fs_path_change_add;
}
else if (strcmp(str, ACTION_DELETE) == 0)
{
- change->kind = svn_fs_path_change_delete;
+ info->change_kind = svn_fs_path_change_delete;
}
else if (strcmp(str, ACTION_REPLACE) == 0)
{
- change->kind = svn_fs_path_change_replace;
+ info->change_kind = svn_fs_path_change_replace;
}
else if (strcmp(str, ACTION_RESET) == 0)
{
- change->kind = svn_fs_path_change_reset;
+ info->change_kind = svn_fs_path_change_reset;
}
else
{
@@ -803,11 +805,11 @@ read_change(change_t **change_p,
if (strcmp(str, FLAG_TRUE) == 0)
{
- change->text_mod = TRUE;
+ info->text_mod = TRUE;
}
else if (strcmp(str, FLAG_FALSE) == 0)
{
- change->text_mod = FALSE;
+ info->text_mod = FALSE;
}
else
{
@@ -823,11 +825,11 @@ read_change(change_t **change_p,
if (strcmp(str, FLAG_TRUE) == 0)
{
- change->prop_mod = TRUE;
+ info->prop_mod = TRUE;
}
else if (strcmp(str, FLAG_FALSE) == 0)
{
- change->prop_mod = FALSE;
+ info->prop_mod = FALSE;
}
else
{
@@ -836,15 +838,16 @@ read_change(change_t **change_p,
}
/* Get the changed path. */
- change->path = apr_pstrdup(pool, last_str);
-
+ change->path.len = strlen(last_str);
+ change->path.data = apr_pstrmemdup(pool, last_str, change->path.len);
/* Read the next line, the copyfrom line. */
SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, pool));
+ info->copyfrom_known = TRUE;
if (eof || line->len == 0)
{
- change->copyfrom_rev = SVN_INVALID_REVNUM;
- change->copyfrom_path = NULL;
+ info->copyfrom_rev = SVN_INVALID_REVNUM;
+ info->copyfrom_path = NULL;
}
else
{
@@ -853,13 +856,13 @@ read_change(change_t **change_p,
if (! str)
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Invalid changes line in rev-file"));
- change->copyfrom_rev = SVN_STR_TO_REV(str);
+ info->copyfrom_rev = SVN_STR_TO_REV(str);
if (! last_str)
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Invalid changes line in rev-file"));
- change->copyfrom_path = apr_pstrdup(pool, last_str);
+ info->copyfrom_path = apr_pstrdup(pool, last_str);
}
*change_p = change;
Modified:
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c?rev=1483422&r1=1483421&r2=1483422&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c
Thu May 16 15:57:11 2013
@@ -1072,10 +1072,10 @@ serialize_change(svn_temp_serializer__co
sizeof(*change));
/* serialize sub-structures */
- svn_fs_fs__id_serialize(context, &change->noderev_id);
+ svn_fs_fs__id_serialize(context, &change->info.node_rev_id);
- svn_temp_serializer__add_string(context, &change->path);
- svn_temp_serializer__add_string(context, &change->copyfrom_path);
+ svn_temp_serializer__add_string(context, &change->path.data);
+ svn_temp_serializer__add_string(context, &change->info.copyfrom_path);
/* return to the caller's nesting level */
svn_temp_serializer__pop(context);
@@ -1097,10 +1097,10 @@ deserialize_change(void *buffer, change_
return;
/* fix-up of sub-structures */
- svn_fs_fs__id_deserialize(change, (svn_fs_id_t **)&change->noderev_id);
+ svn_fs_fs__id_deserialize(change, (svn_fs_id_t **)&change->info.node_rev_id);
- svn_temp_deserializer__resolve(change, (void **)&change->path);
- svn_temp_deserializer__resolve(change, (void **)&change->copyfrom_path);
+ svn_temp_deserializer__resolve(change, (void **)&change->path.data);
+ svn_temp_deserializer__resolve(change, (void **)&change->info.copyfrom_path);
}
/* Auxiliary structure representing the content of a change_t array.
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c?rev=1483422&r1=1483421&r2=1483422&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c
(original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c Thu
May 16 15:57:11 2013
@@ -657,17 +657,18 @@ fold_change(apr_hash_t *changes,
{
apr_pool_t *pool = apr_hash_pool_get(changes);
svn_fs_path_change2_t *old_change, *new_change;
- const char *path;
- apr_size_t path_len = strlen(change->path);
+ const svn_string_t *path = &change->path;
+ const svn_fs_path_change2_t *info = &change->info;
- if ((old_change = apr_hash_get(changes, change->path, path_len)))
+ if (old_change = apr_hash_get(changes, path->data, path->len))
{
/* This path already exists in the hash, so we have to merge
this change into the already existing one. */
/* Sanity check: only allow NULL node revision ID in the
`reset' case. */
- if ((! change->noderev_id) && (change->kind != svn_fs_path_change_reset))
+ if ((! info->node_rev_id)
+ && (info->change_kind != svn_fs_path_change_reset))
return svn_error_create
(SVN_ERR_FS_CORRUPT, NULL,
_("Missing required node revision ID"));
@@ -675,8 +676,8 @@ fold_change(apr_hash_t *changes,
/* Sanity check: we should be talking about the same node
revision ID as our last change except where the last change
was a deletion. */
- if (change->noderev_id
- && (! svn_fs_fs__id_eq(old_change->node_rev_id, change->noderev_id))
+ if (info->node_rev_id
+ && (! svn_fs_fs__id_eq(old_change->node_rev_id, info->node_rev_id))
&& (old_change->change_kind != svn_fs_path_change_delete))
return svn_error_create
(SVN_ERR_FS_CORRUPT, NULL,
@@ -686,16 +687,16 @@ fold_change(apr_hash_t *changes,
/* Sanity check: an add, replacement, or reset must be the first
thing to follow a deletion. */
if ((old_change->change_kind == svn_fs_path_change_delete)
- && (! ((change->kind == svn_fs_path_change_replace)
- || (change->kind == svn_fs_path_change_reset)
- || (change->kind == svn_fs_path_change_add))))
+ && (! ((info->change_kind == svn_fs_path_change_replace)
+ || (info->change_kind == svn_fs_path_change_reset)
+ || (info->change_kind == svn_fs_path_change_add))))
return svn_error_create
(SVN_ERR_FS_CORRUPT, NULL,
_("Invalid change ordering: non-add change on deleted path"));
/* Sanity check: an add can't follow anything except
a delete or reset. */
- if ((change->kind == svn_fs_path_change_add)
+ if ((info->change_kind == svn_fs_path_change_add)
&& (old_change->change_kind != svn_fs_path_change_delete)
&& (old_change->change_kind != svn_fs_path_change_reset))
return svn_error_create
@@ -703,7 +704,7 @@ fold_change(apr_hash_t *changes,
_("Invalid change ordering: add change on preexisting path"));
/* Now, merge that change in. */
- switch (change->kind)
+ switch (info->change_kind)
{
case svn_fs_path_change_reset:
/* A reset here will simply remove the path change from the
@@ -723,8 +724,8 @@ fold_change(apr_hash_t *changes,
{
/* A deletion overrules all previous changes. */
old_change->change_kind = svn_fs_path_change_delete;
- old_change->text_mod = change->text_mod;
- old_change->prop_mod = change->prop_mod;
+ old_change->text_mod = info->text_mod;
+ old_change->prop_mod = info->prop_mod;
old_change->copyfrom_rev = SVN_INVALID_REVNUM;
old_change->copyfrom_path = NULL;
}
@@ -735,72 +736,54 @@ fold_change(apr_hash_t *changes,
/* An add at this point must be following a previous delete,
so treat it just like a replace. */
old_change->change_kind = svn_fs_path_change_replace;
- old_change->node_rev_id = svn_fs_fs__id_copy(change->noderev_id,
+ old_change->node_rev_id = svn_fs_fs__id_copy(info->node_rev_id,
pool);
- old_change->text_mod = change->text_mod;
- old_change->prop_mod = change->prop_mod;
- if (change->copyfrom_rev == SVN_INVALID_REVNUM)
+ old_change->text_mod = info->text_mod;
+ old_change->prop_mod = info->prop_mod;
+ if (info->copyfrom_rev == SVN_INVALID_REVNUM)
{
old_change->copyfrom_rev = SVN_INVALID_REVNUM;
old_change->copyfrom_path = NULL;
}
else
{
- old_change->copyfrom_rev = change->copyfrom_rev;
+ old_change->copyfrom_rev = info->copyfrom_rev;
old_change->copyfrom_path = apr_pstrdup(pool,
- change->copyfrom_path);
+ info->copyfrom_path);
}
break;
case svn_fs_path_change_modify:
default:
- if (change->text_mod)
+ if (info->text_mod)
old_change->text_mod = TRUE;
- if (change->prop_mod)
+ if (info->prop_mod)
old_change->prop_mod = TRUE;
break;
}
- /* Point our new_change to our (possibly modified) old_change. */
- new_change = old_change;
+ /* remove old_change from the cache if it is no longer needed. */
+ if (old_change == NULL)
+ apr_hash_set(changes, path->data, path->len, NULL);
}
else
{
/* This change is new to the hash, so make a new public change
structure from the internal one (in the hash's pool), and dup
the path into the hash's pool, too. */
- new_change = apr_pcalloc(pool, sizeof(*new_change));
- new_change->node_rev_id = svn_fs_fs__id_copy(change->noderev_id, pool);
- new_change->change_kind = change->kind;
- new_change->text_mod = change->text_mod;
- new_change->prop_mod = change->prop_mod;
- /* In FSFS, copyfrom_known is *always* true, since we've always
- * stored copyfroms in changed paths lists. */
- new_change->copyfrom_known = TRUE;
- if (change->copyfrom_rev != SVN_INVALID_REVNUM)
- {
- new_change->copyfrom_rev = change->copyfrom_rev;
- new_change->copyfrom_path = apr_pstrdup(pool, change->copyfrom_path);
- }
- else
- {
- new_change->copyfrom_rev = SVN_INVALID_REVNUM;
- new_change->copyfrom_path = NULL;
- }
+ new_change = apr_pmemdup(pool, info, sizeof(*new_change));
+ new_change->node_rev_id = svn_fs_fs__id_copy(info->node_rev_id, pool);
+ if (info->copyfrom_path)
+ new_change->copyfrom_path = apr_pstrdup(pool, info->copyfrom_path);
+
+ /* Add this path. The API makes no guarantees that this (new) key
+ will not be retained. Thus, we copy the key into the target pool
+ to ensure a proper lifetime. */
+ apr_hash_set(changes,
+ apr_pstrmemdup(pool, path->data, path->len), path->len,
+ new_change);
}
- if (new_change)
- new_change->node_kind = change->node_kind;
-
- /* Add (or update) this path.
-
- Note: this key might already be present, and it would be nice to
- re-use its value, but there is no way to fetch it. The API makes no
- guarantees that this (new) key will not be retained. Thus, we (again)
- copy the key into the target pool to ensure a proper lifetime. */
- path = apr_pstrmemdup(pool, change->path, path_len);
- apr_hash_set(changes, path, path_len, new_change);
-
return SVN_NO_ERROR;
}
@@ -815,7 +798,6 @@ fold_change(apr_hash_t *changes,
static svn_error_t *
process_changes(apr_hash_t *changed_paths,
apr_array_header_t *changes,
- svn_boolean_t prefolded,
apr_pool_t *pool)
{
apr_pool_t *iterpool = svn_pool_create(pool);
@@ -838,9 +820,8 @@ process_changes(apr_hash_t *changed_path
is already a temporary subpool.
*/
- if (((change->kind == svn_fs_path_change_delete)
- || (change->kind == svn_fs_path_change_replace))
- && ! prefolded)
+ if ((change->info.change_kind == svn_fs_path_change_delete)
+ || (change->info.change_kind == svn_fs_path_change_replace))
{
apr_hash_index_t *hi;
@@ -849,12 +830,12 @@ process_changes(apr_hash_t *changed_path
Also, we should not assume that all paths have been normalized
i.e. some might have trailing path separators.
*/
- apr_ssize_t change_path_len = strlen(change->path);
- apr_ssize_t min_child_len = change_path_len == 0
+ apr_ssize_t path_len = change->path.len;
+ apr_ssize_t min_child_len = path_len == 0
? 1
- : change->path[change_path_len-1] == '/'
- ? change_path_len + 1
- : change_path_len + 2;
+ : change->path.data[path_len-1] == '/'
+ ? path_len + 1
+ : path_len + 2;
/* CAUTION: This is the inner loop of an O(n^2) algorithm.
The number of changes to process may be >> 1000.
@@ -874,13 +855,13 @@ process_changes(apr_hash_t *changed_path
this is actually a sub-path.
*/
if ( klen >= min_child_len
- && svn_dirent_is_child(change->path, path, iterpool))
+ && svn_dirent_is_child(change->path.data, path, iterpool))
apr_hash_set(changed_paths, path, klen, NULL);
}
- }
- /* Clear the per-iteration subpool. */
- svn_pool_clear(iterpool);
+ /* Clear the per-iteration subpool. */
+ svn_pool_clear(iterpool);
+ }
}
/* Destroy the per-iteration subpool. */
@@ -908,7 +889,7 @@ svn_fs_fs__txn_changes_fetch(apr_hash_t
svn_stream_from_aprfile2(file, TRUE,
scratch_pool),
scratch_pool));
- SVN_ERR(process_changes(changed_paths, changes, FALSE, pool));
+ SVN_ERR(process_changes(changed_paths, changes, pool));
svn_pool_destroy(scratch_pool);
*changed_paths_p = changed_paths;
@@ -925,14 +906,17 @@ svn_fs_fs__paths_changed(apr_hash_t **ch
{
apr_hash_t *changed_paths;
apr_array_header_t *changes;
- apr_pool_t *scratch_pool = svn_pool_create(pool);
+ int i;
- SVN_ERR(svn_fs_fs__get_changes(&changes, fs, rev, scratch_pool));
+ SVN_ERR(svn_fs_fs__get_changes(&changes, fs, rev, pool));
changed_paths = svn_hash__make(pool);
-
- SVN_ERR(process_changes(changed_paths, changes, TRUE, pool));
- svn_pool_destroy(scratch_pool);
+ for (i = 0; i < changes->nelts; ++i)
+ {
+ change_t *change = APR_ARRAY_IDX(changes, i, change_t *);
+ apr_hash_set(changed_paths, change->path.data, change->path.len,
+ &change->info);
+ }
*changed_paths_p = changed_paths;