Skip to content

Commit 740a1b6

Browse files
committed
Removed the volatile modifier on the fields in CSVFormat to improve the performances
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/csv/trunk@1299479 13f79535-47bb-0310-9956-ffa450edef68
1 parent 107c90d commit 740a1b6

4 files changed

Lines changed: 37 additions & 82 deletions

File tree

src/main/java/org/apache/commons/csv/CSVFormat.java

Lines changed: 30 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@
2525
/**
2626
* The format specification of a CSV file.
2727
*
28-
* This class is thread-safe.
28+
* This class is immutable.
2929
*/
30-
public class CSVFormat implements Cloneable, Serializable {
30+
public class CSVFormat implements Serializable {
3131

32-
private volatile char delimiter = ',';
33-
private volatile char encapsulator = '"';
34-
private volatile char commentStart = DISABLED;
35-
private volatile char escape = DISABLED;
36-
private volatile boolean leadingSpacesIgnored = true;
37-
private volatile boolean trailingSpacesIgnored = true;
38-
private volatile boolean unicodeEscapesInterpreted = false;
39-
private volatile boolean emptyLinesIgnored = true;
40-
private volatile String lineSeparator = "\r\n";
32+
private final char delimiter;
33+
private final char encapsulator;
34+
private final char commentStart;
35+
private final char escape;
36+
private final boolean leadingSpacesIgnored;
37+
private final boolean trailingSpacesIgnored;
38+
private final boolean unicodeEscapesInterpreted;
39+
private final boolean emptyLinesIgnored;
40+
private final String lineSeparator;
4141

4242

4343
/**
@@ -49,7 +49,7 @@ public class CSVFormat implements Cloneable, Serializable {
4949
static final char DISABLED = '\ufffe';
5050

5151
/** Standard comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. */
52-
public static final CSVFormat DEFAULT = new CSVFormat(',', '"', DISABLED, DISABLED, true, true, false, true);
52+
public static final CSVFormat DEFAULT = new CSVFormat(',', '"', DISABLED, DISABLED, true, true, false, true, "\r\n");
5353

5454
/**
5555
* Excel file format (using a comma as the value delimiter).
@@ -62,11 +62,11 @@ public class CSVFormat implements Cloneable, Serializable {
6262
*
6363
* <pre>CSVFormat fmt = CSVFormat.EXCEL.withDelimiter(';');</pre>
6464
*/
65-
public static final CSVFormat EXCEL = new CSVFormat(',', '"', DISABLED, DISABLED, false, false, false, false);
65+
public static final CSVFormat EXCEL = new CSVFormat(',', '"', DISABLED, DISABLED, false, false, false, false, "\r\n");
6666

6767
/** Tabulation delimited format. */
68-
public static final CSVFormat TDF = new CSVFormat('\t', '"', DISABLED, DISABLED, true, true, false, true);
69-
68+
public static final CSVFormat TDF = new CSVFormat('\t', '"', DISABLED, DISABLED, true, true, false, true, "\r\n");
69+
7070
/**
7171
* Default MySQL format used by the <tt>SELECT INTO OUTFILE</tt> and
7272
* <tt>LOAD DATA INFILE</tt> operations. This is a tabulation delimited
@@ -75,25 +75,8 @@ public class CSVFormat implements Cloneable, Serializable {
7575
*
7676
* @see <a href="http://dev.mysql.com/doc/refman/5.1/en/load-data.html">http://dev.mysql.com/doc/refman/5.1/en/load-data.html</a>
7777
*/
78-
public static final CSVFormat MYSQL = new CSVFormat('\t', DISABLED, DISABLED, '\\', false, false, false, false).withLineSeparator("\n");
79-
80-
81-
/**
82-
* Creates a CSV format with the default parameters.
83-
*/
84-
CSVFormat() {
85-
}
78+
public static final CSVFormat MYSQL = new CSVFormat('\t', DISABLED, DISABLED, '\\', false, false, false, false, "\n");
8679

87-
/**
88-
* Creates a customized CSV format.
89-
*
90-
* @param delimiter the char used for value separation
91-
* @param encapsulator the char used as value encapsulation marker
92-
* @param commentStart the char used for comment identification
93-
*/
94-
CSVFormat(char delimiter, char encapsulator, char commentStart) {
95-
this(delimiter, encapsulator, commentStart, DISABLED, true, true, false, true);
96-
}
9780

9881
/**
9982
* Creates a customized CSV format.
@@ -115,7 +98,8 @@ public class CSVFormat implements Cloneable, Serializable {
11598
boolean leadingSpacesIgnored,
11699
boolean trailingSpacesIgnored,
117100
boolean unicodeEscapesInterpreted,
118-
boolean emptyLinesIgnored) {
101+
boolean emptyLinesIgnored,
102+
String lineSeparator) {
119103
this.delimiter = delimiter;
120104
this.encapsulator = encapsulator;
121105
this.commentStart = commentStart;
@@ -124,6 +108,7 @@ public class CSVFormat implements Cloneable, Serializable {
124108
this.trailingSpacesIgnored = trailingSpacesIgnored;
125109
this.unicodeEscapesInterpreted = unicodeEscapesInterpreted;
126110
this.emptyLinesIgnored = emptyLinesIgnored;
111+
this.lineSeparator = lineSeparator;
127112
}
128113

129114
/**
@@ -182,10 +167,8 @@ public CSVFormat withDelimiter(char delimiter) {
182167
if (isLineBreak(delimiter)) {
183168
throw new IllegalArgumentException("The delimiter cannot be a line break");
184169
}
185-
186-
CSVFormat format = clone();
187-
format.delimiter = delimiter;
188-
return format;
170+
171+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
189172
}
190173

191174
/**
@@ -209,9 +192,7 @@ public CSVFormat withEncapsulator(char encapsulator) {
209192
throw new IllegalArgumentException("The encapsulator cannot be a line break");
210193
}
211194

212-
CSVFormat format = clone();
213-
format.encapsulator = encapsulator;
214-
return format;
195+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
215196
}
216197

217198
boolean isEncapsulating() {
@@ -239,9 +220,7 @@ public CSVFormat withCommentStart(char commentStart) {
239220
throw new IllegalArgumentException("The comment start character cannot be a line break");
240221
}
241222

242-
CSVFormat format = clone();
243-
format.commentStart = commentStart;
244-
return format;
223+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
245224
}
246225

247226
/**
@@ -274,9 +253,7 @@ public CSVFormat withEscape(char escape) {
274253
throw new IllegalArgumentException("The escape character cannot be a line break");
275254
}
276255

277-
CSVFormat format = clone();
278-
format.escape = escape;
279-
return format;
256+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
280257
}
281258

282259
boolean isEscaping() {
@@ -300,9 +277,7 @@ public boolean isLeadingSpacesIgnored() {
300277
* @return A copy of this format with the specified left trimming behavior.
301278
*/
302279
public CSVFormat withLeadingSpacesIgnored(boolean leadingSpacesIgnored) {
303-
CSVFormat format = clone();
304-
format.leadingSpacesIgnored = leadingSpacesIgnored;
305-
return format;
280+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
306281
}
307282

308283
/**
@@ -322,9 +297,7 @@ public boolean isTrailingSpacesIgnored() {
322297
* @return A copy of this format with the specified right trimming behavior.
323298
*/
324299
public CSVFormat withTrailingSpacesIgnored(boolean trailingSpacesIgnored) {
325-
CSVFormat format = clone();
326-
format.trailingSpacesIgnored = trailingSpacesIgnored;
327-
return format;
300+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
328301
}
329302

330303
/**
@@ -335,10 +308,7 @@ public CSVFormat withTrailingSpacesIgnored(boolean trailingSpacesIgnored) {
335308
* @return A copy of this format with the specified trimming behavior.
336309
*/
337310
public CSVFormat withSurroundingSpacesIgnored(boolean surroundingSpacesIgnored) {
338-
CSVFormat format = clone();
339-
format.leadingSpacesIgnored = surroundingSpacesIgnored;
340-
format.trailingSpacesIgnored = surroundingSpacesIgnored;
341-
return format;
311+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, surroundingSpacesIgnored, surroundingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
342312
}
343313

344314
/**
@@ -358,9 +328,7 @@ public boolean isUnicodeEscapesInterpreted() {
358328
* @return A copy of this format with the specified unicode escaping behavior.
359329
*/
360330
public CSVFormat withUnicodeEscapesInterpreted(boolean unicodeEscapesInterpreted) {
361-
CSVFormat format = clone();
362-
format.unicodeEscapesInterpreted = unicodeEscapesInterpreted;
363-
return format;
331+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
364332
}
365333

366334
/**
@@ -380,9 +348,7 @@ public boolean isEmptyLinesIgnored() {
380348
* @return A copy of this format with the specified empty line skipping behavior.
381349
*/
382350
public CSVFormat withEmptyLinesIgnored(boolean emptyLinesIgnored) {
383-
CSVFormat format = clone();
384-
format.emptyLinesIgnored = emptyLinesIgnored;
385-
return format;
351+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
386352
}
387353

388354
/**
@@ -401,9 +367,7 @@ public String getLineSeparator() {
401367
* @return A copy of this format using the specified line separator
402368
*/
403369
public CSVFormat withLineSeparator(String lineSeparator) {
404-
CSVFormat format = clone();
405-
format.lineSeparator = lineSeparator;
406-
return format;
370+
return new CSVFormat(delimiter, encapsulator, commentStart, escape, leadingSpacesIgnored, trailingSpacesIgnored, unicodeEscapesInterpreted, emptyLinesIgnored, lineSeparator);
407371
}
408372

409373
/**
@@ -430,13 +394,4 @@ public String format(String... values) {
430394

431395
return out.toString().trim();
432396
}
433-
434-
@Override
435-
protected CSVFormat clone() {
436-
try {
437-
return (CSVFormat) super.clone();
438-
} catch (CloneNotSupportedException e) {
439-
throw (Error) new InternalError().initCause(e);
440-
}
441-
}
442397
}

src/test/java/org/apache/commons/csv/CSVFormatTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
public class CSVFormatTest extends TestCase {
2323

2424
public void testImmutalibity() {
25-
CSVFormat format = new CSVFormat('!', '!', '!', '!', true, true, true, true);
25+
CSVFormat format = new CSVFormat('!', '!', '!', '!', true, true, true, true, "\r\n");
2626

2727
format.withDelimiter('?');
2828
format.withEncapsulator('?');
@@ -47,7 +47,7 @@ public void testImmutalibity() {
4747
}
4848

4949
public void testMutators() {
50-
CSVFormat format = new CSVFormat('!', '!', '!', '!', true, true, true, true);
50+
CSVFormat format = new CSVFormat('!', '!', '!', '!', true, true, true, true, "\r\n");
5151

5252
assertEquals('?', format.withDelimiter('?').getDelimiter());
5353
assertEquals('?', format.withEncapsulator('?').getEncapsulator());

src/test/java/org/apache/commons/csv/CSVLexerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,13 @@ public void testNextToken6() throws IOException {
147147
* ;;
148148
*/
149149
String code = "a;'b and '' more\n'\n!comment;;;;\n;;";
150-
CSVFormat format = new CSVFormat(';', '\'', '!');
150+
CSVFormat format = CSVFormat.DEFAULT.withDelimiter(';').withEncapsulator('\'').withCommentStart('!');
151151
CSVLexer parser = getLexer(code, format);
152152
assertTokenEquals(TOKEN, "a", parser.nextToken(new Token()));
153153
assertTokenEquals(EORECORD, "b and ' more\n", parser.nextToken(new Token()));
154154
}
155155

156-
// From SANDBOX-153
156+
// From CSV-1
157157
public void testDelimiterIsWhitespace() throws IOException {
158158
String code = "one\ttwo\t\tfour \t five\t six";
159159
CSVLexer parser = getLexer(code, CSVFormat.TDF);

src/test/java/org/apache/commons/csv/CSVParserTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ public void testBackslashEscaping() throws IOException {
269269
};
270270

271271

272-
CSVFormat format = new CSVFormat(',', '\'', CSVFormat.DISABLED, '/', false, false, true, true);
272+
CSVFormat format = new CSVFormat(',', '\'', CSVFormat.DISABLED, '/', false, false, true, true, "\r\n");
273273

274274
CSVParser parser = new CSVParser(code, format);
275275
String[][] tmp = parser.getRecords();
@@ -297,7 +297,7 @@ public void testBackslashEscaping2() throws IOException {
297297
};
298298

299299

300-
CSVFormat format = new CSVFormat(',', CSVFormat.DISABLED, CSVFormat.DISABLED, '/', false, false, true, true);
300+
CSVFormat format = new CSVFormat(',', CSVFormat.DISABLED, CSVFormat.DISABLED, '/', false, false, true, true, "\r\n");
301301

302302
CSVParser parser = new CSVParser(code, format);
303303
String[][] tmp = parser.getRecords();
@@ -340,7 +340,7 @@ public void testDefaultFormat() throws IOException {
340340
{""},
341341
};
342342

343-
format = new CSVFormat(',', '"', '#');
343+
format = CSVFormat.DEFAULT.withCommentStart('#');
344344
parser = new CSVParser(code, format);
345345
tmp = parser.getRecords();
346346

0 commit comments

Comments
 (0)