esdb_graph_nif (reckon_db v1.1.0)

View Source

Optimized graph operations for causation analysis in reckon-db.

This module provides high-performance graph algorithms:

  • Graph building: Build edges from event causation relationships
  • Topological sort: Order events by causation (causes before effects)
  • Path finding: Check paths, find ancestors/descendants
  • DOT export: Generate Graphviz visualization

The mode is automatically detected at startup based on whether the NIF library is available. Community edition users (hex.pm) will always use the Erlang fallbacks, which provide identical functionality.

Usage

  %% Build edges from events (event_id, causation_id pairs)
  Nodes = [{<<"evt-1">>, undefined}, {<<"evt-2">>, <<"evt-1">>}],
  Edges = esdb_graph_nif:build_edges(Nodes).
 
  %% Topological sort
  {ok, Sorted} = esdb_graph_nif:topo_sort([<<"evt-1">>, <<"evt-2">>], Edges).
 
  %% Check which mode is active
  nif = esdb_graph_nif:implementation().  %% Enterprise
  erlang = esdb_graph_nif:implementation(). %% Community

Summary

Functions

Build edges from a list of event_id, causation_id tuples.

Find leaf nodes (nodes with no outgoing edges).

Find root nodes (nodes with no incoming edges).

Get all ancestors of a node (nodes that can reach it).

Get all descendants of a node (nodes reachable from it).

Get graph statistics.

Check if the graph contains cycles.

Check if there's a path between two nodes.

Get the current implementation mode.

Check if the NIF is loaded (Enterprise mode).

Generate DOT format for Graphviz visualization.

Generate DOT format with simplified labels (just type).

Perform topological sort on the graph.

Functions

build_edges(Nodes)

-spec build_edges([{EventId :: binary(), CausationId :: binary() | undefined}]) ->
                     [{binary(), binary()}].

Build edges from a list of event_id, causation_id tuples.

Causation ID can be undefined for root events. Returns list of from_id, to_id edges.

find_leaves(Nodes, Edges)

-spec find_leaves(Nodes :: [binary()], Edges :: [{binary(), binary()}]) -> [binary()].

Find leaf nodes (nodes with no outgoing edges).

find_roots(Nodes, Edges)

-spec find_roots(Nodes :: [binary()], Edges :: [{binary(), binary()}]) -> [binary()].

Find root nodes (nodes with no incoming edges).

get_ancestors(Nodes, Edges, Target)

-spec get_ancestors(Nodes :: [binary()], Edges :: [{binary(), binary()}], Target :: binary()) ->
                       [binary()].

Get all ancestors of a node (nodes that can reach it).

get_descendants(Nodes, Edges, Source)

-spec get_descendants(Nodes :: [binary()], Edges :: [{binary(), binary()}], Source :: binary()) ->
                         [binary()].

Get all descendants of a node (nodes reachable from it).

graph_stats(Nodes, Edges)

-spec graph_stats(Nodes :: [binary()], Edges :: [{binary(), binary()}]) -> map().

Get graph statistics.

Returns a map with node_count, edge_count, root_count, leaf_count, max_depth.

has_cycle(Nodes, Edges)

-spec has_cycle(Nodes :: [binary()], Edges :: [{binary(), binary()}]) -> boolean().

Check if the graph contains cycles.

has_path(Nodes, Edges, From, To)

-spec has_path(Nodes :: [binary()], Edges :: [{binary(), binary()}], From :: binary(), To :: binary()) ->
                  boolean().

Check if there's a path between two nodes.

implementation()

-spec implementation() -> nif | erlang.

Get the current implementation mode.

is_nif_loaded()

-spec is_nif_loaded() -> boolean().

Check if the NIF is loaded (Enterprise mode).

to_dot(Nodes, Edges)

-spec to_dot(Nodes :: [{binary(), binary(), binary()}], Edges :: [{binary(), binary()}]) -> binary().

Generate DOT format for Graphviz visualization.

Nodes are tuples of {event_id, event_type, label}.

to_dot_simple(Nodes, Edges)

-spec to_dot_simple(Nodes :: [{binary(), binary()}], Edges :: [{binary(), binary()}]) -> binary().

Generate DOT format with simplified labels (just type).

Nodes are tuples of {event_id, event_type}.

topo_sort(Nodes, Edges)

-spec topo_sort(Nodes :: [binary()], Edges :: [{binary(), binary()}]) ->
                   {ok, [binary()]} | {error, cycle_detected}.

Perform topological sort on the graph.

Returns nodes in dependency order (causes before effects).