C. Michael Pilato wrote:
> Karl Fogel wrote:
>> Do we really have to loop over (on average) half of changed_revs each
>> time to evaluate whether or not the range in question is operative?
>> After all, changed_revs is in sorted order already -- I don't know which
>> way, but svn_ra_get_log2()'s doc string has details on that. So instead
>> of looping every time, we could just compare
>> APR_ARRAY_IDX(changed_revs, 0, svn_revnum_t *)
>> APR_ARRAY_IDX(changed_revs, changed_revs->nelts, svn_revnum_t *)
>
> changed_revs->nelts-1 here, but yes, I see what you're saying.
Attaching a patch which should do this, for extra eyes and backup purposes.
--
C. Michael Pilato <cmpilato_at_collab.net>
CollabNet <> www.collab.net <> Distributed Development On Demand
More optimizations for the single-file merge case.
* subversion/libsvn_client/merge.c
(remove_noop_merge_ranges): Avoid a linear trampse through the array
of operative revisions if the entire range fails to overlap with the
requested merge range.
Suggested by: kfogel
Index: subversion/libsvn_client/merge.c
===================================================================
--- subversion/libsvn_client/merge.c (revision 31930)
+++ subversion/libsvn_client/merge.c (working copy)
@@ -3920,6 +3920,7 @@
int i;
svn_revnum_t oldest_rev = SVN_INVALID_REVNUM;
svn_revnum_t youngest_rev = SVN_INVALID_REVNUM;
+ svn_revnum_t oldest_changed_rev, youngest_changed_rev;
apr_array_header_t *changed_revs =
apr_array_make(pool, ranges->nelts, sizeof(svn_revnum_t *));
apr_array_header_t *operative_ranges =
@@ -3948,20 +3949,36 @@
apr_array_make(pool, 0, sizeof(const char *)),
log_changed_revs, changed_revs, pool));
+ /* Our list of changed revisions should be in youngest-to-oldest order. */
+ youngest_changed_rev = *(APR_ARRAY_IDX(changed_revs,
+ 0, svn_revnum_t *));
+ oldest_changed_rev = *(APR_ARRAY_IDX(changed_revs,
+ changed_revs->nelts - 1,
+ svn_revnum_t *));
+
/* Now, copy from RANGES to *OPERATIVE_RANGES, filtering out ranges
that aren't operative (by virtue of not having any revisions
represented in the CHANGED_REVS array). */
for (i = 0; i < ranges->nelts; i++)
{
svn_merge_range_t *range = APR_ARRAY_IDX(ranges, i, svn_merge_range_t *);
+ svn_revnum_t range_min = MIN(range->start, range->end) + 1;
+ svn_revnum_t range_max = MAX(range->start, range->end);
int j;
+ /* If the merge range is entirely outside the range of changed
+ revisions, we've no use for it. */
+ if ((range_min > youngest_changed_rev)
+ || (range_max < oldest_changed_rev))
+ continue;
+
+ /* Walk through the changed_revs to see if any of them fall
+ inside our current range. */
for (j = 0; j < changed_revs->nelts; j++)
{
svn_revnum_t *changed_rev =
APR_ARRAY_IDX(changed_revs, j, svn_revnum_t *);
- if ((*changed_rev > MIN(range->start, range->end))
- && (*changed_rev <= MAX(range->start, range->end)))
+ if ((*changed_rev >= range_min) && (*changed_rev <= range_max))
{
APR_ARRAY_PUSH(operative_ranges, svn_merge_range_t *) = range;
break;
Received on 2008-06-30 23:30:46 CEST