[armedbear-cvs] r11970 - trunk/abcl/src/org/armedbear/lisp/util
Erik Huelsmann
ehuelsmann at common-lisp.net
Sun May 31 17:01:11 UTC 2009
Author: ehuelsmann
Date: Sun May 31 13:01:08 2009
New Revision: 11970
Log:
Performance improvement by removing fcn.size() calls;
also lots of reindenting (for some reason I'm seeing lots
of bad indentation in NetBeans; my config?).
Modified:
trunk/abcl/src/org/armedbear/lisp/util/RandomAccessCharacterFile.java
Modified: trunk/abcl/src/org/armedbear/lisp/util/RandomAccessCharacterFile.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/util/RandomAccessCharacterFile.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/util/RandomAccessCharacterFile.java Sun May 31 13:01:08 2009
@@ -59,24 +59,24 @@
super(null);
}
- private byte[] read_buf = new byte[1];
+ private byte[] read_buf = new byte[1];
@Override
- public int read() throws IOException {
- int len = read(read_buf);
- if (len == 1) {
- // byte is signed, char is unsigned, int is signed.
- // buf can hold 0xff, we want it as 0xff in int, not -1.
- return 0xff & (int) read_buf[0];
- } else {
- return -1;
- }
- }
+ public int read() throws IOException {
+ int len = read(read_buf);
+ if (len == 1) {
+ // byte is signed, char is unsigned, int is signed.
+ // buf can hold 0xff, we want it as 0xff in int, not -1.
+ return 0xff & (int) read_buf[0];
+ } else {
+ return -1;
+ }
+ }
- @Override
+ @Override
public int read(byte[] b, int off, int len) throws IOException {
- return RandomAccessCharacterFile.this.read(b, off, len);
- }
+ return RandomAccessCharacterFile.this.read(b, off, len);
+ }
@Override
public void unread(int b) throws IOException {
@@ -125,37 +125,37 @@
return this.read(b, 0, b.length);
}
- @Override
- public void close() throws IOException {
- RandomAccessCharacterFile.this.close();
- }
+ @Override
+ public void close() throws IOException {
+ RandomAccessCharacterFile.this.close();
+ }
}
private class RandomAccessOutputStream extends OutputStream {
- private RandomAccessOutputStream() {
- }
+ private RandomAccessOutputStream() {
+ }
+
+ private byte[] buf = new byte[1];
+ public void write(int b) throws IOException {
+ buf[0] = (byte)b;
+ write(buf);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ RandomAccessCharacterFile.this.write(b, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ RandomAccessCharacterFile.this.flush();
+ }
- private byte[] buf = new byte[1];
- public void write(int b) throws IOException {
- buf[0] = (byte)b;
- write(buf);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- RandomAccessCharacterFile.this.write(b, off, len);
- }
-
- @Override
- public void flush() throws IOException {
- RandomAccessCharacterFile.this.flush();
- }
-
- @Override
- public void close() throws IOException {
- RandomAccessCharacterFile.this.close();
- }
+ @Override
+ public void close() throws IOException {
+ RandomAccessCharacterFile.this.close();
+ }
}
// dummy reader which we need to call the Pushback constructor
@@ -164,16 +164,16 @@
private class RandomAccessReader extends PushbackReader {
- private RandomAccessReader() {
- // because we override all methods of Pushbackreader,
- // staticReader will never be referenced
- super(staticReader);
- }
+ private RandomAccessReader() {
+ // because we override all methods of Pushbackreader,
+ // staticReader will never be referenced
+ super(staticReader);
+ }
- @Override
- public void close() throws IOException {
- RandomAccessCharacterFile.this.close();
- }
+ @Override
+ public void close() throws IOException {
+ RandomAccessCharacterFile.this.close();
+ }
private char[] read_buf = new char[1];
@@ -214,31 +214,29 @@
return RandomAccessCharacterFile.this.read(cbuf, 0, cbuf.length);
}
-
-
- @Override
- public int read(char[] cb, int off, int len) throws IOException {
- return RandomAccessCharacterFile.this.read(cb, off, len);
- }
+ @Override
+ public int read(char[] cb, int off, int len) throws IOException {
+ return RandomAccessCharacterFile.this.read(cb, off, len);
+ }
}
private class RandomAccessWriter extends Writer {
- private RandomAccessWriter() {
- }
+ private RandomAccessWriter() {
+ }
- public void close() throws IOException {
- RandomAccessCharacterFile.this.close();
- }
-
- public void flush() throws IOException {
- RandomAccessCharacterFile.this.flush();
- }
-
- @Override
- public void write(char[] cb, int off, int len) throws IOException {
- RandomAccessCharacterFile.this.write(cb, off, len);
- }
+ public void close() throws IOException {
+ RandomAccessCharacterFile.this.close();
+ }
+
+ public void flush() throws IOException {
+ RandomAccessCharacterFile.this.flush();
+ }
+
+ @Override
+ public void write(char[] cb, int off, int len) throws IOException {
+ RandomAccessCharacterFile.this.write(cb, off, len);
+ }
}
@@ -271,214 +269,215 @@
public RandomAccessCharacterFile(RandomAccessFile raf, String encoding) throws IOException {
- fcn = raf.getChannel();
- fcnpos = fcn.position();
- fcnsize = fcn.size();
-
- cset = (encoding == null) ? Charset.defaultCharset() : Charset.forName(encoding);
- cdec = cset.newDecoder();
- cdec.onMalformedInput(CodingErrorAction.REPLACE);
- cdec.onUnmappableCharacter(CodingErrorAction.REPLACE);
- cenc = cset.newEncoder();
-
- bbuf = ByteBuffer.allocate(BUFSIZ);
-
- // there is no readable data available in the buffers.
- bbuf.flip();
-
- // there is no write pending data in the buffers.
- bbufIsDirty = false;
-
- bbufpos = fcn.position();
-
- reader = new RandomAccessReader();
- writer = new RandomAccessWriter();
- inputStream = new RandomAccessInputStream();
- outputStream = new RandomAccessOutputStream();
+ fcn = raf.getChannel();
+ fcnpos = fcn.position();
+ fcnsize = fcn.size();
+
+ cset = (encoding == null) ? Charset.defaultCharset() : Charset.forName(encoding);
+ cdec = cset.newDecoder();
+ cdec.onMalformedInput(CodingErrorAction.REPLACE);
+ cdec.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ cenc = cset.newEncoder();
+
+ bbuf = ByteBuffer.allocate(BUFSIZ);
+
+ // there is no readable data available in the buffers.
+ bbuf.flip();
+
+ // there is no write pending data in the buffers.
+ bbufIsDirty = false;
+
+ bbufpos = fcn.position();
+
+ reader = new RandomAccessReader();
+ writer = new RandomAccessWriter();
+ inputStream = new RandomAccessInputStream();
+ outputStream = new RandomAccessOutputStream();
}
public Writer getWriter() {
- return writer;
+ return writer;
}
public PushbackReader getReader() {
- return reader;
+ return reader;
}
public PushbackInputStream getInputStream() {
- return inputStream;
+ return inputStream;
}
public OutputStream getOutputStream() {
- return outputStream;
+ return outputStream;
}
public void close() throws IOException {
- internalFlush(true);
- fcn.close();
+ internalFlush(true);
+ fcn.close();
}
public void flush() throws IOException {
- internalFlush(false);
+ internalFlush(false);
}
private int read(char[] cb, int off, int len) throws IOException {
- CharBuffer cbuf = CharBuffer.wrap(cb, off, len);
- boolean decodeWasUnderflow = false;
- boolean atEof = false;
- while ((cbuf.remaining() > 0) && dataIsAvailableForRead()
- && ! atEof) {
- if ((bbuf.remaining() == 0) || decodeWasUnderflow) {
- // need to read from the file.
- flushBbuf(); // in case bbuf is dirty.
- // update bbufpos.
- bbufpos += bbuf.position();
- int partialBytes = bbuf.remaining(); // partialBytes > 0 happens when decodeWasUnderflow
- // if reads and writes are mixed, we may need to seek first.
- if (bbufpos + partialBytes != fcnpos) {
- fcn.position(bbufpos + partialBytes);
- }
- // need to read data from file.
- bbuf.compact();
- //###FIXME: we're ignoring end-of-stream here!!!
- atEof = (fcn.read(bbuf) == -1);
- bbuf.flip();
- fcnpos = bbufpos + bbuf.remaining();
- }
- CoderResult r = cdec.decode(bbuf, cbuf, pointingAtEOF() );
- decodeWasUnderflow = (CoderResult.UNDERFLOW == r);
- }
- if (cbuf.remaining() == len) {
- return -1;
- } else {
- return len - cbuf.remaining();
- }
+ CharBuffer cbuf = CharBuffer.wrap(cb, off, len);
+ boolean decodeWasUnderflow = false;
+ boolean atEof = false;
+ while ((cbuf.remaining() > 0) && dataIsAvailableForRead()
+ && ! atEof) {
+ if ((bbuf.remaining() == 0) || decodeWasUnderflow) {
+ // need to read from the file.
+ flushBbuf(); // in case bbuf is dirty.
+ // update bbufpos.
+ bbufpos += bbuf.position();
+ int partialBytes = bbuf.remaining(); // partialBytes > 0 happens when decodeWasUnderflow
+ // if reads and writes are mixed, we may need to seek first.
+ if (bbufpos + partialBytes != fcnpos) {
+ fcn.position(bbufpos + partialBytes);
+ }
+ // need to read data from file.
+ bbuf.compact();
+ //###FIXME: we're ignoring end-of-stream here!!!
+ atEof = (fcn.read(bbuf) == -1);
+ bbuf.flip();
+ fcnpos = bbufpos + bbuf.remaining();
+ }
+ CoderResult r = cdec.decode(bbuf, cbuf, pointingAtEOF() );
+ decodeWasUnderflow = (CoderResult.UNDERFLOW == r);
+ }
+ if (cbuf.remaining() == len) {
+ return -1;
+ } else {
+ return len - cbuf.remaining();
+ }
}
private boolean dataIsAvailableForRead() throws IOException {
- return ((bbuf.remaining() > 0) || (fcn.position() < fcn.size()));
+ return ((bbuf.remaining() > 0) || (fcn.position() < fcn.size()));
}
private boolean pointingAtEOF() {
- return (bbuf.remaining() == 0) && (fcnpos == fcnsize);
+ return (bbuf.remaining() == 0) && (fcnpos == fcnsize);
}
private void write(char[] cb, int off, int len) throws IOException {
- CharBuffer cbuf = CharBuffer.wrap(cb, off, len);
- encodeAndWrite(cbuf, false, false);
+ CharBuffer cbuf = CharBuffer.wrap(cb, off, len);
+ encodeAndWrite(cbuf, false, false);
}
private void internalFlush(boolean endOfFile) throws IOException {
- if (endOfFile) {
- CharBuffer cbuf = CharBuffer.allocate(0);
- encodeAndWrite(cbuf, true, endOfFile);
- } else {
- flushBbuf();
- }
+ if (endOfFile) {
+ CharBuffer cbuf = CharBuffer.allocate(0);
+ encodeAndWrite(cbuf, true, endOfFile);
+ } else {
+ flushBbuf();
+ }
}
private void encodeAndWrite(CharBuffer cbuf, boolean flush, boolean endOfFile) throws IOException {
- if (bbufpos == fcnsize) {
- bbuf.clear();
- }
- while (cbuf.remaining() > 0) {
- CoderResult r = cenc.encode(cbuf, bbuf, endOfFile);
- bbufIsDirty = true;
- long curpos = bbufpos + bbuf.position();
- if (curpos > fcnsize) {
- // the file is extended.
- fcnsize = curpos;
- }
- if (CoderResult.OVERFLOW == r || bbuf.remaining() == 0) {
- flushBbuf();
- bbufpos += bbuf.limit();
- bbuf.clear();
- if (fcnpos < fcnsize) {
- fcn.read(bbuf);
- bbuf.flip();
- fcnpos += bbuf.remaining();
- }
- // if we are at the end of file, bbuf is simply cleared.
- // in that case, bbufpos + bbuf.position points to the EOF, not fcnpos.
- }
- }
- if (bbuf.position() > 0 && bbufIsDirty && flush) {
- flushBbuf();
- }
+ if (bbufpos == fcnsize) {
+ bbuf.clear();
+ }
+ while (cbuf.remaining() > 0) {
+ CoderResult r = cenc.encode(cbuf, bbuf, endOfFile);
+ bbufIsDirty = true;
+ long curpos = bbufpos + bbuf.position();
+ if (curpos > fcnsize) {
+ // the file is extended.
+ fcnsize = curpos;
+ }
+ if (CoderResult.OVERFLOW == r || bbuf.remaining() == 0) {
+ flushBbuf();
+ bbufpos += bbuf.limit();
+ bbuf.clear();
+ if (fcnpos < fcnsize) {
+ fcn.read(bbuf);
+ bbuf.flip();
+ fcnpos += bbuf.remaining();
+ }
+ // if we are at the end of file, bbuf is simply cleared.
+ // in that case, bbufpos + bbuf.position points to the EOF, not fcnpos.
+ }
+ }
+ if (bbuf.position() > 0 && bbufIsDirty && flush) {
+ flushBbuf();
+ }
}
public void position(long newPosition) throws IOException {
- flushBbuf();
- long bbufend = bbufpos + bbuf.limit();
- if (newPosition >= bbufpos && newPosition < bbufend) {
- // near seek. within existing data of bbuf.
- bbuf.position((int)(newPosition - bbufpos));
- } else {
- // far seek. discard the buffer.
- flushBbuf();
- fcn.position(newPosition);
- fcnpos = newPosition;
- bbuf.clear();
- bbuf.flip(); // "there is no useful data on this buffer yet."
- bbufpos = fcnpos;
- }
+ flushBbuf();
+ long bbufend = bbufpos + bbuf.limit();
+ if (newPosition >= bbufpos && newPosition < bbufend) {
+ // near seek. within existing data of bbuf.
+ bbuf.position((int)(newPosition - bbufpos));
+ } else {
+ // far seek. discard the buffer.
+ flushBbuf();
+ fcn.position(newPosition);
+ fcnpos = newPosition;
+ bbuf.clear();
+ bbuf.flip(); // "there is no useful data on this buffer yet."
+ bbufpos = fcnpos;
+ }
}
public long position() throws IOException {
- flushBbuf();
- return bbufpos + bbuf.position(); // the logical position within the file.
+ flushBbuf();
+ return bbufpos + bbuf.position(); // the logical position within the file.
}
public long length() throws IOException {
- flushBbuf();
- return fcn.size();
+ flushBbuf();
+ return fcn.size();
}
-
+
private void flushBbuf() throws IOException {
- if (bbufIsDirty) {
- if (fcnpos != bbufpos) {
- fcn.position(bbufpos);
- }
- bbuf.position(0);
- if (bbufpos + bbuf.limit() > fcnsize) {
- // the buffer is at the end of the file.
- // area beyond fcnsize does not have data.
- bbuf.limit((int)(fcnsize - bbufpos));
- }
- fcn.write(bbuf);
- fcnpos = bbufpos + bbuf.limit();
- bbufIsDirty = false;
- }
+ if (! bbufIsDirty)
+ return;
+
+ if (fcnpos != bbufpos)
+ fcn.position(bbufpos);
+
+ bbuf.position(0);
+ if (bbufpos + bbuf.limit() > fcnsize) {
+ // the buffer is at the end of the file.
+ // area beyond fcnsize does not have data.
+ bbuf.limit((int)(fcnsize - bbufpos));
+ }
+ fcn.write(bbuf);
+ fcnpos = bbufpos + bbuf.limit();
+ bbufIsDirty = false;
}
public int read(byte[] b, int off, int len) throws IOException {
- int pos = off;
- boolean atEof = false;
- while (pos - off < len && dataIsAvailableForRead()
- && ! atEof) {
- if (bbuf.remaining() == 0) {
- // need to read from the file.
- flushBbuf(); // in case bbuf is dirty.
- // update bbufpos.
- bbufpos += bbuf.limit();
- // if reads and writes are mixed, we may need to seek first.
- if (bbufpos != fcnpos) {
- fcn.position(bbufpos);
- }
- // need to read data from file.
- bbuf.clear();
- atEof = (fcn.read(bbuf) == -1);
- bbuf.flip();
- fcnpos = bbufpos + bbuf.remaining();
- }
- int want = len - pos;
- if (want > bbuf.remaining()) {
- want = bbuf.remaining();
- }
- bbuf.get(b, pos, want);
- pos += want;
- }
- return pos - off;
+ int pos = off;
+ boolean atEof = false;
+ while (pos - off < len && dataIsAvailableForRead()
+ && ! atEof) {
+ if (bbuf.remaining() == 0) {
+ // need to read from the file.
+ flushBbuf(); // in case bbuf is dirty.
+ // update bbufpos.
+ bbufpos += bbuf.limit();
+ // if reads and writes are mixed, we may need to seek first.
+ if (bbufpos != fcnpos) {
+ fcn.position(bbufpos);
+ }
+ // need to read data from file.
+ bbuf.clear();
+ atEof = (fcn.read(bbuf) == -1);
+ bbuf.flip();
+ fcnpos = bbufpos + bbuf.remaining();
+ }
+ int want = len - pos;
+ if (want > bbuf.remaining()) {
+ want = bbuf.remaining();
+ }
+ bbuf.get(b, pos, want);
+ pos += want;
+ }
+ return pos - off;
}
// a method corresponding to the good ol' ungetc in C.
@@ -490,65 +489,73 @@
private CharBuffer singleCharBuf;
private ByteBuffer shortByteBuf;
public void unreadChar(char c) throws IOException {
- // algorithm :
- // 1. encode c into bytes, to find out how many bytes it corresponds to
- // 2. move the position backwards that many bytes.
- // ** we stop here. Don't bother to write the bytes to the buffer,
- // assuming that it is the same as the original data.
- // If we allow to write back different characters, the buffer must get 'dirty'
- // but that would require read/write permissions on files you use unreadChar,
- // even if you are just reading for some tokenizer.
- //
- // So we don't do the following.
- // 3. write the bytes.
- // 4. move the position back again.
- if (singleCharBuf == null) {
- singleCharBuf = CharBuffer.allocate(1);
- shortByteBuf = ByteBuffer.allocate((int)cenc.maxBytesPerChar());
- }
- singleCharBuf.clear();
- singleCharBuf.append(c);
- singleCharBuf.flip();
- shortByteBuf.clear();
- cenc.encode(singleCharBuf, shortByteBuf, false);
- int n = shortByteBuf.position();
- long pos = position() - n;
- position(pos);
+ // algorithm :
+ // 1. encode c into bytes, to find out how many bytes it corresponds to
+ // 2. move the position backwards that many bytes.
+ // ** we stop here. Don't bother to write the bytes to the buffer,
+ // assuming that it is the same as the original data.
+ // If we allow to write back different characters, the buffer must get 'dirty'
+ // but that would require read/write permissions on files you use unreadChar,
+ // even if you are just reading for some tokenizer.
+ //
+ // So we don't do the following.
+ // 3. write the bytes.
+ // 4. move the position back again.
+ if (singleCharBuf == null) {
+ singleCharBuf = CharBuffer.allocate(1);
+ shortByteBuf = ByteBuffer.allocate((int)cenc.maxBytesPerChar());
+ }
+ singleCharBuf.clear();
+ singleCharBuf.append(c);
+ singleCharBuf.flip();
+ shortByteBuf.clear();
+ cenc.encode(singleCharBuf, shortByteBuf, false);
+ int n = shortByteBuf.position();
+ long pos = position() - n;
+ position(pos);
}
public void unreadByte(byte b) throws IOException {
- long pos = position() - 1;
- position(pos);
+ long pos = position() - 1;
+ position(pos);
}
private void write(byte[] b, int off, int len) throws IOException {
- int pos = off;
- while (pos < off + len) {
- int want = len;
- if (want > bbuf.remaining()) {
- want = bbuf.remaining();
- }
- bbuf.put(b, pos, want);
- pos += want;
- bbufIsDirty = true;
- long curpos = bbufpos + bbuf.position();
- if (curpos > fcn.size()) {
- // the file is extended.
- fcnsize = curpos;
- }
- if (bbuf.remaining() == 0) {
- flushBbuf();
- bbufpos += bbuf.limit();
- bbuf.clear();
- if (fcn.position() < fcn.size()) {
- bbufpos = fcn.position();
- fcn.read(bbuf);
- bbuf.flip();
- fcnpos += bbuf.remaining();
- }
- // if we are at the end of file, bbuf is simply cleared.
- // in that case, bbufpos + bbuf.position points to the EOF, not fcnpos.
- }
- }
+ int pos = off;
+ if (len > bbuf.limit()) {
+ if (bbufIsDirty)
+ flushBbuf();
+ fcn.write(ByteBuffer.wrap(b, off, len));
+ fcnpos = fcn.position();
+ if (fcnpos > fcnsize)
+ fcnsize = fcnpos;
+ }
+ while (pos < off + len) {
+ int want = len;
+ if (want > bbuf.remaining()) {
+ want = bbuf.remaining();
+ }
+ bbuf.put(b, pos, want);
+ pos += want;
+ bbufIsDirty = true;
+ long curpos = bbufpos + bbuf.position();
+ if (curpos > fcnsize) {
+ // the file is extended.
+ fcnsize = curpos;
+ }
+ if (bbuf.remaining() == 0) {
+ flushBbuf();
+ bbufpos += bbuf.limit();
+ bbuf.clear();
+ if (fcn.position() < fcnsize) {
+ bbufpos = fcn.position();
+ fcn.read(bbuf);
+ bbuf.flip();
+ fcnpos += bbuf.remaining();
+ }
+ // if we are at the end of file, bbuf is simply cleared.
+ // in that case, bbufpos + bbuf.position points to the EOF, not fcnpos.
+ }
+ }
}
}
More information about the armedbear-cvs
mailing list