Skip to content

Commit a87dc29

Browse files
authored
Merge pull request #3186 from dizzzz/feature/faststrngbuffer_update
FastStringBuffer improvement
2 parents ad564d7 + 00ab734 commit a87dc29

File tree

5 files changed

+185
-60
lines changed

5 files changed

+185
-60
lines changed

exist-core/src/main/java/org/exist/util/FastStringBuffer.java

Lines changed: 63 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,25 @@
77
* modify it under the terms of the GNU Lesser General Public License
88
* as published by the Free Software Foundation; either version 2
99
* of the License, or (at your option) any later version.
10-
*
10+
*
1111
* This program is distributed in the hope that it will be useful,
1212
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1313
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414
* GNU Lesser General Public License for more details.
15-
*
15+
*
1616
* You should have received a copy of the GNU Lesser General Public License
1717
* along with this program; if not, write to the Free Software Foundation
1818
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919
*
2020
* This class is to large extents copied from Saxon 2003-01-21 (version ?).
2121
* See comment at the back about licensing for those parts.
22-
*
22+
*
2323
* $Id$
2424
*/
2525
package org.exist.util;
2626

27+
import org.apache.commons.lang3.StringUtils;
28+
2729
import java.io.Serializable;
2830
import java.io.Writer;
2931

@@ -36,12 +38,17 @@
3638

3739
public final class FastStringBuffer implements CharSequence, Serializable {
3840

39-
private static final long serialVersionUID = -504264698052799896L;
41+
private static final long serialVersionUID = -504264698052799896L;
4042

41-
private char[] array;
43+
private char[] array;
4244
private int used = 0;
4345

44-
public FastStringBuffer(int initialSize) {
46+
/**
47+
* Create a FastStringBuffer with a given initial capacity
48+
* @param initialSize the initial capacity
49+
*/
50+
51+
public FastStringBuffer(final int initialSize) {
4552
array = new char[initialSize];
4653
}
4754

@@ -50,8 +57,8 @@ public FastStringBuffer(int initialSize) {
5057
* @param s the String to be appended
5158
*/
5259

53-
public void append(String s) {
54-
int len = s.length();
60+
public void append(final String s) {
61+
final int len = s.length();
5562
ensureCapacity(len);
5663
s.getChars(0, len, array, used);
5764
used += len;
@@ -62,8 +69,8 @@ public void append(String s) {
6269
* @param s the String to be appended
6370
*/
6471

65-
public void append(CharSlice s) {
66-
int len = s.length();
72+
public void append(final CharSlice s) {
73+
final int len = s.length();
6774
ensureCapacity(len);
6875
s.copyTo(array, used);
6976
used += len;
@@ -74,8 +81,8 @@ public void append(CharSlice s) {
7481
* @param s the FastStringBuffer to be appended
7582
*/
7683

77-
public void append(FastStringBuffer s) {
78-
int len = s.length();
84+
public void append(final FastStringBuffer s) {
85+
final int len = s.length();
7986
ensureCapacity(len);
8087
s.getChars(0, len, array, used);
8188
used += len;
@@ -86,8 +93,8 @@ public void append(FastStringBuffer s) {
8693
* @param s the StringBuffer to be appended
8794
*/
8895

89-
public void append(StringBuffer s) {
90-
int len = s.length();
96+
public void append(final StringBuilder s) {
97+
final int len = s.length();
9198
ensureCapacity(len);
9299
s.getChars(0, len, array, used);
93100
used += len;
@@ -98,7 +105,7 @@ public void append(StringBuffer s) {
98105
* @param s the CharSequence to be appended
99106
*/
100107

101-
public void append(CharSequence s) {
108+
public void append(final CharSequence s) {
102109
// Although we provide variants of this method for different subtypes, Java decides which to use based
103110
// on the static type of the operand. We want to use the right method based on the dynamic type, to avoid
104111
// creating objects and copying strings unnecessarily. So we do a dynamic dispatch.
@@ -126,7 +133,7 @@ public void append(CharSequence s) {
126133
* @param length the number of characters to be copied
127134
*/
128135

129-
public void append(char[] srcArray, int start, int length) {
136+
public void append(final char[] srcArray, final int start, final int length) {
130137
ensureCapacity(length);
131138
System.arraycopy(srcArray, start, array, used, length);
132139
used += length;
@@ -137,7 +144,7 @@ public void append(char[] srcArray, int start, int length) {
137144
* @param srcArray the array whose contents are to be added
138145
*/
139146

140-
public void append(char[] srcArray) {
147+
public void append(final char[] srcArray) {
141148
final int length = srcArray.length;
142149
ensureCapacity(length);
143150
System.arraycopy(srcArray, 0, array, used, length);
@@ -149,7 +156,7 @@ public void append(char[] srcArray) {
149156
* @param ch the character to be added
150157
*/
151158

152-
public void append(char ch) {
159+
public void append(final char ch) {
153160
ensureCapacity(1);
154161
array[used++] = ch;
155162
}
@@ -173,7 +180,7 @@ public void appendWideChar(final int ch) {
173180
*
174181
* @param ch the character
175182
*/
176-
public void prependWideChar(int ch) {
183+
public void prependWideChar(final int ch) {
177184
if (ch > 0xffff) {
178185
insertCharAt(0, XMLChar.lowSurrogate(ch));
179186
insertCharAt(0, XMLChar.highSurrogate(ch));
@@ -207,7 +214,7 @@ public int length() {
207214
* @throws IndexOutOfBoundsException if the <code>index</code> argument is negative or not less than
208215
* <code>length()</code>
209216
*/
210-
public char charAt(int index) {
217+
public char charAt(final int index) {
211218
if (index >= used) {
212219
throw new IndexOutOfBoundsException("" + index);
213220
}
@@ -229,7 +236,7 @@ public char charAt(int index) {
229236
* if <code>end</code> is greater than <code>length()</code>,
230237
* or if <code>start</code> is greater than <code>end</code>
231238
*/
232-
public CharSequence subSequence(int start, int end) {
239+
public CharSequence subSequence(final int start, final int end) {
233240
return new CharSlice(array, start, end - start);
234241
}
235242

@@ -263,7 +270,7 @@ public CharSequence subSequence(int start, int end) {
263270
* <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
264271
* <code>dst.length</code></ul>
265272
*/
266-
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
273+
public void getChars(final int srcBegin, final int srcEnd, final char[] dst, final int dstBegin) {
267274
if (srcBegin < 0) {
268275
throw new StringIndexOutOfBoundsException(srcBegin);
269276
}
@@ -281,7 +288,7 @@ public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
281288
* @param ch the character to search for
282289
* @return the position of the first occurrence, or -1 if not found
283290
*/
284-
public int indexOf(char ch) {
291+
public int indexOf(final char ch) {
285292
for (int i=0; i<used; i++) {
286293
if (array[i] == ch) {
287294
return i;
@@ -304,7 +311,7 @@ public String toString() {
304311
* @param ch the new character to overwrite the existing character at that location
305312
* @throws IndexOutOfBoundsException if {@code int < 0 || int >= length()}
306313
*/
307-
public void setCharAt(int index, char ch) {
314+
public void setCharAt(final int index, final char ch) {
308315
if (index<0 || index>used) {
309316
throw new IndexOutOfBoundsException(""+index);
310317
}
@@ -317,14 +324,12 @@ public void setCharAt(int index, char ch) {
317324
* @param ch the new character to insert at that location
318325
* @throws IndexOutOfBoundsException if {@code int < 0 || int >= length()}
319326
*/
320-
public void insertCharAt(int index, char ch) {
327+
public void insertCharAt(final int index, final char ch) {
321328
if (index<0 || index>used) {
322329
throw new IndexOutOfBoundsException(""+index);
323330
}
324331
ensureCapacity(1);
325-
for (int i=used; i>index; i--) {
326-
array[i] = array[i-1];
327-
}
332+
System.arraycopy(array, index, array, index + 1, used - index);
328333
used++;
329334
array[index] = ch;
330335
}
@@ -334,14 +339,12 @@ public void insertCharAt(int index, char ch) {
334339
* @param index the index of the character to be set
335340
* @throws IndexOutOfBoundsException if {@code int < 0 || int >= length()}
336341
*/
337-
public void removeCharAt(int index) {
342+
public void removeCharAt(final int index) {
338343
if (index<0 || index>used) {
339344
throw new IndexOutOfBoundsException(""+index);
340345
}
341346
used--;
342-
for (int i=index; i<used; i++) {
343-
array[i] = array[i+1];
344-
}
347+
System.arraycopy(array, index + 1, array, index, used - index);
345348
}
346349

347350
/**
@@ -351,7 +354,7 @@ public void removeCharAt(int index) {
351354
*
352355
* @param length the new length
353356
*/
354-
public void setLength(int length) {
357+
public void setLength(final int length) {
355358
if (length < 0 || length > used) {
356359
return;
357360
}
@@ -363,13 +366,13 @@ public void setLength(int length) {
363366
*
364367
* @param extra the extra capacity needed.
365368
*/
366-
public void ensureCapacity(int extra) {
369+
public void ensureCapacity(final int extra) {
367370
if (used + extra > array.length) {
368371
int newlen = array.length * 2;
369372
if (newlen < used + extra) {
370373
newlen = used + extra*2;
371374
}
372-
char[] array2 = new char[newlen];
375+
final char[] array2 = new char[newlen];
373376
System.arraycopy(array, 0, array2, 0, used);
374377
array = array2;
375378
}
@@ -385,7 +388,7 @@ public void ensureCapacity(int extra) {
385388
*/
386389
public CharSequence condense() {
387390
if (array.length - used > 256 || array.length > used * 2) {
388-
char[] array2 = new char[used];
391+
final char[] array2 = new char[used];
389392
System.arraycopy(array, 0, array2, 0, used);
390393
array = array2;
391394
}
@@ -410,7 +413,7 @@ public void write(final Writer writer) throws java.io.IOException {
410413
*
411414
* @return the diagnostic print
412415
*/
413-
public static String diagnosticPrint(CharSequence in) {
416+
public static String diagnosticPrint(final CharSequence in) {
414417
final FastStringBuffer buff = new FastStringBuffer(in.length()*2);
415418
for (int i=0; i<in.length(); i++) {
416419
final char c = in.charAt(i);
@@ -425,9 +428,9 @@ public static String diagnosticPrint(CharSequence in) {
425428
}
426429
return buff.toString();
427430
}
428-
431+
429432
//Quick copies from old eXist's FastStringBuffer
430-
433+
431434
/**
432435
* Manefest constant: Suppress leading whitespace. This should be used when
433436
* normalize-to-SAX is called for the first chunk of a multi-chunk output,
@@ -451,32 +454,35 @@ public static String diagnosticPrint(CharSequence in) {
451454
*
452455
* see sendNormalizedSAXcharacters(char[],int,int,org.xml.sax.ContentHandler,int)
453456
*/
454-
public final static int SUPPRESS_BOTH
455-
= SUPPRESS_LEADING_WS | SUPPRESS_TRAILING_WS;
456-
457+
public final static int SUPPRESS_BOTH = SUPPRESS_LEADING_WS | SUPPRESS_TRAILING_WS;
458+
457459
/**
458460
* Gets the normalizedString attribute of the FastStringBuffer object
459461
*
460-
*@param mode Description of the Parameter
462+
*@param mode Trim mode
461463
*@return The normalizedString value
462464
*/
463-
public String getNormalizedString( int mode ) {
464-
return getNormalizedString( new StringBuffer(toString()), mode ).toString();
465+
public String getNormalizedString(final int mode ) {
466+
467+
switch(mode){
468+
case SUPPRESS_BOTH:
469+
return toString().trim();
470+
471+
case SUPPRESS_LEADING_WS:
472+
return StringUtils.stripStart(toString(),null);
473+
474+
case SUPPRESS_TRAILING_WS:
475+
return StringUtils.stripEnd(toString(),null);
476+
477+
default:
478+
return toString().trim();
479+
}
480+
465481
}
466482

467483

468-
/**
469-
* Gets the normalizedString attribute of the FastStringBuffer object
470-
*
471-
*@param sb Description of the Parameter
472-
*@param mode Description of the Parameter
473-
*@return The normalizedString value
474-
*/
475-
public StringBuffer getNormalizedString(StringBuffer sb, int mode ) {
476-
//TODO : switch (mode)
477-
return new StringBuffer(toString().trim());
478-
}
479-
484+
485+
480486
}
481487

482488
//

exist-core/src/main/java/org/exist/xquery/value/DayTimeDurationValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public String getStringValue() {
128128
// sb.append(Double.toString(ms).substring(2));
129129
//}
130130
//0 is a dummy parameter
131-
FloatingPointConverter.appendFloat(sb, s.floatValue()).getNormalizedString(0);
131+
FloatingPointConverter.appendFloat(sb, s.floatValue()).getNormalizedString(FastStringBuffer.SUPPRESS_BOTH);
132132
sb.append("S");
133133
/*
134134
if (micros == 0) {

exist-core/src/main/java/org/exist/xquery/value/DoubleValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public int getType() {
7575
public String getStringValue() {
7676
final FastStringBuffer sb = new FastStringBuffer(20);
7777
//0 is a dummy parameter
78-
FloatingPointConverter.appendDouble(sb, value).getNormalizedString(0);
78+
FloatingPointConverter.appendDouble(sb, value).getNormalizedString(FastStringBuffer.SUPPRESS_BOTH);
7979
return sb.toString();
8080
}
8181

exist-core/src/main/java/org/exist/xquery/value/FloatValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public String getStringValue() throws XPathException {
101101

102102
final FastStringBuffer sb = new FastStringBuffer(20);
103103
//0 is a dummy parameter
104-
FloatingPointConverter.appendFloat(sb, value).getNormalizedString(0);
104+
FloatingPointConverter.appendFloat(sb, value).getNormalizedString(FastStringBuffer.SUPPRESS_BOTH);
105105
return sb.toString();
106106
}
107107

0 commit comments

Comments
 (0)