mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-01 17:12:03 +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
1b7218fcef
commit
d95d88c102
1 changed files with 101 additions and 40 deletions
|
@ -2311,6 +2311,9 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
||||||
}
|
}
|
||||||
|
|
||||||
countOther = [aString length];
|
countOther = [aString length];
|
||||||
|
|
||||||
|
/* A zero length string is always found at the start of the given range.
|
||||||
|
*/
|
||||||
if (0 == countOther)
|
if (0 == countOther)
|
||||||
{
|
{
|
||||||
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
|
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
|
||||||
|
@ -2321,6 +2324,91 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
||||||
return searchRange;
|
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)
|
if ((mask & NSLiteralSearch) == NSLiteralSearch)
|
||||||
{
|
{
|
||||||
NSRange result;
|
NSRange result;
|
||||||
|
@ -2382,58 +2470,31 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
||||||
GS_BEGINITEMBUF2(charsSelf, (searchRange.length*sizeof(unichar)),
|
GS_BEGINITEMBUF2(charsSelf, (searchRange.length*sizeof(unichar)),
|
||||||
unichar)
|
unichar)
|
||||||
[self getCharacters: charsSelf range: searchRange];
|
[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
|
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,
|
break;
|
||||||
countOther * sizeof(unichar)) == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
pos++;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
while (pos < end)
|
|
||||||
{
|
|
||||||
if (memcmp(&charsSelf[pos], charsOther,
|
|
||||||
countOther * sizeof(unichar)) == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos >= end)
|
if (pos >= end)
|
||||||
{
|
{
|
||||||
result = NSMakeRange(NSNotFound, 0);
|
result = NSMakeRange(NSNotFound, 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue