Current section
Files
Jump to
Current section
Files
src/themis@internal@store.erl
-module(themis@internal@store).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([init/0, new_metric/5, find_metric/3, match_metrics/2, increment_record_by/4, increment_record/3, insert_record/4, match_records/2, find_record/3]).
-export_type([store_error/0, store/0]).
-type store_error() :: metric_name_already_exists |
insert_error |
{decode_errors, list(gleam@dynamic:decode_error())} |
table_error |
invalid_increment |
single_result_expected |
invalid_type |
metric_not_found.
-type store() :: {store,
themis@internal@erlang@ets:table(),
themis@internal@erlang@ets:table()}.
-file("/git/Themis/src/themis/internal/store.gleam", 34).
-spec init() -> store().
init() ->
Metrics_table = themis@internal@erlang@ets:new(
{table_builder, set, public},
<<"themis_metrics"/utf8>>
),
Records_table = themis@internal@erlang@ets:new(
{table_builder, set, public},
<<"themis_records"/utf8>>
),
{store, Metrics_table, Records_table}.
-file("/git/Themis/src/themis/internal/store.gleam", 42).
-spec new_metric(
store(),
themis@internal@metric:metric_name(),
binary(),
binary(),
list(float())
) -> {ok, nil} | {error, store_error()}.
new_metric(Store, Name, Description, Kind, Buckets) ->
Table = erlang:element(2, Store),
_pipe@2 = themis@internal@erlang@ets:insert_new_raw(
Table,
begin
_pipe@1 = {begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end,
Description,
Kind,
Buckets},
gleam_stdlib:identity(_pipe@1)
end
),
gleam@result:replace_error(_pipe@2, metric_name_already_exists).
-file("/git/Themis/src/themis/internal/store.gleam", 58).
-spec find_metric(store(), themis@internal@metric:metric_name(), binary()) -> {ok,
{binary(), binary(), list(float())}} |
{error, store_error()}.
find_metric(Store, Name, Given_kind) ->
Table = erlang:element(2, Store),
gleam@result:'try'(
case begin
_pipe@1 = themis@internal@erlang@ets:lookup(
Table,
begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end
),
gleam@list:map(
_pipe@1,
fun(Found) ->
(gleam@dynamic:tuple4(
fun gleam@dynamic:string/1,
fun gleam@dynamic:string/1,
fun gleam@dynamic:string/1,
gleam@dynamic:list(fun gleam@dynamic:float/1)
))(Found)
end
)
end of
[{ok, {_, Description, Kind, Buckets}}] ->
{ok, {Description, Kind, Buckets}};
[] ->
{error, metric_not_found};
_ ->
{error, table_error}
end,
fun(_use0) ->
{Description@1, Kind@1, Buckets@1} = _use0,
case Kind@1 =:= Given_kind of
false ->
{error, invalid_type};
true ->
{ok, {Description@1, Kind@1, Buckets@1}}
end
end
).
-file("/git/Themis/src/themis/internal/store.gleam", 86).
-spec match_metrics(store(), binary()) -> {ok,
list({binary(), binary(), list(float())})} |
{error, store_error()}.
match_metrics(Store, Kind) ->
Table = erlang:element(2, Store),
_pipe = themis@internal@erlang@ets:match_metric(Table, Kind),
_pipe@3 = gleam@list:map(
_pipe,
fun(Found) ->
R = begin
_pipe@1 = (gleam@dynamic:tuple4(
fun gleam@dynamic:string/1,
fun gleam@dynamic:string/1,
fun gleam@dynamic:string/1,
gleam@dynamic:list(fun gleam@dynamic:float/1)
))(Found),
gleam@result:try_recover(
_pipe@1,
fun(E) -> {error, {decode_errors, E}} end
)
end,
gleam@result:'try'(
R,
fun(_use0) ->
{Name, Description, _, Buckets} = _use0,
_pipe@2 = {Name, Description, Buckets},
{ok, _pipe@2}
end
)
end
),
gleam@result:all(_pipe@3).
-file("/git/Themis/src/themis/internal/store.gleam", 109).
-spec increment_record_by(
store(),
themis@internal@metric:metric_name(),
themis@internal@label:label_set(),
themis@number:number_()
) -> {ok, nil} | {error, store_error()}.
increment_record_by(Store, Name, Labels, Value) ->
case Value of
{dec, _} ->
_pipe = begin
Table = erlang:element(3, Store),
Labels@1 = themis@internal@label:to_strings(Labels),
Name@1 = themis@internal@metric:name_to_string(Name),
themis@internal@erlang@ets:counter_increment_by(
Table,
{Name@1, Labels@1},
Value
)
end,
{ok, _pipe};
{int, _} ->
_pipe = begin
Table = erlang:element(3, Store),
Labels@1 = themis@internal@label:to_strings(Labels),
Name@1 = themis@internal@metric:name_to_string(Name),
themis@internal@erlang@ets:counter_increment_by(
Table,
{Name@1, Labels@1},
Value
)
end,
{ok, _pipe};
na_n ->
{error, invalid_increment};
neg_inf ->
{error, invalid_increment};
pos_inf ->
{error, invalid_increment}
end.
-file("/git/Themis/src/themis/internal/store.gleam", 128).
-spec increment_record(
store(),
themis@internal@metric:metric_name(),
themis@internal@label:label_set()
) -> {ok, nil} | {error, store_error()}.
increment_record(Store, Name, Labels) ->
increment_record_by(Store, Name, Labels, themis@number:integer(1)).
-file("/git/Themis/src/themis/internal/store.gleam", 136).
-spec insert_record(
store(),
themis@internal@metric:metric_name(),
themis@internal@label:label_set(),
themis@number:number_()
) -> {ok, nil} | {error, store_error()}.
insert_record(Store, Name, Labels, Value) ->
Table = erlang:element(3, Store),
Labels@1 = themis@internal@label:to_strings(Labels),
{Int_value, Float_value, Flag_value} = case Value of
{dec, Val} ->
{0, Val, <<""/utf8>>};
{int, Val@1} ->
{Val@1, +0.0, <<""/utf8>>};
pos_inf ->
{0, +0.0, <<"+Inf"/utf8>>};
neg_inf ->
{0, +0.0, <<"-Inf"/utf8>>};
na_n ->
{0, +0.0, <<"NaN"/utf8>>}
end,
case themis@internal@erlang@ets:insert_raw(
Table,
{{begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end,
Labels@1},
Int_value,
Float_value,
Flag_value}
) of
false ->
{error, insert_error};
true ->
{ok, nil}
end.
-file("/git/Themis/src/themis/internal/store.gleam", 193).
-spec decode_record(gleam@dynamic:dynamic_()) -> {ok,
{themis@internal@label:label_set(), themis@number:number_()}} |
{error, store_error()}.
decode_record(Record) ->
Record_result = begin
_pipe = (gleam@dynamic:tuple4(
gleam@dynamic:tuple2(
fun gleam@dynamic:string/1,
gleam@dynamic:list(fun gleam@dynamic:string/1)
),
fun gleam@dynamic:int/1,
fun gleam@dynamic:float/1,
fun gleam@dynamic:string/1
))(Record),
gleam@result:try_recover(
_pipe,
fun(E) -> {error, {decode_errors, E}} end
)
end,
gleam@result:'try'(
Record_result,
fun(Record@1) ->
{{_, Labels}, Int_value, Float_value, Flag} = Record@1,
_assert_subject = gleam@float:modulo(Float_value, 1.0),
{ok, Float_decimal} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"themis/internal/store"/utf8>>,
function => <<"decode_record"/utf8>>,
line => 208})
end,
Numeric_value = case Float_decimal =:= +0.0 of
false ->
themis@number:decimal(
begin
_pipe@1 = Int_value,
_pipe@2 = erlang:float(_pipe@1),
gleam@float:add(_pipe@2, Float_value)
end
);
true ->
themis@number:integer(Int_value)
end,
Value = case Flag of
<<"-Inf"/utf8>> ->
themis@number:negative_infinity();
<<"+Inf"/utf8>> ->
themis@number:positive_infinity();
<<"NaN"/utf8>> ->
themis@number:not_a_number();
_ ->
Numeric_value
end,
Labels@1 = begin
_pipe@3 = Labels,
_pipe@4 = gleam@list:map(
_pipe@3,
fun(Label_string) ->
_assert_subject@1 = gleam@string:split_once(
Label_string,
<<":"/utf8>>
),
{ok, {Key, Value@1}} = case _assert_subject@1 of
{ok, {_, _}} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail@1,
module => <<"themis/internal/store"/utf8>>,
function => <<"decode_record"/utf8>>,
line => 222})
end,
{Key, Value@1}
end
),
maps:from_list(_pipe@4)
end,
_assert_subject@2 = themis@internal@label:from_dict(Labels@1),
{ok, Labels@2} = case _assert_subject@2 of
{ok, _} -> _assert_subject@2;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail@2,
module => <<"themis/internal/store"/utf8>>,
function => <<"decode_record"/utf8>>,
line => 226})
end,
_pipe@5 = {Labels@2, Value},
{ok, _pipe@5}
end
).
-file("/git/Themis/src/themis/internal/store.gleam", 164).
-spec match_records(store(), themis@internal@metric:metric_name()) -> {ok,
gleam@dict:dict(themis@internal@label:label_set(), themis@number:number_())} |
{error, store_error()}.
match_records(Store, Name) ->
Table = erlang:element(3, Store),
_pipe@1 = themis@internal@erlang@ets:match_record(
Table,
begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end
),
_pipe@2 = gleam@list:map(_pipe@1, fun decode_record/1),
_pipe@3 = gleam@result:all(_pipe@2),
gleam@result:map(_pipe@3, fun maps:from_list/1).
-file("/git/Themis/src/themis/internal/store.gleam", 175).
-spec find_record(
store(),
themis@internal@metric:metric_name(),
themis@internal@label:label_set()
) -> {ok, {themis@internal@label:label_set(), themis@number:number_()}} |
{error, store_error()}.
find_record(Store, Name, Labels) ->
Table = erlang:element(3, Store),
_pipe@2 = case themis@internal@erlang@ets:lookup(
Table,
{begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end,
begin
_pipe@1 = Labels,
themis@internal@label:to_strings(_pipe@1)
end}
) of
[Entry] ->
{ok, Entry};
_ ->
{error, single_result_expected}
end,
gleam@result:'try'(_pipe@2, fun decode_record/1).