Skip to content

Commit

Permalink
Add an option to fold over keep-while expirations
Browse files Browse the repository at this point in the history
  • Loading branch information
the-mikedavis committed Sep 30, 2024
1 parent 681d738 commit 012c024
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/khepri.erl
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@
%% created/updated tree node.</li>
%% </ul>

-type delete_options() :: #{accumulate_keep_while_expirations => boolean()}.

-type fold_fun() :: fun((khepri_path:native_path(),
khepri:node_props(),
khepri:fold_acc()) -> khepri:fold_acc()).
Expand Down Expand Up @@ -472,6 +474,7 @@
query_options/0,
tree_options/0,
put_options/0,
delete_options/0,

fold_fun/0,
fold_acc/0,
Expand Down
11 changes: 7 additions & 4 deletions src/khepri_machine.erl
Original file line number Diff line number Diff line change
Expand Up @@ -732,10 +732,12 @@ split_query_options(Options) ->
end, {#{}, #{}}, Options1).

-spec split_command_options(Options) ->
{CommandOptions, TreeAndPutOptions} when
Options :: CommandOptions | TreeAndPutOptions,
{CommandOptions, TreeOptions} when
Options :: CommandOptions | TreeOptions,
CommandOptions :: khepri:command_options(),
TreeAndPutOptions :: khepri:tree_options() | khepri:put_options().
TreeOptions :: khepri:tree_options() |
khepri:put_options() |
khepri:delete_options().
%% @private

split_command_options(Options) ->
Expand All @@ -753,7 +755,8 @@ split_command_options(Options) ->
(Option, Value, {C, TP}) when
Option =:= expect_specific_node orelse
Option =:= props_to_return orelse
Option =:= include_root_props ->
Option =:= include_root_props orelse
Option =:= accumulate_keep_while_expirations ->
TP1 = TP#{Option => Value},
{C, TP1};
(keep_while, KeepWhile, {C, TP}) ->
Expand Down
20 changes: 20 additions & 0 deletions src/khepri_tree.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,26 @@ is_parent_being_removed1([], _) ->

remove_expired_nodes([], Walk) ->
{ok, Walk};
remove_expired_nodes(
[PathToDelete | Rest],
#walk{tree = Tree,
applied_changes = AppliedChanges,
'fun' = Fun,
fun_acc = Acc,
tree_options =
#{accumulate_keep_while_expirations := true} = TreeOptions} = Walk) ->
Result = walk_down_the_tree(
Tree, PathToDelete, TreeOptions, AppliedChanges, Fun, Acc),
case Result of
{ok, Tree1, AppliedChanges1, Acc1} ->
AppliedChanges2 = merge_applied_changes(
AppliedChanges, AppliedChanges1),
Walk1 = Walk#walk{tree = Tree1,
node = Tree1#tree.root,
applied_changes = AppliedChanges2,
fun_acc = Acc1},
remove_expired_nodes(Rest, Walk1)
end;
remove_expired_nodes(
[PathToDelete | Rest],
#walk{tree = Tree, applied_changes = AppliedChanges} = Walk) ->
Expand Down
20 changes: 20 additions & 0 deletions test/advanced_delete.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,26 @@ delete_non_existing_node_test_() ->
node_is_target => true})},
khepri_adv:get(?FUNCTION_NAME, [foo]))]}.

%% TODO: find a place for this test
accumulate_keep_while_expirations_test_() ->
{setup,
fun() -> test_ra_server_helpers:setup(?FUNCTION_NAME) end,
fun(Priv) -> test_ra_server_helpers:cleanup(Priv) end,
[?_assertEqual(
ok,
khepri:create(?FUNCTION_NAME, [a, b, c], val1)),
?_assertEqual(
ok,
khepri:create(
?FUNCTION_NAME, [d, e], val2,
#{keep_while => #{[a, b, c] => #if_node_exists{exists = true}}})),
?_assertMatch(
{ok, #{[a, b, c] := #{data := val1},
[d, e] := #{data := val2}}},
khepri_adv:delete_many(
?FUNCTION_NAME, [a, b, c],
#{accumulate_keep_while_expirations => true}))]}.

delete_existing_node_test_() ->
{setup,
fun() -> test_ra_server_helpers:setup(?FUNCTION_NAME) end,
Expand Down

0 comments on commit 012c024

Please sign in to comment.