mirror of
https://github.com/kennethreitz-archive/gitx.git
synced 2026-06-05 23:40:18 +00:00
Multithread test
This commit is contained in:
@@ -274,8 +274,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5C6F6750E65FE2B00478D97 /* Graphing */,
|
||||
F5FF4E780E082E440006317A /* PBGitGrapher.h */,
|
||||
F5FF4E790E082E440006317A /* PBGitGrapher.m */,
|
||||
F5945E150E02B0C200706420 /* PBGitRepository.h */,
|
||||
F5945E160E02B0C200706420 /* PBGitRepository.m */,
|
||||
F56524EE0E02D45200F03B52 /* PBGitCommit.h */,
|
||||
@@ -342,6 +340,8 @@
|
||||
F5C6F6750E65FE2B00478D97 /* Graphing */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5FF4E780E082E440006317A /* PBGitGrapher.h */,
|
||||
F5FF4E790E082E440006317A /* PBGitGrapher.m */,
|
||||
F5C007730E731B48007B84B2 /* PBGitRef.h */,
|
||||
F5C007740E731B48007B84B2 /* PBGitRef.m */,
|
||||
F50FE0E10E07BE9600854FCD /* PBGitRevisionCell.h */,
|
||||
|
||||
+4
-1
@@ -20,11 +20,14 @@ struct PBGitGraphColumn {
|
||||
#define PBGitMaxColumns 100
|
||||
|
||||
@interface PBGitGrapher : NSObject {
|
||||
PBGraphCellInfo* previous;
|
||||
NSMutableArray* previousLanes;
|
||||
NSMutableArray* cellsInfo;
|
||||
NSDictionary* refs;
|
||||
PBGitRepository* repository;
|
||||
}
|
||||
|
||||
- (id) initWithRepository: (PBGitRepository*) repo;
|
||||
- (void) parseCommits: (NSArray *) array;
|
||||
- (void) decorateCommit: (PBGitCommit *) commit;
|
||||
- (PBGraphCellInfo*) cellInfoForRow: (int) row;
|
||||
@end
|
||||
|
||||
+105
-118
@@ -14,139 +14,127 @@
|
||||
|
||||
- (id) initWithRepository: (PBGitRepository*) repo
|
||||
{
|
||||
repository = repo;
|
||||
refs = repo.refs;
|
||||
// We don't know how many commits to parse.
|
||||
cellsInfo = [NSMutableArray arrayWithCapacity:100];
|
||||
|
||||
previousLanes = [NSMutableArray array];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) parseCommits: (NSArray *) commits
|
||||
- (void) decorateCommit: (PBGitCommit *) commit
|
||||
{
|
||||
cellsInfo = [NSMutableArray arrayWithCapacity: [commits count]];
|
||||
int row = 0;
|
||||
int i = 0, newPos = -1;
|
||||
NSMutableArray* currentLanes = [NSMutableArray array];
|
||||
NSMutableArray* lines = [NSMutableArray array];
|
||||
PBGitLane* currentLane = NULL;
|
||||
BOOL didFirst = NO;
|
||||
|
||||
NSDictionary* refs = nil;
|
||||
if (repository)
|
||||
refs = repository.refs;
|
||||
// First, iterate over earlier columns and pass through any that don't want this commit
|
||||
if (previous != nil) {
|
||||
|
||||
PBGraphCellInfo* previous;
|
||||
NSMutableArray* previousLanes = [NSMutableArray array];
|
||||
|
||||
for (PBGitCommit* commit in commits) {
|
||||
int i = 0, newPos = -1;
|
||||
NSMutableArray* currentLanes = [NSMutableArray array];
|
||||
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]]];
|
||||
// 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];
|
||||
}
|
||||
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?
|
||||
[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) {
|
||||
|
||||
// This was used as a hack to stop large lanes from drawing
|
||||
//if (previous->columns[i].color == 10)
|
||||
// continue;
|
||||
|
||||
[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]]];
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
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;
|
||||
// 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]]];
|
||||
}
|
||||
}
|
||||
if (was_displayed)
|
||||
continue;
|
||||
|
||||
// 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]]];
|
||||
// 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]]];
|
||||
}
|
||||
|
||||
++row;
|
||||
previous = [[PBGraphCellInfo alloc] initWithPosition:newPos andLines:lines];
|
||||
previous.sign = commit.sign;
|
||||
if (refs && [refs objectForKey:commit.sha])
|
||||
previous.refs = [refs objectForKey:commit.sha];
|
||||
|
||||
// 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;
|
||||
[cellsInfo addObject: previous];
|
||||
}
|
||||
|
||||
//Add your own parents
|
||||
|
||||
// If we already did the first parent, don't do so again
|
||||
if (!didFirst) {
|
||||
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;
|
||||
|
||||
// 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 (refs && [refs objectForKey:commit.sha])
|
||||
previous.refs = [refs objectForKey:commit.sha];
|
||||
|
||||
// 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;
|
||||
[cellsInfo addObject: previous];
|
||||
}
|
||||
|
||||
- (PBGraphCellInfo*) cellInfoForRow: (int) row
|
||||
@@ -156,7 +144,6 @@
|
||||
|
||||
- (void) finalize
|
||||
{
|
||||
free(cellsInfo);
|
||||
[super finalize];
|
||||
}
|
||||
@end
|
||||
|
||||
+42
-18
@@ -65,7 +65,6 @@
|
||||
|
||||
NSMutableArray* newArray = [NSMutableArray array];
|
||||
NSMutableArray* arguments;
|
||||
NSDate* start = [NSDate date];
|
||||
BOOL showSign = [rev hasLeftRight];
|
||||
|
||||
if (showSign)
|
||||
@@ -80,6 +79,10 @@
|
||||
|
||||
NSFileHandle* handle = [repository handleForArguments: arguments];
|
||||
|
||||
// We decorate the commits in a separate thread.
|
||||
NSThread * decorationThread = [[NSThread alloc] initWithTarget: self selector: @selector(decorateRevisions:) object:newArray];
|
||||
[decorationThread start];
|
||||
|
||||
int fd = [handle fileDescriptor];
|
||||
FILE* f = fdopen(fd, "r");
|
||||
int BUFFERSIZE = 2048;
|
||||
@@ -87,7 +90,7 @@
|
||||
buffer[BUFFERSIZE - 2] = 0;
|
||||
|
||||
char* l;
|
||||
int num = 0;
|
||||
|
||||
NSMutableString* currentLine = [NSMutableString string];
|
||||
while (l = fgets(buffer, BUFFERSIZE, f)) {
|
||||
NSString *s = [NSString stringWithCString:(const char *)l encoding:NSUTF8StringEncoding];
|
||||
@@ -117,28 +120,49 @@
|
||||
if (showSign)
|
||||
newCommit.sign = [[components objectAtIndex:5] characterAtIndex:0];
|
||||
|
||||
[newArray addObject: newCommit];
|
||||
num++;
|
||||
if (num % 10000 == 0)
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:NO];
|
||||
@synchronized(newArray) {
|
||||
[newArray addObject: newCommit];
|
||||
}
|
||||
currentLine = [NSMutableString string];
|
||||
}
|
||||
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:YES];
|
||||
[decorationThread cancel];
|
||||
|
||||
if (![rev hasPathLimiter]) {
|
||||
PBGitGrapher* g = [[PBGitGrapher alloc] initWithRepository: repository];
|
||||
[g parseCommits: self.commits];
|
||||
[self performSelectorOnMainThread:@selector(setGrapher:) withObject:g waitUntilDone:YES];
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:YES];
|
||||
}
|
||||
else
|
||||
grapher = nil;
|
||||
|
||||
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:start];
|
||||
NSLog(@"Loaded %i commits in %f seconds", num, duration);
|
||||
[NSThread exit];
|
||||
}
|
||||
|
||||
- (void) decorateRevisions: (NSMutableArray*) revisions
|
||||
{
|
||||
NSDate* start = [NSDate date];
|
||||
|
||||
NSMutableArray* allRevisions = [NSMutableArray arrayWithCapacity:1000];
|
||||
int num = 0;
|
||||
PBGitGrapher* g = [[PBGitGrapher alloc] initWithRepository: repository];
|
||||
[self performSelectorOnMainThread:@selector(setGrapher:) withObject:g waitUntilDone:YES];
|
||||
|
||||
while (!([[NSThread currentThread] isCancelled] && [revisions count] == 0)) {
|
||||
if ([revisions count] == 0)
|
||||
usleep(10000);
|
||||
|
||||
NSArray* currentRevisions;
|
||||
@synchronized(revisions) {
|
||||
currentRevisions = [revisions copy];
|
||||
[revisions removeAllObjects];
|
||||
}
|
||||
for (PBGitCommit* commit in currentRevisions) {
|
||||
num++;
|
||||
[g decorateCommit: commit];
|
||||
[allRevisions addObject: commit];
|
||||
if (num % 1000 == 0)
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:allRevisions waitUntilDone:NO];
|
||||
}
|
||||
}
|
||||
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:allRevisions waitUntilDone:YES];
|
||||
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:start];
|
||||
NSLog(@"Loaded %i commits in %f seconds", num, duration);
|
||||
|
||||
[NSThread exit];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user