Current section
Files
Jump to
Current section
Files
lib/async.ex
defmodule Thoth.Async do
defp recv_loop(vids, 0), do: vids
defp recv_loop(vids, n) do
receive do
{:ok, vid} -> recv_loop([vid|vids], n - 1)
_ -> recv_loop(vids, n - 1)
end
end
defp limited_recv_loop(vids, 0), do: vids
defp limited_recv_loop(vids, n) do
receive do
{:ok, vid} -> limited_recv_loop([vid|vids], n - 1)
_ -> limited_recv_loop(vids, n)
end
end
defp spawn_chunk(graph, loop, filter, vtype, vids) do
spawn_link(fn ->
Enum.each vids, fn vid ->
case :digraph.vertex(graph, vid) do
{^vid, %{type: ^vtype}=node} ->
if filter.(node) do
send(loop, {:ok, vid})
else
send(loop, nil)
end
_ -> send(loop, nil)
end
end
end)
end
defp remote_filter(_, _, _, _, [], _), do: nil
defp remote_filter(graph, loop, filter, vtype, vids, chunk_size) do
spawn_chunk(graph, loop, filter, vtype, Enum.take(vids, chunk_size))
remote_filter(graph, loop, filter, vtype, Enum.drop(vids, chunk_size), chunk_size)
end
def find(graph, vtype, filter) do
parent = self()
rcv = spawn_link fn -> send(parent, recv_loop([], :digraph.no_vertices(graph))) end
remote_filter(graph, rcv, filter, vtype, :digraph.vertices(graph), round(Float.ceil(:digraph.no_vertices(graph) / 10.5)))
receive do
vids -> vids
end
end
def find(graph, vtype, filter, limit) do
parent = self()
rcv = spawn_link fn -> send(parent, limited_recv_loop([], limit)) end
remote_filter(graph, rcv, filter, vtype, :digraph.vertices(graph), round(Float.ceil(:digraph.no_vertices(graph) / 10.5)))
receive do
vids -> vids
end
end
def find(graph, vtype) do
find(graph, vtype, fn _ -> true end)
end
end