From 43b4fe830074d998a74fa21fe324b853283770d9 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Wed, 21 Apr 2010 17:04:53 +0000
Subject: [PATCH]     * ReusableGZIPStreams:       - Concurrent       -
 Workaround for Apache Harmony 5.0M13 Deflater bug

---
 .../net/i2p/util/ReusableGZIPInputStream.java | 26 ++++++++++++-------
 .../i2p/util/ReusableGZIPOutputStream.java    | 25 +++++++++++-------
 2 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/core/java/src/net/i2p/util/ReusableGZIPInputStream.java b/core/java/src/net/i2p/util/ReusableGZIPInputStream.java
index a24ad12829..229814de9e 100644
--- a/core/java/src/net/i2p/util/ReusableGZIPInputStream.java
+++ b/core/java/src/net/i2p/util/ReusableGZIPInputStream.java
@@ -3,8 +3,8 @@ package net.i2p.util;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.zip.GZIPOutputStream;
+import java.util.concurrent.LinkedBlockingQueue;
 
 import net.i2p.data.DataHelper;
 
@@ -14,16 +14,24 @@ import net.i2p.data.DataHelper;
  *
  */
 public class ReusableGZIPInputStream extends ResettableGZIPInputStream {
-    private final static ArrayList _available = new ArrayList(8);
+    // Apache Harmony 5.0M13 Deflater doesn't work after reset()
+    private static final boolean ENABLE_CACHING = !System.getProperty("java.vendor").startsWith("Apache");
+    private static final LinkedBlockingQueue<ReusableGZIPInputStream> _available;
+    static {
+        if (ENABLE_CACHING)
+            _available = new LinkedBlockingQueue(8);
+        else
+            _available = null;
+    }
+
     /**
      * Pull a cached instance
      */
     public static ReusableGZIPInputStream acquire() {
         ReusableGZIPInputStream rv = null;
-        synchronized (_available) {
-            if (_available.size() > 0)
-                rv = (ReusableGZIPInputStream)_available.remove(0);
-        }
+        // Apache Harmony 5.0M13 Deflater doesn't work after reset()
+        if (ENABLE_CACHING)
+            rv = _available.poll();
         if (rv == null) {
             rv = new ReusableGZIPInputStream();
         } 
@@ -34,10 +42,8 @@ public class ReusableGZIPInputStream extends ResettableGZIPInputStream {
      * state)
      */
     public static void release(ReusableGZIPInputStream released) {
-        synchronized (_available) {
-            if (_available.size() < 8)
-                _available.add(released);
-        }
+        if (ENABLE_CACHING)
+            _available.offer(released);
     }
     
     private ReusableGZIPInputStream() { super(); }
diff --git a/core/java/src/net/i2p/util/ReusableGZIPOutputStream.java b/core/java/src/net/i2p/util/ReusableGZIPOutputStream.java
index 4229796482..97680ecafb 100644
--- a/core/java/src/net/i2p/util/ReusableGZIPOutputStream.java
+++ b/core/java/src/net/i2p/util/ReusableGZIPOutputStream.java
@@ -2,9 +2,9 @@ package net.i2p.util;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
 import java.util.zip.Deflater;
 import java.util.zip.GZIPInputStream;
+import java.util.concurrent.LinkedBlockingQueue;
 
 import net.i2p.data.DataHelper;
 
@@ -14,16 +14,23 @@ import net.i2p.data.DataHelper;
  *
  */
 public class ReusableGZIPOutputStream extends ResettableGZIPOutputStream {
-    private static final ArrayList _available = new ArrayList(16);
+    // Apache Harmony 5.0M13 Deflater doesn't work after reset()
+    private static final boolean ENABLE_CACHING = !System.getProperty("java.vendor").startsWith("Apache");
+    private static final LinkedBlockingQueue<ReusableGZIPOutputStream> _available;
+    static {
+        if (ENABLE_CACHING)
+            _available = new LinkedBlockingQueue(16);
+        else
+            _available = null;
+    }
+
     /**
      * Pull a cached instance
      */
     public static ReusableGZIPOutputStream acquire() {
         ReusableGZIPOutputStream rv = null;
-        synchronized (_available) {
-            if (_available.size() > 0)
-                rv = (ReusableGZIPOutputStream)_available.remove(0);
-        }
+        if (ENABLE_CACHING)
+            rv = _available.poll();
         if (rv == null) {
             rv = new ReusableGZIPOutputStream();
         } 
@@ -36,10 +43,8 @@ public class ReusableGZIPOutputStream extends ResettableGZIPOutputStream {
      */
     public static void release(ReusableGZIPOutputStream out) {
         out.reset();
-        synchronized (_available) {
-            if (_available.size() < 16)
-                _available.add(out);
-        }
+        if (ENABLE_CACHING)
+            _available.offer(out);
     }
     
     private ByteArrayOutputStream _buffer = null;
-- 
GitLab