Skip to content

Commit 0dc03d6

Browse files
Eric WongJunio C Hamano
authored andcommitted
git-svn: clean up caching of SVN::Ra functions
This patch was originally intended to make the Perl GC more sensitive to the SVN::Pool objects and not accidentally clean them up when they shouldn't be (causing segfaults). That didn't work, but this patch makes the code a bit cleaner regardless Put our caches for get_dir and check_path calls directly into the SVN::Ra object so they auto-expire when it is destroyed. dirents returned by get_dir() no longer needs the pool object stored persistently along with the cache data, as they'll be converted to native Perl hash references. Since calling rev_proplist repeatedly per-revision is no longer needed in git-svn, we do not cache calls to it. Signed-off-by: Eric Wong <[email protected]>
1 parent 645833b commit 0dc03d6

File tree

1 file changed

+42
-26
lines changed

1 file changed

+42
-26
lines changed

git-svn.perl

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,7 @@ sub traverse_ignore {
13901390
}
13911391
}
13921392
foreach (sort keys %$dirent) {
1393-
next if $dirent->{$_}->kind != $SVN::Node::dir;
1393+
next if $dirent->{$_}->{kind} != $SVN::Node::dir;
13941394
$self->traverse_ignore($fh, "$path/$_", $r);
13951395
}
13961396
}
@@ -2888,7 +2888,7 @@ package Git::SVN::Ra;
28882888
BEGIN {
28892889
# enforce temporary pool usage for some simple functions
28902890
my $e;
2891-
foreach (qw/get_latest_revnum get_uuid get_repos_root/) {
2891+
foreach (qw/rev_proplist get_latest_revnum get_uuid get_repos_root/) {
28922892
$e .= "sub $_ {
28932893
my \$self = shift;
28942894
my \$pool = SVN::Pool->new;
@@ -2897,29 +2897,7 @@ BEGIN
28972897
wantarray ? \@ret : \$ret[0]; }\n";
28982898
}
28992899

2900-
# get_dir needs $pool held in cache for dirents to work,
2901-
# check_path is cacheable and rev_proplist is close enough
2902-
# for our purposes.
2903-
foreach (qw/check_path get_dir rev_proplist/) {
2904-
$e .= "my \%${_}_cache; my \$${_}_rev = 0; sub $_ {
2905-
my \$self = shift;
2906-
my \$r = pop;
2907-
my \$k = join(\"\\0\", \@_);
2908-
if (my \$x = \$${_}_cache{\$r}->{\$k}) {
2909-
return wantarray ? \@\$x : \$x->[0];
2910-
}
2911-
my \$pool = SVN::Pool->new;
2912-
my \@ret = \$self->SUPER::$_(\@_, \$r, \$pool);
2913-
if (\$r != \$${_}_rev) {
2914-
\%${_}_cache = ( pool => [] );
2915-
\$${_}_rev = \$r;
2916-
}
2917-
\$${_}_cache{\$r}->{\$k} = \\\@ret;
2918-
push \@{\$${_}_cache{pool}}, \$pool;
2919-
wantarray ? \@ret : \$ret[0]; }\n";
2920-
}
2921-
$e .= "\n1;";
2922-
eval $e or die $@;
2900+
eval "$e; 1;" or die $@;
29232901
}
29242902

29252903
sub new {
@@ -2952,9 +2930,47 @@ sub new {
29522930
$self->{svn_path} = $url;
29532931
$self->{repos_root} = $self->get_repos_root;
29542932
$self->{svn_path} =~ s#^\Q$self->{repos_root}\E(/|$)##;
2933+
$self->{cache} = { check_path => { r => 0, data => {} },
2934+
get_dir => { r => 0, data => {} } };
29552935
$RA = bless $self, $class;
29562936
}
29572937

2938+
sub check_path {
2939+
my ($self, $path, $r) = @_;
2940+
my $cache = $self->{cache}->{check_path};
2941+
if ($r == $cache->{r} && exists $cache->{data}->{$path}) {
2942+
return $cache->{data}->{$path};
2943+
}
2944+
my $pool = SVN::Pool->new;
2945+
my $t = $self->SUPER::check_path($path, $r, $pool);
2946+
$pool->clear;
2947+
if ($r != $cache->{r}) {
2948+
%{$cache->{data}} = ();
2949+
$cache->{r} = $r;
2950+
}
2951+
$cache->{data}->{$path} = $t;
2952+
}
2953+
2954+
sub get_dir {
2955+
my ($self, $dir, $r) = @_;
2956+
my $cache = $self->{cache}->{get_dir};
2957+
if ($r == $cache->{r}) {
2958+
if (my $x = $cache->{data}->{$dir}) {
2959+
return wantarray ? @$x : $x->[0];
2960+
}
2961+
}
2962+
my $pool = SVN::Pool->new;
2963+
my ($d, undef, $props) = $self->SUPER::get_dir($dir, $r, $pool);
2964+
my %dirents = map { $_ => { kind => $d->{$_}->kind } } keys %$d;
2965+
$pool->clear;
2966+
if ($r != $cache->{r}) {
2967+
%{$cache->{data}} = ();
2968+
$cache->{r} = $r;
2969+
}
2970+
$cache->{data}->{$dir} = [ \%dirents, $r, $props ];
2971+
wantarray ? (\%dirents, $r, $props) : \%dirents;
2972+
}
2973+
29582974
sub DESTROY {
29592975
# do not call the real DESTROY since we store ourselves in $RA
29602976
}
@@ -3169,7 +3185,7 @@ sub match_globs {
31693185
return unless scalar @x == 3;
31703186
my $dirents = $x[0];
31713187
foreach my $de (keys %$dirents) {
3172-
next if $dirents->{$de}->kind != $SVN::Node::dir;
3188+
next if $dirents->{$de}->{kind} != $SVN::Node::dir;
31733189
my $p = $g->{path}->full_path($de);
31743190
next if $exists->{$p};
31753191
next if (length $g->{path}->{right} &&

0 commit comments

Comments
 (0)