Internal Buffer 코드 mergeOrAppend() 병목 해결
해당 방식 분석 및 현재 Celper의 InternalBuffer의 병목 System.arraycopy(..) 잦은 호출 문제점 개선 생각
// TODO fastCSV 코드 기반으로 새롭게 작성
@SuppressWarnings("checkstyle:visibilitymodifier")
private static class CsvBuffer implements Closeable {
private static final int READ_SIZE = 8192;
private static final int BUFFER_SIZE = READ_SIZE;
char[] buf;
int len;
int begin;
int pos;
private final Reader reader;
CsvBuffer(final Reader reader) {
this.reader = reader;
buf = new char[BUFFER_SIZE];
}
CsvBuffer(final String data) {
reader = null;
buf = data.toCharArray();
len = data.length();
}
/**
* Reads data from the underlying reader and manages the local buffer.
*
* @return {@code true}, if data was fetched, {@code false} if the end of the stream was reached
* @throws IOException if a read error occurs
*/
private boolean fetchData() throws IOException {
if (reader == null) {
return false;
}
if (begin < pos) {
// we have data that can be relocated
if (READ_SIZE > buf.length - pos) {
// need to relocate data in buffer -- not enough capacity left
final int lenToCopy = pos - begin;
if (READ_SIZE > buf.length - lenToCopy) {
// need to relocate data in new, larger buffer
buf = extendAndRelocate(buf, begin);
} else {
// relocate data in existing buffer
System.arraycopy(buf, begin, buf, 0, lenToCopy);
}
pos -= begin;
begin = 0;
}
} else {
// all data was consumed -- nothing to relocate
pos = begin = 0;
}
final int cnt = reader.read(buf, pos, READ_SIZE);
if (cnt == -1) {
return false;
}
len = pos + cnt;
return true;
}
private static char[] extendAndRelocate(final char[] buf, final int begin) {
final int newBufferSize = buf.length * 2;
if (newBufferSize > Limits.MAX_FIELD_SIZE) {
throw new CsvParseException(String.format("The maximum buffer size of %d is "
+ "insufficient to read the data of a single field. "
+ "This issue typically arises when a quotation begins but does not conclude within the "
+ "confines of this buffer's maximum limit.",
Limits.MAX_FIELD_SIZE));
}
final char[] newBuf = new char[newBufferSize];
System.arraycopy(buf, begin, newBuf, 0, buf.length - begin);
return newBuf;
}
private void reset() {
len = 0;
begin = 0;
pos = 0;
}
@Override
public void close() throws IOException {
if (reader != null) {
reader.close();
}
}
}
}
Java
복사