Packages

An embedded, crash-safe key-value store for Gleam, inspired by CubDB

Current section

Files

Jump to
trove src trove@internal@btree@diff.erl
Raw

src/trove@internal@btree@diff.erl

-module(trove@internal@btree@diff).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/trove/internal/btree/diff.gleam").
-export([diff/6]).
-export_type([diff_entry/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type diff_entry(MDD) :: {upserted, MDD} | removed.
-file("src/trove/internal/btree/diff.gleam", 73).
?DOC(false).
-spec do_merge_step(
gleam@yielder:step({MDU, MDV}, gleam@yielder:yielder({MDU, MDV})),
gleam@yielder:step({MDU, MDV}, gleam@yielder:yielder({MDU, MDV})),
fun((MDU, MDU) -> gleam@order:order())
) -> gleam@yielder:step({MDU, diff_entry(MDV)}, {gleam@yielder:step({MDU, MDV}, gleam@yielder:yielder({MDU,
MDV})),
gleam@yielder:step({MDU, MDV}, gleam@yielder:yielder({MDU, MDV}))}).
do_merge_step(Old_step, New_step, Compare) ->
case {Old_step, New_step} of
{done, done} ->
done;
{done, {next, {New_key, New_value}, New_rest}} ->
{next,
{New_key, {upserted, New_value}},
{done, gleam@yielder:step(New_rest)}};
{{next, {Old_key, _}, Old_rest}, done} ->
{next, {Old_key, removed}, {gleam@yielder:step(Old_rest), done}};
{{next, {Old_key@1, Old_value}, Old_rest@1},
{next, {New_key@1, New_value@1}, New_rest@1}} ->
case Compare(Old_key@1, New_key@1) of
lt ->
{next,
{Old_key@1, removed},
{gleam@yielder:step(Old_rest@1), New_step}};
gt ->
{next,
{New_key@1, {upserted, New_value@1}},
{Old_step, gleam@yielder:step(New_rest@1)}};
eq ->
case Old_value =:= New_value@1 of
true ->
do_merge_step(
gleam@yielder:step(Old_rest@1),
gleam@yielder:step(New_rest@1),
Compare
);
false ->
{next,
{New_key@1, {upserted, New_value@1}},
{gleam@yielder:step(Old_rest@1),
gleam@yielder:step(New_rest@1)}}
end
end
end.
-file("src/trove/internal/btree/diff.gleam", 62).
?DOC(false).
-spec lazy_merge_diff(
gleam@yielder:yielder({MDO, MDP}),
gleam@yielder:yielder({MDO, MDP}),
fun((MDO, MDO) -> gleam@order:order())
) -> gleam@yielder:yielder({MDO, diff_entry(MDP)}).
lazy_merge_diff(Old, New, Compare) ->
gleam@yielder:unfold(
{gleam@yielder:step(Old), gleam@yielder:step(New)},
fun(State) ->
{Old_step, New_step} = State,
do_merge_step(Old_step, New_step, Compare)
end
).
-file("src/trove/internal/btree/diff.gleam", 23).
?DOC(false).
-spec diff(
trove@internal@btree:btree(MDE, MDF),
trove@internal@btree:btree(MDE, MDF),
trove@internal@store:store(),
trove@codec:codec(MDE),
trove@codec:codec(MDF),
fun((MDE, MDE) -> gleam@order:order())
) -> gleam@yielder:yielder({MDE, diff_entry(MDF)}).
diff(Old, New, Store, Key_codec, Value_codec, Compare) ->
gleam@bool:guard(
trove@internal@btree:root(Old) =:= trove@internal@btree:root(New),
gleam@yielder:empty(),
fun() ->
Old_yielder = trove@internal@btree@range:'query'(
Old,
Store,
none,
none,
forward,
Key_codec,
Value_codec,
Compare
),
New_yielder = trove@internal@btree@range:'query'(
New,
Store,
none,
none,
forward,
Key_codec,
Value_codec,
Compare
),
lazy_merge_diff(Old_yielder, New_yielder, Compare)
end
).