mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 08:21:25 +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
46b480c41d
commit
6da6e5b251
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>
|
2003-02-15 15:53 Alexander Malmberg <alexander@malmberg.org>
|
||||||
|
|
||||||
* Source/NSRunLoop.m (-performSelector:target:argument:order:modes:):
|
* Source/NSRunLoop.m (-performSelector:target:argument:order:modes:):
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <Foundation/NSDebug.h>
|
#include <Foundation/NSDebug.h>
|
||||||
|
|
||||||
static SEL eqSel;
|
static SEL eqSel;
|
||||||
|
static SEL oaiSel;
|
||||||
|
|
||||||
static Class GSInlineArrayClass;
|
static Class GSInlineArrayClass;
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ static Class GSInlineArrayClass;
|
||||||
{
|
{
|
||||||
[self setVersion: 1];
|
[self setVersion: 1];
|
||||||
eqSel = @selector(isEqual:);
|
eqSel = @selector(isEqual:);
|
||||||
|
oaiSel = @selector(objectAtIndex:);
|
||||||
GSInlineArrayClass = [GSInlineArray class];
|
GSInlineArrayClass = [GSInlineArray class];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,6 +228,33 @@ static Class GSInlineArrayClass;
|
||||||
return NSNotFound;
|
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
|
- (id) lastObject
|
||||||
{
|
{
|
||||||
if (_count)
|
if (_count)
|
||||||
|
|
|
@ -244,6 +244,42 @@ static SEL objSel;
|
||||||
return self;
|
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
|
- (NSEnumerator*) keyEnumerator
|
||||||
{
|
{
|
||||||
return AUTORELEASE([[GSDictionaryKeyEnumerator allocWithZone:
|
return AUTORELEASE([[GSDictionaryKeyEnumerator allocWithZone:
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
|
|
||||||
#include <base/GSIMap.h>
|
#include <base/GSIMap.h>
|
||||||
|
|
||||||
|
static SEL memberSel;
|
||||||
|
|
||||||
@interface GSSet : NSSet
|
@interface GSSet : NSSet
|
||||||
{
|
{
|
||||||
@public
|
@public
|
||||||
|
@ -107,6 +109,7 @@ static Class mutableSetClass;
|
||||||
arrayClass = [NSArray class];
|
arrayClass = [NSArray class];
|
||||||
setClass = [GSSet class];
|
setClass = [GSSet class];
|
||||||
mutableSetClass = [GSMutableSet class];
|
mutableSetClass = [GSMutableSet class];
|
||||||
|
memberSel = @selector(member:);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,13 +286,19 @@ static Class mutableSetClass;
|
||||||
{
|
{
|
||||||
GSIMapEnumerator_t enumerator;
|
GSIMapEnumerator_t enumerator;
|
||||||
GSIMapNode node;
|
GSIMapNode node;
|
||||||
|
IMP imp;
|
||||||
|
|
||||||
// -1. members of this set(self) <= that of otherSet
|
// -1. members of this set(self) <= that of otherSet
|
||||||
if (map.nodeCount > [otherSet count])
|
if (map.nodeCount > [otherSet count])
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
if (map.nodeCount == 0)
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
imp = [otherSet methodForSelector: memberSel];
|
||||||
enumerator = GSIMapEnumeratorForMap(&map);
|
enumerator = GSIMapEnumeratorForMap(&map);
|
||||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||||
|
|
||||||
|
@ -297,7 +306,7 @@ static Class mutableSetClass;
|
||||||
while (node != 0)
|
while (node != 0)
|
||||||
{
|
{
|
||||||
// 1. check the member is in the otherSet.
|
// 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.
|
// 1.1 if true -> continue, try to check the next member.
|
||||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||||
|
@ -334,6 +343,10 @@ static Class mutableSetClass;
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
else if (map.nodeCount == 0)
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GSIMapEnumerator_t enumerator;
|
GSIMapEnumerator_t enumerator;
|
||||||
|
@ -360,17 +373,23 @@ static Class mutableSetClass;
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
else if (map.nodeCount == 0)
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GSIMapEnumerator_t enumerator;
|
GSIMapEnumerator_t enumerator;
|
||||||
GSIMapNode node;
|
GSIMapNode node;
|
||||||
|
IMP imp;
|
||||||
|
|
||||||
|
imp = [other methodForSelector: memberSel];
|
||||||
enumerator = GSIMapEnumeratorForMap(&map);
|
enumerator = GSIMapEnumeratorForMap(&map);
|
||||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||||
|
|
||||||
while (node != 0)
|
while (node != 0)
|
||||||
{
|
{
|
||||||
if ([other member: node->key.obj] == nil)
|
if ((*imp)(other, memberSel, node->key.obj) == nil)
|
||||||
{
|
{
|
||||||
GSIMapEndEnumerator(&enumerator);
|
GSIMapEndEnumerator(&enumerator);
|
||||||
return NO;
|
return NO;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue