1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-23 20:59:10 +03:00

python/graph: rework shorten_vertex_names to not need edges

This will be necessary for the forthcoming full_matrix function.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Douglas Bagnall
2018-06-01 16:39:19 +12:00
committed by Andrew Bartlett
parent 4f7638f8ab
commit 6813e1b3c2

View File

@ -61,91 +61,82 @@ def quote_graph_label(s, reformat=False):
return "%s" % s
def shorten_vertex_names(edges, vertices, suffix=',...', aggressive=False):
def shorten_vertex_names(vertices, suffix=',...', aggressive=False):
"""Replace the common suffix (in practice, the base DN) of a number of
vertices with a short string (default ",..."). If this seems
pointless because the replaced string is very short or the results
seem strange, the original vertices are retained.
:param edges: a sequence of vertex pairs to shorten
:param vertices: a sequence of vertices to shorten
:param suffix: the replacement string [",..."]
:param aggressive: replace certain common non-suffix strings
:return: tuple of (edges, vertices, replacement)
:return: tuple of (rename map, replacements)
If no change is made, the returned edges and vertices will be the
original lists and replacement will be None.
If a change is made, replacement will be a tuple (new, original)
indicating the new suffix that replaces the old.
The rename map is a dictionary mapping the old vertex names to
their shortened versions. If no changes are made, replacements
will be empty.
"""
vlist = list(set(x[0] for x in edges) |
set(x[1] for x in edges) |
set(vertices))
vmap = dict((v, v) for v in vertices)
replacements = []
if len(vlist) < 2:
return edges, vertices, None
if len(vmap) > 1:
# walk backwards along all the strings until we meet a character
# that is not shared by all.
i = -1
vlist = vmap.values()
try:
while True:
c = set(x[i] for x in vlist)
if len(c) > 1 or c == {'*'}:
break
i -= 1
except IndexError:
# We have indexed beyond the start of a string, which should
# only happen if one node is a strict suffix of all others.
return vmap, replacements
# walk backwards along all the strings until we meet a character
# that is not shared by all.
i = -1
try:
while True:
c = set(x[i] for x in vlist)
if len(c) > 1:
break
i -= 1
except IndexError:
# We have indexed beyond the start of a string, which should
# only happen if one node is a strict suffix of all others.
return edges, vertices, None
# add one to get to the last unanimous character.
i += 1
# now, we actually really want to split on a comma. So we walk
# back to a comma.
x = vlist[0]
while i < len(x) and x[i] != ',':
# add one to get to the last unanimous character.
i += 1
if i >= -len(suffix):
# there is nothing to gain here
return edges, vertices, None
# now, we actually really want to split on a comma. So we walk
# back to a comma.
x = vlist[0]
while i < len(x) and x[i] != ',':
i += 1
edges2 = []
vertices2 = []
if i >= -len(suffix):
# there is nothing to gain here
return vmap, replacements
for a, b in edges:
edges2.append((a[:i] + suffix, b[:i] + suffix))
for a in vertices:
vertices2.append(a[:i] + suffix)
replacements.append((suffix, x[i:]))
replacements = [(suffix, a[i:])]
for k, v in vmap.items():
vmap[k] = v[:i] + suffix
if aggressive:
# Remove known common annoying strings
map = dict((v, v) for v in vertices2)
for v in vertices2:
for v in vmap.values():
if ',CN=Servers,' not in v:
break
else:
map = dict((k, v.replace(',CN=Servers,', ',**,'))
for k, v in map.items())
vmap = dict((k, v.replace(',CN=Servers,', ',**,', 1))
for k, v in vmap.items())
replacements.append(('**', 'CN=Servers'))
for v in vertices2:
for v in vmap.values():
if not v.startswith('CN=NTDS Settings,'):
break
else:
map = dict((k, v.replace('CN=NTDS Settings,', '*,'))
for k, v in map.items())
vmap = dict((k, v.replace('CN=NTDS Settings,', '*,', 1))
for k, v in vmap.items())
replacements.append(('*', 'CN=NTDS Settings'))
edges2 = [(map.get(a, a), map.get(b, b)) for a, b in edges2]
vertices2 = [map.get(a, a) for a in vertices2]
return vmap, replacements
return edges2, vertices2, replacements
def compile_graph_key(key_items, nodes_above=[], elisions=None,
@ -292,7 +283,13 @@ def dot_graph(vertices, edges,
vertices = set(x[0] for x in edges) | set(x[1] for x in edges)
if shorten_names:
edges, vertices, elisions = shorten_vertex_names(edges, vertices)
vlist = list(set(x[0] for x in edges) |
set(x[1] for x in edges) |
set(vertices))
vmap, elisions = shorten_vertex_names(vlist)
vertices = [vmap[x] for x in vertices]
edges = [(vmap[a], vmap[b]) for a, b in edges]
else:
elisions = None
@ -566,10 +563,14 @@ def distance_matrix(vertices, edges,
colour_list = [next(colour_cycle) for v in vertices]
if shorten_names:
edges, vertices, replacements = shorten_vertex_names(edges,
vertices,
'+',
aggressive=True)
vlist = list(set(x[0] for x in edges) |
set(x[1] for x in edges) |
set(vertices))
vmap, replacements = shorten_vertex_names(vlist, '+',
aggressive=True)
vertices = [vmap[x] for x in vertices]
edges = [(vmap[a], vmap[b]) for a, b in edges]
vlen = max(6, max(len(v) for v in vertices))