aboutsummaryrefslogtreecommitdiff
path: root/objectivec
diff options
context:
space:
mode:
authorThomas Van Lenten <thomasvl@google.com>2016-09-19 13:09:22 -0400
committerThomas Van Lenten <thomasvl@google.com>2016-09-19 13:12:54 -0400
commit6ab51a0ebdddd10dc78c8fc30c06878b96356416 (patch)
tree783afef7bd6ecb50639bd0758e092269c2738385 /objectivec
parent5904279ebde364d8fce42f1a3dd60313643518ad (diff)
downloadprotobuf-6ab51a0ebdddd10dc78c8fc30c06878b96356416.tar.gz
protobuf-6ab51a0ebdddd10dc78c8fc30c06878b96356416.tar.bz2
protobuf-6ab51a0ebdddd10dc78c8fc30c06878b96356416.zip
Use a custom dictionary to avoid NSNumber operations.
For the secondary dictionary, use a custom CFDictionary with integer keys to avoid the NSNumber conversions.
Diffstat (limited to 'objectivec')
-rw-r--r--objectivec/GPBExtensionRegistry.m47
1 files 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<NSCopying>)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