summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 645833b)
raw | patch | inline | side by side (parent: 645833b)
author | Eric Wong <normalperson@yhbt.net> | |
Sun, 13 May 2007 08:04:43 +0000 (01:04 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Sun, 13 May 2007 19:10:42 +0000 (12:10 -0700) |
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 <normalperson@yhbt.net>
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 <normalperson@yhbt.net>
git-svn.perl | patch | blob | history |
diff --git a/git-svn.perl b/git-svn.perl
index d74e6d3112eb6ad444df35a1dae1fc4fab2afb00..721a46817b13f828735572646f39729531a60d60 100755 (executable)
--- a/git-svn.perl
+++ b/git-svn.perl
}
}
foreach (sort keys %$dirent) {
- next if $dirent->{$_}->kind != $SVN::Node::dir;
+ next if $dirent->{$_}->{kind} != $SVN::Node::dir;
$self->traverse_ignore($fh, "$path/$_", $r);
}
}
BEGIN {
# enforce temporary pool usage for some simple functions
my $e;
- foreach (qw/get_latest_revnum get_uuid get_repos_root/) {
+ foreach (qw/rev_proplist get_latest_revnum get_uuid get_repos_root/) {
$e .= "sub $_ {
my \$self = shift;
my \$pool = SVN::Pool->new;
wantarray ? \@ret : \$ret[0]; }\n";
}
- # get_dir needs $pool held in cache for dirents to work,
- # check_path is cacheable and rev_proplist is close enough
- # for our purposes.
- foreach (qw/check_path get_dir rev_proplist/) {
- $e .= "my \%${_}_cache; my \$${_}_rev = 0; sub $_ {
- my \$self = shift;
- my \$r = pop;
- my \$k = join(\"\\0\", \@_);
- if (my \$x = \$${_}_cache{\$r}->{\$k}) {
- return wantarray ? \@\$x : \$x->[0];
- }
- my \$pool = SVN::Pool->new;
- my \@ret = \$self->SUPER::$_(\@_, \$r, \$pool);
- if (\$r != \$${_}_rev) {
- \%${_}_cache = ( pool => [] );
- \$${_}_rev = \$r;
- }
- \$${_}_cache{\$r}->{\$k} = \\\@ret;
- push \@{\$${_}_cache{pool}}, \$pool;
- wantarray ? \@ret : \$ret[0]; }\n";
- }
- $e .= "\n1;";
- eval $e or die $@;
+ eval "$e; 1;" or die $@;
}
sub new {
$self->{svn_path} = $url;
$self->{repos_root} = $self->get_repos_root;
$self->{svn_path} =~ s#^\Q$self->{repos_root}\E(/|$)##;
+ $self->{cache} = { check_path => { r => 0, data => {} },
+ get_dir => { r => 0, data => {} } };
$RA = bless $self, $class;
}
+sub check_path {
+ my ($self, $path, $r) = @_;
+ my $cache = $self->{cache}->{check_path};
+ if ($r == $cache->{r} && exists $cache->{data}->{$path}) {
+ return $cache->{data}->{$path};
+ }
+ my $pool = SVN::Pool->new;
+ my $t = $self->SUPER::check_path($path, $r, $pool);
+ $pool->clear;
+ if ($r != $cache->{r}) {
+ %{$cache->{data}} = ();
+ $cache->{r} = $r;
+ }
+ $cache->{data}->{$path} = $t;
+}
+
+sub get_dir {
+ my ($self, $dir, $r) = @_;
+ my $cache = $self->{cache}->{get_dir};
+ if ($r == $cache->{r}) {
+ if (my $x = $cache->{data}->{$dir}) {
+ return wantarray ? @$x : $x->[0];
+ }
+ }
+ my $pool = SVN::Pool->new;
+ my ($d, undef, $props) = $self->SUPER::get_dir($dir, $r, $pool);
+ my %dirents = map { $_ => { kind => $d->{$_}->kind } } keys %$d;
+ $pool->clear;
+ if ($r != $cache->{r}) {
+ %{$cache->{data}} = ();
+ $cache->{r} = $r;
+ }
+ $cache->{data}->{$dir} = [ \%dirents, $r, $props ];
+ wantarray ? (\%dirents, $r, $props) : \%dirents;
+}
+
sub DESTROY {
# do not call the real DESTROY since we store ourselves in $RA
}
return unless scalar @x == 3;
my $dirents = $x[0];
foreach my $de (keys %$dirents) {
- next if $dirents->{$de}->kind != $SVN::Node::dir;
+ next if $dirents->{$de}->{kind} != $SVN::Node::dir;
my $p = $g->{path}->full_path($de);
next if $exists->{$p};
next if (length $g->{path}->{right} &&