Clean up interface to GSIMap

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8389 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2000-12-21 10:31:33 +00:00
parent 36457b0023
commit 012ba919ad
8 changed files with 187 additions and 131 deletions

View file

@ -2,6 +2,13 @@
* Headers/Foundation/GSIMap.h: On initialisation set number of nodes
to exactly equal capacity, for improved memory efficiency.
* Source/Makefile.postamble: correct dependencies for GSIMap.
* Source/GSCountedSet.m: Use map enumerator rather than messing with
the internals of a GSIMap directly.
* Source/GSSet.m: ditto
* Source/NSConnection.m: ditto
* Source/NSGDictionary.m: ditto
* Source/NSNotificationCenter.m: ditto
2000-12-18 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -566,25 +566,14 @@ GSIMapRightSizeMap(GSIMapTable map, size_t capacity)
* With that in mind, read the following warnings carefully. But
* remember, DON'T MESS WITH A MAP WHILE YOU'RE ENUMERATING IT. */
/* IMPORTANT WARNING: Map enumerators, as I have map them up, have a
* wonderous property. Namely, that, while enumerating, one may add
* new elements (i.e., new nodes) to the map while an enumeration is
* in progress (i.e., after `o_map_enumerator_for_map()' has been
* called), and the enumeration remains the same. */
/* WARNING: The above warning should not, in any way, be taken as
* assurance that this property of map enumerators will be preserved
* in future editions of the library. I'm still thinking about
* this. */
/* IMPORTANT WARNING: Enumerators have yet another wonderous property.
/* IMPORTANT WARNING: Enumerators have a wonderous property.
* Once a node has been returned by `GSIMapEnumeratorNextNode()', it may be
* removed from the map without effecting the rest of the current
* enumeration. */
/* EXTREMELY IMPORTANT WARNING: The purpose of this warning is point
* out that, at this time, various (i.e., many) functions depend on
* the behaviours outlined above. So be prepared for some serious
* the behaviour outlined above. So be prepared for some serious
* breakage when you go fudging around with these things. */
static INLINE GSIMapEnumerator_t

View file

@ -48,8 +48,8 @@
@interface GSCountedSetEnumerator : NSEnumerator
{
GSCountedSet *set;
GSIMapNode node;
GSCountedSet *set;
GSIMapEnumerator_t enumerator;
}
@end
@ -64,24 +64,23 @@
- (id) initWithSet: (NSSet*)d
{
self = [super init];
if (self)
if (self != nil)
{
set = RETAIN((GSCountedSet*)d);
node = set->map.firstNode;
enumerator = GSIMapEnumeratorForMap(&set->map);
}
return self;
}
- (id) nextObject
{
GSIMapNode old = node;
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
if (node == 0)
{
return nil;
}
node = node->nextInMap;
return old->key.obj;
return node->key.obj;
}
@end
@ -145,12 +144,13 @@
- (void) encodeWithCoder: (NSCoder*)aCoder
{
unsigned count = map.nodeCount;
GSIMapNode node = map.firstNode;
SEL sel1 = @selector(encodeObject:);
IMP imp1 = [aCoder methodForSelector: sel1];
SEL sel2 = @selector(encodeValueOfObjCType:at:);
IMP imp2 = [aCoder methodForSelector: sel2];
const char *type = @encode(unsigned);
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
(*imp2)(aCoder, sel2, type, &count);
@ -158,7 +158,7 @@
{
(*imp1)(aCoder, sel1, node->key.obj);
(*imp2)(aCoder, sel2, type, &node->value.uint);
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
@ -252,11 +252,12 @@
{
if (level > 0)
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
GSIMapNode tmp = node->nextInMap;
GSIMapNode next = GSIMapEnumeratorNextNode(&enumerator);
if (node->value.uint <= level)
{
@ -266,7 +267,7 @@
GSIMapRemoveNodeFromMap(&map, bucket, node);
GSIMapFreeNode(&map, node);
}
node = tmp;
node = next;
}
}
}

View file

@ -55,8 +55,8 @@
@interface GSSetEnumerator : NSEnumerator
{
GSSet *set;
GSIMapNode node;
GSSet *set;
GSIMapEnumerator_t enumerator;
}
@end
@ -68,21 +68,20 @@
if (self != nil)
{
set = (GSSet*)RETAIN(d);
node = set->map.firstNode;
enumerator = GSIMapEnumeratorForMap(&set->map);
}
return self;
}
- (id) nextObject
{
GSIMapNode old = node;
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
if (node == 0)
{
return nil;
}
node = node->nextInMap;
return old->key.obj;
return node->key.obj;
}
- (void) dealloc
@ -112,14 +111,15 @@ static Class mutableSetClass;
- (NSArray*) allObjects
{
id objs[map.nodeCount];
GSIMapNode node = map.firstNode;
unsigned i = 0;
id objs[map.nodeCount];
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
unsigned i = 0;
while (node != 0)
{
objs[i++] = node->key.obj;
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
return AUTORELEASE([[arrayClass allocWithZone: NSDefaultMallocZone()]
initWithObjects: objs count: i]);
@ -150,16 +150,17 @@ static Class mutableSetClass;
- (void) encodeWithCoder: (NSCoder*)aCoder
{
unsigned count = map.nodeCount;
GSIMapNode node = map.firstNode;
SEL sel = @selector(encodeObject:);
IMP imp = [aCoder methodForSelector: sel];
unsigned count = map.nodeCount;
SEL sel = @selector(encodeObject:);
IMP imp = [aCoder methodForSelector: sel];
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
while (node != 0)
{
(*imp)(aCoder, sel, node->key.obj);
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
@ -233,7 +234,9 @@ static Class mutableSetClass;
c = GSObjCClass(otherSet);
if (c == setClass || c == mutableSetClass)
{
GSIMapNode node = ((GSSet*)otherSet)->map.firstNode;
GSIMapTable m = &((GSSet*)otherSet)->map;
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(m);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
@ -241,7 +244,7 @@ static Class mutableSetClass;
{
return YES;
}
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
else
@ -263,7 +266,8 @@ static Class mutableSetClass;
- (BOOL) isSubsetOfSet: (NSSet*) otherSet
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
// -1. members of this set(self) <= that of otherSet
if (map.nodeCount > [otherSet count])
@ -271,20 +275,23 @@ static Class mutableSetClass;
return NO;
}
enumerator = GSIMapEnumeratorForMap(&map);
node = GSIMapEnumeratorNextNode(&enumerator);
// 0. Loop for all members in this set(self).
while (node != 0)
{
// 1. check the member is in the otherSet.
if ([otherSet member: node->key.obj])
{
// 1.1 if true -> continue, try to check the next member.
node = node->nextInMap;
}
{
// 1.1 if true -> continue, try to check the next member.
node = GSIMapEnumeratorNextNode(&enumerator);
}
else
{
// 1.2 if false -> return NO;
return NO;
}
{
// 1.2 if false -> return NO;
return NO;
}
}
// 2. return YES; all members in this set are also in the otherSet.
return YES;
@ -312,16 +319,19 @@ static Class mutableSetClass;
}
else
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
enumerator = GSIMapEnumeratorForMap(&map);
node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
if (GSIMapNodeForKey(&(((GSSet*)other)->map), node->key)
== 0)
if (GSIMapNodeForKey(&(((GSSet*)other)->map), node->key) == 0)
{
return NO;
}
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
}
@ -333,7 +343,11 @@ static Class mutableSetClass;
}
else
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
enumerator = GSIMapEnumeratorForMap(&map);
node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
@ -341,7 +355,7 @@ static Class mutableSetClass;
{
return NO;
}
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
}
@ -351,45 +365,49 @@ static Class mutableSetClass;
- (void) makeObjectsPerform: (SEL)aSelector
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
[node->key.obj performSelector: aSelector];
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
- (void) makeObjectsPerformSelector: (SEL)aSelector
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
[node->key.obj performSelector: aSelector];
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: argument
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
[node->key.obj performSelector: aSelector withObject: argument];
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
- (void) makeObjectsPerform: (SEL)aSelector withObject: argument
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
[node->key.obj performSelector: aSelector withObject: argument];
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
@ -505,11 +523,12 @@ static Class mutableSetClass;
{
if (other != self)
{
GSIMapNode node = map.firstNode;
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
GSIMapNode next = node->nextInMap;
GSIMapNode next = GSIMapEnumeratorNextNode(&enumerator);
if ([other containsObject: node->key.obj] == NO)
{

View file

@ -216,6 +216,7 @@ $(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
# Files that include GSIArray.h will need a rebuild if it is changed.
#
$(GNUSTEP_OBJ_DIR)/NSNotificationCenter.o \
$(GNUSTEP_OBJ_DIR)/NSPortCoder.o \
$(GNUSTEP_OBJ_DIR)/NSRunLoop.o \
$(GNUSTEP_OBJ_DIR)/NSSerializer.o \
$(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
@ -227,8 +228,11 @@ $(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
$(GNUSTEP_OBJ_DIR)/GSCountedSet.o \
$(GNUSTEP_OBJ_DIR)/GSSet.o \
$(GNUSTEP_OBJ_DIR)/NSArchiver.o \
$(GNUSTEP_OBJ_DIR)/NSConnection.o \
$(GNUSTEP_OBJ_DIR)/NSGAttributedString.o \
$(GNUSTEP_OBJ_DIR)/NSGDictionary.o \
$(GNUSTEP_OBJ_DIR)/NSNotificationCenter.o \
$(GNUSTEP_OBJ_DIR)/NSPortCoder.o \
$(GNUSTEP_OBJ_DIR)/NSSerializer.o \
: $(HEADER_DIR)/GSIMap.h $(HEADER_DIR)/GSUnion.h

View file

@ -950,14 +950,16 @@ static BOOL multi_threaded = NO;
{
NSMutableArray *targets;
unsigned i = _localTargets->nodeCount;
GSIMapNode node;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
targets = [[NSMutableArray alloc] initWithCapacity: i];
node = _localTargets->firstNode;
enumerator = GSIMapEnumeratorForMap(_localTargets);
node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
[targets addObject: node->value.obj];
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
while (i-- > 0)
{
@ -978,12 +980,16 @@ static BOOL multi_threaded = NO;
}
if (_localObjects != 0)
{
GSIMapNode node = _localObjects->firstNode;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
enumerator = GSIMapEnumeratorForMap(_localObjects);
node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
RELEASE(node->key.obj);
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEmptyMap(_localObjects);
NSZoneFree(_localObjects->zone, (void*)_localObjects);
@ -1007,13 +1013,17 @@ static BOOL multi_threaded = NO;
M_LOCK(_proxiesGate);
if (_localObjects != 0)
{
GSIMapNode node = _localObjects->firstNode;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
enumerator = GSIMapEnumeratorForMap(_localObjects);
node = GSIMapEnumeratorNextNode(&enumerator);
c = [NSMutableArray arrayWithCapacity: _localObjects->nodeCount];
while (node != 0)
{
[c addObject: node->key.obj];
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
else
@ -1086,13 +1096,17 @@ static BOOL multi_threaded = NO;
M_LOCK(_proxiesGate);
if (_remoteProxies != 0)
{
GSIMapNode node = _remoteProxies->firstNode;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
enumerator = GSIMapEnumeratorForMap(_remoteProxies);
node = GSIMapEnumeratorNextNode(&enumerator);
c = [NSMutableArray arrayWithCapacity: _remoteProxies->nodeCount];
while (node != 0)
{
[c addObject: node->key.obj];
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
else
@ -1363,13 +1377,19 @@ static BOOL multi_threaded = NO;
DESTROY(_requestQueue);
if (_replyMap != 0)
{
GSIMapNode node = _replyMap->firstNode;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
enumerator = GSIMapEnumeratorForMap(_replyMap);
node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
if (node->key.obj != dummyObject)
RELEASE(node->key.obj);
node = node->nextInMap;
{
RELEASE(node->key.obj);
}
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEmptyMap(_replyMap);
NSZoneFree(_replyMap->zone, (void*)_replyMap);

View file

@ -65,8 +65,8 @@
@interface NSGDictionaryKeyEnumerator : NSEnumerator
{
NSGDictionary *dictionary;
GSIMapNode node;
NSGDictionary *dictionary;
GSIMapEnumerator_t enumerator;
}
@end
@ -102,16 +102,17 @@ static SEL objSel;
- (void) encodeWithCoder: (NSCoder*)aCoder
{
unsigned count = map.nodeCount;
GSIMapNode node = map.firstNode;
SEL sel = @selector(encodeObject:);
IMP imp = [aCoder methodForSelector: sel];
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
while (node != 0)
{
(*imp)(aCoder, sel, node->key.obj);
(*imp)(aCoder, sel, node->value.obj);
node = node->nextInMap;
node = GSIMapEnumeratorNextNode(&enumerator);
}
}
@ -337,20 +338,19 @@ static SEL objSel;
{
[super init];
dictionary = (NSGDictionary*)RETAIN(d);
node = dictionary->map.firstNode;
enumerator = GSIMapEnumeratorForMap(&dictionary->map);
return self;
}
- (id) nextObject
{
GSIMapNode old = node;
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
if (node == 0)
{
return nil;
}
node = node->nextInMap;
return old->key.obj;
return node->key.obj;
}
- (void) dealloc
@ -365,14 +365,13 @@ static SEL objSel;
- (id) nextObject
{
GSIMapNode old = node;
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
if (node == 0)
{
return nil;
}
node = node->nextInMap;
return old->value.obj;
return node->value.obj;
}
@end

View file

@ -243,7 +243,8 @@ static void mapFree(NCTable *t, GSIMapTable m)
static void endNCTable(NCTable *t)
{
unsigned i;
unsigned i;
GSIMapEnumerator_t e0;
GSIMapNode n0;
Observation *l;
@ -261,11 +262,12 @@ static void endNCTable(NCTable *t)
/*
* Free lists of observations without notification names.
*/
n0 = t->nameless->firstNode;
e0 = GSIMapEnumeratorForMap(t->nameless);
n0 = GSIMapEnumeratorNextNode(&e0);
while (n0 != 0)
{
l = (Observation*)n0->value.ptr;
n0 = n0->nextInMap;
n0 = GSIMapEnumeratorNextNode(&e0);
listFree(l);
}
GSIMapEmptyMap(t->nameless);
@ -274,18 +276,20 @@ static void endNCTable(NCTable *t)
/*
* Free lists of observations keyed by name and observer.
*/
n0 = t->named->firstNode;
e0 = GSIMapEnumeratorForMap(t->named);
n0 = GSIMapEnumeratorNextNode(&e0);
while (n0 != 0)
{
GSIMapTable m = (GSIMapTable)n0->value.ptr;
GSIMapNode n1 = m->firstNode;
GSIMapTable m = (GSIMapTable)n0->value.ptr;
GSIMapEnumerator_t e1 = GSIMapEnumeratorForMap(m);
GSIMapNode n1 = GSIMapEnumeratorNextNode(&e1);
n0 = n0->nextInMap;
n0 = GSIMapEnumeratorNextNode(&e0);
while (n1 != 0)
{
l = (Observation*)n1->value.ptr;
n1 = n1->nextInMap;
n1 = GSIMapEnumeratorNextNode(&e1);
listFree(l);
}
GSIMapEmptyMap(m);
@ -295,7 +299,9 @@ static void endNCTable(NCTable *t)
NSZoneFree(NSDefaultMallocZone(), (void*)t->named);
for (i = 0; i < t->numChunks; i++)
NSZoneFree(NSDefaultMallocZone(), t->chunks[i]);
{
NSZoneFree(NSDefaultMallocZone(), t->chunks[i]);
}
for (i = 0; i < t->cacheIndex; i++)
{
GSIMapEmptyMap(t->cache[i]);
@ -692,7 +698,9 @@ static NSNotificationCenter *default_center = nil;
}
if (object != nil)
object = CHEATGC(object);
{
object = CHEATGC(object);
}
if (name == nil && object == nil)
{
@ -701,30 +709,33 @@ static NSNotificationCenter *default_center = nil;
if (name == nil)
{
GSIMapNode n;
GSIMapEnumerator_t e0;
GSIMapNode n0;
/*
* First try removing all named items set for this object.
*/
n = NAMED->firstNode;
while (n != 0)
e0 = GSIMapEnumeratorForMap(NAMED);
n0 = GSIMapEnumeratorNextNode(&e0);
while (n0 != 0)
{
GSIMapTable m = (GSIMapTable)n->value.ptr;
NSString *thisName = (NSString*)n->key.obj;
GSIMapNode n1;
GSIMapTable m = (GSIMapTable)n0->value.ptr;
NSString *thisName = (NSString*)n0->key.obj;
n = n->nextInMap;
n0 = GSIMapEnumeratorNextNode(&e0);
if (object == nil)
{
GSIMapEnumerator_t e1 = GSIMapEnumeratorForMap(m);
GSIMapNode n1 = GSIMapEnumeratorNextNode(&e1);
/*
* Nil object and nil name, so we step through all the maps
* keyed under the current name and remove all the objects
* that match the observer.
*/
n1 = m->firstNode;
while (n1 != 0)
{
GSIMapNode next = n1->nextInMap;
GSIMapNode next = GSIMapEnumeratorNextNode(&e1);
purgeMapNode(m, n1, observer);
n1 = next;
@ -732,6 +743,8 @@ static NSNotificationCenter *default_center = nil;
}
else
{
GSIMapNode n1;
/*
* Nil name, but non-nil object - we locate the map for the
* specified object, and remove all the items that match
@ -759,57 +772,61 @@ static NSNotificationCenter *default_center = nil;
*/
if (object == nil)
{
n = NAMELESS->firstNode;
while (n != 0)
e0 = GSIMapEnumeratorForMap(NAMELESS);
n0 = GSIMapEnumeratorNextNode(&e0);
while (n0 != 0)
{
GSIMapNode next = n->nextInMap;
GSIMapNode next = GSIMapEnumeratorNextNode(&e0);
purgeMapNode(NAMELESS, n, observer);
n = next;
purgeMapNode(NAMELESS, n0, observer);
n0 = next;
}
}
else
{
n = GSIMapNodeForSimpleKey(NAMELESS, (GSIMapKey)object);
if (n != 0)
n0 = GSIMapNodeForSimpleKey(NAMELESS, (GSIMapKey)object);
if (n0 != 0)
{
purgeMapNode(NAMELESS, n, observer);
purgeMapNode(NAMELESS, n0, observer);
}
}
}
else
{
GSIMapTable m;
GSIMapNode n;
GSIMapTable m;
GSIMapEnumerator_t e0;
GSIMapNode n0;
/*
* Locate the map table for this name.
*/
n = GSIMapNodeForKey(NAMED, (GSIMapKey)name);
if (n == 0)
n0 = GSIMapNodeForKey(NAMED, (GSIMapKey)name);
if (n0 == 0)
{
unlockNCTable(TABLE);
return; /* Nothing to do. */
}
m = (GSIMapTable)n->value.ptr;
m = (GSIMapTable)n0->value.ptr;
if (object == nil)
{
n = m->firstNode;
while (n != 0)
{
GSIMapNode next = n->nextInMap;
e0 = GSIMapEnumeratorForMap(m);
n0 = GSIMapEnumeratorNextNode(&e0);
purgeMapNode(m, n, observer);
n = next;
while (n0 != 0)
{
GSIMapNode next = GSIMapEnumeratorNextNode(&e0);
purgeMapNode(m, n0, observer);
n0 = next;
}
}
else
{
n = GSIMapNodeForSimpleKey(m, (GSIMapKey)object);
if (n != 0)
n0 = GSIMapNodeForSimpleKey(m, (GSIMapKey)object);
if (n0 != 0)
{
purgeMapNode(m, n, observer);
purgeMapNode(m, n0, observer);
}
}
if (m->nodeCount == 0)