mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Optimise test for dictionary equality
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@15973 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
bfed503388
commit
64d7feafd2
4 changed files with 93 additions and 2 deletions
|
@ -1,3 +1,10 @@
|
|||
2003-02-16 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/GSDictionary.m: ([-isEqualToDictionary:]) implement optimised
|
||||
version which does not need to create a key enumerator.
|
||||
* Source/GSArray.m: ditto
|
||||
* Source/GSSet.m: similar minor optimisations.
|
||||
|
||||
2003-02-15 15:53 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
* Source/NSRunLoop.m (-performSelector:target:argument:order:modes:):
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <Foundation/NSDebug.h>
|
||||
|
||||
static SEL eqSel;
|
||||
static SEL oaiSel;
|
||||
|
||||
static Class GSInlineArrayClass;
|
||||
|
||||
|
@ -75,6 +76,7 @@ static Class GSInlineArrayClass;
|
|||
{
|
||||
[self setVersion: 1];
|
||||
eqSel = @selector(isEqual:);
|
||||
oaiSel = @selector(objectAtIndex:);
|
||||
GSInlineArrayClass = [GSInlineArray class];
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +228,33 @@ static Class GSInlineArrayClass;
|
|||
return NSNotFound;
|
||||
}
|
||||
|
||||
- (BOOL) isEqualToArray: (NSArray*)otherArray
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (self == (id)otherArray)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
if (_count != [otherArray count])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
if (_count > 0)
|
||||
{
|
||||
IMP get1 = [otherArray methodForSelector: oaiSel];
|
||||
|
||||
for (i = 0; i < _count; i++)
|
||||
{
|
||||
if (![_contents_array[i] isEqual: (*get1)(otherArray, oaiSel, i)])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id) lastObject
|
||||
{
|
||||
if (_count)
|
||||
|
|
|
@ -244,6 +244,42 @@ static SEL objSel;
|
|||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isEqualToDictionary: (NSDictionary*)other
|
||||
{
|
||||
unsigned count;
|
||||
|
||||
if (other == self)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
count = map.nodeCount;
|
||||
if (count == [other count])
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
GSIMapEnumerator_t enumerator;
|
||||
GSIMapNode node;
|
||||
IMP otherObj = [other methodForSelector: objSel];
|
||||
|
||||
enumerator = GSIMapEnumeratorForMap(&map);
|
||||
while ((node = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
||||
{
|
||||
id o1 = node->value.obj;
|
||||
id o2 = (*otherObj)(other, objSel, node->key.obj);
|
||||
|
||||
if (o1 != o2 && [o1 isEqual: o2] == NO)
|
||||
{
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSEnumerator*) keyEnumerator
|
||||
{
|
||||
return AUTORELEASE([[GSDictionaryKeyEnumerator allocWithZone:
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
|
||||
#include <base/GSIMap.h>
|
||||
|
||||
static SEL memberSel;
|
||||
|
||||
@interface GSSet : NSSet
|
||||
{
|
||||
@public
|
||||
|
@ -107,6 +109,7 @@ static Class mutableSetClass;
|
|||
arrayClass = [NSArray class];
|
||||
setClass = [GSSet class];
|
||||
mutableSetClass = [GSMutableSet class];
|
||||
memberSel = @selector(member:);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,13 +286,19 @@ static Class mutableSetClass;
|
|||
{
|
||||
GSIMapEnumerator_t enumerator;
|
||||
GSIMapNode node;
|
||||
IMP imp;
|
||||
|
||||
// -1. members of this set(self) <= that of otherSet
|
||||
if (map.nodeCount > [otherSet count])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
if (map.nodeCount == 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
imp = [otherSet methodForSelector: memberSel];
|
||||
enumerator = GSIMapEnumeratorForMap(&map);
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
|
||||
|
@ -297,7 +306,7 @@ static Class mutableSetClass;
|
|||
while (node != 0)
|
||||
{
|
||||
// 1. check the member is in the otherSet.
|
||||
if ([otherSet member: node->key.obj])
|
||||
if ((*imp)(otherSet, memberSel, node->key.obj) != nil)
|
||||
{
|
||||
// 1.1 if true -> continue, try to check the next member.
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
|
@ -334,6 +343,10 @@ static Class mutableSetClass;
|
|||
{
|
||||
return NO;
|
||||
}
|
||||
else if (map.nodeCount == 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
GSIMapEnumerator_t enumerator;
|
||||
|
@ -360,17 +373,23 @@ static Class mutableSetClass;
|
|||
{
|
||||
return NO;
|
||||
}
|
||||
else if (map.nodeCount == 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
GSIMapEnumerator_t enumerator;
|
||||
GSIMapNode node;
|
||||
IMP imp;
|
||||
|
||||
imp = [other methodForSelector: memberSel];
|
||||
enumerator = GSIMapEnumeratorForMap(&map);
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
|
||||
while (node != 0)
|
||||
{
|
||||
if ([other member: node->key.obj] == nil)
|
||||
if ((*imp)(other, memberSel, node->key.obj) == nil)
|
||||
{
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
return NO;
|
||||
|
|
Loading…
Reference in a new issue