Bladeren bron

Merge pull request #2137 from thomasvl/objc_extensions_tweak

Objc extensions tweaks
Thomas Van Lenten 9 jaren geleden
bovenliggende
commit
7b00595ddf
2 gewijzigde bestanden met toevoegingen van 34 en 56 verwijderingen
  1. 31 16
      objectivec/GPBExtensionRegistry.m
  2. 3 40
      objectivec/GPBUnknownFieldSet.m

+ 31 - 16
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

+ 3 - 40
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;