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 addnode(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 delnode(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 allnodes(self): |
346 |
"returns all nodes in the dictionary" |
367 |
return self.order[:] |
347 |
return self.dict.keys() |
|
|
348 |
|
368 |
|
349 |
def firstzero(self): |
369 |
def firstzero(self): |
350 |
"returns first node with zero references, or NULL if no such node exists" |
370 |
"""Returns the first node with no children or else the first node |
351 |
for x in self.okeys: |
371 |
only soft-deps on children. Returns None if all children on every |
352 |
if self.dict[x][0]==0: |
372 |
node are hard-deps.""" |
353 |
return x |
373 |
|
|
|
374 |
for node in self.order: |
375 |
if not self.nodes[node][0]: |
376 |
return node |
354 |
return None |
377 |
return None |
355 |
|
378 |
|
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): |
379 |
def allzeros(self): |
364 |
"returns all nodes with zero references, or NULL if no such node exists" |
380 |
zeros = [] |
365 |
zerolist = [] |
381 |
for node in self.nodes: |
366 |
for x in self.dict.keys(): |
382 |
if not self.nodes[node][0]: |
367 |
mys = string.split(x) |
383 |
zeros.append(node) |
368 |
if mys[0] != "blocks" and self.dict[x][0]==0: |
384 |
return zeros |
369 |
zerolist.append(x) |
385 |
|
370 |
return zerolist |
386 |
def depth(self, node): |
|
|
387 |
"""Find how many nodes are in the parent chain of the passed node |
388 |
|
389 |
This method doesn't make sense unless there is no more than one |
390 |
parent for each node. As this digraph is capable of having multiple |
391 |
parents on a node, this implementation chooses an arbitrary parent |
392 |
for calculations, stopping as soon as a loop is detected in order |
393 |
to mimic the sorts of counts that would have previously been |
394 |
returned. |
395 |
|
396 |
This method is only used by emerge's --tree option. That option |
397 |
needs to be reworked to not use this so that this method can be |
398 |
removed altogether.""" |
399 |
|
400 |
parents = {} |
401 |
while self.nodes[node][1]: |
402 |
parent = self.nodes[node][1].keys()[0] |
403 |
if parent in parents: |
404 |
break |
405 |
parents[parent] = True |
406 |
node = parent |
407 |
return len(parents) |
371 |
|
408 |
|
372 |
def hasallzeros(self): |
409 |
def hasallzeros(self): |
373 |
"returns 0/1, Are all nodes zeros? 1 : 0" |
410 |
for node in self.nodes: |
374 |
zerolist = [] |
411 |
if self.nodes[node][0]: |
375 |
for x in self.dict.keys(): |
412 |
return False |
376 |
if self.dict[x][0]!=0: |
413 |
return True |
377 |
return 0 |
|
|
378 |
return 1 |
379 |
|
414 |
|
380 |
def empty(self): |
415 |
def empty(self): |
381 |
if len(self.dict)==0: |
416 |
"""Checks if the digraph is empty""" |
382 |
return 1 |
417 |
return len(self.nodes) == 0 |
383 |
return 0 |
|
|
384 |
|
418 |
|
385 |
def hasnode(self,mynode): |
419 |
def hasnode(self, node): |
386 |
return self.dict.has_key(mynode) |
420 |
"""Checks if the digraph contains mynode""" |
|
|
421 |
return node in self.nodes |
387 |
|
422 |
|
388 |
def copy(self): |
423 |
def copy(self): |
389 |
mygraph=digraph() |
424 |
clone = digraph() |
390 |
for x in self.dict.keys(): |
425 |
clone.nodes = copy.deepcopy(self.nodes) |
391 |
mygraph.dict[x]=self.dict[x][:] |
426 |
clone.order = self.order[:] |
392 |
mygraph.okeys=self.okeys[:] |
427 |
return clone |
393 |
return mygraph |
428 |
|
|
|
429 |
def child_nodes(self, node): |
430 |
return self.nodes[node][0].keys() |
431 |
|
432 |
def parent_nodes(self, node): |
433 |
return self.nodes[node][1].keys() |
434 |
|
394 |
|
435 |
|
395 |
def elog_process(cpv, mysettings): |
436 |
def elog_process(cpv, mysettings): |
396 |
mylogfiles = listdir(mysettings["T"]+"/logging/") |
437 |
mylogfiles = listdir(mysettings["T"]+"/logging/") |