mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Fix the case where we replace a value already in the map
This commit is contained in:
parent
b78b2e2030
commit
28ba7788ce
4 changed files with 84 additions and 11 deletions
|
@ -457,11 +457,20 @@ NSHashInsert(NSHashTable *table, const void *element)
|
|||
GSIMapAddKey(t, (GSIMapKey)element);
|
||||
((NSConcreteHashTable*)table)->version++;
|
||||
}
|
||||
else if (element != n->key.ptr)
|
||||
{
|
||||
GSI_MAP_RELEASE_KEY(t, n->key);
|
||||
n->key = (GSIMapKey)element;
|
||||
GSI_MAP_RETAIN_KEY(t, n->key);
|
||||
else if (GSI_MAP_READ_KEY(t, &n->key).ptr != element)
|
||||
{
|
||||
if (t->legacy)
|
||||
{
|
||||
t->cb.old.release(t, n->key.ptr);
|
||||
n->key = (GSIMapKey)element;
|
||||
t->cb.old.retain(t, n->key.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerFunctionsRelinquish(&t->cb.pf, (void**)&n->key);
|
||||
pointerFunctionsReplace(&t->cb.pf, (void**)&n->key,
|
||||
(void*)element);
|
||||
}
|
||||
((NSConcreteHashTable*)table)->version++;
|
||||
}
|
||||
}
|
||||
|
@ -854,11 +863,19 @@ const NSHashTableCallBacks NSPointerToStructHashCallBacks =
|
|||
GSIMapAddKey(t, (GSIMapKey)anObject);
|
||||
version++;
|
||||
}
|
||||
else if (n->key.obj != anObject)
|
||||
else if (GSI_MAP_READ_KEY(t, &n->key).ptr != anObject)
|
||||
{
|
||||
GSI_MAP_RELEASE_KEY(t, n->key);
|
||||
n->key = (GSIMapKey)anObject;
|
||||
GSI_MAP_RETAIN_KEY(t, n->key);
|
||||
if (t->legacy)
|
||||
{
|
||||
t->cb.old.release(t, n->key.ptr);
|
||||
n->key.ptr = anObject;
|
||||
t->cb.old.retain(t, n->key.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerFunctionsRelinquish(&t->cb.pf, (void**)&n->key);
|
||||
pointerFunctionsReplace(&t->cb.pf, (void**)&n->key, (void*)anObject);
|
||||
}
|
||||
version++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -641,7 +641,18 @@ NSMapInsert(NSMapTable *table, const void *key, const void *value)
|
|||
}
|
||||
else if (GSI_MAP_READ_VALUE(t, &n->value).ptr != value)
|
||||
{
|
||||
GSI_MAP_STORE_VALUE(t, &n->value, (GSIMapVal)value);
|
||||
if (t->legacy)
|
||||
{
|
||||
t->cb.old.v.release(t, n->value.ptr);
|
||||
n->value = (GSIMapVal)value;
|
||||
t->cb.old.v.retain(t, n->value.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerFunctionsRelinquish(&t->cb.pf.v, (void**)&n->value);
|
||||
pointerFunctionsReplace(&t->cb.pf.v, (void**)&n->value,
|
||||
(void*)value);
|
||||
}
|
||||
t->version++;
|
||||
}
|
||||
}
|
||||
|
@ -1380,7 +1391,18 @@ const NSMapTableValueCallBacks NSOwnedPointerMapValueCallBacks =
|
|||
{
|
||||
if (GSI_MAP_READ_VALUE(self, &node->value).obj != anObject)
|
||||
{
|
||||
GSI_MAP_STORE_VALUE(self, &node->value, (GSIMapVal)anObject);
|
||||
if (self->legacy)
|
||||
{
|
||||
self->cb.old.v.release(self, node->value.ptr);
|
||||
node->value = (GSIMapVal)anObject;
|
||||
self->cb.old.v.retain(self, node->value.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
pointerFunctionsRelinquish(&self->cb.pf.v, (void**)&node->value);
|
||||
pointerFunctionsReplace(&self->cb.pf.v, (void**)&node->value,
|
||||
(void*)anObject);
|
||||
}
|
||||
version++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
@end
|
||||
|
||||
@implementation MyClass
|
||||
- (NSUInteger) hash
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
- (BOOL) isEqual: (id)other
|
||||
{
|
||||
return [other isKindOfClass: [self class]];
|
||||
}
|
||||
#if 0
|
||||
- (oneway void) release
|
||||
{
|
||||
|
@ -27,6 +35,7 @@ int main()
|
|||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||
NSHashTable *t;
|
||||
MyClass *o;
|
||||
MyClass *o2;
|
||||
int c;
|
||||
|
||||
t = [[NSHashTable alloc] initWithOptions: NSHashTableObjectPointerPersonality
|
||||
|
@ -63,8 +72,17 @@ int main()
|
|||
[t removeObject: o];
|
||||
PASS([o retainCount] == c, "remove from hash table decrements retain count")
|
||||
|
||||
o2 = [MyClass new];
|
||||
PASS([o2 retainCount] == 1, "initial retain count of second object OK")
|
||||
|
||||
[t addObject: o];
|
||||
[t addObject: o2];
|
||||
PASS([o retainCount] == 1, "first object was removed")
|
||||
PASS([o2 retainCount] == 2, "second object was added")
|
||||
|
||||
RELEASE(t);
|
||||
RELEASE(o);
|
||||
RELEASE(o2);
|
||||
|
||||
[arp release]; arp = nil;
|
||||
return 0;
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
@end
|
||||
|
||||
@implementation MyClass
|
||||
- (NSUInteger) hash
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
- (BOOL) isEqual: (id)other
|
||||
{
|
||||
return [other isKindOfClass: [self class]];
|
||||
}
|
||||
#if 0
|
||||
- (oneway void) release
|
||||
{
|
||||
|
@ -27,6 +35,7 @@ int main()
|
|||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||
NSMapTable *t;
|
||||
MyClass *o;
|
||||
MyClass *o2;
|
||||
int c;
|
||||
|
||||
t = [[NSMapTable alloc] initWithKeyOptions: NSMapTableObjectPointerPersonality
|
||||
|
@ -78,8 +87,15 @@ int main()
|
|||
[t removeObjectForKey: @"a"];
|
||||
PASS([o retainCount] == c, "remove map table val decrements retain count")
|
||||
|
||||
[t setObject: o forKey: @"a"];
|
||||
o2 = [MyClass new];
|
||||
[t setObject: o2 forKey: @"a"];
|
||||
PASS([o retainCount] == 1, "old instance removed")
|
||||
PASS([o2 retainCount] == 2, "new instance added")
|
||||
|
||||
RELEASE(t);
|
||||
RELEASE(o);
|
||||
RELEASE(o2);
|
||||
|
||||
[arp release]; arp = nil;
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue