Current section
Files
Jump to
Current section
Files
src/slabs.erl
-module(slabs).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/slabs.gleam").
-export([new/0, insert/2, insert_many/2, remove/2, remove_many/2, get/2, get_values/1, length/1]).
-export_type([entry/1, slab/1, slab_error/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type entry(DTX) :: {vacant, gleam@option:option(integer())} | {occupied, DTX}.
-opaque slab(DTY) :: {slab,
list(entry(DTY)),
gleam@option:option(integer()),
integer()}.
-type slab_error() :: {bad_index, integer()}.
-file("src/slabs.gleam", 18).
?DOC(" Create a new slab container\n").
-spec new() -> slab(any()).
new() ->
{slab, [], none, 0}.
-file("src/slabs.gleam", 23).
?DOC(" Insert an item into the slab\n").
-spec insert(slab(DUB), DUB) -> {slab(DUB), integer()}.
insert(Slab, Value) ->
case erlang:element(3, Slab) of
{some, Slot_index} ->
Index = (erlang:element(4, Slab) - 1) - Slot_index,
{Left, Right} = begin
_pipe = erlang:element(2, Slab),
gleam@list:split(_pipe, Index)
end,
Next_id@1 = case begin
_pipe@1 = Right,
gleam@list:first(_pipe@1)
end of
{ok, {vacant, Next_id}} -> Next_id;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"slabs"/utf8>>,
function => <<"insert"/utf8>>,
line => 32,
value => _assert_fail,
start => 639,
'end' => 707,
pattern_start => 650,
pattern_end => 669})
end,
Right@1 = case Right of
[_ | Rest] ->
Rest;
[] ->
[]
end,
Inner = lists:append(Left, [{occupied, Value} | Right@1]),
{{slab, Inner, Next_id@1, erlang:element(4, Slab)}, Slot_index};
none ->
Index@1 = erlang:length(erlang:element(2, Slab)),
{{slab,
[{occupied, Value} | erlang:element(2, Slab)],
erlang:element(3, Slab),
erlang:element(4, Slab) + 1},
Index@1}
end.
-file("src/slabs.gleam", 60).
-spec insert_accum(slab(DUE), list(DUE), list(integer())) -> {slab(DUE),
list(integer())}.
insert_accum(Slab, Values, Acc) ->
case Values of
[V | Rest] ->
{Slab@1, Index} = insert(Slab, V),
insert_accum(Slab@1, Rest, [Index | Acc]);
[] ->
{Slab, Acc}
end.
-file("src/slabs.gleam", 75).
?DOC(" Insert several items into the slab\n").
-spec insert_many(slab(DUK), list(DUK)) -> {slab(DUK), list(integer())}.
insert_many(Slab, Values) ->
insert_accum(Slab, Values, []).
-file("src/slabs.gleam", 80).
?DOC(" Remove an entry from the slab\n").
-spec remove(slab(DUP), integer()) -> {ok, {slab(DUP), DUP}} |
{error, slab_error()}.
remove(Slab, Index) ->
case (Index >= 0) andalso (Index < erlang:element(4, Slab)) of
true ->
{Left, Right} = begin
_pipe = erlang:element(2, Slab),
gleam@list:split(_pipe, (erlang:element(4, Slab) - 1) - Index)
end,
Entry@1 = case begin
_pipe@1 = Right,
gleam@list:first(_pipe@1)
end of
{ok, Entry} -> Entry;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"slabs"/utf8>>,
function => <<"remove"/utf8>>,
line => 87,
value => _assert_fail,
start => 1840,
'end' => 1898,
pattern_start => 1851,
pattern_end => 1860})
end,
Right@1 = case Right of
[_ | Rest] ->
Rest;
[] ->
[]
end,
Inner = lists:append(
Left,
[{vacant, erlang:element(3, Slab)} | Right@1]
),
Value@1 = case Entry@1 of
{occupied, Value} -> Value;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"slabs"/utf8>>,
function => <<"remove"/utf8>>,
line => 99,
value => _assert_fail@1,
start => 2135,
'end' => 2169,
pattern_start => 2146,
pattern_end => 2161})
end,
{ok,
{{slab, Inner, {some, Index}, erlang:element(4, Slab)}, Value@1}};
false ->
{error, {bad_index, Index}}
end.
-file("src/slabs.gleam", 107).
-spec remove_many_accum(slab(DUU), list(integer()), list(DUU)) -> {slab(DUU),
list(DUU)}.
remove_many_accum(Slab, Indexes, Acc) ->
case Indexes of
[Index | Rest] ->
case remove(Slab, Index) of
{ok, {Slab@1, Value}} ->
remove_many_accum(Slab@1, Rest, [Value | Acc]);
{error, _} ->
remove_many_accum(Slab, Rest, Acc)
end;
[] ->
{Slab, Acc}
end.
-file("src/slabs.gleam", 124).
?DOC(" Remove several items from a slab at once\n").
-spec remove_many(slab(DVA), list(integer())) -> {slab(DVA), list(DVA)}.
remove_many(Slab, Indexes) ->
remove_many_accum(Slab, Indexes, []).
-file("src/slabs.gleam", 128).
-spec get_items(list(entry(DVF)), integer(), integer()) -> gleam@option:option(DVF).
get_items(Items, Acc, Index) ->
case Items of
[V, _] when Acc =:= Index ->
case V of
{vacant, _} ->
none;
{occupied, V@1} ->
{some, V@1}
end;
[V] when Acc =:= Index ->
case V of
{vacant, _} ->
none;
{occupied, V@1} ->
{some, V@1}
end;
[_ | Rest] ->
get_items(Rest, Acc - 1, Index);
[] ->
none
end.
-file("src/slabs.gleam", 144).
?DOC(" Index into the slab and retrieve a value\n").
-spec get(slab(DVJ), integer()) -> gleam@option:option(DVJ).
get(Slab, Index) ->
get_items(erlang:element(2, Slab), erlang:element(4, Slab) - 1, Index).
-file("src/slabs.gleam", 148).
-spec get_values_accum(list(entry(DVM)), integer(), list({integer(), DVM})) -> list({integer(),
DVM}).
get_values_accum(Entries, Index, Acc) ->
case Entries of
[{occupied, Value} | Rest] ->
get_values_accum(Rest, Index - 1, [{Index, Value} | Acc]);
[_ | Rest@1] ->
get_values_accum(Rest@1, Index - 1, Acc);
_ ->
Acc
end.
-file("src/slabs.gleam", 162).
?DOC(" Retrieve a list of the occupied values and their corresponding indexes\n").
-spec get_values(slab(DVR)) -> list({integer(), DVR}).
get_values(Slab) ->
get_values_accum(erlang:element(2, Slab), erlang:element(4, Slab) - 1, []).
-file("src/slabs.gleam", 167).
?DOC(" Returns the amount of items in the slab (including vacant slots)\n").
-spec length(slab(any())) -> integer().
length(Slab) ->
erlang:element(4, Slab).