Speed up lookup for GSOrderedSet by using a map.

This commit is contained in:
fredkiefer 2019-06-28 17:20:21 +02:00
parent 2a810e5bd9
commit b8f8d6a617

View file

@ -44,10 +44,18 @@
#import "GNUstepBase/GSIArray.h" #import "GNUstepBase/GSIArray.h"
#define GSI_MAP_HAS_VALUE 0
#define GSI_MAP_KTYPES GSUNION_OBJ
#define GSI_MAP_RETAIN_KEY(M, X)
#define GSI_MAP_RELEASE_KEY(M, X)
#include "GNUstepBase/GSIMap.h"
@interface GSOrderedSet : NSOrderedSet @interface GSOrderedSet : NSOrderedSet
{ {
@public @public
GSIArray_t array; GSIArray_t array;
GSIMapTable_t map;
} }
@end @end
@ -55,6 +63,7 @@
{ {
@public @public
GSIArray_t array; GSIArray_t array;
GSIMapTable_t map;
@private @private
NSUInteger _version; NSUInteger _version;
} }
@ -150,6 +159,7 @@ static Class mutableSetClass;
- (void) dealloc - (void) dealloc
{ {
GSIArrayEmpty(&array); GSIArrayEmpty(&array);
GSIMapEmptyMap(&map);
[super dealloc]; [super dealloc];
} }
@ -192,6 +202,20 @@ static Class mutableSetClass;
} }
// Put required overrides here... // Put required overrides here...
- (BOOL) containsObject: (id)anObject
{
if (anObject != nil)
{
GSIMapNode node = GSIMapNodeForKey(&map, (GSIMapKey)anObject);
if (node != 0)
{
return YES;
}
}
return NO;
}
- (NSUInteger) count - (NSUInteger) count
{ {
return GSIArrayCount(&array); return GSIArrayCount(&array);
@ -210,24 +234,27 @@ static Class mutableSetClass;
// Initialize and fill the set. // Initialize and fill the set.
GSIArrayInitWithZoneAndCapacity(&array, [self zone], c); GSIArrayInitWithZoneAndCapacity(&array, [self zone], c);
GSIMapInitWithZoneAndCapacity(&map, [self zone], c);
for (i = 0; i < c; i++) for (i = 0; i < c; i++)
{ {
id obj = objs[i]; id obj = objs[i];
GSIArrayItem item;
if (objs[i] == nil) if (obj == nil)
{ {
DESTROY(self); DESTROY(self);
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
format: @"Tried to init set with nil value"]; format: @"Tried to init set with nil value"];
} }
item.obj = obj;
if (![self containsObject: obj]) if (![self containsObject: obj])
{ {
GSIArrayItem item;
item.obj = obj;
GSIArrayAddItem(&array, item); GSIArrayAddItem(&array, item);
GSIMapAddKey(&map, (GSIMapKey)obj);
} }
} }
return self; return self;
} }
@ -245,7 +272,6 @@ static Class mutableSetClass;
- (void) insertObject: (id)object atIndex: (NSUInteger)index - (void) insertObject: (id)object atIndex: (NSUInteger)index
{ {
GSIArrayItem item;
if (object == nil) if (object == nil)
{ {
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
@ -255,8 +281,12 @@ static Class mutableSetClass;
{ {
if ([self containsObject: object] == NO) if ([self containsObject: object] == NO)
{ {
GSIArrayItem item;
_version++;
item.obj = object; item.obj = object;
GSIArrayInsertItem(&array, item, index); GSIArrayInsertItem(&array, item, index);
GSIMapAddKey(&map, (GSIMapKey)object);
_version++; _version++;
} }
} }
@ -264,8 +294,12 @@ static Class mutableSetClass;
- (void) removeObjectAtIndex: (NSUInteger)index - (void) removeObjectAtIndex: (NSUInteger)index
{ {
GSIArrayItem item = GSIArrayItemAtIndex(&array, index);
_version++; _version++;
GSIArrayRemoveItemAtIndex(&array, index); GSIArrayRemoveItemAtIndex(&array, index);
GSIMapRemoveKey(&map, (GSIMapKey)item.obj);
_version++;
} }
- (id) init - (id) init
@ -277,6 +311,7 @@ static Class mutableSetClass;
- (id) initWithCapacity: (NSUInteger)cap - (id) initWithCapacity: (NSUInteger)cap
{ {
GSIArrayInitWithZoneAndCapacity(&array, [self zone], cap); GSIArrayInitWithZoneAndCapacity(&array, [self zone], cap);
GSIMapInitWithZoneAndCapacity(&map, [self zone], cap);
return self; return self;
} }