Skip to content

Commit 4785ab5

Browse files
committed
Performance improvements.
1 parent 81dbc29 commit 4785ab5

File tree

1 file changed

+61
-64
lines changed

1 file changed

+61
-64
lines changed

httprpc/src/main/java/org/httprpc/io/CSVDecoder.java

Lines changed: 61 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.ArrayList;
2323
import java.util.Iterator;
2424
import java.util.LinkedHashMap;
25-
import java.util.List;
2625
import java.util.Map;
2726
import java.util.NoSuchElementException;
2827

@@ -32,10 +31,13 @@
3231
public class CSVDecoder {
3332
// Cursor
3433
private static class Cursor implements Iterable<Map<String, String>> {
35-
private List<String> keys;
3634
private Reader reader;
3735
private char delimiter;
3836

37+
private StringBuilder valueBuilder = new StringBuilder();
38+
39+
private ArrayList<String> keys = new ArrayList<>();
40+
3941
private ArrayList<String> values = new ArrayList<>();
4042
private LinkedHashMap<String, String> row = new LinkedHashMap<>();
4143

@@ -46,6 +48,8 @@ private static class Cursor implements Iterable<Map<String, String>> {
4648
public boolean hasNext() {
4749
if (hasNext == null) {
4850
try {
51+
values.clear();
52+
4953
decodeValues(reader, values, delimiter);
5054
} catch (IOException exception) {
5155
throw new RuntimeException(exception);
@@ -75,10 +79,61 @@ public Map<String, String> next() {
7579
}
7680
};
7781

78-
private Cursor(List<String> keys, Reader reader, char delimiter) {
79-
this.keys = keys;
82+
private static final int EOF = -1;
83+
84+
public Cursor(Reader reader, char delimiter) throws IOException {
8085
this.reader = reader;
8186
this.delimiter = delimiter;
87+
88+
decodeValues(reader, keys, delimiter);
89+
}
90+
91+
public void decodeValues(Reader reader, ArrayList<String> values, char delimiter) throws IOException {
92+
int c = reader.read();
93+
94+
while (c != '\r' && c != '\n' && c != EOF) {
95+
valueBuilder.setLength(0);
96+
97+
boolean quoted = false;
98+
99+
if (c == '"') {
100+
quoted = true;
101+
102+
c = reader.read();
103+
}
104+
105+
while ((quoted || (c != delimiter && c != '\r' && c != '\n')) && c != EOF) {
106+
valueBuilder.append((char)c);
107+
108+
c = reader.read();
109+
110+
if (c == '"') {
111+
c = reader.read();
112+
113+
if (c != '"') {
114+
quoted = false;
115+
}
116+
}
117+
}
118+
119+
if (quoted) {
120+
throw new IOException("Unterminated quoted value.");
121+
}
122+
123+
values.add(valueBuilder.toString());
124+
125+
if (c == delimiter) {
126+
c = reader.read();
127+
}
128+
}
129+
130+
if (c == '\r') {
131+
c = reader.read();
132+
133+
if (c != '\n') {
134+
throw new IOException("Improperly terminated record.");
135+
}
136+
}
82137
}
83138

84139
@Override
@@ -89,8 +144,6 @@ public Iterator<Map<String, String>> iterator() {
89144

90145
private char delimiter;
91146

92-
private static final int EOF = -1;
93-
94147
/**
95148
* Constructs a new CSV decoder.
96149
*/
@@ -131,68 +184,12 @@ public Iterable<Map<String, String>> readValues(InputStream inputStream) throws
131184
* The character stream to read from.
132185
*
133186
* @return
134-
* A cursor over the values in the input stream.
187+
* A cursor over the values in the character stream.
135188
*
136189
* @throws IOException
137190
* If an exception occurs.
138191
*/
139192
public Iterable<Map<String, String>> readValues(Reader reader) throws IOException {
140-
reader = new BufferedReader(reader);
141-
142-
ArrayList<String> keys = new ArrayList<>();
143-
144-
decodeValues(reader, keys, delimiter);
145-
146-
return new Cursor(keys, reader, delimiter);
147-
}
148-
149-
private static void decodeValues(Reader reader, ArrayList<String> fields, char delimiter) throws IOException {
150-
fields.clear();
151-
152-
int c = reader.read();
153-
154-
while (c != '\r' && c != '\n' && c != EOF) {
155-
StringBuilder fieldBuilder = new StringBuilder();
156-
157-
boolean quoted = false;
158-
159-
if (c == '"') {
160-
quoted = true;
161-
162-
c = reader.read();
163-
}
164-
165-
while ((quoted || (c != delimiter && c != '\r' && c != '\n')) && c != EOF) {
166-
fieldBuilder.append((char)c);
167-
168-
c = reader.read();
169-
170-
if (c == '"') {
171-
c = reader.read();
172-
173-
if (c != '"') {
174-
quoted = false;
175-
}
176-
}
177-
}
178-
179-
if (quoted) {
180-
throw new IOException("Unterminated quoted value.");
181-
}
182-
183-
fields.add(fieldBuilder.toString());
184-
185-
if (c == delimiter) {
186-
c = reader.read();
187-
}
188-
}
189-
190-
if (c == '\r') {
191-
c = reader.read();
192-
193-
if (c != '\n') {
194-
throw new IOException("Improperly terminated record.");
195-
}
196-
}
193+
return new Cursor(new BufferedReader(reader), delimiter);
197194
}
198195
}

0 commit comments

Comments
 (0)