Hi.

Here comes a patch and two new Java-classes which speeds up Zlib deflate and inflate to more or less C-Ruby-standards. Very nice.

Status for RubyGems right now is that YAML.load(spec) seems to have problems with loading a spec in the size of 3megs. It fizzles for a few hours and then goes OutOfMemoryError.
This is probably the next place for me to start hacking.

The speedups in Zlib could probably be done in the GzipReader/GzipWriters too, it's just a matter of time.

Regards
 Ola Bini
Index: src/lib/ruby/1.8/zlib.rb
===================================================================
RCS file: /cvsroot/jruby/jruby/src/lib/ruby/1.8/zlib.rb,v
retrieving revision 1.8
diff -u -r1.8 zlib.rb
--- src/lib/ruby/1.8/zlib.rb    26 Mar 2006 21:21:40 -0000      1.8
+++ src/lib/ruby/1.8/zlib.rb    6 Apr 2006 16:49:15 -0000
@@ -33,6 +33,8 @@
 include_class "java.io.InputStreamReader"
 include_class "java.io.PipedInputStream"
 include_class "java.io.PipedOutputStream"
+include_class "java.io.StringBufferInputStream"
+include_class "java.lang.StringBuffer"
 
 include_class "java.util.zip.Deflater"
 include_class "java.util.zip.DeflaterOutputStream"
@@ -45,6 +47,8 @@
 include_class "org.jruby.util.CRC32Ext"
 include_class "org.jruby.util.IOInputStream"
 include_class "org.jruby.util.IOOutputStream"
+include_class "org.jruby.util.ZlibInflate"
+include_class "org.jruby.util.ZlibDeflate"
 
 #
 # Implementation of the Zlib library with the help of Java classes
@@ -301,32 +305,21 @@
     # Decompresses string. Raises a Zlib::NeedDict exception if a preset 
dictionary is needed for decompression.
     #
     def self.inflate(string)
-      zstream = Zlib::Inflate.new
-      buf = zstream.inflate(string)
-      zstream.finish
-      zstream.close
-      buf
+      ZlibInflate.s_inflate(self,string)
     end
 
     #
     # Creates a new inflate stream for decompression. See zlib.h for details 
of the argument. If window_bits is nil, the default value is used.
     #
     def initialize(window_bits=nil)
-      if window_bits.nil?
-        window_bits = Zlib::MAX_WBITS
-      end
-      @flater = Inflater.new
-      @write_stream = PipedOutputStream.new
-      @intern_stream = PipedInputStream.new(@write_stream)
-      @stream = InflaterInputStream.new(@intern_stream,@flater)
-      @val = ""
+      @infl = ZlibInflate.new(self)
     end
 
     #
     # Adds p1 to stream and returns self
     #
     def <<(p1)
-      @write_stream.write JString.new(p1.to_s).getBytes("ISO-8859-1")
+      @infl._append(p1)
       self
     end
 
@@ -334,15 +327,14 @@
     # No idea, no implementation
     #
     def sync_point?
-      false
+      @infl.sync_point
     end
 
     #
     # Sets the preset dictionary and returns string. This method is available 
just only after a Zlib::NeedDict exception was raised. See zlib.h for details.
     #
     def set_dictionary(p1)
-      @flater.setDictionary(JString.new(p1).getBytes("ISO-8859-1")) 
-      p1
+      @infl.set_dictionary(p1)
     end
 
     #
@@ -354,23 +346,14 @@
     # Set the dictionary by Zlib::Inflate#set_dictionary and then call this 
method again with an empty string.
     #
     def inflate(string)
-      if string
-        @write_stream.write JString.new(string).getBytes("ISO-8859-1")
-      end
-      while (n = @stream.read) != -1
-        @val << n
-      end
-      raise Zlib::NeedDict.new if @flater.needsDictionary
-      val
+      @infl.inflate(string)
     end
 
     #
     # This implementation is not correct
     #
     def sync(string)
-      @write_stream.write JString.new(p1).getBytes("ISO-8859-1")
-      @write_stream.flush
-      false
+      @infl.sync(string)
     end
 end
 
@@ -686,10 +669,7 @@
     # Zlib::BEST_COMPRESSION, Zlib::DEFAULT_COMPRESSION, and an integer from 0 
to 9.
     #
     def self.deflate(string, level=Zlib::DEFAULT_COMPRESSION)
-      z = Zlib::Deflate.new(level)
-      dst = z.deflate(string,Zlib::FINISH)
-      z.close
-      dst
+      ZlibDeflate.s_deflate(self,string,level)
     end
 
     # 
@@ -709,10 +689,7 @@
       if memlevel.nil?
         memlevel = Zlib::DEF_MEM_LEVEL
       end
-      @flater = Deflater.new(level)
-      @flater.setStrategy(strategy)
-      @intern_stream = ByteArrayOutputStream.new
-      @stream = DeflaterOutputStream.new(@intern_stream,@flater)
+      @defl = ZlibDeflate.new(self,level,window_bits,memlevel,strategy)
     end
 
     #
@@ -720,7 +697,7 @@
     # Returns self
     #
     def <<(p1)
-      deflate(p1.to_s,Zlib::NO_FLUSH)
+      @defl._append(p1)
       self
     end
 
@@ -728,8 +705,7 @@
     # Changes the parameters of the deflate stream. See zlib.h for details. 
The output from the stream by changing the params is preserved in output buffer.
     #
     def params(level,strategy)
-      @flater.setLevel(level)
-      @flater.setStrategy(strategy)
+      @defl.params(level,strategy)
     end
 
     #
@@ -737,7 +713,7 @@
     # Zlib::ZStream#reset method was called. See zlib.h for details.
     # 
     def set_dictionary(string)
-      @flater.setDictionary(JString.new(string).getBytes("ISO-8859-1")) 
+      @defl.set_dictionary(string)
     end
 
     #
@@ -745,7 +721,7 @@
     # method is just provided to improve the readability of your Ruby program.
     #
     def flush(flush=Zlib::SYNC_FLUSH)
-      deflate('',flush)
+      @defl.flush(flush)
     end
 
     # 
@@ -756,21 +732,7 @@
     # The value of flush should be either Zlib::NO_FLUSH, Zlib::SYNC_FLUSH, 
Zlib::FULL_FLUSH, or Zlib::FINISH. See zlib.h for details. 
     #
     def deflate(string,flush=nil)
-      if string.nil?
-        finish
-        @intern_stream.toByteArray.to_a.pack("C*")
-      else
-        @stream.write(JString.new(string).getBytes("ISO-8859-1"))
-        case flush
-        when Zlib::FINISH
-          finish
-          @intern_stream.toByteArray.to_a.pack("C*")
-        when Zlib::SYNC_FLUSH
-          @stream.flush
-        when Zlib::FULL_FLUSH
-          @stream.flush
-        end
-      end
+      @defl.deflate(string,flush)
     end
 end
 

Attachment: ZlibInflate.java
Description: Binary data

Attachment: ZlibDeflate.java
Description: Binary data

Reply via email to