Skip to content

Commit

Permalink
khepri_tree: Make tree_v*() and keep_while_conds_revidx_v*() opaq…
Browse files Browse the repository at this point in the history
…ue types

[Why]
They should only be known by `khepri_tree`.

[How]
The definition of `#tree{}` is moved to the `khepri_tree` module and
accessor functions are added and exported.

The types `tree()` and `keep_while_conds_revidx()` are kept as regular
types because the opaque subtypes they group together are used directly.
Moreover, if the generic types were marked as opaque too, Dialyzer would
enter some infinite loop and never return.
  • Loading branch information
dumbbell committed Oct 1, 2024
1 parent caf1ae3 commit 2c2b36c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/khepri_import_export.erl
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ open_write(Module, ModulePriv) ->
%% @private

write(State, Path, #node{payload = Payload}, Module, ModulePriv) ->
#tree{keep_while_conds = KeepWhileConds} = khepri_machine:get_tree(State),
KeepWhileConds = khepri_machine:get_keep_while_conds(State),
PutOptions = case KeepWhileConds of
#{Path := KeepWhile} -> #{keep_while => KeepWhile};
_ -> #{}
Expand Down
6 changes: 4 additions & 2 deletions src/khepri_machine.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2161,7 +2161,8 @@ set_tree(State, Tree) ->
%% @private

get_root(State) ->
#tree{root = Root} = get_tree(State),
Tree = get_tree(State),
Root = khepri_tree:get_root(Tree),
Root.

-spec get_keep_while_conds(State) -> KeepWhileConds when
Expand All @@ -2172,7 +2173,8 @@ get_root(State) ->
%% @private

get_keep_while_conds(State) ->
#tree{keep_while_conds = KeepWhileConds} = get_tree(State),
Tree = get_tree(State),
KeepWhileConds = khepri_tree:get_keep_while_conds(Tree),
KeepWhileConds.

-spec get_triggers(State) -> Triggers when
Expand Down
2 changes: 1 addition & 1 deletion src/khepri_pattern_tree.erl
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ fold_matching(PatternTree, Tree, Path, FoldFun, Acc) ->
[] ->
fold_data(PatternTree, [], FoldFun, Acc);
_ ->
Root = Tree#tree.root,
Root = khepri_tree:get_root(Tree),
fold_matching1(PatternTree, Root, Path, FoldFun, Acc, [])
end.

Expand Down
51 changes: 40 additions & 11 deletions src/khepri_tree.erl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
-include("src/khepri_tree.hrl").

-export([new/0,
get_root/1,
get_keep_while_conds/1,

are_keep_while_conditions_met/2,

Expand All @@ -35,25 +37,30 @@

convert_tree/3]).

-record(tree, {root = #node{} :: khepri_tree:tree_node(),
keep_while_conds = #{} :: khepri_tree:keep_while_conds_map(),
keep_while_conds_revidx = #{} ::
khepri_tree:keep_while_conds_revidx()}).

-type tree_node() :: #node{}.
%% A node in the tree structure.

-type tree_v0() :: #tree{keep_while_conds_revidx ::
khepri_tree:keep_while_conds_revidx_v0()}.
-type tree_v1() :: #tree{keep_while_conds_revidx ::
khepri_tree:keep_while_conds_revidx_v1()}.
-opaque tree_v0() :: #tree{keep_while_conds_revidx ::
khepri_tree:keep_while_conds_revidx_v0()}.
-opaque tree_v1() :: #tree{keep_while_conds_revidx ::
khepri_tree:keep_while_conds_revidx_v1()}.

-type tree() :: tree_v0() | tree_v1().

-type keep_while_conds_map() :: #{khepri_path:native_path() =>
khepri_condition:native_keep_while()}.
%% Per-node `keep_while' conditions.

-type keep_while_conds_revidx_v0() :: #{khepri_path:native_path() =>
#{khepri_path:native_path() => ok}}.
-opaque keep_while_conds_revidx_v0() :: #{khepri_path:native_path() =>
#{khepri_path:native_path() => ok}}.

-type keep_while_conds_revidx_v1() :: khepri_prefix_tree:tree(
#{khepri_path:native_path() => ok}).
-opaque keep_while_conds_revidx_v1() :: khepri_prefix_tree:tree(
#{khepri_path:native_path() => ok}).

-type keep_while_conds_revidx() :: keep_while_conds_revidx_v0() |
keep_while_conds_revidx_v1().
Expand All @@ -64,9 +71,6 @@
%% and folded over the entries in the map using `lists:prefix/2' to find
%% matching conditions. In version 1 this type was replaced with a prefix tree
%% which improves lookup time when the reverse index contains many entries.
%%
%% This type should be treated as opaque. It is not marked as such because of
%% limitations in the dialyzer.

-type applied_changes() :: #{khepri_path:native_path() =>
khepri:node_props() | delete}.
Expand Down Expand Up @@ -105,6 +109,20 @@
new() ->
#tree{}.

-spec get_root(Tree) -> Root when
Tree :: khepri_tree:tree(),
Root :: khepri_tree:tree_node().

get_root(#tree{root = Root}) ->
Root.

-spec get_keep_while_conds(Tree) -> KeepWhileConds when
Tree :: khepri_tree:tree(),
KeepWhileConds :: khepri_tree:keep_while_conds_map().

get_keep_while_conds(#tree{keep_while_conds = KeepWhileConds}) ->
KeepWhileConds.

-spec create_node_record(Payload) -> Node when
Payload :: khepri_payload:payload(),
Node :: tree_node().
Expand Down Expand Up @@ -497,6 +515,17 @@ find_matching_nodes_cb(_, {interrupted, _, _}, _, Acc, _) ->
%% Delete matching nodes.
%% -------------------------------------------------------------------

-spec delete_matching_nodes(Tree, PathPattern, AppliedChanges, TreeOptions) ->
Ret when
Tree :: khepri_tree:tree(),
PathPattern :: khepri_path:pattern(),
AppliedChanges :: applied_changes(),
TreeOptions :: khepri:tree_options(),
Ret :: {ok, NewTree, NewAppliedChanges, Result} | khepri:error(),
NewTree :: khepri_tree:tree(),
NewAppliedChanges :: applied_changes(),
Result :: any().

delete_matching_nodes(Tree, PathPattern, AppliedChanges, TreeOptions) ->
Fun = fun(Path, Node, Result) ->
delete_matching_nodes_cb(Path, Node, TreeOptions, Result)
Expand Down
5 changes: 0 additions & 5 deletions src/khepri_tree.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,3 @@
-record(node, {props = ?INIT_NODE_PROPS :: khepri_machine:props(),
payload = ?NO_PAYLOAD :: khepri_payload:payload(),
child_nodes = #{} :: #{khepri_path:component() := #node{}}}).

-record(tree, {root = #node{} :: khepri_tree:tree_node(),
keep_while_conds = #{} :: khepri_tree:keep_while_conds_map(),
keep_while_conds_revidx = #{} ::
khepri_tree:keep_while_conds_revidx()}).

0 comments on commit 2c2b36c

Please sign in to comment.