macula_mri_nif (macula v1.4.23)
View SourceMRI (Macula Resource Identifier) operations for Macula mesh.
This module provides high-performance MRI parsing, validation, and hierarchy queries. It uses Rust NIFs when available, falling back to pure Erlang implementations otherwise.
NIF vs Erlang
The Rust NIFs provide significant performance improvements: - Parsing: ~3-5x faster (single-pass parsing) - Validation: ~4-6x faster (avoids binary_to_list conversion) - Path joining: ~5-10x faster (single allocation) - Hierarchy queries: ~10-20x faster (efficient prefix matching)
Trie Index for Million-Scale Deployments
For large-scale deployments (millions of MRIs), use the persistent index:
%% Build index once (O(n))
{ok, Index} = macula_mri_nif:build_path_index(AllMRIs),
%% Fast O(d) queries instead of O(n)
{ok, Children} = macula_mri_nif:index_find_children(Index, Realm, Path),
{ok, Descendants} = macula_mri_nif:index_find_descendants(Index, Realm, Path),
%% Dynamic updates for device churn
ok = macula_mri_nif:index_insert(Index, Realm, Path, MRI),
ok = macula_mri_nif:index_remove(Index, Realm, Path).The pure Erlang fallbacks ensure the module works even when NIFs cannot be loaded (e.g., different architecture, missing Rust toolchain).
MRI Format
MRIs follow the format: mri:type:realm or mri:type:realm/path
Examples: mri:realm:io.macula — A realm mri:app:io.macula/counter — An app in the io.macula realm mri:service:io.macula/counter/api — A service endpoint
Summary
Functions
Build a trie index from a list of MRIs.
Find children of a parent MRI from a list of MRIs.
Find descendants of a parent MRI from a list of MRIs.
Format MRI components into an MRI string.
Find direct children using a trie index.
Find all descendants using a trie index.
Insert a single MRI into an existing index.
Remove a single MRI from an existing index.
Get the number of MRIs in an index.
Check if a type is a builtin MRI type.
Check if the NIF is loaded.
Join path segments into a single path binary.
Parse an MRI string into its components.
Validate realm format.
Validate segment characters.
Functions
Build a trie index from a list of MRIs.
Creates a persistent trie index that enables O(d) queries where d is the path depth. For million-scale deployments, this is orders of magnitude faster than O(n) list scanning.
When NIFs are loaded, returns an opaque reference to the Rust trie. When using Erlang fallback, returns a map-based index (slower but functional).
Example:
AllMRIs = [
{<<"io.macula">>, [<<"apps">>], <<"mri:app:io.macula/apps">>},
{<<"io.macula">>, [<<"apps">>, <<"counter">>], <<"mri:app:io.macula/apps/counter">>}
],
{ok, Index} = macula_mri_nif:build_path_index(AllMRIs).
-spec find_children(ParentRealm :: binary(), ParentPath :: [binary()], AllMRIs :: [{binary(), [binary()], binary()}]) -> [binary()].
Find children of a parent MRI from a list of MRIs.
Children are MRIs that have the same realm, path starts with parent's path, and have exactly one more path segment.
The AllMRIs parameter is a list of {Realm, PathSegments, FullMRI} tuples.
Example:
AllMRIs = [
{<<"io.macula">>, [<<"apps">>], <<"mri:app:io.macula/apps">>},
{<<"io.macula">>, [<<"apps">>, <<"counter">>], <<"mri:app:io.macula/apps/counter">>}
],
[<<"mri:app:io.macula/apps/counter">>] =
macula_mri_nif:find_children(<<"io.macula">>, [<<"apps">>], AllMRIs).
-spec find_descendants(ParentRealm :: binary(), ParentPath :: [binary()], AllMRIs :: [{binary(), [binary()], binary()}]) -> [binary()].
Find descendants of a parent MRI from a list of MRIs.
Descendants are MRIs that have the same realm, path starts with parent's path, and have at least one more path segment.
The AllMRIs parameter is a list of {Realm, PathSegments, FullMRI} tuples.
-spec format_mri(Type :: binary(), Realm :: binary(), Path :: [binary()]) -> {ok, binary()} | {error, invalid_type | invalid_realm}.
Format MRI components into an MRI string.
Example:
{ok, <<"mri:app:io.macula/counter">>} =
macula_mri_nif:format_mri(<<"app">>, <<"io.macula">>, [<<"counter">>]).
-spec index_find_children(Index :: reference() | map(), Realm :: binary(), Path :: [binary()]) -> {ok, [binary()]} | {error, invalid_realm}.
Find direct children using a trie index.
O(d) complexity where d is the path depth, vs O(n) for list scanning.
Example:
{ok, Index} = macula_mri_nif:build_path_index(AllMRIs),
{ok, [<<"mri:app:io.macula/apps/counter">>]} =
macula_mri_nif:index_find_children(Index, <<"io.macula">>, [<<"apps">>]).
-spec index_find_descendants(Index :: reference() | map(), Realm :: binary(), Path :: [binary()]) -> {ok, [binary()]} | {error, invalid_realm}.
Find all descendants using a trie index.
O(d + m) complexity where d is path depth and m is number of descendants, vs O(n) for list scanning where n is total MRIs.
-spec index_insert(Index :: reference() | map(), Realm :: binary(), Path :: [binary()], MRI :: binary()) -> ok | {error, invalid_realm}.
Insert a single MRI into an existing index.
Use this for dynamic updates when devices connect.
Example:
ok = macula_mri_nif:index_insert(Index, <<"io.macula">>, [<<"devices">>, <<"sensor1">>],
<<"mri:device:io.macula/devices/sensor1">>).
-spec index_remove(Index :: reference() | map(), Realm :: binary(), Path :: [binary()]) -> ok | {error, not_found | invalid_realm}.
Remove a single MRI from an existing index.
Use this for dynamic updates when devices disconnect.
-spec index_size(Index :: reference() | map()) -> {ok, non_neg_integer()}.
Get the number of MRIs in an index.
Check if a type is a builtin MRI type.
Builtin types: realm, org, user, app, service, artifact, license, cert, key, topic, proc, content, device, cluster, location, zone, network, model, dataset, config, class, taxonomy.
-spec is_nif_loaded() -> boolean().
Check if the NIF is loaded.
Join path segments into a single path binary.
Example:
<<"foo/bar/baz">> = macula_mri_nif:join_path_segments([<<"foo">>, <<"bar">>, <<"baz">>]).
-spec parse_mri(MRI :: binary()) -> {ok, #{type := binary(), realm := binary(), path := [binary()]}} | {error, invalid_format | invalid_realm | invalid_segment}.
Parse an MRI string into its components.
Returns a map with type, realm, and path keys.
Example:
{ok, #{type := <<"app">>, realm := <<"io.macula">>, path := [<<"counter">>]}} =
macula_mri_nif:parse_mri(<<"mri:app:io.macula/counter">>).
Validate realm format.
Valid realm: reverse domain notation (e.g., "io.macula.example") Must contain at least one dot and only lowercase letters, digits, and dots.
Validate segment characters.
Valid segment: a-z, 0-9, hyphen (-), underscore (_)