Current section
Files
Jump to
Current section
Files
src/shards_opts.erl
%%%-------------------------------------------------------------------
%%% @doc
%%% Utilities for parsing the given shards/ets options..
%%% @end
%%%-------------------------------------------------------------------
-module(shards_opts).
-export([parse/1]).
%% Macro to check if option is a valid ETS type
-define(is_ets_type(T_),
T_ == set;
T_ == ordered_set;
T_ == bag;
T_ == duplicate_bag
).
%% Macro to check if option is valid ETS option
-define(is_ets_opt(V_),
V_ == public;
V_ == protected;
V_ == private;
V_ == named_table;
V_ == compressed
).
%%%===================================================================
%%% API
%%%===================================================================
-spec parse([shards:option()]) -> shards_meta:meta_map().
parse(Opts) ->
MetaMap = shards_meta:to_map(shards_meta:new()),
ParsedOpts = parse_opts(Opts, MetaMap#{ets_opts => []}),
%% @FIXME: workaround to support ordered_set
case maps:take(type, ParsedOpts) of
{ordered_set, ParsedOpts1} ->
ParsedOpts1#{partitions := 1};
{_Type, ParsedOpts1} ->
ParsedOpts1;
error ->
ParsedOpts
end.
%% @private
parse_opts([], #{ets_opts := EtsOpts} = Acc) ->
Acc#{ets_opts := lists:reverse(EtsOpts)};
parse_opts([{keypos, Pos} | Opts], #{ets_opts := NOpts} = Acc) when is_integer(Pos), Pos > 0 ->
parse_opts(Opts, Acc#{keypos := Pos, ets_opts := [{keypos, Pos} | NOpts]});
parse_opts([{partitions, N} | Opts], Acc) when is_integer(N), N > 0 ->
parse_opts(Opts, Acc#{partitions := N});
parse_opts([{keyslot_fun, Val} | Opts], Acc) when is_function(Val, 2) ->
parse_opts(Opts, Acc#{keyslot_fun := Val});
parse_opts([{parallel, Val} | Opts], Acc) when is_boolean(Val) ->
parse_opts(Opts, Acc#{parallel := Val});
parse_opts([{parallel_timeout, Val} | Opts], Acc)
when (is_integer(Val) andalso Val >= 0) orelse Val == infinity ->
parse_opts(Opts, Acc#{parallel_timeout := Val});
parse_opts([{restore, _, _} = Opt | Opts], #{ets_opts := NOpts} = Acc) ->
parse_opts(Opts, Acc#{ets_opts := [Opt | NOpts]});
parse_opts([{heir, _, _} = Opt | Opts], #{ets_opts := NOpts} = Acc) ->
parse_opts(Opts, Acc#{ets_opts := [Opt | NOpts]});
parse_opts([{heir, none} = Opt | Opts], #{ets_opts := NOpts} = Acc) ->
parse_opts(Opts, Acc#{ets_opts := [Opt | NOpts]});
parse_opts([{write_concurrency, _} = Opt | Opts], #{ets_opts := NOpts} = Acc) ->
parse_opts(Opts, Acc#{ets_opts := [Opt | NOpts]});
parse_opts([{read_concurrency, _} = Opt | Opts], #{ets_opts := NOpts} = Acc) ->
parse_opts(Opts, Acc#{ets_opts := [Opt | NOpts]});
parse_opts([{decentralized_counters, _} = Opt | Opts], #{ets_opts := NOpts} = Acc) ->
parse_opts(Opts, Acc#{ets_opts := [Opt | NOpts]});
parse_opts([Opt | Opts], #{ets_opts := NOpts} = Acc) when ?is_ets_type(Opt) ->
parse_opts(Opts, Acc#{type => Opt, ets_opts := [Opt | NOpts]});
parse_opts([Opt | Opts], #{ets_opts := NOpts} = Acc) when ?is_ets_opt(Opt) ->
parse_opts(Opts, Acc#{ets_opts := [Opt | NOpts]});
parse_opts([Opt | _], _Acc) ->
error({badoption, Opt}).