]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/GzipFilter.pm
www: switch to zadd for the majority of buffering
[public-inbox.git] / lib / PublicInbox / GzipFilter.pm
index bdd313f5a799c5f003adb61ea205219d85b60281..1f11acb8095bee0b09864370a0274fef9d1d1728 100644 (file)
@@ -100,19 +100,12 @@ sub translate ($$) {
        # allocate the zlib context lazily here, instead of in ->new.
        # Deflate contexts are memory-intensive and this object may
        # be sitting in the Qspawn limiter queue for a while.
-       my $gz = $self->{gz} //= gzip_or_die();
-       my $zbuf = delete($self->{zbuf});
+       $self->{gz} //= gzip_or_die();
        if (defined $_[1]) { # my $buf = $_[1];
-               my $err = $gz->deflate($_[1], $zbuf);
-               die "gzip->deflate: $err" if $err != Z_OK;
-               return $zbuf if length($zbuf) >= 8192;
-
-               $self->{zbuf} = $zbuf;
-               '';
+               zmore($self, $_[1]);
+               length($self->{zbuf}) >= 8192 ? delete($self->{zbuf}) : '';
        } else { # undef == EOF
-               my $err = $gz->flush($zbuf);
-               die "gzip->flush: $err" if $err != Z_OK;
-               $zbuf;
+               zflush($self);
        }
 }
 
@@ -134,29 +127,38 @@ sub write {
        http_out($_[0])->write(translate($_[0], $_[1]));
 }
 
+sub zadd {
+       my $self = shift;
+       $self->{pbuf} .= $_ for @_; # perl internal pad memory use here
+}
+
 # similar to ->translate; use this when we're sure we know we have
 # more data to buffer after this
 sub zmore {
-       my $self = $_[0]; # $_[1] => input
+       my $self = shift; # $_[1] => input
        http_out($self);
-       my $err = $self->{gz}->deflate($_[1], $self->{zbuf});
-       die "gzip->deflate: $err" if $err != Z_OK;
+       my $x;
+       defined($x = delete($self->{pbuf})) and unshift(@_, $x);
+       for (@_) {
+               ($x = $self->{gz}->deflate($_, $self->{zbuf})) == Z_OK or
+                       die "gzip->deflate: $x";
+       }
        undef;
 }
 
 # flushes and returns the final bit of gzipped data
-sub zflush ($;$) {
-       my $self = $_[0]; # $_[1] => final input (optional)
+sub zflush ($;@) {
+       my $self = shift; # $_[1..Inf] => final input (optional)
        my $zbuf = delete $self->{zbuf};
        my $gz = delete $self->{gz};
-       my $err;
-       if (defined $_[1]) { # it's a bug iff $gz is undef w/ $_[1]
-               $err = $gz->deflate($_[1], $zbuf);
-               die "gzip->deflate: $err" if $err != Z_OK;
+       my $x;
+       defined($x = delete($self->{pbuf})) and unshift(@_, $x);
+       for (@_) { # it's a bug iff $gz is undef if @_ isn't empty, here:
+               ($x = $gz->deflate($_, $zbuf)) == Z_OK or
+                       die "gzip->deflate: $x";
        }
        $gz // return ''; # not a bug, recursing on DS->write failure
-       $err = $gz->flush($zbuf);
-       die "gzip->flush: $err" if $err != Z_OK;
+       ($x = $gz->flush($zbuf)) == Z_OK or die "gzip->flush: $x";
        $zbuf;
 }