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 2011/07/22 11:34:29 UTC
svn commit: r1149519 - in /subversion/trunk/subversion:
include/svn_mergeinfo.h libsvn_subr/deprecated.c libsvn_subr/mergeinfo.c
Author: stsp
Date: Fri Jul 22 09:34:28 2011
New Revision: 1149519
URL: http://svn.apache.org/viewvc?rev=1149519&view=rev
Log:
Add svn_rangelist_merge2() which modifies the rangelist in-place to produce
its result, instead of allocating a new rangelist, and also uses the dual-pool
paradigm. The previous svn_rangelist_merge() implementation was awkward
to call from within a loop without potentially using a lot of memory (see
r1148566 for an example).
Suggested by: philip
* subversion/include/svn_mergeinfo.h
(svn_rangelist_merge2): Declare.
(svn_rangelist_merge): Deprecate.
* subversion/libsvn_subr/deprecated.c
(svn_rangelist_merge): Implement as a wrapper around svn_rangelist_merge2().
* subversion/libsvn_subr/mergeinfo.c
(svn_rangelist_merge): Rename to ...
(svn_rangelist_merge2): ... this. Change the RANGELIST parameter to
an apr_array_header_t* (rather than apr_array_header_t**). Replace
the POOL parameter with RESULT_POOL and SCRATCH_POOL parameters.
Produce the merged rangelist in place, allocating any elements newly
added to the array in RESULT_POOL.
Modified:
subversion/trunk/subversion/include/svn_mergeinfo.h
subversion/trunk/subversion/libsvn_subr/deprecated.c
subversion/trunk/subversion/libsvn_subr/mergeinfo.c
Modified: subversion/trunk/subversion/include/svn_mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_mergeinfo.h?rev=1149519&r1=1149518&r2=1149519&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_mergeinfo.h (original)
+++ subversion/trunk/subversion/include/svn_mergeinfo.h Fri Jul 22 09:34:28 2011
@@ -270,20 +270,38 @@ svn_rangelist_diff(apr_array_header_t **
apr_pool_t *pool);
/** Merge two rangelists consisting of @c svn_merge_range_t *
- * elements, @a *rangelist and @a changes, placing the results in
- * @a *rangelist. Either rangelist may be empty.
+ * elements, @a rangelist and @a changes, placing the results in
+ * @a rangelist. New elements added to @a rangelist are allocated
+ * in @a result_pool. Either rangelist may be empty.
*
* When intersecting rangelists are merged, the inheritability of
* the resulting svn_merge_range_t depends on the inheritability of the
* operands: see svn_mergeinfo_merge().
*
- * Note: @a *rangelist and @a changes must be sorted as said by @c
- * svn_sort_compare_ranges(). @a *rangelist is guaranteed to remain
+ * Note: @a rangelist and @a changes must be sorted as said by @c
+ * svn_sort_compare_ranges(). @a rangelist is guaranteed to remain
* in sorted order and be compacted to the minimal number of ranges
* needed to represent the merged result.
*
+ * Use @a scratch_pool for temporary allocations.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_rangelist_merge2(apr_array_header_t *rangelist,
+ const apr_array_header_t *changes,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/** Like svn_rangelist_merge2(), but with @a rangelist as an input/output
+ * argument. This function always allocates a new rangelist in @a pool and
+ * returns its result in @a *rangelist. It does not modify @a *rangelist
+ * in place. If not used carefully, this function can use up a lot of memory
+ * if called in a loop.
+ *
* @since New in 1.5.
*/
+SVN_DEPRECATED
svn_error_t *
svn_rangelist_merge(apr_array_header_t **rangelist,
const apr_array_header_t *changes,
Modified: subversion/trunk/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/deprecated.c?rev=1149519&r1=1149518&r2=1149519&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_subr/deprecated.c Fri Jul 22 09:34:28 2011
@@ -1126,3 +1126,12 @@ svn_xml_make_header(svn_stringbuf_t **st
{
svn_xml_make_header2(str, NULL, pool);
}
+
+svn_error_t *
+svn_rangelist_merge(apr_array_header_t **rangelist,
+ const apr_array_header_t *changes,
+ apr_pool_t *pool)
+{
+ return svn_error_trace(svn_rangelist_merge2(*rangelist, changes,
+ pool, pool));
+}
Modified: subversion/trunk/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/mergeinfo.c?rev=1149519&r1=1149518&r2=1149519&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_subr/mergeinfo.c Fri Jul 22 09:34:28 2011
@@ -37,6 +37,7 @@
#include "private/svn_string_private.h"
#include "svn_private_config.h"
#include "svn_hash.h"
+#include "private/svn_dep_compat.h"
/* Attempt to combine two ranges, IN1 and IN2. If they are adjacent or
overlapping, and their inheritability allows them to be combined, put
@@ -707,23 +708,26 @@ svn_mergeinfo_parse(svn_mergeinfo_t *mer
return err;
}
-
svn_error_t *
-svn_rangelist_merge(apr_array_header_t **rangelist,
- const apr_array_header_t *changes,
- apr_pool_t *pool)
+svn_rangelist_merge2(apr_array_header_t *rangelist,
+ const apr_array_header_t *changes,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
int i, j;
- apr_array_header_t *output = apr_array_make(pool, 1,
- sizeof(svn_merge_range_t *));
+ apr_array_header_t *original_rangelist;
+
+ original_rangelist = apr_array_copy(scratch_pool, rangelist);
+ apr_array_clear(rangelist);
+
i = 0;
j = 0;
- while (i < (*rangelist)->nelts && j < changes->nelts)
+ while (i < (original_rangelist)->nelts && j < changes->nelts)
{
svn_merge_range_t *elt1, *elt2;
int res;
- elt1 = APR_ARRAY_IDX(*rangelist, i, svn_merge_range_t *);
+ elt1 = APR_ARRAY_IDX(original_rangelist, i, svn_merge_range_t *);
elt2 = APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
res = svn_sort_compare_ranges(&elt1, &elt2);
@@ -734,46 +738,45 @@ svn_rangelist_merge(apr_array_header_t *
result. */
if (elt1->inheritable || elt2->inheritable)
elt1->inheritable = TRUE;
- SVN_ERR(combine_with_lastrange(elt1, output,
- TRUE, pool, pool));
+ SVN_ERR(combine_with_lastrange(elt1, rangelist, TRUE, result_pool,
+ scratch_pool));
i++;
j++;
}
else if (res < 0)
{
- SVN_ERR(combine_with_lastrange(elt1, output,
- TRUE, pool, pool));
+ SVN_ERR(combine_with_lastrange(elt1, rangelist, TRUE, result_pool,
+ scratch_pool));
i++;
}
else
{
- SVN_ERR(combine_with_lastrange(elt2, output,
- TRUE, pool, pool));
+ SVN_ERR(combine_with_lastrange(elt2, rangelist, TRUE, result_pool,
+ scratch_pool));
j++;
}
}
/* Copy back any remaining elements.
Only one of these loops should end up running, if anything. */
- SVN_ERR_ASSERT(!(i < (*rangelist)->nelts && j < changes->nelts));
+ SVN_ERR_ASSERT(!(i < (original_rangelist)->nelts && j < changes->nelts));
- for (; i < (*rangelist)->nelts; i++)
+ for (; i < (original_rangelist)->nelts; i++)
{
- svn_merge_range_t *elt = APR_ARRAY_IDX(*rangelist, i,
+ svn_merge_range_t *elt = APR_ARRAY_IDX(original_rangelist, i,
svn_merge_range_t *);
- SVN_ERR(combine_with_lastrange(elt, output,
- TRUE, pool, pool));
+ SVN_ERR(combine_with_lastrange(elt, rangelist, TRUE, result_pool,
+ scratch_pool));
}
for (; j < changes->nelts; j++)
{
svn_merge_range_t *elt = APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
- SVN_ERR(combine_with_lastrange(elt, output,
- TRUE, pool, pool));
+ SVN_ERR(combine_with_lastrange(elt, rangelist,
+ TRUE, result_pool, scratch_pool));
}
- *rangelist = output;
return SVN_NO_ERROR;
}