@matheusbsbs / matheus-bagliano / commits / 7d944c3399
Fork 0

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 <sam@vilain.net> Acked-by: Eric Wong <normalperson@yhbt.net>

Sam Vilain committed Dec 20, 2009 at 00:55 UTC 7d944c3399c4145293d599e1ddc76d1ac0c1e118
1 file changed +54 -37
git-svn.perl
+54 -37
@@ -1634,6 +1634,7 @@ use Carp qw/croak/;
1634 use File::Path qw/mkpath/;
1635 use File::Copy qw/copy/;
1636 use IPC::Open3;
1637 +use Memoize; # core since 5.8.0, Jul 2002
1638
1639 my ($_gc_nr, $_gc_period);
1640
@@ -2994,6 +2995,55 @@ sub find_extra_svk_parents {
2995 }
2996 }
2997
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 +
3047 # note: this function should only be called if the various dirprops
3048 # have actually changed
3049 sub find_extra_svn_parents {
@@ -3008,44 +3058,11 @@ sub find_extra_svn_parents {
3058 my @merge_tips;
3059 my @merged_commit_ranges;
3060 my $url = $self->rewrite_root || $self->{url};
3061 + my $uuid = $self->ra_uuid;
3062 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;
3066 unless (!$tip_commit or
3067 grep { $_ eq $tip_commit } @$parents ) {
3068 push @merge_tips, $tip_commit;