[kaffe] CVS kaffe (doogie): The java spec allows for buffering when doing encoding conversions. This
Kaffe CVS
cvs-commits at kaffe.org
Tue Dec 7 16:49:53 PST 2004
PatchSet 5562
Date: 2004/12/08 00:45:12
Author: doogie
Branch: HEAD
Tag: (none)
Log:
The java spec allows for buffering when doing encoding conversions. This
change does internal buffering in these classes, for a huge speedup.
Members:
ChangeLog:1.3108->1.3109
libraries/javalib/gnu/java/io/decode/KaffeDecoder.java:1.4->1.5
libraries/javalib/gnu/java/io/encode/KaffeEncoder.java:1.4->1.5
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3108 kaffe/ChangeLog:1.3109
--- kaffe/ChangeLog:1.3108 Tue Dec 7 22:06:12 2004
+++ kaffe/ChangeLog Wed Dec 8 00:45:12 2004
@@ -1,3 +1,11 @@
+2004-12-07 Adam Heath <doogie at brainfood.com>
+
+ * libraries/javalib/gnu/java/io/decoder/KaffeDecoder.java,
+ libraries/javalib/gnu/java/io/encoder/KaffeEncoder.java:
+ The java spec allows for buffering when doing encoding
+ conversions. This change does internal buffering in these
+ classes, for a huge speedup.
+
2004-12-07 Ito Kazumitsu <kaz at maczuka.gcd.org>
* libltdl/install-sh:
Index: kaffe/libraries/javalib/gnu/java/io/decode/KaffeDecoder.java
diff -u kaffe/libraries/javalib/gnu/java/io/decode/KaffeDecoder.java:1.4 kaffe/libraries/javalib/gnu/java/io/decode/KaffeDecoder.java:1.5
--- kaffe/libraries/javalib/gnu/java/io/decode/KaffeDecoder.java:1.4 Tue May 18 16:13:28 2004
+++ kaffe/libraries/javalib/gnu/java/io/decode/KaffeDecoder.java Wed Dec 8 00:45:15 2004
@@ -56,6 +56,14 @@
ByteToCharConverter converter;
+/* These three vars are used for the general buffer management */
+private int ptr = 0;
+private int end = 0;
+private char[] buffer = new char[4096];
+
+/* This array is a temporary used during the conversion process. */
+private byte[] inbuf = new byte[4096];
+
/*************************************************************************/
/*
@@ -103,15 +111,83 @@
return(cbuf);
}
-/**
- * Read the requested number of chars from the underlying stream.
- * Some byte fragments may remain in the converter and they are
- * used by the following read. So read and convertToChars must
- * not be used for the same converter instance.
- */
-// copied from kaffe's java/io/InputStreamReader.java
+
+public int
+read() throws IOException
+{
+ synchronized (lock) {
+ if (ptr < end) return buffer[ptr++];
+ int r = _read(buffer, 0, buffer.length);
+ if (r == -1) return -1;
+ ptr = 1;
+ end = r;
+ return buffer[0];
+ }
+}
+
public int
-read ( char cbuf[], int off, int len ) throws IOException
+read(char cbuf[], int off, int len) throws IOException
+{
+ synchronized (lock) {
+ int bytesRead = 0;
+ if (len < end - ptr) {
+ System.arraycopy(buffer, ptr, cbuf, off, len);
+ ptr += len;
+ return len;
+ }
+
+ int preCopy = end - ptr;
+ if (preCopy > 0) {
+ System.arraycopy(buffer, ptr, cbuf, off, preCopy);
+ off += preCopy;
+ len -= preCopy;
+ bytesRead += preCopy;
+ }
+ ptr = 0;
+ end = 0;
+
+ int remainder = len % buffer.length;
+ int bulkCopy = len - remainder;
+ if (bulkCopy > 0) {
+ int r = _read(cbuf, off, bulkCopy);
+ if (r == -1) {
+ return bytesRead == 0 ? -1 : bytesRead;
+ }
+ off += r;
+ len -= r;
+ bytesRead += r;
+ }
+
+ if (remainder > 0) {
+ int r = _read(buffer, 0, buffer.length);
+ if (r == -1) {
+ return bytesRead == 0 ? -1 : bytesRead;
+ }
+ end = r;
+ int remainderCopy = r < remainder ? r : remainder;
+ System.arraycopy(buffer, 0, cbuf, off, remainderCopy);
+ off += remainderCopy;
+ len -= remainderCopy;
+ ptr = remainderCopy;
+ bytesRead += remainderCopy;
+ }
+
+ return bytesRead;
+ }
+}
+
+/*
+ * Read the requested number of chars from the underlying stream.
+ * Some byte fragments may remain in the converter and they are
+ * used by the following read. So read and convertToChars must
+ * not be used for the same converter instance.
+ *
+ * This method *must* be called with lock held, as it uses the
+ * instance variable inbuf.
+ */
+// copied from kaffe's java/io/InputStreamReader.java
+private int
+_read ( char cbuf[], int off, int len ) throws IOException
{
if (len < 0 || off < 0 || off + len > cbuf.length) {
throw new IndexOutOfBoundsException();
@@ -119,8 +195,6 @@
int outlen = 0;
boolean seenEOF = false;
-
- byte[] inbuf = new byte[2048];
while (len > outlen) {
// First we retreive anything left in the converter
Index: kaffe/libraries/javalib/gnu/java/io/encode/KaffeEncoder.java
diff -u kaffe/libraries/javalib/gnu/java/io/encode/KaffeEncoder.java:1.4 kaffe/libraries/javalib/gnu/java/io/encode/KaffeEncoder.java:1.5
--- kaffe/libraries/javalib/gnu/java/io/encode/KaffeEncoder.java:1.4 Mon Dec 6 21:20:40 2004
+++ kaffe/libraries/javalib/gnu/java/io/encode/KaffeEncoder.java Wed Dec 8 00:45:15 2004
@@ -65,6 +65,15 @@
CharToByteConverter converter;
+/* These 2 variables are used in the general buffer management */
+private int ptr = 0;
+private char[] buffer = new char[4096];
+
+/* This buffer is used during the conversion process. It gets expanded
+ * automatically when it overflows.
+ */
+private byte[] bbuf = new byte[buffer.length * 3];
+
/*************************************************************************/
/*
@@ -127,9 +136,74 @@
* Write the requested number of chars to the underlying stream
*/
public void
+write(int c) throws IOException
+{
+ synchronized (lock) {
+ buffer[ptr++] = (char) c;
+ if (ptr == buffer.length) localFlush();
+ }
+}
+
+/**
+ * Write the requested number of chars to the underlying stream
+ */
+public void
write(char[] buf, int offset, int len) throws IOException
{
- out.write(convertToBytes(buf, offset, len));
+ synchronized (lock) {
+ if (len > buffer.length - ptr) {
+ localFlush();
+ _write(buf, offset, len);
+ } else if (len == 1) {
+ buffer[ptr++] = buf[offset];
+ } else {
+ System.arraycopy(buf, offset, buffer, ptr, len);
+ ptr += len;
+ }
+ }
+}
+
+/* This *must* be called with the lock held. */
+private void
+localFlush() throws IOException
+{
+ if (ptr > 0) {
+ // Reset ptr to 0 before the _write call. Otherwise, a
+ // very nasty loop could occur. Please don't ask.
+ int length = ptr;
+ ptr = 0;
+ _write(buffer, 0, length);
+ }
+}
+
+public void
+flush() throws IOException
+{
+ synchronized (lock) {
+ localFlush();
+ out.flush();
+ }
+}
+/*
+ * Write the requested number of chars to the underlying stream
+ *
+ * This method *must* be called with the lock held, as it accesses
+ * the variable bbuf.
+ */
+private void
+_write(char[] buf, int offset, int len) throws IOException
+{
+ int bbuflen = converter.convert(buf, offset, len, bbuf, 0, bbuf.length);
+ int bufferNeeded = 0;
+ while (bbuflen > 0) {
+ out.write(bbuf, 0, bbuflen);
+ bbuflen = converter.flush(bbuf, 0, bbuf.length);
+ bufferNeeded += bbuflen;
+ }
+ if (bufferNeeded > bbuf.length) {
+ // increase size of array
+ bbuf = new byte[bufferNeeded];
+ }
}
} // class KaffEncoder
More information about the kaffe
mailing list