mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +00:00
Corrected [-hash] implementations.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3123 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
af846fdfd3
commit
c1befc7b44
8 changed files with 502 additions and 324 deletions
|
@ -37,57 +37,63 @@
|
|||
* instances of the string classes we know about!
|
||||
*/
|
||||
typedef struct {
|
||||
Class *isa;
|
||||
char *_contents_chars;
|
||||
int _count;
|
||||
NSZone *_zone;
|
||||
unsigned _hash;
|
||||
Class *isa;
|
||||
char *_contents_chars;
|
||||
int _count;
|
||||
NSZone *_zone;
|
||||
unsigned _hash;
|
||||
} *dictAccessToStringHack;
|
||||
|
||||
static INLINE unsigned
|
||||
myHash(NSObject *obj)
|
||||
myHash(id obj)
|
||||
{
|
||||
if (fastIsInstance(obj)) {
|
||||
Class c = fastClass(obj);
|
||||
if (fastIsInstance(obj))
|
||||
{
|
||||
Class c = fastClass(obj);
|
||||
|
||||
if (c == _fastCls._NXConstantString ||
|
||||
c == _fastCls._NSGCString ||
|
||||
c == _fastCls._NSGMutableCString ||
|
||||
c == _fastCls._NSGString ||
|
||||
c == _fastCls._NSGMutableString) {
|
||||
|
||||
if (((dictAccessToStringHack)obj)->_hash == 0) {
|
||||
((dictAccessToStringHack)obj)->_hash =
|
||||
if (c == _fastCls._NXConstantString ||
|
||||
c == _fastCls._NSGCString ||
|
||||
c == _fastCls._NSGMutableCString ||
|
||||
c == _fastCls._NSGString ||
|
||||
c == _fastCls._NSGMutableString)
|
||||
{
|
||||
if (((dictAccessToStringHack)obj)->_hash == 0)
|
||||
{
|
||||
((dictAccessToStringHack)obj)->_hash =
|
||||
_fastImp._NSString_hash(obj, @selector(hash));
|
||||
}
|
||||
return ((dictAccessToStringHack)obj)->_hash;
|
||||
return ((dictAccessToStringHack)obj)->_hash;
|
||||
}
|
||||
}
|
||||
return [obj hash];
|
||||
return [obj hash];
|
||||
}
|
||||
|
||||
static INLINE BOOL
|
||||
myEqual(NSObject *self, NSObject *other)
|
||||
myEqual(id self, id other)
|
||||
{
|
||||
if (self == other) {
|
||||
return YES;
|
||||
if (self == other)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
if (fastIsInstance(self)) {
|
||||
Class c = fastClass(self);
|
||||
if (fastIsInstance(self))
|
||||
{
|
||||
Class c = fastClass(self);
|
||||
|
||||
if (c == _fastCls._NXConstantString ||
|
||||
c == _fastCls._NSGCString ||
|
||||
c == _fastCls._NSGMutableCString) {
|
||||
return _fastImp._NSGCString_isEqual_(self,
|
||||
if (c == _fastCls._NXConstantString ||
|
||||
c == _fastCls._NSGCString ||
|
||||
c == _fastCls._NSGMutableCString)
|
||||
{
|
||||
return _fastImp._NSGCString_isEqual_(self,
|
||||
@selector(isEqual:), other);
|
||||
}
|
||||
if (c == _fastCls._NSGString ||
|
||||
c == _fastCls._NSGMutableString) {
|
||||
return _fastImp._NSGString_isEqual_(self,
|
||||
if (c == _fastCls._NSGString ||
|
||||
c == _fastCls._NSGMutableString)
|
||||
{
|
||||
return _fastImp._NSGString_isEqual_(self,
|
||||
@selector(isEqual:), other);
|
||||
}
|
||||
}
|
||||
return [self isEqual: other];
|
||||
return [self isEqual: other];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -106,21 +112,21 @@ myEqual(NSObject *self, NSObject *other)
|
|||
@interface NSGDictionary : NSDictionary
|
||||
{
|
||||
@public
|
||||
FastMapTable_t map;
|
||||
FastMapTable_t map;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface NSGMutableDictionary : NSMutableDictionary
|
||||
{
|
||||
@public
|
||||
FastMapTable_t map;
|
||||
FastMapTable_t map;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface NSGDictionaryKeyEnumerator : NSEnumerator
|
||||
{
|
||||
NSGDictionary *dictionary;
|
||||
FastMapNode node;
|
||||
NSGDictionary *dictionary;
|
||||
FastMapNode node;
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -131,112 +137,182 @@ myEqual(NSObject *self, NSObject *other)
|
|||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSGDictionary class]) {
|
||||
behavior_class_add_class(self, [NSDictionaryNonCore class]);
|
||||
if (self == [NSGDictionary class])
|
||||
{
|
||||
behavior_class_add_class(self, [NSDictionaryNonCore class]);
|
||||
}
|
||||
}
|
||||
|
||||
- (unsigned) count
|
||||
{
|
||||
return map.nodeCount;
|
||||
return map.nodeCount;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
FastMapEmptyMap(&map);
|
||||
[super dealloc];
|
||||
FastMapEmptyMap(&map);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
unsigned count = map.nodeCount;
|
||||
FastMapNode node = map.firstNode;
|
||||
SEL sel = @selector(encodeObject:);
|
||||
IMP imp = [aCoder methodForSelector: sel];
|
||||
unsigned count = map.nodeCount;
|
||||
FastMapNode node = map.firstNode;
|
||||
SEL sel = @selector(encodeObject:);
|
||||
IMP imp = [aCoder methodForSelector: sel];
|
||||
|
||||
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
|
||||
while (node != 0) {
|
||||
(*imp)(aCoder, sel, node->key.o);
|
||||
(*imp)(aCoder, sel, node->value.o);
|
||||
node = node->nextInMap;
|
||||
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
|
||||
while (node != 0)
|
||||
{
|
||||
(*imp)(aCoder, sel, node->key.o);
|
||||
(*imp)(aCoder, sel, node->value.o);
|
||||
node = node->nextInMap;
|
||||
}
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
{
|
||||
return map.nodeCount;
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
unsigned count;
|
||||
id key;
|
||||
id value;
|
||||
SEL sel = @selector(decodeValueOfObjCType:at:);
|
||||
IMP imp = [aCoder methodForSelector: sel];
|
||||
const char *type = @encode(id);
|
||||
unsigned count;
|
||||
id key;
|
||||
id value;
|
||||
SEL sel = @selector(decodeValueOfObjCType:at:);
|
||||
IMP imp = [aCoder methodForSelector: sel];
|
||||
const char *type = @encode(id);
|
||||
|
||||
[aCoder decodeValueOfObjCType: @encode(unsigned)
|
||||
at: &count];
|
||||
[aCoder decodeValueOfObjCType: @encode(unsigned)
|
||||
at: &count];
|
||||
|
||||
FastMapInitWithZoneAndCapacity(&map, fastZone(self), count);
|
||||
while (count-- > 0) {
|
||||
(*imp)(aCoder, sel, type, &key);
|
||||
(*imp)(aCoder, sel, type, &value);
|
||||
FastMapAddPairNoRetain(&map, (FastMapItem)key, (FastMapItem)value);
|
||||
FastMapInitWithZoneAndCapacity(&map, fastZone(self), count);
|
||||
while (count-- > 0)
|
||||
{
|
||||
(*imp)(aCoder, sel, type, &key);
|
||||
(*imp)(aCoder, sel, type, &value);
|
||||
FastMapAddPairNoRetain(&map, (FastMapItem)key, (FastMapItem)value);
|
||||
}
|
||||
return self;
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Designated initialiser */
|
||||
- (id) initWithObjects: (id*)objs forKeys: (NSObject**)keys count: (unsigned)c
|
||||
- (id) initWithObjects: (id*)objs forKeys: (id*)keys count: (unsigned)c
|
||||
{
|
||||
int i;
|
||||
FastMapInitWithZoneAndCapacity(&map, fastZone(self), c);
|
||||
for (i = 0; i < c; i++) {
|
||||
FastMapNode node;
|
||||
int i;
|
||||
|
||||
if (keys[i] == nil) {
|
||||
[self autorelease];
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to init dictionary with nil key"];
|
||||
FastMapInitWithZoneAndCapacity(&map, fastZone(self), c);
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
FastMapNode node;
|
||||
|
||||
if (keys[i] == nil)
|
||||
{
|
||||
[self autorelease];
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to init dictionary with nil key"];
|
||||
}
|
||||
if (objs[i] == nil) {
|
||||
[self autorelease];
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to init dictionary with nil value"];
|
||||
if (objs[i] == nil)
|
||||
{
|
||||
[self autorelease];
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to init dictionary with nil value"];
|
||||
}
|
||||
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)keys[i]);
|
||||
if (node) {
|
||||
[objs[i] retain];
|
||||
[node->value.o release];
|
||||
node->value.o = objs[i];
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)keys[i]);
|
||||
if (node)
|
||||
{
|
||||
[objs[i] retain];
|
||||
[node->value.o release];
|
||||
node->value.o = objs[i];
|
||||
}
|
||||
else {
|
||||
FastMapAddPair(&map, (FastMapItem)keys[i], (FastMapItem)objs[i]);
|
||||
else
|
||||
{
|
||||
FastMapAddPair(&map, (FastMapItem)keys[i], (FastMapItem)objs[i]);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* This avoids using the designated initialiser for performance reasons.
|
||||
*/
|
||||
- (id) initWithDictionary: (NSDictionary*)other
|
||||
copyItems: (BOOL)shouldCopy
|
||||
{
|
||||
NSEnumerator *e = [other keyEnumerator];
|
||||
NSZone *z = fastZone(self);
|
||||
unsigned c = [other count];
|
||||
unsigned i;
|
||||
|
||||
FastMapInitWithZoneAndCapacity(&map, z, c);
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
FastMapNode node;
|
||||
id k = [e nextObject];
|
||||
id o = [other objectForKey: k];
|
||||
|
||||
k = [k copyWithZone: z];
|
||||
if (k == nil)
|
||||
{
|
||||
[self autorelease];
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to init dictionary with nil key"];
|
||||
}
|
||||
if (shouldCopy)
|
||||
{
|
||||
o = [o copyWithZone: z];
|
||||
}
|
||||
else
|
||||
{
|
||||
o = [o retain];
|
||||
}
|
||||
if (o == nil)
|
||||
{
|
||||
[self autorelease];
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to init dictionary with nil value"];
|
||||
}
|
||||
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)k);
|
||||
if (node)
|
||||
{
|
||||
[node->value.o release];
|
||||
node->value.o = o;
|
||||
}
|
||||
else
|
||||
{
|
||||
FastMapAddPairNoRetain(&map, (FastMapItem)k, (FastMapItem)o);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSEnumerator*) keyEnumerator
|
||||
{
|
||||
return [[[NSGDictionaryKeyEnumerator alloc] initWithDictionary: self]
|
||||
return [[[NSGDictionaryKeyEnumerator alloc] initWithDictionary: self]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
- (NSEnumerator*) objectEnumerator
|
||||
{
|
||||
return [[[NSGDictionaryObjectEnumerator alloc] initWithDictionary: self]
|
||||
return [[[NSGDictionaryObjectEnumerator alloc] initWithDictionary: self]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
- (id) objectForKey: aKey
|
||||
{
|
||||
if (aKey != nil) {
|
||||
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)aKey);
|
||||
if (aKey != nil)
|
||||
{
|
||||
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)aKey);
|
||||
|
||||
if (node) {
|
||||
return node->value.o;
|
||||
if (node)
|
||||
{
|
||||
return node->value.o;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -245,51 +321,57 @@ myEqual(NSObject *self, NSObject *other)
|
|||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSGMutableDictionary class]) {
|
||||
behavior_class_add_class(self, [NSMutableDictionaryNonCore class]);
|
||||
behavior_class_add_class(self, [NSGDictionary class]);
|
||||
if (self == [NSGMutableDictionary class])
|
||||
{
|
||||
behavior_class_add_class(self, [NSMutableDictionaryNonCore class]);
|
||||
behavior_class_add_class(self, [NSGDictionary class]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Designated initialiser */
|
||||
- (id) initWithCapacity: (unsigned)cap
|
||||
{
|
||||
FastMapInitWithZoneAndCapacity(&map, fastZone(self), cap);
|
||||
return self;
|
||||
FastMapInitWithZoneAndCapacity(&map, fastZone(self), cap);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setObject: (NSObject*)anObject forKey: (NSObject *)aKey
|
||||
- (void) setObject: (id)anObject forKey: (id)aKey
|
||||
{
|
||||
FastMapNode node;
|
||||
FastMapNode node;
|
||||
|
||||
if (aKey == nil) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to add nil key to dictionary"];
|
||||
if (aKey == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to add nil key to dictionary"];
|
||||
}
|
||||
if (anObject == nil) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to add nil value to dictionary"];
|
||||
if (anObject == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to add nil value to dictionary"];
|
||||
}
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)aKey);
|
||||
if (node) {
|
||||
[anObject retain];
|
||||
[node->value.o release];
|
||||
node->value.o = anObject;
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)aKey);
|
||||
if (node)
|
||||
{
|
||||
[anObject retain];
|
||||
[node->value.o release];
|
||||
node->value.o = anObject;
|
||||
}
|
||||
else {
|
||||
FastMapAddPair(&map, (FastMapItem)aKey, (FastMapItem)anObject);
|
||||
else
|
||||
{
|
||||
FastMapAddPair(&map, (FastMapItem)aKey, (FastMapItem)anObject);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) removeAllObjects
|
||||
{
|
||||
FastMapCleanMap(&map);
|
||||
FastMapCleanMap(&map);
|
||||
}
|
||||
|
||||
- (void) removeObjectForKey: (NSObject *)aKey
|
||||
- (void) removeObjectForKey: (id)aKey
|
||||
{
|
||||
if (aKey) {
|
||||
FastMapRemoveKey(&map, (FastMapItem)aKey);
|
||||
if (aKey)
|
||||
{
|
||||
FastMapRemoveKey(&map, (FastMapItem)aKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,21 +381,22 @@ myEqual(NSObject *self, NSObject *other)
|
|||
|
||||
- (id) initWithDictionary: (NSDictionary*)d
|
||||
{
|
||||
[super init];
|
||||
dictionary = (NSGDictionary*)[d retain];
|
||||
node = dictionary->map.firstNode;
|
||||
return self;
|
||||
[super init];
|
||||
dictionary = (NSGDictionary*)[d retain];
|
||||
node = dictionary->map.firstNode;
|
||||
return self;
|
||||
}
|
||||
|
||||
- nextObject
|
||||
{
|
||||
FastMapNode old = node;
|
||||
FastMapNode old = node;
|
||||
|
||||
if (node == 0) {
|
||||
return nil;
|
||||
if (node == 0)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
node = node->nextInMap;
|
||||
return old->key.o;
|
||||
node = node->nextInMap;
|
||||
return old->key.o;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
|
@ -328,13 +411,14 @@ myEqual(NSObject *self, NSObject *other)
|
|||
|
||||
- nextObject
|
||||
{
|
||||
FastMapNode old = node;
|
||||
FastMapNode old = node;
|
||||
|
||||
if (node == 0) {
|
||||
return nil;
|
||||
if (node == 0)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
node = node->nextInMap;
|
||||
return old->value.o;
|
||||
node = node->nextInMap;
|
||||
return old->value.o;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue