GitGrapher: Rewrite looping code to C++

This makes the revwalking faster by not creating as many NSObjects as before.
This commit is contained in:
Pieter de Bie
2008-11-20 17:30:59 +01:00
parent bb5696c704
commit cef35ac7ce
8 changed files with 255 additions and 210 deletions
+8 -8
View File
@@ -62,7 +62,7 @@
F5AD56790E79B78100EDAAFE /* PBCommitList.m in Sources */ = {isa = PBXBuildFile; fileRef = F5AD56780E79B78100EDAAFE /* PBCommitList.m */; };
F5B721C40E05CF7E00AF29DC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F5B721C20E05CF7E00AF29DC /* MainMenu.xib */; };
F5C007750E731B48007B84B2 /* PBGitRef.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C007740E731B48007B84B2 /* PBGitRef.m */; };
F5C6F68D0E65FF9300478D97 /* PBGitLane.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C6F68C0E65FF9300478D97 /* PBGitLane.m */; };
F5C6F68D0E65FF9300478D97 /* PBGitLane.mm in Sources */ = {isa = PBXBuildFile; fileRef = F5C6F68C0E65FF9300478D97 /* PBGitLane.mm */; };
F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */ = {isa = PBXBuildFile; fileRef = F5DFFA6B0E075D8800617813 /* PBEasyFS.m */; };
F5E424110EA3E4D60046E362 /* PBDiffWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = F5E424100EA3E4D60046E362 /* PBDiffWindow.xib */; };
F5E424150EA3E4E10046E362 /* PBDiffWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E424130EA3E4E10046E362 /* PBDiffWindowController.m */; };
@@ -78,7 +78,7 @@
F5FC43FE0EBD08EE00191D80 /* PBRefMenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FC43FD0EBD08EE00191D80 /* PBRefMenuItem.m */; };
F5FE6C030EB13BC900F30D12 /* PBServicesController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FE6C020EB13BC900F30D12 /* PBServicesController.m */; };
F5FF4E180E0829C20006317A /* PBGitRevList.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FF4E170E0829C20006317A /* PBGitRevList.m */; };
F5FF4E7A0E082E440006317A /* PBGitGrapher.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FF4E790E082E440006317A /* PBGitGrapher.m */; };
F5FF4E7A0E082E440006317A /* PBGitGrapher.mm in Sources */ = {isa = PBXBuildFile; fileRef = F5FF4E790E082E440006317A /* PBGitGrapher.mm */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -194,7 +194,7 @@
F5C007730E731B48007B84B2 /* PBGitRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRef.h; sourceTree = "<group>"; };
F5C007740E731B48007B84B2 /* PBGitRef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitRef.m; sourceTree = "<group>"; };
F5C6F68B0E65FF9300478D97 /* PBGitLane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitLane.h; sourceTree = "<group>"; };
F5C6F68C0E65FF9300478D97 /* PBGitLane.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitLane.m; sourceTree = "<group>"; };
F5C6F68C0E65FF9300478D97 /* PBGitLane.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PBGitLane.mm; sourceTree = "<group>"; };
F5D2DC850EA401A80034AD24 /* PBGitConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitConfig.h; sourceTree = "<group>"; };
F5D619ED0EAE62EA00341D73 /* html */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = folder; path = html; sourceTree = "<group>"; };
F5DFFA6A0E075D8800617813 /* PBEasyFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBEasyFS.h; sourceTree = "<group>"; };
@@ -225,7 +225,7 @@
F5FF4E160E0829C20006317A /* PBGitRevList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRevList.h; sourceTree = "<group>"; };
F5FF4E170E0829C20006317A /* PBGitRevList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitRevList.m; sourceTree = "<group>"; };
F5FF4E780E082E440006317A /* PBGitGrapher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitGrapher.h; sourceTree = "<group>"; };
F5FF4E790E082E440006317A /* PBGitGrapher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitGrapher.m; sourceTree = "<group>"; };
F5FF4E790E082E440006317A /* PBGitGrapher.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PBGitGrapher.mm; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -456,7 +456,7 @@
isa = PBXGroup;
children = (
F5FF4E780E082E440006317A /* PBGitGrapher.h */,
F5FF4E790E082E440006317A /* PBGitGrapher.m */,
F5FF4E790E082E440006317A /* PBGitGrapher.mm */,
F50FE0E10E07BE9600854FCD /* PBGitRevisionCell.h */,
F50FE0E20E07BE9600854FCD /* PBGitRevisionCell.m */,
F56CC7270E65E0AD004307B4 /* PBGitGraphLine.h */,
@@ -464,7 +464,7 @@
F56CC7300E65E0E5004307B4 /* PBGraphCellInfo.h */,
F56CC7310E65E0E5004307B4 /* PBGraphCellInfo.m */,
F5C6F68B0E65FF9300478D97 /* PBGitLane.h */,
F5C6F68C0E65FF9300478D97 /* PBGitLane.m */,
F5C6F68C0E65FF9300478D97 /* PBGitLane.mm */,
);
name = Graphing;
sourceTree = "<group>";
@@ -656,12 +656,12 @@
F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */,
F50FE0E30E07BE9600854FCD /* PBGitRevisionCell.m in Sources */,
F5FF4E180E0829C20006317A /* PBGitRevList.m in Sources */,
F5FF4E7A0E082E440006317A /* PBGitGrapher.m in Sources */,
F5FF4E7A0E082E440006317A /* PBGitGrapher.mm in Sources */,
911111F80E594F3F00BF76B4 /* PBRepositoryDocumentController.m in Sources */,
913D5E5F0E556A9300CECEA2 /* PBCLIProxy.mm in Sources */,
F56CC7290E65E0AD004307B4 /* PBGitGraphLine.m in Sources */,
F56CC7320E65E0E5004307B4 /* PBGraphCellInfo.m in Sources */,
F5C6F68D0E65FF9300478D97 /* PBGitLane.m in Sources */,
F5C6F68D0E65FF9300478D97 /* PBGitLane.mm in Sources */,
F5C007750E731B48007B84B2 /* PBGitRef.m in Sources */,
F5AD56790E79B78100EDAAFE /* PBCommitList.m in Sources */,
F53FF2050E7ABB5300389171 /* PBGitRevSpecifier.m in Sources */,
+1 -9
View File
@@ -11,17 +11,9 @@
#import "PBGitGraphLine.h"
#import "PBGraphCellInfo.h"
struct PBGitGraphColumn {
NSString* commit; // Commit that we're looking for
int color;
};
#define PBGitMaxColumns 100
@interface PBGitGrapher : NSObject {
PBGraphCellInfo* previous;
NSMutableArray* previousLanes;
void *pl;
NSDictionary* refs;
PBGitRepository* repository;
}
-146
View File
@@ -1,146 +0,0 @@
//
// PBGitGrapher.m
// GitX
//
// Created by Pieter de Bie on 17-06-08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "PBGitGrapher.h"
#import "PBGitCommit.h"
#import "PBGitLane.h"
@implementation PBGitGrapher
#define MAX_LANES 32
- (id) initWithRepository: (PBGitRepository*) repo
{
refs = repo.refs;
repository = repo;
previousLanes = [NSMutableArray arrayWithCapacity:MAX_LANES];
[PBGitLane resetColors];
return self;
}
- (void) decorateCommit: (PBGitCommit *) commit
{
int i = 0, newPos = -1;
NSMutableArray* currentLanes = [NSMutableArray arrayWithCapacity:MAX_LANES];
NSMutableArray* lines = [NSMutableArray array];
PBGitLane* currentLane = NULL;
BOOL didFirst = NO;
// First, iterate over earlier columns and pass through any that don't want this commit
if (previous != nil) {
// We can't count until numColumns here, as it's only used for the width of the cell.
for (PBGitLane* lane in previousLanes) {
i++;
// This is our commit! We should do a "merge": move the line from
// our upperMapping to their lowerMapping
if ([lane isCommit:commit.sha]) {
if (!didFirst) {
didFirst = YES;
currentLane = lane;
[currentLanes addObject: lane];
newPos = [currentLanes count];
}
[lines addObject: [PBGitGraphLine upperLineFrom: i to: newPos color: [lane index]]];
}
else {
// We are not this commit.
// Try to find an earlier column for this commit.
int j = 0;
BOOL found = NO;
for (PBGitLane* column in currentLanes) {
j++;
// ??? what is this?
// if (j == newPos)
// continue;
if ([lane isCommit: commit.sha]) {
// We already have a column for this commit. use it instead
[lines addObject: [PBGitGraphLine upperLineFrom: i to: j color: [lane index]]];
found = YES;
break;
}
}
// We need a new column for this.
if (!found) {
[currentLanes addObject: lane];
[lines addObject: [PBGitGraphLine upperLineFrom: i to: [currentLanes count] color: [lane index]]];
[lines addObject: [PBGitGraphLine lowerLineFrom: [currentLanes count] to: [currentLanes count] color: [lane index]]];
}
}
// For existing columns, we always just continue straight down
// ^^ I don't know what that means anymore :(
[lines addObject:[PBGitGraphLine lowerLineFrom:newPos to:newPos color: [currentLane index]]];
}
}
//Add your own parents
// If we already did the first parent, don't do so again
if (!didFirst && [currentLanes count] < MAX_LANES) {
PBGitLane* newLane = [[PBGitLane alloc] initWithCommit:[commit.parents objectAtIndex:0]];
[currentLanes addObject: newLane];
newPos = [currentLanes count];
[lines addObject:[PBGitGraphLine lowerLineFrom: newPos to: newPos color: [newLane index]]];
}
// Add all other parents
// If we add at least one parent, we can go back a single column.
// This boolean will tell us if that happened
BOOL addedParent = NO;
for (NSString* parent in [commit.parents subarrayWithRange:NSMakeRange(1, [commit.parents count] -1)]) {
int i = 0;
BOOL was_displayed = NO;
for (PBGitLane* column in currentLanes) {
i++;
if ([column isCommit: parent]) {
[lines addObject:[PBGitGraphLine lowerLineFrom: i to: newPos color: [column index]]];
was_displayed = YES;
break;
}
}
if (was_displayed)
continue;
if ([currentLanes count] >= MAX_LANES)
break;
// Really add this parent
addedParent = YES;
PBGitLane* newLane = [[PBGitLane alloc] initWithCommit:parent];
[currentLanes addObject: newLane];
[lines addObject:[PBGitGraphLine lowerLineFrom: [currentLanes count] to: newPos color: [newLane index]]];
}
previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines];
previous.sign = commit.sign;
// If a parent was added, we have room to not indent.
if (addedParent)
previous.numColumns = [currentLanes count] - 1;
else
previous.numColumns = [currentLanes count];
if ([commit.parents count] > 0 && ![[commit.parents objectAtIndex:0] isEqualToString:@""])
currentLane.sha = [commit.parents objectAtIndex:0];
else
[currentLanes removeObject:currentLane];
previousLanes = currentLanes;
commit.lineInfo = previous;
}
- (void) finalize
{
[super finalize];
}
@end
+169
View File
@@ -0,0 +1,169 @@
//
// PBGitGrapher.m
// GitX
//
// Created by Pieter de Bie on 17-06-08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "PBGitGrapher.h"
#import "PBGitCommit.h"
#import "PBGitLane.h"
#import <vector>
using namespace std;
@implementation PBGitGrapher
#define MAX_LANES 32
- (id) initWithRepository: (PBGitRepository*) repo
{
refs = repo.refs;
repository = repo;
pl = new std::vector<PBGitLane>;
PBGitLane::resetColors();
//[PBGitLane resetColors];
return self;
}
- (void) decorateCommit: (PBGitCommit *) commit
{
//NSLog(@"Decoriting commit %@", commit.sha);
int i = 0, newPos = -1;
std::vector<PBGitLane *> *currentLanes = new std::vector<PBGitLane *>;
std::vector<PBGitLane *> *previousLanes = (std::vector<PBGitLane *> *)pl;
NSMutableArray* lines = [NSMutableArray array];
PBGitLane *currentLane = NULL;
BOOL didFirst = NO;
// First, iterate over earlier columns and pass through any that don't want this commit
if (previous != nil) {
// We can't count until numColumns here, as it's only used for the width of the cell.
std::vector<PBGitLane *>::iterator it = previousLanes->begin();
for (; it < previousLanes->end(); ++it) {
i++;
// This is our commit! We should do a "merge": move the line from
// our upperMapping to their lowerMapping
if ((*it)->isCommit([commit sha])) {
if (!didFirst) {
didFirst = YES;
currentLanes->push_back(*it);
currentLane = currentLanes->back();
newPos = currentLanes->size();
[lines addObject: [PBGitGraphLine upperLineFrom: i to: newPos color: (*it)->index()]];
}
else {
[lines addObject: [PBGitGraphLine upperLineFrom: i to: newPos color: (*it)->index()]];
delete *it;
}
}
else {
// We are not this commit.
// Try to find an earlier column for this commit.
int j = 0;
BOOL found = NO;
std::vector<PBGitLane *>::iterator it2 = currentLanes->begin();
for (; it2 < currentLanes->end(); ++it2) {
j++;
// ??? what is this?
// if (j == newPos)
// continue;
if ((*it)->isCommit([commit sha])) {
// We already have a column for this commit. use it instead
[lines addObject: [PBGitGraphLine upperLineFrom: i to: j color: (*it)->index()]];
found = YES;
break;
}
}
// We need a new column for this.
if (found) {
//NSLog(@"Need to delete");
} else {
//NSLog(@"Found another");
currentLanes->push_back(*it);
[lines addObject: [PBGitGraphLine upperLineFrom: i to: currentLanes->size() color: (*it)->index()]];
[lines addObject: [PBGitGraphLine lowerLineFrom: currentLanes->size() to: currentLanes->size() color: (*it)->index()]];
}
}
// For existing columns, we always just continue straight down
// ^^ I don't know what that means anymore :(
if (currentLane)
[lines addObject:[PBGitGraphLine lowerLineFrom:newPos to:newPos color: currentLane->index()]];
else
[lines addObject:[PBGitGraphLine lowerLineFrom:newPos to:newPos color: 0]];
}
}
//Add your own parents
// If we already did the first parent, don't do so again
if (!didFirst && currentLanes->size() < MAX_LANES) {
PBGitLane *newLane = new PBGitLane([commit.parents objectAtIndex:0]);
currentLanes->push_back(newLane);
newPos = currentLanes->size();
[lines addObject:[PBGitGraphLine lowerLineFrom: newPos to: newPos color: newLane->index()]];
}
// Add all other parents
// If we add at least one parent, we can go back a single column.
// This boolean will tell us if that happened
BOOL addedParent = NO;
for (NSString* parent in [commit.parents subarrayWithRange:NSMakeRange(1, [commit.parents count] -1)]) {
int i = 0;
BOOL was_displayed = NO;
std::vector<PBGitLane *>::iterator it = currentLanes->begin();
for (; it < currentLanes->end(); ++it) {
i++;
if ((*it)->isCommit(parent)) {
[lines addObject:[PBGitGraphLine lowerLineFrom: i to: newPos color: (*it)->index()]];
was_displayed = YES;
break;
}
}
if (was_displayed)
continue;
if (currentLanes->size() >= MAX_LANES)
break;
// Really add this parent
addedParent = YES;
PBGitLane *newLane = new PBGitLane(parent);
currentLanes->push_back(newLane);
[lines addObject:[PBGitGraphLine lowerLineFrom: currentLanes->size() to: newPos color: newLane->index()]];
}
previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines];
previous.sign = commit.sign;
// If a parent was added, we have room to not indent.
if (addedParent)
previous.numColumns = currentLanes->size() - 1;
else
previous.numColumns = currentLanes->size();
// Update the current lane to point to the new parent
if (currentLane && [commit.parents count] > 0 && ![[commit.parents objectAtIndex:0] isEqualToString:@""])
currentLane->setSha([commit.parents objectAtIndex:0]);
// else
// [currentLanes removeObject:currentLane];
delete previousLanes;
pl = currentLanes;
commit.lineInfo = previous;
}
- (void) finalize
{
[super finalize];
}
@end
+28 -11
View File
@@ -5,19 +5,36 @@
// Created by Pieter de Bie on 27-08-08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface PBGitLane : NSObject {
NSString* sha;
int index;
}
- (id) initWithCommit: (NSString*) c;
- (BOOL) isCommit: (NSString*) c;
class PBGitLane {
static int s_colorIndex;
+ (void) resetColors;
NSString *d_sha;
int d_index;
@property(assign) NSString* sha;
@property(readonly) int index;
public:
@end
PBGitLane(NSString *sha)
{
d_index = s_colorIndex++;
d_sha = [sha copy];
}
PBGitLane()
{
d_index = s_colorIndex++;
d_sha = NULL;
}
bool isCommit(NSString *sha) const;
void setSha(NSString *sha);
NSString *sha() const
{
return [d_sha copy];
}
int index() const;
static void resetColors();
};
-35
View File
@@ -1,35 +0,0 @@
//
// PBGitLane.m
// GitX
//
// Created by Pieter de Bie on 27-08-08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "PBGitLane.h"
@implementation PBGitLane
static int PBGITLANE_CURRENT_INDEX = 0;
@synthesize sha, index;
+ (void) resetColors
{
PBGITLANE_CURRENT_INDEX = 0;
}
- (id) initWithCommit: (NSString*) c
{
index = PBGITLANE_CURRENT_INDEX++;
sha = c;
return self;
}
- (BOOL) isCommit: (NSString*) s
{
return [sha isEqualToString:s];
}
@end
+46
View File
@@ -0,0 +1,46 @@
//
// PBGitLane.m
// GitX
//
// Created by Pieter de Bie on 27-08-08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "PBGitLane.h"
//class PBGitLane {
// static int s_colorIndex;
//
// char d_sha[20];
// int d_index;
//
//public:
// PBGitLane(NSString *sha);
//
// bool isCommit(NSString *sha) const;
// int index(); const;
//
// static resetColors();
//};
int PBGitLane::s_colorIndex = 0;
bool PBGitLane::isCommit(NSString *sha) const
{
//NSLog(@"Comparing %@ with %@", d_sha, sha);
return [d_sha isEqualToString:sha];
}
int PBGitLane::index() const
{
return d_index;
}
void PBGitLane::setSha(NSString *sha)
{
d_sha = sha;
}
void PBGitLane::resetColors()
{
s_colorIndex = 0;
}
+3 -1
View File
@@ -61,7 +61,7 @@
- (void) walkRevisionListWithSpecifier: (PBGitRevSpecifier*) rev
{
NSDate *start = [NSDate date];
NSMutableArray* revisions = [NSMutableArray array];
PBGitGrapher* g = [[PBGitGrapher alloc] initWithRepository: repository];
NSDictionary* refs = [repository refs];
@@ -147,6 +147,8 @@
[currentLine setString: @""];
}
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:start];
NSLog(@"Loaded %i commits in %f seconds", num, duration);
// Make sure the commits are stored before exiting.
[self performSelectorOnMainThread:@selector(setCommits:) withObject:revisions waitUntilDone:YES];
[task waitUntilExit];