[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