Packages

A library for distributed reactive programming with flexible consistency guarantees drawing from QUARP and Rx.. Features the familiar behaviours and event streams in the spirit of FRP.

Current section

Files

Jump to
bquarp lib evaluation graph graph_creation.ex
Raw

lib/evaluation/graph/graph_creation.ex

defmodule Evaluation.Graph.GraphCreation do
@moduledoc false
alias Evaluation.Graph
def generateGraph(params) do
Graph.new(Keyword.get(params, :hosts))
|> generateVars(Keyword.get(params, :nb_of_vars))
|> generateSignalLevels(params)
end
defp generateVars(g, 0), do: g
defp generateVars(g, n) when is_integer(n) and n > 0 do
hosts = Graph.getHosts(g)
host = Enum.at(hosts, :rand.uniform(Enum.count(hosts))-1)
new_v = String.to_atom("var" <> Integer.to_string(n))
new_g = Graph.addVar(g, new_v, host)
generateVars(new_g, n-1)
end
defp generateSignalLevels(g, params) do
l = Keyword.get(params, :graph_depth)
generateSignalLevels(g, params, l)
end
defp generateSignalLevels(g, _params, 1), do: g
defp generateSignalLevels(g, params, k) when is_integer(k) and k > 1 do
n_avg = Keyword.get(params, :signals_per_level_avg)
n_act = :rand.uniform(2*n_avg - 1)
l = Keyword.get(params, :graph_depth) - k + 2
ss = generateSignals(g, params, l, n_act, [])
new_g = addSignals(g, ss)
generateSignalLevels(new_g, params, k-1)
end
defp generateSignals(_g, _params, _l, 0, ss), do: ss
defp generateSignals(g, params, l, n, ss) do
n_deps_avg = Keyword.get(params, :deps_per_signal_avg)
n_deps_act =
case n_deps_avg do
1 -> 1
2 -> :rand.uniform(3)
3 -> :rand.uniform(3) + 1
_ -> raise "deps_per_signal_avg set too high! Locality parameter not independent anymore."
end
new_sig = String.to_atom("sig" <> Integer.to_string(l) <> Integer.to_string(n))
deps = chooseDeps(g, l, n_deps_act, [])
host = chooseHost(g, params, deps)
generateSignals(g, params, l, n-1, [{new_sig, {host, deps}} | ss])
end
defp chooseDeps(_g, _l, 0, deps), do: deps
defp chooseDeps(g, l, n, []) do
pool = Graph.getNodesAtLevel(g, l-1)
dep = Enum.at(pool, :rand.uniform(Enum.count(pool))-1)
chooseDeps(g, l, n-1, [dep])
end
defp chooseDeps(g, l, n, deps) do
pool = Graph.getNodes(g) -- deps
dep = Enum.at(pool, :rand.uniform(Enum.count(pool))-1)
chooseDeps(g, l, n-1, [dep | deps])
end
defp chooseHost(g, params, deps) do
locality = Keyword.get(params, :nodes_locality)
localHosts =
deps
|> Enum.map(fn d -> Graph.getHost(g, d) end)
|> Enum.uniq
remoteHosts = Graph.getHosts(g) -- localHosts
r = :rand.uniform
hostPool =
cond do
r > locality -> localHosts
r <= locality -> remoteHosts
end
Enum.at(hostPool, :rand.uniform(Enum.count(hostPool))-1)
end
defp addSignals(g, []), do: g
defp addSignals(g, [{sig, {host, deps}} | ss]) do
g_new = Graph.addSignal(g, sig, host, deps)
addSignals(g_new, ss)
end
end