optimise search for a range for the case of a single character.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@38573 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2015-05-27 05:18:47 +00:00
parent 0224ae5360
commit d7a6170f24

View file

@ -2311,6 +2311,9 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
}
countOther = [aString length];
/* A zero length string is always found at the start of the given range.
*/
if (0 == countOther)
{
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
@ -2321,6 +2324,91 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
return searchRange;
}
/* If the string to search for is a single codepoint which is not
* decomposable to a sequence, then it can only match the identical
* codepoint, so we can perform the much cheaper literal search.
*/
if (1 == countOther)
{
unichar u = [aString characterAtIndex: 0];
if ((mask & NSLiteralSearch) == NSLiteralSearch || uni_is_decomp(u))
{
NSRange result;
if (searchRange.length < countOther)
{
/* Range to search is smaller than string to look for.
*/
result = NSMakeRange(NSNotFound, 0);
}
else if ((mask & NSAnchoredSearch) == NSAnchoredSearch
|| searchRange.length == 1)
{
/* Range to search is a single character.
*/
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
{
searchRange.location = NSMaxRange(searchRange) - 1;
}
if ([self characterAtIndex: searchRange.location] == u)
{
result = searchRange;
}
else
{
result = NSMakeRange(NSNotFound, 0);
}
}
else
{
NSUInteger pos;
NSUInteger end;
/* Range to search is bigger than string to look for.
*/
GS_BEGINITEMBUF2(charsSelf, (searchRange.length*sizeof(unichar)),
unichar)
[self getCharacters: charsSelf range: searchRange];
end = searchRange.length;
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
{
pos = end;
while (pos-- > 0)
{
if (charsSelf[pos] == u)
{
break;
}
}
}
else
{
pos = 0;
while (pos < end)
{
if (charsSelf[pos] == u)
{
break;
}
pos++;
}
}
GS_ENDITEMBUF2()
if (pos >= end)
{
result = NSMakeRange(NSNotFound, 0);
}
else
{
result = NSMakeRange(searchRange.location + pos, countOther);
}
}
return result;
}
}
if ((mask & NSLiteralSearch) == NSLiteralSearch)
{
NSRange result;
@ -2382,58 +2470,31 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
GS_BEGINITEMBUF2(charsSelf, (searchRange.length*sizeof(unichar)),
unichar)
[self getCharacters: charsSelf range: searchRange];
if (1 == countOther)
{
unichar u = charsOther[0];
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
{
while (pos-- > 0)
{
while (pos-- > 0)
if (memcmp(&charsSelf[pos], charsOther,
countOther * sizeof(unichar)) == 0)
{
if (charsSelf[pos] == u)
{
break;
}
break;
}
}
else
{
while (pos < end)
{
if (charsSelf[pos] == u)
{
break;
}
pos++;
}
}
}
else
{
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
while (pos < end)
{
while (pos-- > 0)
if (memcmp(&charsSelf[pos], charsOther,
countOther * sizeof(unichar)) == 0)
{
if (memcmp(&charsSelf[pos], charsOther,
countOther * sizeof(unichar)) == 0)
{
break;
}
break;
}
}
else
{
while (pos < end)
{
if (memcmp(&charsSelf[pos], charsOther,
countOther * sizeof(unichar)) == 0)
{
break;
}
pos++;
}
}
pos++;
}
}
if (pos >= end)
{
result = NSMakeRange(NSNotFound, 0);