From 5904279ebde364d8fce42f1a3dd60313643518ad Mon Sep 17 00:00:00 2001 From: Thomas Van Lenten Date: Mon, 19 Sep 2016 13:07:25 -0400 Subject: Remove the custom key functions and just use the system provided defaults. --- objectivec/GPBUnknownFieldSet.m | 43 +++-------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/objectivec/GPBUnknownFieldSet.m b/objectivec/GPBUnknownFieldSet.m index 9ba1d65c..a7335f05 100644 --- a/objectivec/GPBUnknownFieldSet.m +++ b/objectivec/GPBUnknownFieldSet.m @@ -36,39 +36,6 @@ #import "GPBUtilities.h" #import "GPBWireFormat.h" -#pragma mark CFDictionaryKeyCallBacks - -// We use a custom dictionary here because our keys are numbers and -// conversion back and forth from NSNumber was costing us performance. -// If/when we move to C++ this could be done using a std::map and some -// careful retain/release calls. - -static const void *GPBUnknownFieldSetKeyRetain(CFAllocatorRef allocator, - const void *value) { -#pragma unused(allocator) - return value; -} - -static void GPBUnknownFieldSetKeyRelease(CFAllocatorRef allocator, - const void *value) { -#pragma unused(allocator) -#pragma unused(value) -} - -static CFStringRef GPBUnknownFieldSetCopyKeyDescription(const void *value) { - return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), - (int)value); -} - -static Boolean GPBUnknownFieldSetKeyEqual(const void *value1, - const void *value2) { - return value1 == value2; -} - -static CFHashCode GPBUnknownFieldSetKeyHash(const void *value) { - return (CFHashCode)value; -} - #pragma mark Helpers static void checkNumber(int32_t number) { @@ -291,13 +258,9 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key, int32_t number = [field number]; checkNumber(number); if (!fields_) { - CFDictionaryKeyCallBacks keyCallBacks = { - // See description above for reason for using custom dictionary. - 0, GPBUnknownFieldSetKeyRetain, GPBUnknownFieldSetKeyRelease, - GPBUnknownFieldSetCopyKeyDescription, GPBUnknownFieldSetKeyEqual, - GPBUnknownFieldSetKeyHash, - }; - fields_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallBacks, + // Use a custom dictionary here because the keys are numbers and conversion + // back and forth from NSNumber isn't worth the cost. + fields_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks); } ssize_t key = number; -- cgit v1.2.3 From 6ab51a0ebdddd10dc78c8fc30c06878b96356416 Mon Sep 17 00:00:00 2001 From: Thomas Van Lenten Date: Mon, 19 Sep 2016 13:09:22 -0400 Subject: Use a custom dictionary to avoid NSNumber operations. For the secondary dictionary, use a custom CFDictionary with integer keys to avoid the NSNumber conversions. --- objectivec/GPBExtensionRegistry.m | 47 ++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/objectivec/GPBExtensionRegistry.m b/objectivec/GPBExtensionRegistry.m index 01eb761f..65534b67 100644 --- a/objectivec/GPBExtensionRegistry.m +++ b/objectivec/GPBExtensionRegistry.m @@ -34,8 +34,6 @@ #import "GPBDescriptor.h" @implementation GPBExtensionRegistry { - // TODO(dmaclach): Reimplement with CFDictionaries that don't use - // objects as keys. NSMutableDictionary *mutableClassMap_; } @@ -65,13 +63,16 @@ return result; } -- (NSMutableDictionary *)extensionMapForContainingMessageClass: +- (CFMutableDictionaryRef)extensionMapForContainingMessageClass: (Class)containingMessageClass { - NSMutableDictionary *extensionMap = + CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef) [mutableClassMap_ objectForKey:containingMessageClass]; if (extensionMap == nil) { - extensionMap = [NSMutableDictionary dictionary]; - [mutableClassMap_ setObject:extensionMap + // Use a custom dictionary here because the keys are numbers and conversion + // back and forth from NSNumber isn't worth the cost. + extensionMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, + &kCFTypeDictionaryValueCallBacks); + [mutableClassMap_ setObject:(id)extensionMap forKey:(id)containingMessageClass]; } return extensionMap; @@ -83,17 +84,28 @@ } Class containingMessageClass = extension.containingMessageClass; - NSMutableDictionary *extensionMap = + CFMutableDictionaryRef extensionMap = [self extensionMapForContainingMessageClass:containingMessageClass]; - [extensionMap setObject:extension forKey:@(extension.fieldNumber)]; + ssize_t key = extension.fieldNumber; + CFDictionarySetValue(extensionMap, (const void *)key, extension); } - (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor fieldNumber:(NSInteger)fieldNumber { Class messageClass = descriptor.messageClass; - NSDictionary *extensionMap = + CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef) [mutableClassMap_ objectForKey:messageClass]; - return [extensionMap objectForKey:@(fieldNumber)]; + ssize_t key = fieldNumber; + GPBExtensionDescriptor *result = + (extensionMap + ? CFDictionaryGetValue(extensionMap, (const void *)key) + : nil); + return result; +} + +static void CopyKeyValue(const void *key, const void *value, void *context) { + CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)context; + CFDictionarySetValue(extensionMap, key, value); } - (void)addExtensions:(GPBExtensionRegistry *)registry { @@ -102,13 +114,16 @@ return; } NSMutableDictionary *otherClassMap = registry->mutableClassMap_; - for (Class containingMessageClass in otherClassMap) { - NSMutableDictionary *extensionMap = + [otherClassMap enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL * stop) { +#pragma unused(stop) + Class containingMessageClass = key; + CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value; + + CFMutableDictionaryRef extensionMap = [self extensionMapForContainingMessageClass:containingMessageClass]; - NSMutableDictionary *otherExtensionMap = - [registry extensionMapForContainingMessageClass:containingMessageClass]; - [extensionMap addEntriesFromDictionary:otherExtensionMap]; - } + + CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap); + }]; } #pragma clang diagnostic pop -- cgit v1.2.3