Skip to content

Commit 2eec846

Browse files
authored
Merge pull request #20 from rabbitmq/use-records-for-payload
Replace macros by records to represent payloads
2 parents e63cb0f + fb62773 commit 2eec846

19 files changed

+296
-280
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ khepri:transaction(
146146
%% There is less than 100 pieces of wood, or there is none
147147
%% at all (the node does not exist in Khepri). We need to
148148
%% request a new order.
149-
{ok, _} = khepri_tx:put([order, wood], ?DATA_PAYLOAD(1000)),
149+
{ok, _} = khepri_tx:put(
150+
[order, wood],
151+
#kpayload_data{data = 1000}),
150152
true
151153
end
152154
end).

doc/overview.edoc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ the future.
9191

9292
Payloads are represented using macros or helper functions:
9393
<ul>
94-
<li>`?NO_PAYLOAD' and {@link khepri:no_payload/0}</li>
95-
<li>`?DATA_PAYLOAD(Term)' and {@link khepri:data_payload/1}</li>
94+
<li>`none' and {@link khepri:no_payload/0}</li>
95+
<li>`#kpayload_data{data = Term}' and {@link khepri:data_payload/1}</li>
9696
</ul>
9797

9898
Functions in {@link khepri_machine} have no assumption on the type of the
@@ -222,7 +222,9 @@ specific use cases may need to rely on that low-level API.
222222
%% Unlike the high-level API's `khepri:insert/2' function, this low-level %
223223
%% insert returns whatever it replaced (if anything). In this case, there was
224224
%% nothing before, so the returned value is pretty empty.
225-
Ret1 = khepri_machine:put(StoreId, [stock, wood, <<"lime tree">>], ?DATA_PAYLOAD(150)),
225+
Ret1 = khepri_machine:put(
226+
StoreId, [stock, wood, <<"lime tree">>],
227+
#kpayload_data{data = 150}),
226228
{ok, #{}} = Ret1,
227229

228230
Ret2 = khepri_machine:get(StoreId, [stock, wood, <<"lime tree">>]),

include/khepri.hrl

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,10 @@
3333
-define(IS_PATH_PATTERN(Path),
3434
(Path =:= [] orelse ?IS_PATH_CONDITION(hd(Path)))).
3535

36-
-define(NO_PAYLOAD, none).
37-
-define(DATA_PAYLOAD(Data), {data, Data}).
38-
-define(IS_PAYLOAD(Payload), (Payload =:= none orelse
39-
(is_tuple(Payload) andalso
40-
size(Payload) =:= 2 andalso
41-
element(1, Payload) =:= data))).
36+
-record(kpayload_data, {data :: khepri_machine:data()}).
37+
38+
-define(IS_KHEPRI_PAYLOAD(Payload), (Payload =:= none orelse
39+
is_record(Payload, kpayload_data))).
4240

4341
%% -------------------------------------------------------------------
4442
%% Path conditions.

src/khepri.erl

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ compare_and_swap(StoreId, Path, DataPattern, Data) ->
632632
%% @private
633633

634634
do_put(StoreId, Path, Data) ->
635-
case khepri_machine:put(StoreId, Path, ?DATA_PAYLOAD(Data)) of
635+
case khepri_machine:put(StoreId, Path, #kpayload_data{data = Data}) of
636636
{ok, _} -> ok;
637637
Error -> Error
638638
end.
@@ -654,7 +654,7 @@ clear_payload(Path) ->
654654
Path :: khepri_path:pattern() | string().
655655
%% @doc Clears the payload of an existing specific tree node in the tree structure.
656656
%%
657-
%% In other words, the payload is set to `?NO_PAYLOAD'.
657+
%% In other words, the payload is set to `none'.
658658
%%
659659
%% The `Path' can be provided as a list of node names and conditions or as a
660660
%% string. See {@link khepri_path:from_string/1}.
@@ -669,7 +669,7 @@ clear_payload(Path) ->
669669

670670
clear_payload(StoreId, Path) ->
671671
Path1 = khepri_path:maybe_from_string(Path),
672-
case khepri_machine:put(StoreId, Path1, ?NO_PAYLOAD) of
672+
case khepri_machine:put(StoreId, Path1, none) of
673673
{ok, _} -> ok;
674674
Error -> Error
675675
end.
@@ -967,23 +967,24 @@ clear_store(StoreId) ->
967967
delete(StoreId, [?STAR]).
968968

969969
-spec no_payload() -> none.
970-
%% @doc Returns `?NO_PAYLOAD'.
970+
%% @doc Returns `none'.
971971
%%
972-
%% This is a helper for cases where using macros is inconvenient, like in an
972+
%% This is a helper for cases where using records is inconvenient, like in an
973973
%% Erlang shell.
974974

975975
no_payload() ->
976-
?NO_PAYLOAD.
976+
none.
977977

978-
-spec data_payload(Term) -> {data, Term} when
979-
Term :: khepri_machine:data().
980-
%% @doc Returns `?DATA_PAYLOAD(Term)'.
978+
-spec data_payload(Term) -> Payload when
979+
Term :: khepri_machine:data(),
980+
Payload :: #kpayload_data{}.
981+
%% @doc Returns `#kpayload_data{data = Term}'.
981982
%%
982983
%% This is a helper for cases where using macros is inconvenient, like in an
983984
%% Erlang shell.
984985

985986
data_payload(Term) ->
986-
?DATA_PAYLOAD(Term).
987+
#kpayload_data{data = Term}.
987988

988989
%% -------------------------------------------------------------------
989990
%% Public helpers.

src/khepri_condition.erl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,17 +345,17 @@ is_met(
345345
_Child) ->
346346
eval_regex(Cond, SourceRegex, CompiledRegex, ChildName);
347347
is_met(#if_has_data{has_data = true},
348-
_ChildName, #node{payload = {data, _}}) ->
348+
_ChildName, #node{payload = #kpayload_data{data = _}}) ->
349349
true;
350350
is_met(#if_has_data{has_data = false} = Cond,
351-
_ChildName, #node{payload = {data, _}}) ->
351+
_ChildName, #node{payload = #kpayload_data{data = _}}) ->
352352
{false, Cond};
353353
is_met(#if_has_data{has_data = true} = Cond, _ChildName, _Child) ->
354354
{false, Cond};
355355
is_met(#if_has_data{has_data = false}, _ChildName, _Child) ->
356356
true;
357357
is_met(#if_data_matches{compiled = CompMatchSpec} = Cond,
358-
_ChildName, #node{payload = {data, Data}}) ->
358+
_ChildName, #node{payload = #kpayload_data{data = Data}}) ->
359359
case term_matches(Data, CompMatchSpec) of
360360
true -> true;
361361
false -> {false, Cond}

src/khepri_machine.erl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
child_list_version := child_list_version()}.
153153
%% Stats attached to each node in the tree structure.
154154

155-
-type payload() :: ?NO_PAYLOAD | ?DATA_PAYLOAD(data()).
155+
-type payload() :: none | #kpayload_data{}.
156156
%% All types of payload stored in the nodes of the tree structure.
157157
%%
158158
%% Beside the absence of payload, the only type of payload supported is data.
@@ -281,16 +281,16 @@ put(StoreId, PathPattern, Payload) ->
281281
%%
282282
%% The payload must be one of the following form:
283283
%% <ul>
284-
%% <li>`?NO_PAYLOAD', meaning there will be no payload attached to the
284+
%% <li>`none', meaning there will be no payload attached to the node</li>
285+
%% <li>`#kpayload_data{data = Term}' to store any type of term in the
285286
%% node</li>
286-
%% <li>`?DATA_PAYLOAD(Term)' to store any type of term in the node</li>
287287
%% </ul>
288288
%%
289289
%% Example:
290290
%% ```
291291
%% %% Insert a node at `/foo/bar', overwriting the previous value.
292292
%% Result = khepri_machine:put(
293-
%% ra_cluster_name, [foo, bar], ?DATA_PAYLOAD(new_value)),
293+
%% ra_cluster_name, [foo, bar], #kpayload_data{data = new_value}),
294294
%%
295295
%% %% Here is the content of `Result'.
296296
%% {ok, #{[foo, bar] => #{data => old_value,
@@ -307,7 +307,7 @@ put(StoreId, PathPattern, Payload) ->
307307
%%
308308
%% @returns an "ok" tuple with a map with one entry, or an "error" tuple.
309309

310-
put(StoreId, PathPattern, Payload, Extra) when ?IS_PAYLOAD(Payload) ->
310+
put(StoreId, PathPattern, Payload, Extra) when ?IS_KHEPRI_PAYLOAD(Payload) ->
311311
khepri_path:ensure_is_valid(PathPattern),
312312
Command = #put{path = PathPattern,
313313
payload = Payload,
@@ -728,11 +728,13 @@ set_node_payload(#node{stat = #{payload_version := DVersion} = Stat} = Node,
728728
-spec remove_node_payload(tree_node()) -> tree_node().
729729
%% @private
730730

731-
remove_node_payload(#node{payload = ?NO_PAYLOAD} = Node) ->
731+
remove_node_payload(
732+
#node{payload = none} = Node) ->
732733
Node;
733-
remove_node_payload(#node{stat = #{payload_version := DVersion} = Stat} = Node) ->
734+
remove_node_payload(
735+
#node{stat = #{payload_version := DVersion} = Stat} = Node) ->
734736
Stat1 = Stat#{payload_version => DVersion + 1},
735-
Node#node{stat = Stat1, payload = ?NO_PAYLOAD}.
737+
Node#node{stat = Stat1, payload = none}.
736738

737739
-spec add_node_child(tree_node(), khepri_path:component(), tree_node()) ->
738740
tree_node().
@@ -790,8 +792,8 @@ gather_node_props(#node{stat = #{payload_version := DVersion,
790792
Result0
791793
end,
792794
case Payload of
793-
?DATA_PAYLOAD(Data) -> Result1#{data => Data};
794-
_ -> Result1
795+
#kpayload_data{data = Data} -> Result1#{data => Data};
796+
_ -> Result1
795797
end.
796798

797799
-spec to_absolute_keep_while(BasePath, KeepWhile) -> KeepWhile when

src/khepri_tx.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ put(PathPattern, Payload) ->
9494
Result :: khepri_machine:result().
9595
%% @doc Creates or modifies a specific tree node in the tree structure.
9696

97-
put(PathPattern, Payload, Extra) when ?IS_PAYLOAD(Payload) ->
97+
put(PathPattern, Payload, Extra) when ?IS_KHEPRI_PAYLOAD(Payload) ->
9898
ensure_path_pattern_is_valid(PathPattern),
9999
ensure_updates_are_allowed(),
100100
State = get_tx_state(),

test/conditions.erl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,11 @@ if_has_data_matching_test() ->
180180
{false, #if_has_data{has_data = false}},
181181
khepri_condition:is_met(
182182
khepri_condition:compile(#if_has_data{has_data = false}),
183-
foo, #node{payload = {data, foo}})),
183+
foo, #node{payload = #kpayload_data{data = foo}})),
184184
?assert(
185185
khepri_condition:is_met(
186186
khepri_condition:compile(#if_has_data{has_data = true}),
187-
foo, #node{payload = {data, foo}})).
187+
foo, #node{payload = #kpayload_data{data = foo}})).
188188

189189
if_data_matches_matching_test() ->
190190
CompiledCond1 = khepri_condition:compile(
@@ -195,7 +195,7 @@ if_data_matches_matching_test() ->
195195
CompiledCond1, foo, #node{})),
196196
?assert(
197197
khepri_condition:is_met(
198-
CompiledCond1, foo, #node{payload = {data, {a, b}}})),
198+
CompiledCond1, foo, #node{payload = #kpayload_data{data = {a, b}}})),
199199

200200
CompiledCond2 = khepri_condition:compile(
201201
#if_data_matches{pattern = {a, '_'}}),
@@ -213,18 +213,18 @@ if_data_matches_matching_test() ->
213213

214214
?assert(
215215
khepri_condition:is_met(
216-
CompiledCond2, foo, #node{payload = {data, {a, b}}})),
216+
CompiledCond2, foo, #node{payload = #kpayload_data{data = {a, b}}})),
217217
?assert(
218218
khepri_condition:is_met(
219-
CompiledCond2, foo, #node{payload = {data, {a, c}}})),
219+
CompiledCond2, foo, #node{payload = #kpayload_data{data = {a, c}}})),
220220
?assertEqual(
221221
{false, CompiledCond2},
222222
khepri_condition:is_met(
223-
CompiledCond2, foo, #node{payload = {data, {b, c}}})),
223+
CompiledCond2, foo, #node{payload = #kpayload_data{data = {b, c}}})),
224224
?assertEqual(
225225
{false, CompiledCond2},
226226
khepri_condition:is_met(
227-
CompiledCond2, foo, #node{payload = {data, other}})).
227+
CompiledCond2, foo, #node{payload = #kpayload_data{data = other}})).
228228

229229
if_payload_version_matching_test() ->
230230
?assert(

test/db_info.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ get_store_info_with_keep_while_conds_test_() ->
112112
[?_assertEqual(
113113
{ok, #{[foo] => #{}}},
114114
khepri_machine:put(
115-
?FUNCTION_NAME, [foo], ?DATA_PAYLOAD(foo_value),
115+
?FUNCTION_NAME, [foo], #kpayload_data{data = foo_value},
116116
#{keep_while => KeepWhile})),
117117
?_assertEqual(
118118
"\n"

0 commit comments

Comments
 (0)