52
52
directparentcache[childindex] = directparent
53
53
return directparent
55
def find_column_from_branchlineid(branchlineid):
56
for index, column in enumerate(columns):
57
if column is not None and column["branchlineid"] == branchlineid:
58
return (index, column)
61
def find_finished_child_column(index, children):
62
for childrevid in children:
63
childbranchlineid = branchlineids[revindex[childrevid]]
64
(columnindex, column) = \
65
find_column_from_branchlineid(childbranchlineid)
66
if column is not None and column["maxindex"] <= index:
67
return (columnindex, column)
70
def has_no_nodes_between (column, startindex, endindex):
71
for nodeindex in column["nodeindexes"]:
72
if nodeindex > startindex and nodeindex < endindex:
76
def append_line (column , startindex, endindex):
77
column["lines"].append((startindex,endindex))
78
if endindex > column["maxindex"] :
79
column["maxindex"] = endindex
57
#This will hold the branchlines that we are current tracking.
58
#The position of the branchline in this list indicates the column, and it
59
#it may change if we need to make space for other branchlines.
60
#Each typle in the list is in the form (child index, parent revision)
61
#A item may be None to indicate that there is no line for a column
82
# This will hold what we plan to put in each column.
83
# The position of the item in this list indicates the column, and it
84
# it may change if we need to make space for other things.
85
# Each typle in the list is in the form:
86
# (branchlineid, nodeindexes, lines, maxindex)
87
# A item may be None to indicate that there is nothing in the column
94
revisionchildren = [[] for revision in revisions]
68
96
for (index, revision) in enumerate(revisions):
69
parents = [parent for parent in revisionparents[index]\
97
parents = [parent for parent in revisionparents[index] \
70
98
if parent!="null:"]
74
#This will hold a list of branchlines whose parent is this rev
75
branchlinesforrev = []
79
#We should maybe should pop None's at the end of branchlines.
80
#I'm not sure what will cost more: resizing the list, or
81
#have this loop ittrate more.
83
#Find lines that end at this rev
84
for (column, branchline) in enumerate(branchlines):
85
if (branchline is not None):
86
(childindex, parentrevid) = branchline
87
if parentrevid == revision.revision_id:
88
branchlinesforrev.append((childindex, parentrevid, column))
89
branchlines[column] = None
90
children.append(linegraph[childindex][0].revision_id)
92
#The node column for this rev will be the smallest
93
#column for the lines that end at this rev
94
#The smallest column is the first one we get to.
95
if revnodecolumn is None:
96
revnodecolumn = column
98
#This will happen for the latest revision
99
if revnodecolumn is None:
105
#Try and see if we are the same "branch" as one of our children
106
#If we are, use the childs colour
107
for childrevid in children:
99
for parentrevid in parents:
100
if parentrevid in revindex:
101
revisionchildren[revindex[parentrevid]]\
102
.append(revision.revision_id)
104
children = revisionchildren[index]
105
linegraph.append([revision, None,
106
[], parents, children])
109
#Try and see if we are the same branchline as one of our children
110
#If we are, use the same branchlineid
111
for childrevid in children:
108
112
childindex = revindex[childrevid]
109
113
childsparents = revisionparents[childindex]
110
childcolour = linegraph[childindex][1][1]
111
childcolours.append(childcolour)
114
childbranchlineid = branchlineids[childindex]
113
116
if len(children) == 1 and len(childsparents) == 1:
114
# one-one relationship between parent and child, same colour
115
#1st [1] selects the node
116
#2nd [1] selects the colour
117
# one-one relationship between parent and child
118
branchlineid = childbranchlineid
120
121
#Is the current revision the direct parent of the child?
121
122
if revision.revision_id == \
122
123
getdirectparent(childindex, childsparents):
124
branchlineid = childbranchlineid
127
# 6 is the len of the colourwheel in graphcell
129
while (colour is None or colour in childcolours):
130
colour = lastcolour = (lastcolour + 1) % 6
127
if branchlineid is None:
128
branchlineid = lastbranchlineid = lastbranchlineid + 1
130
branchlineids.append(branchlineid)
132
(columnindex, column) = find_column_from_branchlineid(branchlineid)
134
if columnindex is None:
135
(columnindex, column) = find_finished_child_column(index, children)
138
if columnindex is None:
139
columnindex = len(columns)
140
column = {"branchlineid": branchlineid,
141
"nodeindexes": [index],
144
columns.append(column)
146
column["branchlineid"] = branchlineid
147
column["nodeindexes"].append(index)
149
opentillparent = getdirectparent(index, parents)
150
if opentillparent == "":
152
opentillparent = parents[0]
132
#If this is getting hit, we should increase the size of the
134
colour = lastcolour = (lastcolour + 1) % 6
154
opentillparent = None
156
if opentillparent is not None and opentillparent in revindex:
157
parentindex = revindex[opentillparent]
158
if parentindex > column["maxindex"]:
159
column["maxindex"] = parentindex
161
for childrevid in children:
162
childindex = revindex[childrevid]
163
childbranchlineid = branchlineids[childindex]
164
(childcolumnindex, childcolumn) = \
165
find_column_from_branchlineid(childbranchlineid)
137
#We now have every thing (except for the lines) so we can add
138
#our tuple to our list.
139
linegraph.append((revision, (revnodecolumn, colour),
140
[], parents, children))
142
#add all the line bits to the rev that the branchline passes
143
for (childindex, parentrevid, column) in branchlinesforrev:
144
if index>childindex+1:
145
#out from the child to line
146
linegraph[childindex][2].append(
147
(linegraph[childindex][1][0], #the column of the child
148
column, #the column of the line
152
for linepartindex in range(childindex+1, index-1):
153
linegraph[linepartindex][2].append(
154
(column, #the column of the line
155
column, #the column of the line
159
linegraph[index-1][2].append(
160
(column, #the column of the line
161
revnodecolumn, #the column of the parent
167
if index-childindex == 1 or childcolumnindex is None:
168
append_line(column,childindex,index)
169
elif childcolumnindex >= columnindex and \
170
has_no_nodes_between(childcolumn, childindex, index):
171
append_line(childcolumn,childindex,index)
172
elif childcolumnindex > columnindex and \
173
has_no_nodes_between(column, childindex, index):
174
append_line(column,childindex,index)
175
elif childcolumnindex < columnindex and \
176
has_no_nodes_between(column, childindex, index):
177
append_line(column,childindex,index)
178
elif childcolumnindex < columnindex and \
179
has_no_nodes_between(childcolumn, childindex, index):
180
append_line(childcolumn,childindex,index)
165
linegraph[childindex][2].append(
166
(linegraph[childindex][1][0], #the column of the child
167
revnodecolumn, #the column of the parent
170
for parentrevid in parents:
171
column = revnodecolumn
172
branchline = (index,parentrevid)
174
if column<len(branchlines):
175
if branchlines[column] is None:
176
#An empty column. Put line here
177
branchlines[column] = branchline
182
columns.append({"branchlineid": None,
184
"lines": [(childindex,index)],
187
num_of_unfinished_cols = 0
188
for (columnindex, column) in enumerate(columns):
189
if column is not None and column["maxindex"] > index:
190
num_of_unfinished_cols += 1
192
if num_of_unfinished_cols == 1:
193
for (columnindex, column) in enumerate(columns):
194
if column is not None:
195
for nodeindex in column["nodeindexes"]:
196
linegraph[nodeindex][1] = (columnindex,
197
branchlineids[nodeindex])
199
for (columnindex, column) in enumerate(columns):
200
for (childindex, parentindex) in column["lines"]:
201
childnode = linegraph[childindex][1]
202
parentnode = linegraph[parentindex][1]
203
if parentindex>childindex+1:
204
#out from the child to line
205
linegraph[childindex][2].append(
206
(childnode[0], #the column of the child
207
columnindex, #the column of the line
211
for linepartindex in range(childindex+1, parentindex-1):
212
linegraph[linepartindex][2].append(
213
(columnindex, #the column of the line
214
columnindex, #the column of the line
218
linegraph[parentindex-1][2].append(
219
(columnindex, #the column of the line
220
parentnode[0], #the column of the parent
180
if branchlines[column][0] == index:
181
#This column is allready used for a line for
182
#this rev, Move along.
185
#This column is allready used for a line for another
188
#See if there is a None after us that we could
189
#move the lines after us into
192
range(column+1,len(branchlines)):
193
if branchlines[i] is None:
197
if movetocolumn is None:
198
#No None was found. Insert line here
199
branchlines.insert(column, branchline)
201
#Move the lines after us out to the None
203
reversed(range(column,movetocolumn)):
204
branchlines[movecolumn+1] = \
205
branchlines[movecolumn]
207
branchlines[column] = branchline
224
linegraph[childindex][2].append(
225
(childnode[0], #the column of the child
226
parentnode[0], #the column of the parent
229
if column["maxindex"] <= index:
230
columns[columnindex] = None
211
#no more columns, so add one to the end
212
branchlines.append(branchline)
232
columns[columnindex]["nodeindexes"] = []
233
columns[columnindex]["lines"] = []
234
columns = [column for column in columns if column is not None]