Ragex.Graph.Store (Ragex v0.12.0)

View Source

Knowledge graph storage using ETS tables.

Manages nodes (modules, functions, types, etc.) and edges (calls, imports, etc.) representing relationships in the codebase.

Summary

Functions

Adds an edge between two nodes.

Adds a node to the graph.

Returns a specification to start this module under a supervisor.

Clears all data from the graph.

Counts nodes of a specific type.

Returns the ETS table reference for embeddings.

Finds a function node by module and name (any arity).

Finds a node by type and id.

Gets the weight of an edge between two nodes.

Retrieves the embedding for a node.

Retrieves a function node by module, name, and arity.

Gets all incoming edges to a node of a specific type.

Retrieves a module node by name.

Retrieves a node by its composite key.

Gets all outgoing edges from a node of a specific type.

Lists all edges with optional filtering by type and limit.

Lists all embeddings with optional type filter.

Lists function nodes with optional filtering by module.

Lists all module nodes.

Lists nodes with optional filtering by type.

Switches the store to a specific project path.

Removes a node from the graph.

Returns statistics about the graph.

Stores an embedding vector for a node.

Synchronous barrier: blocks until all pending casts have been processed.

Functions

add_edge(from_node, to_node, edge_type, opts \\ [])

Adds an edge between two nodes.

Edge types: :calls, :imports, :defines, :inherits, :implements

Options

  • :weight - Edge weight (default: 1.0) for weighted graph algorithms
  • :metadata - Additional metadata map

add_node(node_type, node_id, data)

Adds a node to the graph.

Node types: :module, :function, :type, :variable, :file

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

clear()

Clears all data from the graph.

count_nodes_by_type(node_type)

Counts nodes of a specific type.

embeddings_table()

Returns the ETS table reference for embeddings.

Useful for direct access or persistence operations.

find_function(module, name)

Finds a function node by module and name (any arity).

find_node(node_type, node_id)

Finds a node by type and id.

get_edge_weight(from_node, to_node, edge_type)

Gets the weight of an edge between two nodes.

Returns the weight (default: 1.0) if edge exists, nil otherwise.

get_embedding(node_type, node_id)

Retrieves the embedding for a node.

Returns {embedding, text} tuple or nil if not found.

get_function(module, name, arity)

Retrieves a function node by module, name, and arity.

Returns the function data or nil if not found.

Parameters

  • module - The module containing the function
  • name - The function name (atom)
  • arity - The function arity (non-negative integer)

Examples

iex> Store.add_node(:function, {MyModule, :test, 2}, %{name: :test, arity: 2})
iex> Store.get_function(MyModule, :test, 2)
%{name: :test, arity: 2}

iex> Store.get_function(MyModule, :nonexistent, 1)
nil

get_incoming_edges(to_node, edge_type)

Gets all incoming edges to a node of a specific type.

get_module(module)

Retrieves a module node by name.

Returns the module data or nil if not found.

Examples

iex> Store.add_node(:module, MyModule, %{name: MyModule, file: "lib/my_module.ex"})
iex> Store.get_module(MyModule)
%{name: MyModule, file: "lib/my_module.ex"}

iex> Store.get_module(NonExistentModule)
nil

get_node(arg)

Retrieves a node by its composite key.

Parameters

  • node_key - Tuple of {node_type, node_id}

Returns

  • Node data map if found
  • nil if not found

Examples

iex> Store.add_node(:module, MyModule, %{name: MyModule})
iex> Store.get_node({:module, MyModule})
%{name: MyModule}

iex> Store.get_node({:module, NonExistent})
nil

get_outgoing_edges(from_node, edge_type)

Gets all outgoing edges from a node of a specific type.

list_edges(opts \\ [])

Lists all edges with optional filtering by type and limit.

Parameters

  • opts - Keyword list with options:
    • :edge_type - Filter by edge type (optional)
    • :limit - Maximum number of edges to return (default: 1000)

Returns

List of edge maps with keys:

  • :from - Source node
  • :to - Target node
  • :type - Edge type
  • :metadata - Edge metadata including weight

Examples

iex> Store.list_edges(limit: 100)
[%{from: node1, to: node2, type: :calls, metadata: %{weight: 1.0}}, ...]

iex> Store.list_edges(edge_type: :imports)
[%{from: mod1, to: mod2, type: :imports, metadata: %{weight: 1.0}}, ...]

list_embeddings(node_type \\ nil, limit \\ 1000)

Lists all embeddings with optional type filter.

Returns list of {node_type, node_id, embedding, text} tuples.

list_functions(opts \\ [])

Lists function nodes with optional filtering by module.

Parameters

  • opts - Keyword list with options:
    • :module - Filter by module (optional)
    • :limit - Maximum number of functions to return (default: 1000)

Returns

List of function maps with keys:

  • :id - Function identifier tuple {module, name, arity}
  • :data - Function data

Examples

iex> Store.add_node(:function, {MyModule, :test, 2}, %{name: :test, arity: 2})
iex> Store.list_functions()
[%{id: {MyModule, :test, 2}, data: %{name: :test, arity: 2}}]

iex> Store.list_functions(module: MyModule, limit: 50)
[%{id: {MyModule, :test, 2}, data: ...}, ...]

list_modules()

Lists all module nodes.

Returns

List of module maps with keys:

  • :id - Module identifier (atom)
  • :data - Module data

Examples

iex> Store.add_node(:module, ModuleA, %{name: ModuleA, file: "lib/a.ex"})
iex> Store.add_node(:module, ModuleB, %{name: ModuleB, file: "lib/b.ex"})
iex> Store.list_modules()
[%{id: ModuleA, data: %{name: ModuleA, file: "lib/a.ex"}}, ...]

list_nodes(node_type \\ nil, limit \\ 1000)

Lists nodes with optional filtering by type.

load_project(project_path)

@spec load_project(String.t()) :: :ok

Switches the store to a specific project path.

Clears all current graph data (nodes, edges, embeddings, file tracker), then loads the cached graph and embeddings for the given project path. This ensures the store contains only data for the target project.

Parameters

  • project_path - Absolute path to the project directory

Returns

  • :ok

remove_node(node_type, node_id)

Removes a node from the graph.

Also removes all edges connected to this node (both incoming and outgoing) and any embedding associated with the node.

Returns :ok if successful, {:error, :timeout} on timeout.

start_link(opts \\ [])

stats()

Returns statistics about the graph.

store_embedding(node_type, node_id, embedding, text)

Stores an embedding vector for a node.

sync()

Synchronous barrier: blocks until all pending casts have been processed.

Useful in tests to ensure async operations (add_node, add_edge, etc.) have been applied to ETS before querying.