Skip to content

Instantly share code, notes, and snippets.

@tacticiankerala
Created February 21, 2018 22:35
Show Gist options
  • Save tacticiankerala/bda3fb9d482c0cf275c6a432fbd5730a to your computer and use it in GitHub Desktop.
Save tacticiankerala/bda3fb9d482c0cf275c6a432fbd5730a to your computer and use it in GitHub Desktop.
Naive Tree implementation in Elixir
defmodule Tree do
@moduledoc false
def create_job(reducer_pid, func) do
receive do
job_input -> send(reducer_pid, func.(job_input))
end
end
def mappers(_, _, [], job_pids), do: job_pids
def mappers(reducer_pid, func, [job_input | rest], job_pids) do
pid = spawn_link(Tree, :create_job, [reducer_pid, func])
send(pid, job_input)
mappers(reducer_pid, func, rest, [pid | job_pids])
end
def reducer(from_pid, job_count, acc) when job_count == length(acc), do: send(from_pid, acc)
def reducer(from_pid, job_count, acc) do
receive do
result -> reducer(from_pid, job_count, [result | acc])
end
end
def map_reduce(from_pid, func, inputs) do
reducer_pid = spawn_link(Tree, :reducer, [from_pid, Enum.count(inputs), []])
_ = mappers(reducer_pid, func, inputs, [])
end
def contents_of(dir_path) do
{:ok, dir_content} = File.ls(dir_path)
{directories, files} = Enum.split_with(dir_content, &File.dir?/1)
sub_dir_paths = Enum.map(directories, &(Path.join(dir_path, &1)))
[dir_path: dir_path, files: files, sub_directories: tree(sub_dir_paths)]
end
def tree(directories) do
task = Task.async(fn ->
map_reduce(self(), &contents_of/1, directories)
receive do
res -> res
end
end)
Task.await(task)
end
def main(args) do
IO.puts inspect(tree(args), pretty: true)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment