mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
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:
parent
0224ae5360
commit
d7a6170f24
1 changed files with 101 additions and 40 deletions
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue