InternalBuffer의 fill() 최적화
1.
상태 머신 적용
2.
fill() 메서드 내에 extend, relocate 메서드 분리
boolean fill(){
while (true){
switch (state){
case INITIAL:
int cnt = read(buf, pos);
state = BufferState.PROGRESSING;
return cnt != -1;
case PROGRESSING:
/**
* if -> begin >= limit 일 경우 즉, 커서가 끝까지 갔는데 아무 변화 없을때
* state = (pos == 0) ? EXTEND : RELOCATE;
* continue;
* retrun true;
*/
if (begin >= limit){
state = pos == 0 ? BufferState.EXTEND : BufferState.RELOCATE;
continue;
}
return true;
case EXTEND:
/**
* 확장 및 read
* extend() 확장
* cnt = read(begin) -> READ_SIZE 만큼 읽기
* if -> cnt == -1 LAST_LINE
* else -> PROGRESSING and limit += cnt
* continue;
*/
extendAndLoad();
return true;
case RELOCATE:
/**
* 재배치 및 read
* relocate()
* begin = limit - pos;
* pos = 0;
* cnt = read(begin) // READ_SIZE 만큼 데이터 로드
* if -> cnt == -1 LAST_LINE
* else -> PROGRESSING
*/
relocateAndLoad();
return true;
}
}
}
boolean isLastLine(){
return state == BufferState.LAST_LINE;
}
private int read(char[] buf, int off) {
try {
return reader.read(buf, off, READ_SIZE);
} catch (IOException e){
throw new UncheckedIOException(e);
}
}
private void extendAndLoad() {
// TODO max size 예외처리
char[] newBuf = new char[buf.length * 2];
System.arraycopy(buf, 0, newBuf, 0, buf.length);
buf = newBuf;
int cnt = read(buf, begin);
state = cnt == -1 ? BufferState.LAST_LINE : BufferState.PROGRESSING;
limit = state == BufferState.LAST_LINE ? limit : limit + cnt;
}
private void relocateAndLoad(){
final int copyLength = limit - pos;
System.arraycopy(buf, pos, buf, 0, copyLength);
int cnt = read(buf, copyLength);
state = cnt == -1 ? BufferState.LAST_LINE : BufferState.PROGRESSING;
pos = 0;
begin = limit;
limit = state == BufferState.LAST_LINE ? limit : copyLength + cnt;
}
Java
복사