From: Nathan Kinsinger <[email protected]>

Pre-calculating isSimpleRef is a huge performance win for the repository's
reloadRef by speeding up the addBranch method which checks each new
revSpec against all the existing ones. The rangeOf.. methods are slow.

isEqualTo: is for the scripting bridge. isEqual: is used by the collection
classes, like NSArray, for testing equality beyond pointer equality.

Since I had touched pretty much everything already I updated the last few
methods to the current coding style.
---
 PBGitRepository.m   |    4 +-
 PBGitRevSpecifier.h |   17 ++++---
 PBGitRevSpecifier.m |  120 ++++++++++++++++++++++++++++++++++++--------------
 3 files changed, 98 insertions(+), 43 deletions(-)

diff --git a/PBGitRepository.m b/PBGitRepository.m
index e778f22..23a3fb6 100644
--- a/PBGitRepository.m
+++ b/PBGitRepository.m
@@ -300,7 +300,7 @@ - (PBGitRevSpecifier*) addBranch: (PBGitRevSpecifier*) rev
 
        // First check if the branch doesn't exist already
        for (PBGitRevSpecifier* r in branches)
-               if ([rev isEqualTo: r])
+               if ([rev isEqual:r])
                        return r;
 
        [self willChangeValueForKey:@"branches"];
@@ -312,7 +312,7 @@ - (PBGitRevSpecifier*) addBranch: (PBGitRevSpecifier*) rev
 - (BOOL)removeBranch:(PBGitRevSpecifier *)rev
 {
        for (PBGitRevSpecifier *r in branches) {
-               if ([rev isEqualTo:r]) {
+               if ([rev isEqual:r]) {
                        [self willChangeValueForKey:@"branches"];
                        [branches removeObject:r];
                        [self didChangeValueForKey:@"branches"];
diff --git a/PBGitRevSpecifier.h b/PBGitRevSpecifier.h
index 0461908..5d75c07 100644
--- a/PBGitRevSpecifier.h
+++ b/PBGitRevSpecifier.h
@@ -13,17 +13,19 @@
        NSString *description;
        NSArray *parameters;
        NSURL *workingDirectory;
+       BOOL isSimpleRef;
 }
 
-- (id) initWithParameters:(NSArray*) params;
-- (id) initWithRef: (PBGitRef*) ref;
+- (id) initWithParameters:(NSArray *)params;
+- (id) initWithRef:(PBGitRef *)ref;
 
-- (BOOL) isSimpleRef;
-- (NSString*) simpleRef;
-- (BOOL) hasPathLimiter;
-- (BOOL) hasLeftRight;
+- (NSString *)simpleRef;
+- (PBGitRef *)ref;
+- (BOOL)hasPathLimiter;
+- (BOOL)hasLeftRight;
 
-- (BOOL) isEqualTo: (PBGitRevSpecifier*) other;
+- (BOOL)isAllBranchesRev;
+- (BOOL)isLocalBranchesRev;
 
 + (PBGitRevSpecifier *)allBranchesRevSpec;
 + (PBGitRevSpecifier *)localBranchesRevSpec;
@@ -31,5 +33,6 @@
 @property(retain)   NSString *description;
 @property(readonly) NSArray *parameters;
 @property(retain)   NSURL *workingDirectory;
+...@property(readonly) BOOL isSimpleRef;
 
 @end
diff --git a/PBGitRevSpecifier.m b/PBGitRevSpecifier.m
index 0fe9093..5c794a2 100644
--- a/PBGitRevSpecifier.m
+++ b/PBGitRevSpecifier.m
@@ -12,92 +12,144 @@
 @implementation PBGitRevSpecifier
 
 @synthesize parameters, description, workingDirectory;
+...@synthesize isSimpleRef;
 
-- (id) initWithParameters:(NSArray*) params
+
+// designated init
+- (id)initWithParameters:(NSArray *)params description:(NSString *)descrip
 {
        parameters = params;
-       description = nil;
+       description = descrip;
+
+       if (([parameters count] > 1) || ([parameters count] == 0))
+               isSimpleRef =  NO;
+       else {
+               NSString *param = [parameters objectAtIndex:0];
+               if ([param hasPrefix:@"-"]
+                       || ([param rangeOfCharacterFromSet:[NSCharacterSet 
characterSetWithCharactersInString:@"^...@{}~:"]].location != NSNotFound)
+                       || ([param rangeOfString:@".."].location != NSNotFound))
+                       isSimpleRef =  NO;
+               else
+                       isSimpleRef =  YES;
+       }
+
        return self;
 }
 
-- (id) initWithRef: (PBGitRef*) ref
+- (id)initWithParameters:(NSArray *)params
 {
-       parameters = [NSArray arrayWithObject: ref.ref];
-       description = ref.shortName;
+       [self initWithParameters:params description:nil];
        return self;
 }
 
-- (id) initWithCoder:(NSCoder *)coder
+- (id)initWithRef:(PBGitRef *)ref
 {
-       parameters = [coder decodeObjectForKey:@"Parameters"];
-       description = [coder decodeObjectForKey:@"Description"];
+       [self initWithParameters:[NSArray arrayWithObject:ref.ref] 
description:ref.shortName];
+       return self;
+}
+
+- (id)initWithCoder:(NSCoder *)coder
+{
+       [self initWithParameters:[coder decodeObjectForKey:@"Parameters"] 
description:[coder decodeObjectForKey:@"Description"]];
        return self;
 }
 
 + (PBGitRevSpecifier *)allBranchesRevSpec
 {
-       id revspec = [[PBGitRevSpecifier alloc] initWithParameters:[NSArray 
arrayWithObject:@"--all"]];
-       [revspec setDescription:@"All branches"];
-       return revspec;
+       return [[PBGitRevSpecifier alloc] initWithParameters:[NSArray 
arrayWithObject:@"--all"] description:@"All branches"];
 }
 
 + (PBGitRevSpecifier *)localBranchesRevSpec
 {
-       id revspec = [[PBGitRevSpecifier alloc] initWithParameters:[NSArray 
arrayWithObject:@"--branches"]];
-       [revspec setDescription:@"Local branches"];
-       return revspec;
+       return [[PBGitRevSpecifier alloc] initWithParameters:[NSArray 
arrayWithObject:@"--branches"] description:@"Local branches"];
 }
-- (BOOL) isSimpleRef
+
+- (NSString *)simpleRef
 {
-       return ([parameters count] == 1 && ![[parameters objectAtIndex:0] 
hasPrefix:@"-"]);
+       if (![self isSimpleRef])
+               return nil;
+       return [parameters objectAtIndex:0];
 }
 
-- (NSString*) simpleRef
+- (PBGitRef *)ref
 {
        if (![self isSimpleRef])
                return nil;
-       return [parameters objectAtIndex:0];
+
+       return [PBGitRef refFromString:[self simpleRef]];
 }
 
-- (NSString*) description
+- (NSString *)description
 {
-       if (description)
-               return description;
+       if (!description)
+               description = [parameters componentsJoinedByString:@" "];
        
-       return [parameters componentsJoinedByString:@" "];
+       return description;
 }
 
-- (BOOL) hasPathLimiter;
+- (BOOL)hasPathLimiter;
 {
-       for (NSString* param in parameters)
+       for (NSString *param in parameters)
                if ([param isEqualToString:@"--"])
                        return YES;
        return NO;
 }
 
-- (BOOL) hasLeftRight
+- (BOOL)hasLeftRight
 {
-       for (NSString* param in parameters)
+       for (NSString *param in parameters)
                if ([param isEqualToString:@"--left-right"])
                        return YES;
        return NO;
 }
-       
-- (BOOL) isEqualTo: (PBGitRevSpecifier*) other
+
+- (BOOL)isEqual:(id)other
 {
-       if ([self isSimpleRef] ^ [other isSimpleRef])
+       if (![other isMemberOfClass:[PBGitRevSpecifier class]])
                return NO;
-       
+
+       PBGitRevSpecifier *otherRev = (PBGitRevSpecifier *)other;
+
+       if ([self isSimpleRef] ^ [otherRev isSimpleRef])
+               return NO;
+
        if ([self isSimpleRef])
-               return [[[self parameters] objectAtIndex: 0] isEqualToString: 
[other.parameters objectAtIndex: 0]];
+               return [[[self parameters] objectAtIndex:0] 
isEqualToString:[otherRev.parameters objectAtIndex:0]];
+
+       return [self.description isEqualToString:otherRev.description];
+}
+
+- (NSUInteger)hash
+{
+       if ([self isSimpleRef])
+               return [[[self parameters] objectAtIndex:0] hash];
+
+       return [self.description hash];
+}
 
-       return ([[parameters componentsJoinedByString:@" "] isEqualToString: 
[other.parameters componentsJoinedByString:@" "]] &&
-                        (!description  || [description 
isEqualToString:other.description]));
+- (BOOL)isAllBranchesRev
+{
+       return [self isEqual:[PBGitRevSpecifier allBranchesRevSpec]];
 }
 
-- (void) encodeWithCoder:(NSCoder *)coder
+- (BOOL)isLocalBranchesRev
+{
+       return [self isEqual:[PBGitRevSpecifier localBranchesRevSpec]];
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
 {
        [coder encodeObject:description forKey:@"Description"];
        [coder encodeObject:parameters forKey:@"Parameters"];
 }
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    PBGitRevSpecifier *copy = [[[self class] allocWithZone:zone] 
initWithParameters:[self.parameters copy]];
+    copy.description = [self.description copy];
+       copy.workingDirectory = [self.workingDirectory copy];
+
+    return copy;
+}
+
 @end
-- 
1.7.0.3

To unsubscribe from this group, send email to gitx+unsubscribegooglegroups.com 
or reply to this email with the words "REMOVE ME" as the subject.

Reply via email to