Skip to content

Commit 7d944c3

Browse files
samvEric Wong
authored andcommitted
git-svn: memoize conversion of SVN merge ticket info to git commit ranges
Each time the svn mergeinfo ticket changes, we look it up in the rev_map; when there are a lot of merged branches, this will result in many repeated lookups of the same information for subsequent commits. Arrange the slow part of the function so that it may be memoized, and memoize it. The more expensive revision walking operation can be memoized separately. [ew: changed "next" to "return" for function exit] Signed-off-by: Sam Vilain <[email protected]> Acked-by: Eric Wong <[email protected]>
1 parent 1d144aa commit 7d944c3

File tree

1 file changed

+54
-37
lines changed

1 file changed

+54
-37
lines changed

git-svn.perl

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,7 @@ package Git::SVN;
16341634
use File::Path qw/mkpath/;
16351635
use File::Copy qw/copy/;
16361636
use IPC::Open3;
1637+
use Memoize; # core since 5.8.0, Jul 2002
16371638

16381639
my ($_gc_nr, $_gc_period);
16391640

@@ -2994,6 +2995,55 @@ sub find_extra_svk_parents {
29942995
}
29952996
}
29962997

2998+
sub lookup_svn_merge {
2999+
my $uuid = shift;
3000+
my $url = shift;
3001+
my $merge = shift;
3002+
3003+
my ($source, $revs) = split ":", $merge;
3004+
my $path = $source;
3005+
$path =~ s{^/}{};
3006+
my $gs = Git::SVN->find_by_url($url.$source, $url, $path);
3007+
if ( !$gs ) {
3008+
warn "Couldn't find revmap for $url$source\n";
3009+
return;
3010+
}
3011+
my @ranges = split ",", $revs;
3012+
my ($tip, $tip_commit);
3013+
my @merged_commit_ranges;
3014+
# find the tip
3015+
for my $range ( @ranges ) {
3016+
my ($bottom, $top) = split "-", $range;
3017+
$top ||= $bottom;
3018+
my $bottom_commit =
3019+
$gs->rev_map_get($bottom, $uuid) ||
3020+
$gs->rev_map_get($bottom+1, $uuid);
3021+
my $top_commit;
3022+
for (; !$top_commit && $top >= $bottom; --$top) {
3023+
$top_commit =
3024+
$gs->rev_map_get($top, $uuid);
3025+
}
3026+
3027+
unless ($top_commit and $bottom_commit) {
3028+
warn "W:unknown path/rev in svn:mergeinfo "
3029+
."dirprop: $source:$range\n";
3030+
next;
3031+
}
3032+
3033+
push @merged_commit_ranges,
3034+
"$bottom_commit..$top_commit";
3035+
3036+
if ( !defined $tip or $top > $tip ) {
3037+
$tip = $top;
3038+
$tip_commit = $top_commit;
3039+
}
3040+
}
3041+
return ($tip_commit, @merged_commit_ranges);
3042+
}
3043+
BEGIN {
3044+
memoize 'lookup_svn_merge';
3045+
}
3046+
29973047
# note: this function should only be called if the various dirprops
29983048
# have actually changed
29993049
sub find_extra_svn_parents {
@@ -3008,44 +3058,11 @@ sub find_extra_svn_parents {
30083058
my @merge_tips;
30093059
my @merged_commit_ranges;
30103060
my $url = $self->rewrite_root || $self->{url};
3061+
my $uuid = $self->ra_uuid;
30113062
for my $merge ( @merges ) {
3012-
my ($source, $revs) = split ":", $merge;
3013-
my $path = $source;
3014-
$path =~ s{^/}{};
3015-
my $gs = Git::SVN->find_by_url($url.$source, $url, $path);
3016-
if ( !$gs ) {
3017-
warn "Couldn't find revmap for $url$source\n";
3018-
next;
3019-
}
3020-
my @ranges = split ",", $revs;
3021-
my ($tip, $tip_commit);
3022-
# find the tip
3023-
for my $range ( @ranges ) {
3024-
my ($bottom, $top) = split "-", $range;
3025-
$top ||= $bottom;
3026-
my $bottom_commit =
3027-
$gs->rev_map_get($bottom, $self->ra_uuid) ||
3028-
$gs->rev_map_get($bottom+1, $self->ra_uuid);
3029-
my $top_commit;
3030-
for (; !$top_commit && $top >= $bottom; --$top) {
3031-
$top_commit =
3032-
$gs->rev_map_get($top, $self->ra_uuid);
3033-
}
3034-
3035-
unless ($top_commit and $bottom_commit) {
3036-
warn "W:unknown path/rev in svn:mergeinfo "
3037-
."dirprop: $source:$range\n";
3038-
next;
3039-
}
3040-
3041-
push @merged_commit_ranges,
3042-
"$bottom_commit..$top_commit";
3043-
3044-
if ( !defined $tip or $top > $tip ) {
3045-
$tip = $top;
3046-
$tip_commit = $top_commit;
3047-
}
3048-
}
3063+
my ($tip_commit, @ranges) =
3064+
lookup_svn_merge( $uuid, $url, $merge );
3065+
push @merged_commit_ranges, @ranges;
30493066
unless (!$tip_commit or
30503067
grep { $_ eq $tip_commit } @$parents ) {
30513068
push @merge_tips, $tip_commit;

0 commit comments

Comments
 (0)