Current section
Files
Jump to
Current section
Files
lib/graph/implementations/map_impl.ex
defmodule Paradigm.Graph.MapImpl do
@moduledoc """
A map-based implementation of the Graph behaviour for handling in-memory data.
"""
@behaviour Paradigm.Graph
alias Paradigm.Graph.Node
@type t :: %{Paradigm.id() => Node.t()}
@impl true
def new(), do: %{}
@impl true
def get_all_nodes(graph) do
Map.keys(graph)
end
@impl true
def get_all_classes(graph) do
graph
|> Map.values()
|> Enum.map(& &1.class)
|> Enum.uniq()
end
@impl true
def get_node(graph, node_id) do
graph[node_id]
end
@impl true
def insert_node(graph, node_id, class, data \\ %{}) do
Map.put(graph, node_id, %Node{class: class, data: data})
end
@impl true
def insert_nodes(graph, nodes) when is_map(nodes) do
Map.merge(graph, nodes)
end
@impl true
def insert_nodes(graph, nodes) when is_list(nodes) do
Enum.reduce(nodes, graph, fn {id, node}, acc ->
Map.put(acc, id, node)
end)
end
@impl true
def get_all_nodes_of_class(graph, class_ids) when is_list(class_ids) do
graph
|> Enum.filter(fn {_id, node} -> node.class in class_ids end)
|> Enum.map(fn {id, _node} -> id end)
end
@impl true
def get_all_nodes_of_class(graph, class_id) do
get_all_nodes_of_class(graph, [class_id])
end
@impl true
def get_node_data(graph, node_id, key, default \\ nil) do
case graph[node_id] do
%Node{data: data} -> Map.get(data, key, default)
nil -> default
end
end
@impl true
def follow_reference(graph, node_id, reference_key) do
case get_node_data(graph, node_id, reference_key) do
nil -> nil
ref_id -> graph[ref_id]
end
end
end