* ReusableGZIPStreams:

- Concurrent
      - Workaround for Apache Harmony 5.0M13 Deflater bug
This commit is contained in:
zzz
2010-04-21 17:04:53 +00:00
parent 7c3e4fd947
commit 43b4fe8300
2 changed files with 31 additions and 20 deletions

View File

@ -3,8 +3,8 @@ package net.i2p.util;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import java.util.concurrent.LinkedBlockingQueue;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
@ -14,16 +14,24 @@ import net.i2p.data.DataHelper;
* *
*/ */
public class ReusableGZIPInputStream extends ResettableGZIPInputStream { 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 * Pull a cached instance
*/ */
public static ReusableGZIPInputStream acquire() { public static ReusableGZIPInputStream acquire() {
ReusableGZIPInputStream rv = null; ReusableGZIPInputStream rv = null;
synchronized (_available) { // Apache Harmony 5.0M13 Deflater doesn't work after reset()
if (_available.size() > 0) if (ENABLE_CACHING)
rv = (ReusableGZIPInputStream)_available.remove(0); rv = _available.poll();
}
if (rv == null) { if (rv == null) {
rv = new ReusableGZIPInputStream(); rv = new ReusableGZIPInputStream();
} }
@ -34,10 +42,8 @@ public class ReusableGZIPInputStream extends ResettableGZIPInputStream {
* state) * state)
*/ */
public static void release(ReusableGZIPInputStream released) { public static void release(ReusableGZIPInputStream released) {
synchronized (_available) { if (ENABLE_CACHING)
if (_available.size() < 8) _available.offer(released);
_available.add(released);
}
} }
private ReusableGZIPInputStream() { super(); } private ReusableGZIPInputStream() { super(); }

View File

@ -2,9 +2,9 @@ package net.i2p.util;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.zip.Deflater; import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.concurrent.LinkedBlockingQueue;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
@ -14,16 +14,23 @@ import net.i2p.data.DataHelper;
* *
*/ */
public class ReusableGZIPOutputStream extends ResettableGZIPOutputStream { 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 * Pull a cached instance
*/ */
public static ReusableGZIPOutputStream acquire() { public static ReusableGZIPOutputStream acquire() {
ReusableGZIPOutputStream rv = null; ReusableGZIPOutputStream rv = null;
synchronized (_available) { if (ENABLE_CACHING)
if (_available.size() > 0) rv = _available.poll();
rv = (ReusableGZIPOutputStream)_available.remove(0);
}
if (rv == null) { if (rv == null) {
rv = new ReusableGZIPOutputStream(); rv = new ReusableGZIPOutputStream();
} }
@ -36,10 +43,8 @@ public class ReusableGZIPOutputStream extends ResettableGZIPOutputStream {
*/ */
public static void release(ReusableGZIPOutputStream out) { public static void release(ReusableGZIPOutputStream out) {
out.reset(); out.reset();
synchronized (_available) { if (ENABLE_CACHING)
if (_available.size() < 16) _available.offer(out);
_available.add(out);
}
} }
private ByteArrayOutputStream _buffer = null; private ByteArrayOutputStream _buffer = null;