optimize QString::toLower()/toUpper() for special cases, step 1

reorganize QUnicodeTables::specialCaseMap as follows:
specialCaseMap contains sequence entries in form { length, a, b, .. }

Change-Id: Iea1f80bc2f4dc1f505428dad981cde26daaa52c7
Merge-request: 70
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Reviewed-by: Olivier
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Konstantin Ritt 2011-10-18 19:12:20 +02:00 committed by Qt by Nokia
parent 20faf6408a
commit 5f04962132
2 changed files with 40 additions and 27 deletions

View File

@ -4920,11 +4920,12 @@ QString QString::toLower() const
prop = qGetProp(*p); prop = qGetProp(*p);
} }
if (prop->lowerCaseSpecial) { if (prop->lowerCaseSpecial) {
int pos = pp - s.d->data();
s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
pp = s.d->data() + pos;
const ushort *specialCase = specialCaseMap + prop->lowerCaseDiff; const ushort *specialCase = specialCaseMap + prop->lowerCaseDiff;
while (*specialCase) ushort length = *specialCase++;
int pos = pp - s.d->data();
s.resize(s.d->size + length - 1);
pp = s.d->data() + pos;
while (length--)
*pp++ = *specialCase++; *pp++ = *specialCase++;
} else { } else {
*pp++ = *p + prop->lowerCaseDiff; *pp++ = *p + prop->lowerCaseDiff;
@ -4936,7 +4937,6 @@ QString QString::toLower() const
while (e != d->data() + d->size) while (e != d->data() + d->size)
*pp++ = *e++; *pp++ = *e++;
s.truncate(pp - s.d->data());
return s; return s;
} }
++p; ++p;
@ -5042,11 +5042,12 @@ QString QString::toUpper() const
prop = qGetProp(*p); prop = qGetProp(*p);
} }
if (prop->upperCaseSpecial) { if (prop->upperCaseSpecial) {
int pos = pp - s.d->data();
s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
pp = s.d->data() + pos;
const ushort *specialCase = specialCaseMap + prop->upperCaseDiff; const ushort *specialCase = specialCaseMap + prop->upperCaseDiff;
while (*specialCase) ushort length = *specialCase++;
int pos = pp - s.d->data();
s.resize(s.d->size + length - 1);
pp = s.d->data() + pos;
while (length--)
*pp++ = *specialCase++; *pp++ = *specialCase++;
} else { } else {
*pp++ = *p + prop->upperCaseDiff; *pp++ = *p + prop->upperCaseDiff;
@ -5058,7 +5059,6 @@ QString QString::toUpper() const
while (e != d->data() + d->size) while (e != d->data() + d->size)
*pp++ = *e++; *pp++ = *e++;
s.truncate(pp - s.d->data());
return s; return s;
} }
++p; ++p;

View File

@ -472,17 +472,23 @@ static int appendToSpecialCaseMap(const QList<int> &map)
utf16map << val; utf16map << val;
} }
} }
specialCaseMaxLen = qMax(specialCaseMaxLen, utf16map.size()); int length = utf16map.size();
utf16map << 0; utf16map.prepend(length);
specialCaseMaxLen = qMax(specialCaseMaxLen, length);
for (int i = 0; i < specialCaseMap.size() - utf16map.size() + 1; ++i) { int i = 0;
int j; while (i < specialCaseMap.size()) {
for (j = 0; j < utf16map.size(); ++j) { int n = specialCaseMap.at(i);
if (specialCaseMap.at(i+j) != utf16map.at(j)) if (n == length) {
break; int j;
for (j = 1; j <= n; ++j) {
if (specialCaseMap.at(i+j) != utf16map.at(j))
break;
}
if (j > n)
return i;
} }
if (j == utf16map.size()) i += n + 1;
return i;
} }
int pos = specialCaseMap.size(); int pos = specialCaseMap.size();
@ -1528,7 +1534,8 @@ static inline void foldCase(uint ch, ushort *out)
*(out++) = ch + p->caseFoldDiff; *(out++) = ch + p->caseFoldDiff;
} else { } else {
const ushort *folded = specialCaseMap + p->caseFoldDiff; const ushort *folded = specialCaseMap + p->caseFoldDiff;
while (*folded) ushort length = *folded++;
while (length--)
*out++ = *folded++; *out++ = *folded++;
} }
*out = 0; *out = 0;
@ -2243,13 +2250,19 @@ static QByteArray createPropertyInfo()
" return (QUnicodeTables::LineBreakClass)qGetProp(ucs4)->line_break_class;\n" " return (QUnicodeTables::LineBreakClass)qGetProp(ucs4)->line_break_class;\n"
"}\n\n"; "}\n\n";
out += "static const ushort specialCaseMap[] = {\n ";
for (int i = 0; i < specialCaseMap.size(); ++i) { out += "static const ushort specialCaseMap[] = {";
out += QByteArray(" 0x") + QByteArray::number(specialCaseMap.at(i), 16); int i = 0;
if (i < specialCaseMap.size() - 1) while (i < specialCaseMap.size()) {
out += ","; out += "\n ";
if (!specialCaseMap.at(i)) int n = specialCaseMap.at(i);
out += "\n "; int j;
for (j = 0; j <= n; ++j) {
out += QByteArray(" 0x") + QByteArray::number(specialCaseMap.at(i+j), 16);
if (i+j < specialCaseMap.size() - 1)
out += ",";
}
i += n + 1;
} }
out += "\n};\n"; out += "\n};\n";
out += "#define SPECIAL_CASE_MAX_LEN " + QByteArray::number(specialCaseMaxLen) + "\n\n"; out += "#define SPECIAL_CASE_MAX_LEN " + QByteArray::number(specialCaseMaxLen) + "\n\n";