Closed aymanosman closed 5 months ago
As of libgraph 1.16 this isn't fixed; Also btw it's not only an infinite loop but a rapid memory leak. https://asciinema.org/a/HKCGZkPMeTxQcxu4gn083Pse7
This appears to be due to this bit of code:
@spec add_vertex(t, vertex, label) :: t
def add_vertex(g, v, labels \\ [])
def add_vertex(
%__MODULE__{vertices: vs, vertex_labels: vl, vertex_identifier: vertex_identifier} = g,
v,
labels
)
when is_list(labels) do
id = vertex_identifier.(v)
case Map.get(vs, id) do
nil ->
%__MODULE__{g | vertices: Map.put(vs, id, v), vertex_labels: Map.put(vl, id, labels)}
_ ->
g
end
end
def add_vertex(g, v, label) do
add_vertex(g, v, [label])
end
When you call add_vertex(nil, vertex)
a default empty list gets supplied as the label. Because nil
does not match the function head that requires g
to be %__MODULE__{}
it tries to match the next def which is add_vertex(g, v, label)
with no guards. So the empty list gets wrapped in another list and supplied to another call for add_vertex(nil, v, [label])
. This will still only match the same function head and keep wrapping label in lists for eternity. The easiest fix is likely to just make the last function head also match g
on a %__MODULE__{}
or to make label
match on not is_list
.
def add_vertex(%__MODULE__{} = g, v, label) do
add_vertex(g, v, [label])
end
def add_vertex(g, v, label) when not is_list(label) do
add_vertex(g, v, [label])
end
PR here
The following code results in an infinite loop: