From: Markus Scherer Date: Thu, 18 Jun 2015 14:09:54 +0000 (+0000) Subject: ICU-11317 split out a new doAppend() from the more general doReplace(), each optimizi... X-Git-Tag: milestone-59-0-1~1057 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3d77fc18b8b1f1fbeb584790ebab1e5259e70b94;p=icu ICU-11317 split out a new doAppend() from the more general doReplace(), each optimizing for different cases X-SVN-Rev: 37601 --- diff --git a/icu4c/source/common/unicode/unistr.h b/icu4c/source/common/unicode/unistr.h index eda044f14c0..93e3048aaed 100644 --- a/icu4c/source/common/unicode/unistr.h +++ b/icu4c/source/common/unicode/unistr.h @@ -3494,6 +3494,9 @@ private: int32_t srcStart, int32_t srcLength); + UnicodeString& doAppend(const UnicodeString& src, int32_t srcStart, int32_t srcLength); + UnicodeString& doAppend(const UChar *srcChars, int32_t srcStart, int32_t srcLength); + UnicodeString& doReverse(int32_t start, int32_t length); @@ -4529,30 +4532,30 @@ inline UnicodeString& UnicodeString::append(const UnicodeString& srcText, int32_t srcStart, int32_t srcLength) -{ return doReplace(length(), 0, srcText, srcStart, srcLength); } +{ return doAppend(srcText, srcStart, srcLength); } inline UnicodeString& UnicodeString::append(const UnicodeString& srcText) -{ return doReplace(length(), 0, srcText, 0, srcText.length()); } +{ return doAppend(srcText, 0, srcText.length()); } inline UnicodeString& UnicodeString::append(const UChar *srcChars, int32_t srcStart, int32_t srcLength) -{ return doReplace(length(), 0, srcChars, srcStart, srcLength); } +{ return doAppend(srcChars, srcStart, srcLength); } inline UnicodeString& UnicodeString::append(const UChar *srcChars, int32_t srcLength) -{ return doReplace(length(), 0, srcChars, 0, srcLength); } +{ return doAppend(srcChars, 0, srcLength); } inline UnicodeString& UnicodeString::append(UChar srcChar) -{ return doReplace(length(), 0, &srcChar, 0, 1); } +{ return doAppend(&srcChar, 0, 1); } inline UnicodeString& UnicodeString::operator+= (UChar ch) -{ return doReplace(length(), 0, &ch, 0, 1); } +{ return doAppend(&ch, 0, 1); } inline UnicodeString& UnicodeString::operator+= (UChar32 ch) { @@ -4561,7 +4564,7 @@ UnicodeString::operator+= (UChar32 ch) { inline UnicodeString& UnicodeString::operator+= (const UnicodeString& srcText) -{ return doReplace(length(), 0, srcText, 0, srcText.length()); } +{ return doAppend(srcText, 0, srcText.length()); } inline UnicodeString& UnicodeString::insert(int32_t start, diff --git a/icu4c/source/common/unistr.cpp b/icu4c/source/common/unistr.cpp index 4b4a53eafba..3b4bbffb8a1 100644 --- a/icu4c/source/common/unistr.cpp +++ b/icu4c/source/common/unistr.cpp @@ -208,13 +208,13 @@ UnicodeString::UnicodeString(UChar32 ch) { UnicodeString::UnicodeString(const UChar *text) { fUnion.fFields.fLengthAndFlags = kShortString; - doReplace(0, 0, text, 0, -1); + doAppend(text, 0, -1); } UnicodeString::UnicodeString(const UChar *text, int32_t textLength) { fUnion.fFields.fLengthAndFlags = kShortString; - doReplace(0, 0, text, 0, textLength); + doAppend(text, 0, textLength); } UnicodeString::UnicodeString(UBool isTerminated, @@ -1357,8 +1357,8 @@ UnicodeString::append(UChar32 srcChar) { UBool isError = FALSE; U16_APPEND(buffer, _length, U16_MAX_LENGTH, srcChar, isError); // We test isError so that the compiler does not complain that we don't. - // If isError then _length==0 which turns the doReplace() into a no-op anyway. - return isError ? *this : doReplace(length(), 0, buffer, 0, _length); + // If isError then _length==0 which turns the doAppend() into a no-op anyway. + return isError ? *this : doAppend(buffer, 0, _length); } UnicodeString& @@ -1368,17 +1368,12 @@ UnicodeString::doReplace( int32_t start, int32_t srcStart, int32_t srcLength) { - if(!src.isBogus()) { - // pin the indices to legal values - src.pinIndices(srcStart, srcLength); + // pin the indices to legal values + src.pinIndices(srcStart, srcLength); - // get the characters from src - // and replace the range in ourselves with them - return doReplace(start, length, src.getArrayStart(), srcStart, srcLength); - } else { - // remove the range - return doReplace(start, length, 0, 0, 0); - } + // get the characters from src + // and replace the range in ourselves with them + return doReplace(start, length, src.getArrayStart(), srcStart, srcLength); } UnicodeString& @@ -1414,6 +1409,10 @@ UnicodeString::doReplace(int32_t start, } } + if(start == oldLength) { + return doAppend(srcChars, srcStart, srcLength); + } + if(srcChars == 0) { srcStart = srcLength = 0; } else if(srcLength < 0) { @@ -1421,42 +1420,13 @@ UnicodeString::doReplace(int32_t start, srcLength = u_strlen(srcChars + srcStart); } - // calculate the size of the string after the replace - int32_t newLength; - - // optimize append() onto a large-enough, owned string - if(start >= oldLength) { - if(srcLength == 0) { - return *this; - } - newLength = oldLength + srcLength; - if(newLength <= getCapacity() && isBufferWritable()) { - UChar *oldArray = getArrayStart(); - // Do not copy characters when - // UChar *buffer=str.getAppendBuffer(...); - // is followed by - // str.append(buffer, length); - // or - // str.appendString(buffer, length) - // or similar. - if(srcChars + srcStart != oldArray + start || start > oldLength) { - us_arrayCopy(srcChars, srcStart, oldArray, oldLength, srcLength); - } - setLength(newLength); - return *this; - } else { - // pin the indices to legal values - start = oldLength; - length = 0; - } - } else { - // pin the indices to legal values - pinIndices(start, length); + // pin the indices to legal values + pinIndices(start, length); - newLength = oldLength - length + srcLength; - } + // calculate the size of the string after the replace + int32_t newLength = oldLength - length + srcLength; - // the following may change fArray but will not copy the current contents; + // cloneArrayIfNeeded(doCopyArray=FALSE) may change fArray but will not copy the current contents; // therefore we need to keep the current fArray UChar oldStackBuffer[US_STACKBUF_SIZE]; UChar *oldArray; @@ -1507,6 +1477,54 @@ UnicodeString::doReplace(int32_t start, return *this; } +// Versions of doReplace() only for append() variants. +// doReplace() and doAppend() optimize for different cases. + +UnicodeString& +UnicodeString::doAppend(const UnicodeString& src, int32_t srcStart, int32_t srcLength) { + if(srcLength == 0) { + return *this; + } + + // pin the indices to legal values + src.pinIndices(srcStart, srcLength); + return doAppend(src.getArrayStart(), srcStart, srcLength); +} + +UnicodeString& +UnicodeString::doAppend(const UChar *srcChars, int32_t srcStart, int32_t srcLength) { + if(!isWritable() || srcLength == 0 || srcChars == NULL) { + return *this; + } + + if(srcLength < 0) { + // get the srcLength if necessary + if((srcLength = u_strlen(srcChars + srcStart)) == 0) { + return *this; + } + } + + int32_t oldLength = length(); + int32_t newLength = oldLength + srcLength; + // optimize append() onto a large-enough, owned string + if((newLength <= getCapacity() && isBufferWritable()) || + cloneArrayIfNeeded(newLength, newLength + (newLength >> 2) + kGrowSize)) { + UChar *newArray = getArrayStart(); + // Do not copy characters when + // UChar *buffer=str.getAppendBuffer(...); + // is followed by + // str.append(buffer, length); + // or + // str.appendString(buffer, length) + // or similar. + if(srcChars + srcStart != newArray + oldLength) { + us_arrayCopy(srcChars, srcStart, newArray, oldLength, srcLength); + } + setLength(newLength); + } + return *this; +} + /** * Replaceable API */ @@ -1806,7 +1824,7 @@ UnicodeStringAppendable::~UnicodeStringAppendable() {} UBool UnicodeStringAppendable::appendCodeUnit(UChar c) { - return str.doReplace(str.length(), 0, &c, 0, 1).isWritable(); + return str.doAppend(&c, 0, 1).isWritable(); } UBool @@ -1815,12 +1833,12 @@ UnicodeStringAppendable::appendCodePoint(UChar32 c) { int32_t cLength = 0; UBool isError = FALSE; U16_APPEND(buffer, cLength, U16_MAX_LENGTH, c, isError); - return !isError && str.doReplace(str.length(), 0, buffer, 0, cLength).isWritable(); + return !isError && str.doAppend(buffer, 0, cLength).isWritable(); } UBool UnicodeStringAppendable::appendString(const UChar *s, int32_t length) { - return str.doReplace(str.length(), 0, s, 0, length).isWritable(); + return str.doAppend(s, 0, length).isWritable(); } UBool