Skip to content

Commit

Permalink
Add buffer relocation in reader
Browse files Browse the repository at this point in the history
  • Loading branch information
charphi committed Oct 28, 2024
1 parent 45c73d6 commit 4c77c85
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add buffer relocation in reader

## [2.4.0] - 2024-03-27

This is a feature release of **picocsv**.
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/nbbrd/picocsv/Csv.java
Original file line number Diff line number Diff line change
Expand Up @@ -677,23 +677,29 @@ public boolean readLine() throws IOException {
// WARNING: default value in JDK21 -XX:MinJumpTableSize=10
switch (state) {
case STATE_0_READY:
relocateBuffer();
parseNextField(true);
return state != STATE_6_DONE;
case STATE_1_FIRST:
skipRemainingFields();
relocateBuffer();
parseNextField(true);
return state != STATE_6_DONE;
case STATE_2_NOT_LAST:
skipRemainingFields();
relocateBuffer();
parseNextField(true);
return state != STATE_6_DONE;
case STATE_3_LAST:
relocateBuffer();
parseNextField(true);
return state != STATE_6_DONE;
case STATE_4_SINGLE:
relocateBuffer();
parseNextField(true);
return state != STATE_6_DONE;
case STATE_5_MISSING:
relocateBuffer();
parseNextField(true);
return state != STATE_6_DONE;
case STATE_6_DONE:
Expand Down Expand Up @@ -779,9 +785,21 @@ private void skipRemainingFields() throws IOException {
} while (state == STATE_2_NOT_LAST);
}

private void relocateBuffer() throws IOException {
if (bufferIndex > buffer.length / 2) {
int remainingChars = buffer.length - bufferIndex;
System.arraycopy(buffer, bufferIndex, buffer, 0, remainingChars);
int newChars = charReader.read(buffer, remainingChars, bufferIndex);
bufferIndex = 0;
bufferLength = remainingChars + newChars;
}
}

// WARNING: main loop; lots of duplication to maximize performances
// WARNING: comparing ints more performant than comparing chars
// WARNING: local var access slightly quicker that field access
// WARNING: the main trick is to never get out of this method when reading a field
// WARNING: and therefore never have to fill the buffer
private void parseNextField(final boolean firstField) throws IOException {
int fieldLength = this.fieldLength;
int i = this.bufferIndex;
Expand Down

0 comments on commit 4c77c85

Please sign in to comment.