Lines 313-396
Link Here
|
313 |
|
313 |
|
314 |
class digraph: |
314 |
class digraph: |
315 |
def __init__(self): |
315 |
def __init__(self): |
316 |
self.dict={} |
316 |
"""Create an empty digraph""" |
317 |
#okeys = keys, in order they were added (to optimize firstzero() ordering) |
317 |
|
318 |
self.okeys=[] |
318 |
# { node : ( { child : hard_dep } , { parent : hard_dep } ) } |
319 |
|
319 |
self.nodes = {} |
320 |
def addnode(self,mykey,myparent): |
320 |
self.order = [] |
321 |
if not self.dict.has_key(mykey): |
321 |
|
322 |
self.okeys.append(mykey) |
322 |
def add(self, node, parent, hard_dep=True): |
323 |
if myparent is None: |
323 |
"""Adds the specified node with the specified parent. If the dep |
324 |
self.dict[mykey]=[0,[]] |
324 |
is a hard-dep and the node already has a relationship to the parent |
325 |
else: |
325 |
the relationship is ensured to be hard.""" |
326 |
self.dict[mykey]=[0,[myparent]] |
326 |
|
327 |
self.dict[myparent][0]=self.dict[myparent][0]+1 |
327 |
if node not in self.nodes: |
|
|
328 |
self.nodes[node] = ({}, {}) |
329 |
self.order.append(node) |
330 |
|
331 |
if not parent: |
328 |
return |
332 |
return |
329 |
if myparent and (not myparent in self.dict[mykey][1]): |
333 |
|
330 |
self.dict[mykey][1].append(myparent) |
334 |
if parent not in self.nodes: |
331 |
self.dict[myparent][0]=self.dict[myparent][0]+1 |
335 |
self.nodes[parent] = ({}, {}) |
332 |
|
336 |
self.order.append(parent) |
333 |
def delnode(self,mykey): |
337 |
|
334 |
if not self.dict.has_key(mykey): |
338 |
if parent in self.nodes[node][1]: |
|
|
339 |
if hard_dep: |
340 |
self.nodes[node][1][parent] = True |
341 |
else: |
342 |
self.nodes[node][1][parent] = hard_dep |
343 |
|
344 |
if node in self.nodes[parent][0]: |
345 |
if hard_dep: |
346 |
self.nodes[parent][0][node] = True |
347 |
else: |
348 |
self.nodes[parent][0][node] = hard_dep |
349 |
|
350 |
def remove(self, node): |
351 |
"""Removes the specified node from the digraph, also removing |
352 |
and ties to other nodes in the digraph. Does nothing if the node |
353 |
doesn't exist.""" |
354 |
|
355 |
if node not in self.nodes: |
335 |
return |
356 |
return |
336 |
for x in self.dict[mykey][1]: |
357 |
|
337 |
self.dict[x][0]=self.dict[x][0]-1 |
358 |
for parent in self.nodes[node][1]: |
338 |
del self.dict[mykey] |
359 |
del self.nodes[parent][0][node] |
339 |
while 1: |
360 |
for child in self.nodes[node][0]: |
340 |
try: |
361 |
del self.nodes[child][1][node] |
341 |
self.okeys.remove(mykey) |
362 |
|
342 |
except ValueError: |
363 |
del self.nodes[node] |
343 |
break |
364 |
self.order.remove(node) |
344 |
|
365 |
|
345 |
def allnodes(self): |
366 |
def contains(self, node): |
346 |
"returns all nodes in the dictionary" |
367 |
"""Checks if the digraph contains mynode""" |
347 |
return self.dict.keys() |
368 |
return node in self.nodes |
|
|
369 |
|
370 |
def all_nodes(self): |
371 |
return self.order[:] |
372 |
|
373 |
def child_nodes(self, node): |
374 |
return self.nodes[node][0].keys() |
375 |
|
376 |
def parent_nodes(self, node): |
377 |
return self.nodes[node][1].keys() |
378 |
|
379 |
def leaf_nodes(self, include_soft_deps=False): |
380 |
leaf_nodes = [] |
381 |
for node in self.nodes: |
382 |
is_leaf_node = True |
383 |
if include_soft_deps: |
384 |
for child in self.nodes[node][0]: |
385 |
if self.nodes[node][0][child]: |
386 |
is_leaf_node = False |
387 |
break |
388 |
if is_leaf_node: |
389 |
leaf_nodes.append(node) |
390 |
return leaf_nodes |
391 |
|
392 |
def is_empty(self): |
393 |
"""Checks if the digraph is empty""" |
394 |
return len(self.nodes) == 0 |
395 |
|
396 |
def clone(self): |
397 |
clone = digraph() |
398 |
clone.nodes = copy.deepcopy(self.nodes) |
399 |
clone.order = self.order[:] |
400 |
return clone |
401 |
|
402 |
# Backward compatibility |
403 |
addnode = add |
404 |
delnode = remove |
405 |
allnodes = all_nodes |
406 |
allzeros = leaf_nodes |
407 |
hasnode = contains |
408 |
empty = is_empty |
409 |
copy = clone |
348 |
|
410 |
|
349 |
def firstzero(self): |
411 |
def firstzero(self): |
350 |
"returns first node with zero references, or NULL if no such node exists" |
412 |
leaf_nodes = self.leaf_nodes() |
351 |
for x in self.okeys: |
413 |
if leaf_nodes: |
352 |
if self.dict[x][0]==0: |
414 |
return leaf_nodes[0] |
353 |
return x |
|
|
354 |
return None |
415 |
return None |
355 |
|
416 |
|
356 |
def depth(self, mykey): |
|
|
357 |
depth=0 |
358 |
while (self.dict[mykey][1]): |
359 |
depth=depth+1 |
360 |
mykey=self.dict[mykey][1][0] |
361 |
return depth |
362 |
|
363 |
def allzeros(self): |
364 |
"returns all nodes with zero references, or NULL if no such node exists" |
365 |
zerolist = [] |
366 |
for x in self.dict.keys(): |
367 |
mys = string.split(x) |
368 |
if mys[0] != "blocks" and self.dict[x][0]==0: |
369 |
zerolist.append(x) |
370 |
return zerolist |
371 |
|
372 |
def hasallzeros(self): |
417 |
def hasallzeros(self): |
373 |
"returns 0/1, Are all nodes zeros? 1 : 0" |
418 |
return len(self.leaf_nodes() == 0) |
374 |
zerolist = [] |
|
|
375 |
for x in self.dict.keys(): |
376 |
if self.dict[x][0]!=0: |
377 |
return 0 |
378 |
return 1 |
379 |
|
419 |
|
380 |
def empty(self): |
420 |
def depth(self, node): |
381 |
if len(self.dict)==0: |
421 |
"""Find how many nodes are in the parent chain of the passed node |
382 |
return 1 |
422 |
|
383 |
return 0 |
423 |
This method doesn't make sense unless there is no more than one |
|
|
424 |
parent for each node. As this digraph is capable of having multiple |
425 |
parents on a node, this implementation chooses an arbitrary parent |
426 |
for calculations, stopping as soon as a loop is detected in order |
427 |
to mimic the sorts of counts that would have previously been |
428 |
returned. |
429 |
|
430 |
This method is only used by emerge's --tree option. That option |
431 |
needs to be reworked to not use this so that this method can be |
432 |
removed altogether.""" |
433 |
|
434 |
parents = {} |
435 |
while self.nodes[node][1]: |
436 |
parent = self.nodes[node][1].keys()[0] |
437 |
if parent in parents: |
438 |
break |
439 |
parents[parent] = True |
440 |
node = parent |
441 |
return len(parents) |
384 |
|
442 |
|
385 |
def hasnode(self,mynode): |
|
|
386 |
return self.dict.has_key(mynode) |
387 |
|
443 |
|
388 |
def copy(self): |
|
|
389 |
mygraph=digraph() |
390 |
for x in self.dict.keys(): |
391 |
mygraph.dict[x]=self.dict[x][:] |
392 |
mygraph.okeys=self.okeys[:] |
393 |
return mygraph |
394 |
|
444 |
|
395 |
def elog_process(cpv, mysettings): |
445 |
def elog_process(cpv, mysettings): |
396 |
mylogfiles = listdir(mysettings["T"]+"/logging/") |
446 |
mylogfiles = listdir(mysettings["T"]+"/logging/") |