mirror of
https://github.com/kennethreitz-archive/gitx.git
synced 2026-06-05 23:40:18 +00:00
Merge commit 'ciaran/grapher'
* commit 'ciaran/grapher': Grapher: add speed tests Discard branches that run for too long PBGitRevList: use --topo-order for better graphs PBGitGrapher: Improve the grapher First take on graphing
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
F5B721C40E05CF7E00AF29DC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F5B721C20E05CF7E00AF29DC /* MainMenu.xib */; };
|
||||
F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */ = {isa = PBXBuildFile; fileRef = F5DFFA6B0E075D8800617813 /* PBEasyFS.m */; };
|
||||
F5FF4E180E0829C20006317A /* PBGitRevList.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FF4E170E0829C20006317A /* PBGitRevList.m */; };
|
||||
F5FF4E7A0E082E440006317A /* PBGitGrapher.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FF4E790E082E440006317A /* PBGitGrapher.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -103,6 +104,8 @@
|
||||
F5DFFA6B0E075D8800617813 /* PBEasyFS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBEasyFS.m; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -229,6 +232,8 @@
|
||||
F56174540E05887E001DCD79 /* Git */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F5FF4E780E082E440006317A /* PBGitGrapher.h */,
|
||||
F5FF4E790E082E440006317A /* PBGitGrapher.m */,
|
||||
F5945E150E02B0C200706420 /* PBGitRepository.h */,
|
||||
F5945E160E02B0C200706420 /* PBGitRepository.m */,
|
||||
F56524EE0E02D45200F03B52 /* PBGitCommit.h */,
|
||||
@@ -385,6 +390,7 @@
|
||||
F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */,
|
||||
F50FE0E30E07BE9600854FCD /* PBGitRevisionCell.m in Sources */,
|
||||
F5FF4E180E0829C20006317A /* PBGitRevList.m in Sources */,
|
||||
F5FF4E7A0E082E440006317A /* PBGitGrapher.m in Sources */,
|
||||
911111F80E594F3F00BF76B4 /* PBRepositoryDocumentController.m in Sources */,
|
||||
913D5E5F0E556A9300CECEA2 /* PBCLIProxy.mm in Sources */,
|
||||
);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#import "PBDetailController.h"
|
||||
#import "CWQuickLook.h"
|
||||
#import "PBGitGrapher.h"
|
||||
|
||||
#define QLPreviewPanel NSClassFromString(@"QLPreviewPanel")
|
||||
|
||||
@@ -148,7 +149,9 @@
|
||||
if (![[aTableColumn identifier] isEqualToString:@"subject"])
|
||||
return;
|
||||
|
||||
NSNumber* n = [NSNumber numberWithInt:(rowIndex % 2)];
|
||||
[aCell setCommit:n];
|
||||
if (self.repository.revisionList.grapher) {
|
||||
PBGitGrapher* g = self.repository.revisionList.grapher;
|
||||
[aCell setCellInfo: [g cellInfoForRow:rowIndex]];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// PBGitGrapher.h
|
||||
// GitX
|
||||
//
|
||||
// Created by Pieter de Bie on 17-06-08.
|
||||
// Copyright 2008 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "PBGitCommit.h"
|
||||
|
||||
|
||||
struct PBGitGraphColumn {
|
||||
NSString* commit; // Commit that we're looking for
|
||||
int color;
|
||||
};
|
||||
|
||||
|
||||
#define PBGitMaxColumns 100
|
||||
|
||||
struct PBGitGraphCellInfo {
|
||||
struct PBGitGraphColumn columns[PBGitMaxColumns];
|
||||
int upperMapping[PBGitMaxColumns]; //How are the offsets compared to previous cell?
|
||||
int lowerMapping[PBGitMaxColumns]; //How are the offsets compared to this cell?
|
||||
int position;
|
||||
NSString* commit; // Commit in cell
|
||||
int numColumns;
|
||||
int numNewColumns;
|
||||
};
|
||||
|
||||
void add_commit_to_graph(struct PBGitGraphCellInfo* info, NSString* parent, int* mapping_index);
|
||||
|
||||
typedef struct PBGitGraphCellInfo PBGitCellInfo;
|
||||
|
||||
|
||||
@interface PBGitGrapher : NSObject {
|
||||
PBGitCellInfo* cellsInfo;
|
||||
}
|
||||
|
||||
- (void) parseCommits: (NSArray *) array;
|
||||
- (struct PBGitGraphCellInfo) cellInfoForRow: (int) row;
|
||||
@end
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// PBGitGrapher.m
|
||||
// GitX
|
||||
//
|
||||
// Created by Pieter de Bie on 17-06-08.
|
||||
// Copyright 2008 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "PBGitGrapher.h"
|
||||
#import "PBGitCommit.h"
|
||||
|
||||
@implementation PBGitGrapher
|
||||
|
||||
|
||||
- (void) parseCommits: (NSArray *) commits
|
||||
{
|
||||
cellsInfo = malloc(sizeof(struct PBGitGraphCellInfo) * [commits count]);
|
||||
memset(cellsInfo, 0, sizeof(struct PBGitGraphCellInfo) * [commits count]);
|
||||
|
||||
int row = 0;
|
||||
|
||||
struct PBGitGraphCellInfo *previous = nil;
|
||||
for (PBGitCommit* commit in commits) {
|
||||
struct PBGitGraphCellInfo *info = &(cellsInfo[row]);
|
||||
info->commit = commit.sha;
|
||||
info->numColumns = 0;
|
||||
|
||||
int i = 0, newPos = -1;
|
||||
for (i = 0; i < PBGitMaxColumns; i++) {
|
||||
info->lowerMapping[i] = -1;
|
||||
info->upperMapping[i] = -1;
|
||||
}
|
||||
|
||||
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 (i = 0; i < PBGitMaxColumns; i++) {
|
||||
if ((previous->columns[i].commit) == nil)
|
||||
continue;
|
||||
|
||||
// This is our commit! We should do a "merge": move the line from
|
||||
// our upperMapping to their lowerMapping
|
||||
if ([previous->columns[i].commit isEqualToString:info->commit]) {
|
||||
if (!didFirst) {
|
||||
didFirst = YES;
|
||||
info->position = info->numColumns++;
|
||||
info->columns[info->position].commit = [commit.parents objectAtIndex:0];
|
||||
}
|
||||
newPos = info->position;
|
||||
info->upperMapping[i] = newPos;
|
||||
}
|
||||
else {
|
||||
// We are not this commit.
|
||||
// Try to find an earlier column for this commit.
|
||||
int j;
|
||||
BOOL found = NO;
|
||||
for (j = 0; j < info->numColumns; j++) {
|
||||
if (j == info->position)
|
||||
continue;
|
||||
if ([previous->columns[i].commit isEqualToString: info->columns[j].commit]) {
|
||||
// We already have a column for this commit. use it instead
|
||||
newPos = j;
|
||||
info->upperMapping[previous->lowerMapping[i]] = newPos;
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We need a new column for this.
|
||||
if (!found) {
|
||||
|
||||
if (previous->columns[i].color == 10)
|
||||
continue;
|
||||
|
||||
newPos = info->numColumns++;
|
||||
info->columns[newPos] = previous->columns[i];
|
||||
info->columns[newPos].color++;
|
||||
info->upperMapping[newPos] = newPos;
|
||||
}
|
||||
}
|
||||
// For existing columns, we always just continue straight down
|
||||
info->lowerMapping[newPos] = newPos;
|
||||
}
|
||||
}
|
||||
|
||||
//Add your own parents
|
||||
|
||||
// If we already did the first parent, don't do so again
|
||||
if (!didFirst) {
|
||||
info->position = info->numColumns++;
|
||||
info->columns[info->position].commit = [commit.parents objectAtIndex:0];
|
||||
info->lowerMapping[info->position] = info->position;
|
||||
}
|
||||
|
||||
// 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;
|
||||
BOOL was_displayed = NO;
|
||||
for (i = 0; i < info->numColumns; i++)
|
||||
if ([info->columns[i].commit isEqualToString: parent]) {
|
||||
// TODO!
|
||||
// !!! BUG
|
||||
// This overwrites an existing mapping.
|
||||
// We should instead have the possibility
|
||||
// to add multiple lower mappings
|
||||
// As we don't have that now, pieces of the graph are missing
|
||||
info->lowerMapping[i] = info->position;
|
||||
was_displayed = YES;
|
||||
break;
|
||||
}
|
||||
if (was_displayed)
|
||||
continue;
|
||||
|
||||
// Really add this parent
|
||||
addedParent = YES;
|
||||
info->columns[info->numColumns++].commit = parent;
|
||||
info->lowerMapping[info->numColumns -1] = info->position;
|
||||
}
|
||||
|
||||
// A parent was added, so we have room to not indent.
|
||||
if (addedParent)
|
||||
info->numColumns--;
|
||||
previous = info;
|
||||
++row;
|
||||
}
|
||||
}
|
||||
- (struct PBGitGraphCellInfo) cellInfoForRow: (int) row
|
||||
{
|
||||
return cellsInfo[row];
|
||||
}
|
||||
|
||||
- (void) finalize
|
||||
{
|
||||
free(cellsInfo);
|
||||
[super finalize];
|
||||
}
|
||||
@end
|
||||
@@ -12,6 +12,7 @@
|
||||
@interface PBGitRevList : NSObject {
|
||||
NSArray* commits;
|
||||
NSArray* parameters;
|
||||
id grapher;
|
||||
id repository;
|
||||
NSString* currentRef;
|
||||
}
|
||||
@@ -20,4 +21,6 @@
|
||||
- readCommits;
|
||||
|
||||
@property(retain) NSArray* commits;
|
||||
@property(retain) id grapher;
|
||||
|
||||
@end
|
||||
|
||||
+9
-2
@@ -9,10 +9,11 @@
|
||||
#import "PBGitRevList.h"
|
||||
#import "PBGitRepository.h"
|
||||
#import "PBGitCommit.h"
|
||||
#import "PBGitGrapher.h"
|
||||
|
||||
@implementation PBGitRevList
|
||||
|
||||
@synthesize commits;
|
||||
@synthesize commits, grapher;
|
||||
- initWithRepository: (id) repo andRevListParameters: (NSArray*) params
|
||||
{
|
||||
parameters = params;
|
||||
@@ -101,10 +102,16 @@
|
||||
}
|
||||
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:YES];
|
||||
|
||||
PBGitGrapher* g = [[PBGitGrapher alloc] init];
|
||||
[g parseCommits: self.commits];
|
||||
[self performSelectorOnMainThread:@selector(setGrapher:) withObject:g waitUntilDone:YES];
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:YES];
|
||||
|
||||
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:start];
|
||||
NSLog(@"Loaded %i commits in %f seconds", num, duration);
|
||||
|
||||
[NSThread exit];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
+4
-2
@@ -7,10 +7,12 @@
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "PBGitGrapher.h"
|
||||
|
||||
@interface PBGitRevisionCell : NSTextFieldCell {
|
||||
NSNumber* commit;
|
||||
PBGitCellInfo cellInfo;
|
||||
BOOL isReady;
|
||||
}
|
||||
|
||||
@property(retain) NSNumber* commit;
|
||||
@property(assign) PBGitCellInfo cellInfo;
|
||||
@end
|
||||
|
||||
+81
-36
@@ -10,15 +10,79 @@
|
||||
|
||||
|
||||
@implementation PBGitRevisionCell
|
||||
@synthesize commit;
|
||||
|
||||
@synthesize cellInfo;
|
||||
-(void) setCellInfo: (PBGitCellInfo) info
|
||||
{
|
||||
isReady = YES;
|
||||
cellInfo = info;
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (id) coder
|
||||
{
|
||||
self = [super initWithCoder:coder];
|
||||
if (self != nil) {
|
||||
isReady = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSArray*) colors
|
||||
{
|
||||
return [NSArray arrayWithObjects:[NSColor redColor], [NSColor blueColor],
|
||||
[NSColor orangeColor], [NSColor blackColor], [NSColor greenColor], nil];
|
||||
}
|
||||
|
||||
- (void) drawLineFromColumn: (int) from toColumn: (int) to inRect: (NSRect) r offset: (int) offset
|
||||
{
|
||||
|
||||
int columnWidth = 10;
|
||||
NSPoint origin = r.origin;
|
||||
|
||||
NSPoint source = NSMakePoint(origin.x + columnWidth* from, origin.y + offset);
|
||||
NSPoint center = NSMakePoint( origin.x + columnWidth * to, origin.y + r.size.height * 0.5);
|
||||
|
||||
// Just use red for now.
|
||||
[[[self colors] objectAtIndex:0] set];
|
||||
|
||||
NSBezierPath * path = [NSBezierPath bezierPath];
|
||||
[path setLineWidth:2];
|
||||
|
||||
[path moveToPoint: source];
|
||||
[path lineToPoint: center];
|
||||
[path stroke];
|
||||
|
||||
}
|
||||
|
||||
- (void) drawCircleForColumn: (int) c inRect: (NSRect) r
|
||||
{
|
||||
NSArray* col = [NSArray arrayWithObjects:[NSColor redColor], [NSColor blueColor],
|
||||
[NSColor orangeColor], [NSColor blackColor], [NSColor greenColor], nil];
|
||||
|
||||
int columnWidth = 10;
|
||||
NSPoint origin = r.origin;
|
||||
NSPoint columnOrigin = { origin.x + columnWidth * c, origin.y};
|
||||
|
||||
NSRect oval = { columnOrigin.x - 5, columnOrigin.y + r.size.height * 0.5 - 5, 10, 10};
|
||||
|
||||
|
||||
NSBezierPath * path = [NSBezierPath bezierPath];
|
||||
path = [NSBezierPath bezierPathWithOvalInRect:oval];
|
||||
[[col objectAtIndex:cellInfo.columns[c].color] set];
|
||||
[path fill];
|
||||
|
||||
NSRect smallOval = { columnOrigin.x - 3, columnOrigin.y + r.size.height * 0.5 - 3, 6, 6};
|
||||
[[NSColor whiteColor] set];
|
||||
path = [NSBezierPath bezierPathWithOvalInRect:smallOval];
|
||||
[path fill];
|
||||
}
|
||||
|
||||
- (void) drawWithFrame: (NSRect) rect inView:(NSView *)view
|
||||
{
|
||||
|
||||
// Don't do all this drawing for now.
|
||||
[super drawWithFrame:rect inView:view];
|
||||
return;
|
||||
float pathWidth = 20;
|
||||
if (!isReady)
|
||||
return [super drawWithFrame:rect inView:view];
|
||||
|
||||
float pathWidth = 10 + 10 * cellInfo.numColumns;
|
||||
|
||||
NSRect ownRect;
|
||||
NSDivideRect(rect, &ownRect, &rect, pathWidth, NSMinXEdge);
|
||||
@@ -26,42 +90,23 @@
|
||||
// Adjust by removing the border
|
||||
ownRect.size.height += 2;
|
||||
ownRect.origin.y -= 1;
|
||||
ownRect.origin.x += 10;
|
||||
|
||||
NSPoint origin = ownRect.origin;
|
||||
NSPoint middle = { origin.x + pathWidth / 2, origin.y + ownRect.size.height * 0.5 };
|
||||
int column = 0;
|
||||
|
||||
[[NSColor redColor] set];
|
||||
NSBezierPath * path = [NSBezierPath bezierPath];
|
||||
[path moveToPoint:NSMakePoint(middle.x, origin.y)];
|
||||
[path setLineWidth:2];
|
||||
[path lineToPoint: NSMakePoint(middle.x, origin.y + ownRect.size.height)];
|
||||
[path stroke];
|
||||
[path setLineWidth:1];
|
||||
|
||||
// We can't iterate over numColumns here, as there may be connections to be drawn outside our columns.
|
||||
for (column = 0; column < PBGitMaxColumns; column++) {
|
||||
if (cellInfo.upperMapping[column] !=-1)
|
||||
[self drawLineFromColumn:column toColumn: cellInfo.upperMapping[column] inRect:ownRect offset: 0];
|
||||
if (cellInfo.lowerMapping[column] !=-1)
|
||||
[self drawLineFromColumn: column toColumn: cellInfo.lowerMapping[column] inRect:ownRect offset: ownRect.size.height];
|
||||
}
|
||||
|
||||
NSRect oval = { middle.x - 5, middle.y -5, 10, 10};
|
||||
[[NSColor orangeColor] set];
|
||||
path = [NSBezierPath bezierPathWithOvalInRect:oval];
|
||||
[path fill];
|
||||
[self drawCircleForColumn: cellInfo.position inRect: ownRect];
|
||||
|
||||
if ([self.commit intValue] == 0)
|
||||
[[NSColor redColor] set];
|
||||
else
|
||||
[[NSColor blueColor] set];
|
||||
|
||||
[path stroke];
|
||||
|
||||
NSRect smallOval = { middle.x - 3, middle.y - 3, 6, 6};
|
||||
[[NSColor whiteColor] set];
|
||||
path = [NSBezierPath bezierPathWithOvalInRect:smallOval];
|
||||
[path fill];
|
||||
[[NSColor blackColor] set];
|
||||
[path stroke];
|
||||
|
||||
|
||||
[super drawWithFrame:rect inView:view];
|
||||
[[NSColor blueColor] set];
|
||||
//[path stroke];
|
||||
isReady = NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
These tests demonstrate 3 different ways to allocate memory for the graph
|
||||
viewer.
|
||||
|
||||
The methods:
|
||||
|
||||
1. global
|
||||
This method allocates a global memory pool that is used by all structs.
|
||||
It is the fastest method and should be easy to clean up. You do have to
|
||||
make sure that any pointers to the memory used by others is cleaned up.
|
||||
1. malloc
|
||||
This methods does two mallocs for every iteration. It is slightly slower
|
||||
(2x as slow), but won't require as much unfragmented memory. It is harder
|
||||
to clean up this memory, as it requires an equal amount of free's.
|
||||
2. array
|
||||
This method uses NSMutableArray's to store the necessary information. It is
|
||||
by far the slowest (10x slower than global) but will make use of
|
||||
Objective-C's garbage collection. This is the easiest way to go if it isn't
|
||||
too slow. Looping and creating the arrays takes about 2 seconds for 800k
|
||||
iterations. The question is if this significantly slows down the work.
|
||||
|
||||
Results:
|
||||
|
||||
global: 0.18 seconds
|
||||
malloc: 0.39 seconds
|
||||
array: 1.90 seconds
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <xlocale.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
int main() {
|
||||
srandomdev();
|
||||
|
||||
int i = 0; struct list* last;
|
||||
int num = atoi("8000000");
|
||||
|
||||
int size = 1000;
|
||||
int totColumns = 10000;
|
||||
int currentColumn = 0;
|
||||
|
||||
NSMutableArray* array = [NSMutableArray arrayWithCapacity: 100*size];
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
int numColumns = i % 5;
|
||||
|
||||
NSMutableArray* arr = [NSMutableArray arrayWithCapacity: numColumns];
|
||||
int j;
|
||||
for (j = 0; j < numColumns; j++)
|
||||
[arr addObject: @"Ha"];
|
||||
[array addObject: arr];
|
||||
}
|
||||
|
||||
[array release];
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <xlocale.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
struct list {
|
||||
void* columns;
|
||||
int numColumns;
|
||||
};
|
||||
struct hash {
|
||||
char value[40];
|
||||
};
|
||||
|
||||
int main() {
|
||||
srandomdev();
|
||||
|
||||
int i = 0; struct list* last;
|
||||
int num = atoi("8000000");
|
||||
|
||||
int size = 1000;
|
||||
int totColumns = 10000;
|
||||
int currentColumn = 0;
|
||||
|
||||
/* Initialize initial list of revisions */
|
||||
struct list* revisionList = malloc(size * sizeof(struct list));
|
||||
struct hash* columns = malloc(totColumns * sizeof(struct hash));
|
||||
|
||||
struct hash standardColumn;
|
||||
strcpy(standardColumn.value, "Haha pieter");
|
||||
for (i = 0; i < num; i++) {
|
||||
if (size <= i) {
|
||||
size *= 2;
|
||||
revisionList = realloc(revisionList, size * sizeof(struct list));
|
||||
}
|
||||
|
||||
struct list* a = revisionList + i;
|
||||
a->numColumns = i % 5;
|
||||
if (currentColumn + a->numColumns > totColumns) {
|
||||
totColumns *= 2;
|
||||
printf("Reallocing columns. New total: %i\n", totColumns);
|
||||
columns = realloc(columns, totColumns * sizeof(struct hash));
|
||||
}
|
||||
int j;
|
||||
for (j = 0; j < a->numColumns; j++) {
|
||||
//ccolumns[currentColumn++] = st
|
||||
strncpy(columns[currentColumn++].value, "Haha pieter is cool", 20);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Num value at 3000 is: %i vs %i\n", revisionList[3000].numColumns, (int) (5 * random()));
|
||||
printf("Value of 1000'd column is: %s\n", columns[1000].value);
|
||||
sleep(5);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <xlocale.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
struct list {
|
||||
struct hash* columns;
|
||||
int numColumns;
|
||||
};
|
||||
struct hash {
|
||||
char value[40];
|
||||
};
|
||||
|
||||
int main() {
|
||||
srandomdev();
|
||||
|
||||
int i = 0; struct list* last;
|
||||
int num = atoi("8000000");
|
||||
|
||||
int size = 1000;
|
||||
/* Initialize initial list of revisions */
|
||||
struct list** revisionList = malloc(size * sizeof(struct list*));
|
||||
|
||||
struct hash standardColumn;
|
||||
strcpy(standardColumn.value, "Haha pieter");
|
||||
for (i = 0; i < num; i++) {
|
||||
if (size <= i) {
|
||||
size *= 2;
|
||||
revisionList = realloc(revisionList, size * sizeof(struct list*));
|
||||
}
|
||||
|
||||
struct list* a = malloc(sizeof(struct list));
|
||||
revisionList[i] = a;
|
||||
|
||||
a->numColumns = i % 5;
|
||||
a->columns = malloc(a->numColumns * sizeof(struct hash));
|
||||
int j;
|
||||
for (j = 0; j < a->numColumns; j++) {
|
||||
//ccolumns[currentColumn++] = st
|
||||
strncpy(a->columns[j].value, "Haha pieter is cool", 20);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Num value at 3000 is: %i vs %i\n", revisionList[3000]->numColumns, (int) (5 * random()));
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user