On Thu, May 15, 2008 at 3:56 AM, Matthew Toseland <toad at amphibian.dyndns.org> wrote: > On Friday 09 May 2008 15:28, j16sdiz at freenetproject.org wrote: >> Author: j16sdiz >> Date: 2008-05-09 14:28:23 +0000 (Fri, 09 May 2008) >> New Revision: 19875 >> >> Added: >> trunk/freenet/src/freenet/support/ByteBufferInputStream.java >> Modified: >> trunk/freenet/src/freenet/io/comm/FreenetInetAddress.java >> trunk/freenet/src/freenet/io/comm/Message.java >> trunk/freenet/src/freenet/io/comm/Peer.java >> trunk/freenet/src/freenet/support/BitArray.java >> trunk/freenet/src/freenet/support/Buffer.java >> trunk/freenet/src/freenet/support/Serializer.java >> trunk/freenet/src/freenet/support/ShortBuffer.java >> Log: >> Fix #2270: Performance, CPU usage on idle node >> - Use ByteBufferInputStream >> - Relax DataInputStream to DataInput in some classes >> >> >> Added: trunk/freenet/src/freenet/support/ByteBufferInputStream.java >> =================================================================== >> --- trunk/freenet/src/freenet/support/ByteBufferInputStream.java > (rev 0) >> +++ trunk/freenet/src/freenet/support/ByteBufferInputStream.java >> 2008-05-09 > 14:28:23 UTC (rev 19875) >> @@ -0,0 +1,202 @@ >> +/* This code is part of Freenet. It is distributed under the GNU General >> + * Public License, version 2 (or at your option any later version). See >> + * http://www.gnu.org/ for further details of the GPL. */ >> +package freenet.support; >> + >> +import java.io.DataInput; >> +import java.io.DataInputStream; >> +import java.io.EOFException; >> +import java.io.IOException; >> +import java.io.InputStream; >> +import java.nio.BufferUnderflowException; >> +import java.nio.ByteBuffer; >> + >> +/** >> + * @author sdiz >> + */ >> +public class ByteBufferInputStream extends InputStream implements DataInput > { >> + protected ByteBuffer buf; >> + >> + public ByteBufferInputStream(byte[] array) { >> + this(array, 0, array.length); >> + } >> + >> + public ByteBufferInputStream(byte[] array, int offset, int length) { >> + this(ByteBuffer.wrap(array, offset, length)); >> + } >> + public ByteBufferInputStream(ByteBuffer buf) { >> + this.buf = buf; >> + } >> + >> + public int read() throws IOException { >> + try { >> + return buf.get() & Integer.MAX_VALUE; >> + } catch (BufferUnderflowException e) { >> + return -1; >> + } >> + } >> + >> + >> + public int remaining() { >> + return buf.remaining(); >> + } >> + >> + public boolean readBoolean() throws IOException { >> + try { >> + return buf.get() != 0; >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public byte readByte() throws IOException { >> + try { >> + return buf.get(); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public char readChar() throws IOException { >> + try { >> + return buf.getChar(); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public double readDouble() throws IOException { >> + try { >> + return buf.getDouble(); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public float readFloat() throws IOException { >> + try { >> + return buf.getFloat(); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public void readFully(byte[] b) throws IOException { >> + try { >> + buf.get(b); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public void readFully(byte[] b, int off, int len) throws IOException { >> + try { >> + buf.get(b, off, len); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public int readInt() throws IOException { >> + try { >> + return buf.getInt(); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public long readLong() throws IOException { >> + try { >> + return buf.getLong(); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public short readShort() throws IOException { >> + try { >> + return buf.getShort(); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + >> + public int readUnsignedByte() throws IOException { >> + try { >> + return buf.get() & Integer.MAX_VALUE; >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public int readUnsignedShort() throws IOException { >> + try { >> + return buf.getShort() & Integer.MAX_VALUE; >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> + public int skipBytes(int n) throws IOException { >> + int skip = Math.min(n, buf.remaining()); >> + buf.position(buf.position() + skip); > > This should throw IOException, not IllegalArgumentException, if there isn't > enough space left.
It don't. It never skip more then buf.remaining() : (unless you use it in multithread, which have many more race conditions) int skip = Math.min(n, buf.remaining()); It may skip lessor bytes then n. ( javadoc for DataInputStream#skipBytes() didn't mention it, but DataInputStream#skip(int n) do. ) >> + return skip; >> + } >> + >> + public String readUTF() throws IOException { >> + return DataInputStream.readUTF(this); >> + } >> + /** >> + * @deprecated {@link DataInputStream#readLine()} is deprecated, so why > not? >> + */ >> + public String readLine() throws IOException { >> + // hmmmm bad >> + return new DataInputStream(this).readLine(); >> + } >> + >> + /** >> + * Slice a piece of ByteBuffer into a new ByteBufferInputStream >> + * >> + * @param size >> + */ >> + public ByteBufferInputStream slice(int size) throws IOException { >> + try { >> + ByteBuffer bf2 = buf.slice(); >> + bf2.limit(size); > > Likewise here. Fixed in r19936, thanks. >> + >> + skip(size); >> + >> + return new ByteBufferInputStream(bf2); >> + } catch (BufferUnderflowException e) { >> + EOFException ioe = new EOFException(); >> + ioe.initCause(e); >> + throw ioe; >> + } >> + } >> + >> +} >> >> Modified: trunk/freenet/src/freenet/support/Serializer.java >> =================================================================== >> --- trunk/freenet/src/freenet/support/Serializer.java 2008-05-09 13:15:41 > UTC (rev 19874) >> +++ trunk/freenet/src/freenet/support/Serializer.java 2008-05-09 14:28:23 > UTC (rev 19875) >> @@ -19,7 +19,7 @@ >> >> package freenet.support; >> >> -import java.io.DataInputStream; >> +import java.io.DataInput; >> import java.io.DataOutputStream; >> import java.io.IOException; >> import java.util.Iterator; >> @@ -44,7 +44,7 @@ >> public static final String VERSION = "$Id: Serializer.java,v 1.5 > 2005/09/15 18:16:04 amphibian Exp $"; >> public static final int MAX_BITARRAY_SIZE = 2048*8; >> >> - public static List readListFromDataInputStream(Class elementType, > DataInputStream dis) throws IOException { >> + public static List readListFromDataInputStream(Class elementType, > DataInput dis) throws IOException { >> LinkedList ret = new LinkedList(); >> int length = dis.readInt(); >> for (int x = 0; x < length; x++) { >> @@ -53,18 +53,16 @@ >> return ret; >> } >> >> - public static Object readFromDataInputStream(Class type, >> DataInputStream > dis) throws IOException { >> + public static Object readFromDataInputStream(Class type, DataInput dis) > throws IOException { >> if (type.equals(Boolean.class)) { >> - int bool=dis.read(); >> + int bool = dis.readByte(); >> if (bool==1) >> return Boolean.TRUE; >> if (bool==0) >> return Boolean.FALSE; >> throw new IOException("Boolean is non boolean value: >> "+bool); >> } else if (type.equals(Byte.class)) { >> - int b=dis.read(); >> - if (b<0) >> - throw new IOException(); >> + int b = dis.readByte(); >> return new Byte((byte)b); >> } else if (type.equals(Short.class)) { >> return new Short(dis.readShort()); >> >> Modified: trunk/freenet/src/freenet/support/ShortBuffer.java >> =================================================================== >> --- trunk/freenet/src/freenet/support/ShortBuffer.java 2008-05-09 >> 13:15:41 > UTC (rev 19874) >> +++ trunk/freenet/src/freenet/support/ShortBuffer.java 2008-05-09 >> 14:28:23 > UTC (rev 19875) >> @@ -41,7 +41,7 @@ >> * @param dis >> * @throws IOException >> */ >> - public ShortBuffer(DataInputStream dis) throws IOException { >> + public ShortBuffer(DataInput dis) throws IOException { >> _data = new byte[dis.readShort()]; >> _length = (short)_data.length; >> _start = 0; > > I wonder if we can get rid of or at least rename Buffer and/or ShortBuffer. > Why?