From 005e3fbbae6a34eb685274244e10b7e1d3719831 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 7 Jul 2015 13:53:44 +0300 Subject: [PATCH] optimisation: avoid recalculating hashcode if possible --- .../openapi/diff/impl/string/DiffString.java | 131 +++++--------- .../util/text/CharSequenceWithStringHash.java | 4 +- .../openapi/util/text/StringUtil.java | 17 +- .../util/text/ByteArrayCharSequence.java | 8 +- .../util/text/CharArrayCharSequence.java | 27 +-- .../util/text/CharSequenceSubSequence.java | 18 +- .../com/intellij/util/text/ImmutableText.java | 12 +- .../convertToJava/MyStringBuilder.java | 164 ------------------ 8 files changed, 105 insertions(+), 276 deletions(-) delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/MyStringBuilder.java diff --git a/platform/util/src/com/intellij/openapi/diff/impl/string/DiffString.java b/platform/util/src/com/intellij/openapi/diff/impl/string/DiffString.java index 76aa43418ccc..984634542776 100644 --- a/platform/util/src/com/intellij/openapi/diff/impl/string/DiffString.java +++ b/platform/util/src/com/intellij/openapi/diff/impl/string/DiffString.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.intellij.openapi.diff.impl.string; import com.intellij.openapi.diff.LineTokenizerBase; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.text.CharArrayCharSequence; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,14 +26,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class DiffString implements CharSequence { +public class DiffString extends CharArrayCharSequence { @NotNull public static final DiffString EMPTY = new DiffString(new char[0], 0, 0); - @NotNull private final char[] myData; - private final int myStart; - private final int myLength; - private int myHash; - @Nullable public static DiffString createNullable(@Nullable String string) { if (string == null) return null; @@ -58,63 +54,43 @@ public class DiffString implements CharSequence { } private DiffString(@NotNull char[] data, int start, int length) { - myData = data; - myStart = start; - myLength = length; - } - - @Override - public int length() { - return myLength; + super(data, start, start + length); } public boolean isEmpty() { - return myLength == 0; + return length() == 0; } - @Override - public char charAt(int index) { - if (index < 0 || index >= myLength) { - throw new StringIndexOutOfBoundsException(index); - } - return data(index); - } - - public char data(int index) { - return myData[myStart + index]; + private char data(int index) { + return charAt(index); } @NotNull public DiffString substring(int start) { - return substring(start, myLength); + return substring(start, length()); } @NotNull public DiffString substring(int start, int end) { - if (start == 0 && end == myLength) return this; - checkBounds(start, end - start, myLength); - return create(myData, myStart + start, end - start); + if (start == 0 && end == length()) return this; + checkBounds(start, end - start, length()); + return create(myChars, myStart + start, end - start); } + @NotNull @Override public DiffString subSequence(int start, int end) { return substring(start, end); } - @NotNull - @Override - public String toString() { - return new String(myData, myStart, myLength); - } - @NotNull public DiffString copy() { - return create(Arrays.copyOfRange(myData, myStart, myStart + myLength)); + return create(Arrays.copyOfRange(myChars, myStart, myStart + length())); } public void copyData(@NotNull char[] dst, int start) { - checkBounds(start, myLength, dst.length); - System.arraycopy(myData, myStart, dst, start, myLength); + checkBounds(start, length(), dst.length); + System.arraycopy(myChars, myStart, dst, start, length()); } @Override @@ -124,26 +100,15 @@ public class DiffString implements CharSequence { DiffString that = (DiffString)o; - if (myLength != that.myLength) return false; + if (length() != that.length()) return false; if (hashCode() != that.hashCode()) return false; - for (int i = 0; i < myLength; i++) { + for (int i = 0; i < length(); i++) { if (data(i) != that.data(i)) return false; } return true; } - @Override - public int hashCode() { - int h = myHash; - if (h == 0) { - h = StringUtil.stringHashCode(myData, myStart, myStart + myLength); - if (h == 0) h = 1; - myHash = h; - } - return h; - } - @Nullable public static DiffString concatenateNullable(@Nullable DiffString s1, @Nullable DiffString s2) { if (s1 == null || s2 == null) { @@ -160,13 +125,13 @@ public class DiffString implements CharSequence { if (s1.isEmpty()) return s2; if (s2.isEmpty()) return s1; - if (s1.myData == s2.myData && s1.myStart + s1.myLength == s2.myStart) { - return create(s1.myData, s1.myStart, s1.myLength + s2.myLength); + if (s1.myChars == s2.myChars && s1.myStart + s1.length() == s2.myStart) { + return create(s1.myChars, s1.myStart, s1.length() + s2.length()); } - char[] data = new char[s1.myLength + s2.myLength]; - System.arraycopy(s1.myData, s1.myStart, data, 0, s1.myLength); - System.arraycopy(s2.myData, s2.myStart, data, s1.myLength, s2.myLength); + char[] data = new char[s1.length() + s2.length()]; + System.arraycopy(s1.myChars, s1.myStart, data, 0, s1.length()); + System.arraycopy(s2.myChars, s2.myStart, data, s1.length(), s2.length()); return create(data); } @@ -174,7 +139,7 @@ public class DiffString implements CharSequence { if (s1.isEmpty()) return true; if (s2.isEmpty()) return true; - if (s1.myData == s2.myData && s1.myStart + s1.myLength == s2.myStart) { + if (s1.myChars == s2.myChars && s1.myStart + s1.length() == s2.myStart) { return true; } @@ -193,7 +158,7 @@ public class DiffString implements CharSequence { int len = 0; for (int i = 0; i < length; i++) { DiffString string = strings[start + i]; - len += string == null ? 0 : string.myLength; + len += string == null ? 0 : string.length(); } if (len == 0) return EMPTY; @@ -203,32 +168,32 @@ public class DiffString implements CharSequence { for (int i = 0; i < length; i++) { DiffString string = strings[start + i]; if (string == null || string.isEmpty()) continue; - System.arraycopy(string.myData, string.myStart, data, index, string.myLength); - index += string.myLength; + System.arraycopy(string.myChars, string.myStart, data, index, string.length()); + index += string.length(); } return create(data); } @NotNull public static DiffString concatenate(@NotNull DiffString s, char c) { - if (s.myStart + s.myLength < s.myData.length && s.data(s.myLength) == c) { - return create(s.myData, s.myStart, s.myLength + 1); + if (s.myStart + s.length() < s.myChars.length && s.data(s.length()) == c) { + return create(s.myChars, s.myStart, s.length() + 1); } - char[] data = new char[s.myLength + 1]; - System.arraycopy(s.myData, s.myStart, data, 0, s.myLength); - data[s.myLength] = c; + char[] data = new char[s.length() + 1]; + System.arraycopy(s.myChars, s.myStart, data, 0, s.length()); + data[s.length()] = c; return create(data); } @NotNull public static DiffString concatenate(char c, @NotNull DiffString s) { if (s.myStart > 0 && s.data(-1) == c) { - return create(s.myData, s.myStart - 1, s.myLength + 1); + return create(s.myChars, s.myStart - 1, s.length() + 1); } - char[] data = new char[s.myLength + 1]; - System.arraycopy(s.myData, s.myStart, data, 1, s.myLength); + char[] data = new char[s.length() + 1]; + System.arraycopy(s.myChars, s.myStart, data, 1, s.length()); data[0] = c; return create(data); } @@ -251,16 +216,16 @@ public class DiffString implements CharSequence { DiffString string = strings[start + i]; if (string == null || string.isEmpty()) continue; if (data == null) { - data = string.myData; + data = string.myChars; startIndex = string.myStart; - endIndex = string.myStart + string.myLength; + endIndex = string.myStart + string.length(); continue; } - if (data != string.myData || string.myStart != endIndex) { + if (data != string.myChars || string.myStart != endIndex) { linearized = false; break; } - endIndex += string.myLength; + endIndex += string.length(); } if (linearized) { @@ -288,7 +253,7 @@ public class DiffString implements CharSequence { public boolean isEmptyOrSpaces() { if (isEmpty()) return true; - for (int i = 0; i < myLength; i++) { + for (int i = 0; i < length(); i++) { if (!isWhiteSpace(data(i))) return false; } return true; @@ -297,7 +262,7 @@ public class DiffString implements CharSequence { @NotNull public DiffString trim() { int start = 0; - int end = myLength; + int end = length(); while (start < end && isWhiteSpace(data(start))) start++; while (end > start && isWhiteSpace(data(end - 1))) end--; @@ -309,14 +274,14 @@ public class DiffString implements CharSequence { public DiffString trimLeading() { int i = 0; - while (i < myLength && isWhiteSpace(data(i))) i++; + while (i < length() && isWhiteSpace(data(i))) i++; - return substring(i, myLength); + return substring(i, length()); } @NotNull public DiffString trimTrailing() { - int end = myLength; + int end = length(); while (end > 0 && isWhiteSpace(data(end - 1))) end--; @@ -327,7 +292,7 @@ public class DiffString implements CharSequence { public DiffString getLeadingSpaces() { int i = 0; - while (i < myLength && data(i) == ' ') i++; + while (i < length() && data(i) == ' ') i++; return substring(0, i); } @@ -336,14 +301,14 @@ public class DiffString implements CharSequence { public DiffString skipSpaces() { DiffString s = trim(); int count = 0; - for (int i = 0; i < s.myLength; i++) { + for (int i = 0; i < s.length(); i++) { if (isWhiteSpace(s.data(i))) count++; } if (count == 0) return s; - char[] data = new char[s.myLength - count]; + char[] data = new char[s.length() - count]; int index = 0; - for (int i = 0; i < s.myLength; i++) { + for (int i = 0; i < s.length(); i++) { if (isWhiteSpace(s.data(i))) continue; data[index] = s.data(i); index++; @@ -357,7 +322,7 @@ public class DiffString implements CharSequence { public boolean endsWith(char c) { if (isEmpty()) return false; - return data(myLength - 1) == c; + return data(length() - 1) == c; } public static void checkBounds(int start, int length, int maxLength) { diff --git a/platform/util/src/com/intellij/openapi/util/text/CharSequenceWithStringHash.java b/platform/util/src/com/intellij/openapi/util/text/CharSequenceWithStringHash.java index f467c278b3f1..b57fa1f76e05 100644 --- a/platform/util/src/com/intellij/openapi/util/text/CharSequenceWithStringHash.java +++ b/platform/util/src/com/intellij/openapi/util/text/CharSequenceWithStringHash.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,4 +20,6 @@ package com.intellij.openapi.util.text; * @see com.intellij.openapi.util.text.StringUtil#stringHashCode(CharSequence) */ public interface CharSequenceWithStringHash extends CharSequence{ + @Override + int hashCode(); } diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index b50ab3e3cbc9..dea5319a5de1 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -21,7 +21,6 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.text.CharArrayCharSequence; import com.intellij.util.text.CharArrayUtil; import com.intellij.util.text.CharSequenceSubSequence; import com.intellij.util.text.StringFactory; @@ -859,9 +858,10 @@ public class StringUtil extends StringUtilRt { @Contract(pure = true) public static int stringHashCode(@NotNull CharSequence chars) { - if (chars instanceof String) return chars.hashCode(); - if (chars instanceof CharSequenceWithStringHash) return chars.hashCode(); - if (chars instanceof CharArrayCharSequence) return chars.hashCode(); + if (chars instanceof String || chars instanceof CharSequenceWithStringHash) { + // we know for sure these classes have conformant (and maybe faster) hashCode() + return chars.hashCode(); + } return stringHashCode(chars, 0, chars.length()); } @@ -966,6 +966,15 @@ public class StringUtil extends StringUtilRt { return s; } + @NotNull + @Contract(pure = true) + public static String trimEnd(@NotNull String s, char suffix) { + if (endsWithChar(s, suffix)) { + return s.substring(0, s.length() - 1); + } + return s; + } + @NotNull @Contract(pure = true) public static String trimLog(@NotNull final String text, final int limit) { diff --git a/platform/util/src/com/intellij/util/text/ByteArrayCharSequence.java b/platform/util/src/com/intellij/util/text/ByteArrayCharSequence.java index a48f7c03e195..98da5b7e09c5 100644 --- a/platform/util/src/com/intellij/util/text/ByteArrayCharSequence.java +++ b/platform/util/src/com/intellij/util/text/ByteArrayCharSequence.java @@ -16,6 +16,7 @@ package com.intellij.util.text; import com.intellij.openapi.util.text.CharSequenceWithStringHash; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; public class ByteArrayCharSequence implements CharSequenceWithStringHash { @@ -30,12 +31,7 @@ public class ByteArrayCharSequence implements CharSequenceWithStringHash { public int hashCode() { int h = hash; if (h == 0) { - byte[] chars = myChars; - - for (byte aChar : chars) { - h = 31 * h + aChar; - } - hash = h; + hash = h = StringUtil.stringHashCode(this, 0, length()); } return h; } diff --git a/platform/util/src/com/intellij/util/text/CharArrayCharSequence.java b/platform/util/src/com/intellij/util/text/CharArrayCharSequence.java index f77f70167be8..b61401a5e9de 100644 --- a/platform/util/src/com/intellij/util/text/CharArrayCharSequence.java +++ b/platform/util/src/com/intellij/util/text/CharArrayCharSequence.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,11 @@ */ package com.intellij.util.text; +import com.intellij.openapi.util.text.CharSequenceWithStringHash; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; -public class CharArrayCharSequence implements CharSequenceBackedByArray { +public class CharArrayCharSequence implements CharSequenceBackedByArray, CharSequenceWithStringHash { protected final char[] myChars; protected final int myStart; protected final int myEnd; @@ -29,9 +30,7 @@ public class CharArrayCharSequence implements CharSequenceBackedByArray { public CharArrayCharSequence(@NotNull char[] chars, int start, int end) { if (start < 0 || end > chars.length || start > end) { - throw new IndexOutOfBoundsException("chars.length:" + chars.length + - ", start:" + start + - ", end:" + end); + throw new IndexOutOfBoundsException("chars.length:" + chars.length + ", start:" + start + ", end:" + end); } myChars = chars; myStart = start; @@ -48,6 +47,7 @@ public class CharArrayCharSequence implements CharSequenceBackedByArray { return myChars[index + myStart]; } + @NotNull @Override public CharSequence subSequence(int start, int end) { return start == 0 && end == length() ? this : new CharArrayCharSequence(myChars, myStart + start, myStart + end); @@ -62,17 +62,12 @@ public class CharArrayCharSequence implements CharSequenceBackedByArray { @Override @NotNull public char[] getChars() { - if (myStart == 0 /*&& myEnd == myChars.length*/) return myChars; + if (myStart == 0) return myChars; char[] chars = new char[length()]; System.arraycopy(myChars, myStart, chars, 0, length()); return chars; } - @Override - public int hashCode() { - return StringUtil.stringHashCode(myChars, myStart, myEnd); - } - @Override public void getChars(@NotNull char[] dst, int dstOffset) { System.arraycopy(myChars, myStart, dst, dstOffset, length()); @@ -108,4 +103,14 @@ public class CharArrayCharSequence implements CharSequenceBackedByArray { System.arraycopy(myChars, myStart + start, cbuf, off, readChars); return readChars; } + + private int hash; + @Override + public int hashCode() { + int h = hash; + if (h == 0) { + hash = h = StringUtil.stringHashCode(this, 0, length()); + } + return h; + } } diff --git a/platform/util/src/com/intellij/util/text/CharSequenceSubSequence.java b/platform/util/src/com/intellij/util/text/CharSequenceSubSequence.java index a4d751e16287..0f70193b8562 100644 --- a/platform/util/src/com/intellij/util/text/CharSequenceSubSequence.java +++ b/platform/util/src/com/intellij/util/text/CharSequenceSubSequence.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,11 @@ package com.intellij.util.text; +import com.intellij.openapi.util.text.CharSequenceWithStringHash; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; -public class CharSequenceSubSequence implements CharSequence, CharArrayExternalizable { +public class CharSequenceSubSequence implements CharSequence, CharArrayExternalizable, CharSequenceWithStringHash { private final CharSequence myChars; private final int myStart; private final int myEnd; @@ -48,6 +50,7 @@ public class CharSequenceSubSequence implements CharSequence, CharArrayExternali return myChars.charAt(index + myStart); } + @NotNull @Override public CharSequence subSequence(int start, int end) { if (start == myStart && end == myEnd) return this; @@ -60,6 +63,7 @@ public class CharSequenceSubSequence implements CharSequence, CharArrayExternali return StringFactory.createShared(CharArrayUtil.fromSequence(myChars, myStart, myEnd)); } + @NotNull public CharSequence getBaseSequence() { return myChars; } @@ -69,4 +73,14 @@ public class CharSequenceSubSequence implements CharSequence, CharArrayExternali assert end - start <= myEnd - myStart; CharArrayUtil.getChars(myChars, dest, start + myStart, destPos, end - start); } + + private int hash; + @Override + public int hashCode() { + int h = hash; + if (h == 0) { + hash = h = StringUtil.stringHashCode(this, 0, length()); + } + return h; + } } diff --git a/platform/util/src/com/intellij/util/text/ImmutableText.java b/platform/util/src/com/intellij/util/text/ImmutableText.java index b18a8b8306b0..8112d1b37086 100644 --- a/platform/util/src/com/intellij/util/text/ImmutableText.java +++ b/platform/util/src/com/intellij/util/text/ImmutableText.java @@ -27,6 +27,8 @@ */ package com.intellij.util.text; +import com.intellij.openapi.util.text.CharSequenceWithStringHash; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -53,7 +55,7 @@ import org.jetbrains.annotations.Nullable; * @version 5.3, January 10, 2007 */ @SuppressWarnings({"AssignmentToForLoopParameter","UnnecessaryThis"}) -public final class ImmutableText extends ImmutableCharSequence implements CharArrayExternalizable { +public final class ImmutableText extends ImmutableCharSequence implements CharArrayExternalizable, CharSequenceWithStringHash { /** * Holds the default size for primitive blocks of characters. */ @@ -248,6 +250,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr return true; } + private int hash; /** * Returns the hash code for this text. * @@ -255,10 +258,9 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr */ @Override public int hashCode() { - int h = 0; - final int length = this.length(); - for (int i = 0; i < length;) { - h = 31 * h + charAt(i++); + int h = hash; + if (h == 0) { + hash = h = StringUtil.stringHashCode(this, 0, length()); } return h; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/MyStringBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/MyStringBuilder.java deleted file mode 100644 index 37aafa4b28f9..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/MyStringBuilder.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.refactoring.convertToJava; - -import gnu.trove.TIntArrayList; - -import java.util.ArrayList; -import java.util.List; - -/** - * String builder for only append and remove from the end without insert. - * - * @author Medvedev Max - */ -public class MyStringBuilder implements CharSequence { - private char[] arr = new char[16]; - - private int innerLen = 0; - private int realLength = 0; - - List builders = new ArrayList(4); - TIntArrayList positions = new TIntArrayList(4); - - @Override - public int length() { - return realLength; - } - - @Override - public char charAt(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public CharSequence subSequence(int start, int end) { - throw new UnsupportedOperationException(); - } - - public MyStringBuilder append(char c) { - if (innerLen == arr.length) { - final char[] chars = new char[innerLen * 2]; - System.arraycopy(arr, 0, chars, 0, arr.length); - arr = chars; - } - arr[innerLen] = c; - innerLen++; - realLength++; - return this; - } - - public MyStringBuilder append(CharSequence s) { - builders.add(s); - positions.add(innerLen); - realLength += s.length(); - return this; - } - - public MyStringBuilder removeFromTheEnd(int count) { - if (positions.isEmpty()) { - innerLen -= count; - realLength -= count; - return this; - } - - final int lastIndex = positions.size() - 1; - final int lastPos = positions.getQuick(lastIndex); - - if (lastPos == innerLen) { - final CharSequence last = builders.get(lastIndex); - final int lastLength = last.length(); - if (lastLength <= count) { - positions.remove(lastIndex); - builders.remove(lastIndex); - realLength -= lastLength; - count -= lastLength; - if (count > 0) removeFromTheEnd(count); - } - else { - if (last instanceof MyStringBuilder) { - ((MyStringBuilder)last).removeFromTheEnd(count); - realLength -= count; - } - else { - positions.remove(lastIndex); - builders.remove(lastIndex); - realLength -= lastLength; - int toAppend = lastLength - count; - for (int i = 0; i < toAppend; i++) { - append(last.charAt(i)); - } - } - } - } - else { - if (lastPos+count<=innerLen) { - innerLen-=count; - realLength-=count; - } - else { - final int removed = innerLen - lastPos; - innerLen -= removed; - realLength -= removed; - count -= removed; - if (count > 0) removeFromTheEnd(count); - } - } - return this; - } - - MyStringBuilder append(Object value) { - return append(String.valueOf(value)); - } - - @Override - public String toString() { - if (positions.isEmpty()) { - return new String(arr); - } - - char[] chars = new char[realLength]; - innerToString(chars, 0); - return new String(chars); - } - - private int innerToString(char[] chars, int posInChars) { - int posInInner = 0; - final int size = positions.size(); - for (int i = 0; i < size; i++) { - final int pos = positions.get(i); - final int length = pos - posInInner; - System.arraycopy(arr, posInInner, chars, posInChars, length); - posInChars += length; - posInInner += length; - CharSequence seq = builders.get(i); - if (seq instanceof MyStringBuilder) { - posInChars = ((MyStringBuilder)seq).innerToString(chars, posInChars); - } - else { - final int seqLength = seq.length(); - for (int j = 0; j < seqLength; j++) { - chars[posInChars] = seq.charAt(j); - posInChars++; - } - } - } - - final int length = innerLen - posInInner; - System.arraycopy(arr, posInInner, chars, posInChars, length); - return posInChars + length; - } -}