[svk-commit] r2241 - in branches/2.0-releng/lib/SVK: Mirror/Backend

nobody at bestpractical.com nobody at bestpractical.com
Wed Dec 20 06:42:24 EST 2006


Author: clkao
Date: Wed Dec 20 06:41:58 2006
New Revision: 2241

Modified:
   branches/2.0-releng/lib/SVK/Editor/Serialize.pm
   branches/2.0-releng/lib/SVK/Mirror/Backend/SVNRaPipe.pm

Log:
Fix memory usage for pipelined sync when there's a large textdelta.


Modified: branches/2.0-releng/lib/SVK/Editor/Serialize.pm
==============================================================================
--- branches/2.0-releng/lib/SVK/Editor/Serialize.pm	(original)
+++ branches/2.0-releng/lib/SVK/Editor/Serialize.pm	Wed Dec 20 06:41:58 2006
@@ -49,10 +49,13 @@
 # 
 # END BPS TAGGED BLOCK }}}
 package SVK::Editor::Serialize;
+use strict;
 use base 'SVK::Editor';
 
 __PACKAGE__->mk_accessors(qw(cb_serialize_entry));
 
+use SVK::Util qw(tmpfile slurp_fh);
+
 sub AUTOLOAD {
     my ($self, @arg) = @_;
     my $func = our $AUTOLOAD;
@@ -78,8 +81,23 @@
 
 sub close_file {
     my ($self, $baton, $checksum) = @_;
-    if ($apply_textdelta_entry) {
-	$self->cb_serialize_entry->($apply_textdelta_entry);
+    if (my $entry = $apply_textdelta_entry) {
+	my $fh = $entry->[-1];
+	close $fh;
+	if (-s $fh->filename < 1024 * 1024 * 2) {
+	    # it appears using $entry->[-1] = \$buf and open $entry->[-1]
+	    # breaks in 5.8.4
+	    my $buf = '';
+	    open my ($svndiff), '>', \$buf or die $!;
+	    open my $ifh, '<', $fh->filename or die $!;
+	    slurp_fh($ifh, $svndiff);
+	    unlink $fh->filename;
+	    $entry->[-1] = \$buf;
+	}
+	else {
+	    $entry->[-1] = $fh->filename;
+	}
+	$self->cb_serialize_entry->($entry);
 	$apply_textdelta_entry = undef;
     }
     $self->cb_serialize_entry->([undef, 'close_file', $baton, $checksum]);
@@ -88,9 +106,8 @@
 sub apply_textdelta {
     my ($self, $baton, @arg) = @_;
     pop @arg if ref ($arg[-1]) =~ m/^(?:SVN::Pool|_p_apr_pool_t)$/;
-    my $entry = [undef, 'apply_textdelta', $baton, @arg, ''];
-    open my ($svndiff), '>', \$entry->[-1];
-#    $self->cb_serialize_entry->($entry);
+    my $svndiff = tmpfile('serial-svndiff-', UNLINK => 0);
+    my $entry = [undef, 'apply_textdelta', $baton, @arg, $svndiff];
     $apply_textdelta_entry = $entry;
     return [SVN::TxDelta::to_svndiff($svndiff)];
 }

Modified: branches/2.0-releng/lib/SVK/Mirror/Backend/SVNRaPipe.pm
==============================================================================
--- branches/2.0-releng/lib/SVK/Mirror/Backend/SVNRaPipe.pm	(original)
+++ branches/2.0-releng/lib/SVK/Mirror/Backend/SVNRaPipe.pm	Wed Dec 20 06:41:58 2006
@@ -58,6 +58,7 @@
 use Socket;
 use Storable qw(nfreeze thaw);
 use SVK::Editor::Serialize;
+use SVK::Util qw(slurp_fh);
 
 =head1 NAME
 
@@ -258,14 +259,22 @@
 
 sub emit_editor_call {
     my ($self, $editor, $func, $pool, @arg) = @_;
-    my ($ret, $baton_at);
+    my $ret;
     if ($func eq 'apply_textdelta') {
 	my $svndiff = pop @arg;
 	$ret = $editor->apply_textdelta(@arg, $pool);
 
 	if ($ret && $#$ret > 0) {
 	    my $stream = SVN::TxDelta::parse_svndiff(@$ret, 1, $pool);
-	    print $stream $svndiff;
+	    if (ref $svndiff) { # inline
+		print $stream $$svndiff;
+	    }
+	    else { # filename
+		open my $fh, '<', $svndiff or die $!;
+		slurp_fh($fh, $stream);
+		close $fh;
+		unlink $fh;
+	    }
 	    close $stream;
 	}
     }


More information about the svk-commit mailing list