Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancements and fix issue #13. #14

Merged
merged 2 commits into from
Jun 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions src/shards.erl
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@
%% DistState :: shards_dist:state()
%% }.
%%
%% Defines the `shards' distributed state:
%% Defines the `shards' state:
%% <ul>
%% <li>`PickNode': Function callback to pick/compute the node.</li>
%% <li>`TableType': Table type.</li>
%% <li>`LocalState': Local state handled by `shards_local'.</li>
%% <li>`DistState': Distributed state handled by `shards_dist'.</li>
%% </ul>
-type state() :: {
LocalState :: shards_local:state(),
Expand Down Expand Up @@ -564,9 +564,25 @@ match_spec_run(List, CompiledMatchSpec) ->
member(Tab, Key) ->
call(Tab, member, [Tab, Key]).

%% @equiv shards_local:new(Name, Options)
%% @doc
%% Wrapper to `shards_local:new/2' and `shards_dist:new/2'.
%%
%% @see shards_local:new/2.
%% @see shards_dist:new/2.
%% @end
-spec new(Name, Options) -> Result when
Name :: atom(),
Options :: [shards_local:option()],
LocalState :: shards_local:state(),
DistState :: shards_dist:state(),
Local :: {Name, LocalState},
Dist :: {Name, {LocalState, DistState}},
Result :: Local | Dist.
new(Name, Options) ->
?SHARDS:new(Name, Options).
case lists:keyfind(scope, 1, Options) of
{scope, g} -> shards_dist:new(Name, Options);
_ -> shards_local:new(Name, Options)
end.

%% @doc
%% Wrapper to `shards_local:next/3' and `shards_dist:next/3'.
Expand Down
10 changes: 8 additions & 2 deletions src/shards_dist.erl
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,15 @@ member(Tab, Key, {Local, Dist}) ->
R -> R
end.

%% @equiv shards_local:new(Name, Options)
-spec new(Name, Options) -> Result when
Name :: atom(),
Options :: [shards_local:option()],
LocalState :: shards_local:state(),
DistState :: state(),
Result :: {Name, {LocalState, DistState}}.
new(Name, Options) ->
shards_local:new(Name, Options).
{Name, LocalState} = shards_local:new(Name, Options),
{Name, {LocalState, state(Name)}}.

-spec take(Tab, Key, State) -> [Object] when
Tab :: atom(),
Expand Down
48 changes: 37 additions & 11 deletions src/shards_local.erl
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,46 @@
Continuation :: ets:continuation()
}.

%% @type tweaks() = {write_concurrency, boolean()}
%% | {read_concurrency, boolean()}
%% | compressed.
%%
%% ETS tweaks option
-type tweaks() :: {write_concurrency, boolean()}
| {read_concurrency, boolean()}
| compressed.

%% @type shards_opt() = {n_shards, pos_integer()}
%% | {scope, l | g}
%% | {pick_shard_fun, pick_shard_fun()}
%% | {pick_node_fun, pick_node_fun()}.
%%
%% Shards extended options
-type shards_opt() :: {n_shards, pos_integer()}
| {scope, l | g}
| {pick_shard_fun, pick_shard_fun()}
| {pick_node_fun, pick_node_fun()}.

%% @type option() = ets:type() | ets:access() | named_table
%% | {keypos, pos_integer()}
%% | {heir, pid(), HeirData :: term()}
%% | {heir, none} | tweaks()
%% | shards_opt().
%%
%% Create table options – used by `new/2'.
-type option() :: ets:type() | ets:access() | named_table
| {keypos, pos_integer()}
| {heir, pid(), HeirData :: term()}
| {heir, none} | tweaks()
| shards_opt().

%% Exported types
-export_type([
operation_t/0,
pick_shard_fun/0,
state/0,
continuation/0
continuation/0,
option/0
]).

%% Default number of shards
Expand Down Expand Up @@ -782,17 +816,9 @@ member(Tab, Key, State) ->
%% @end
-spec new(Name, Options) -> Result when
Name :: atom(),
Options :: [Option],
Options :: [option()],
State :: state(),
Result :: {Name, State},
Option :: ets:type() | ets:access() | named_table | {keypos, pos_integer()}
| {heir, pid(), HeirData :: term()} | {heir, none} | Tweaks
| {n_shards, pos_integer()} | {scope, l | g}
| {pick_shard_fun, pick_shard_fun()}
| {pick_node_fun, pick_node_fun()},
Tweaks :: {write_concurrency, boolean()}
| {read_concurrency, boolean()}
| compressed.
Result :: {Name, State}.
new(Name, Options) ->
case lists:keytake(n_shards, 1, Options) of
{value, {n_shards, NumShards}, NewOpts} ->
Expand Down
29 changes: 19 additions & 10 deletions src/shards_owner_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
-define(worker(Mod, Args, Spec), child(worker, Mod, Args, Spec)).

%% Macro to check if option is table type
-define(is_type_prop(T_), T_ == set; T_ == ordered_set; T_ == bag; T_ == duplicate_bag).
-define(is_ets_type(T_), T_ == set; T_ == ordered_set; T_ == bag; T_ == duplicate_bag).

%%%===================================================================
%%% API functions
Expand Down Expand Up @@ -59,24 +59,33 @@ init([Name, Options, NumShards]) ->
ok = init_shards_dist(Name, Module),

% launch shards supervisor
supervise(Children, #{strategy => one_for_one}).
supervise(Children).

%%%===================================================================
%%% Internal functions
%%%===================================================================

%% @private
child(Type, Module, Args, Spec) when is_map(Spec) ->
#{id => maps:get(id, Spec, Module),
start => maps:get(start, Spec, {Module, start_link, Args}),
restart => maps:get(restart, Spec, permanent),
shutdown => maps:get(shutdown, Spec, 5000),
type => Type,
modules => maps:get(modules, Spec, [Module])}.
{maps:get(id, Spec, Module),
maps:get(start, Spec, {Module, start_link, Args}),
maps:get(restart, Spec, permanent),
maps:get(shutdown, Spec, 5000),
Type,
maps:get(modules, Spec, [Module])}.

%% @private
supervise(Children, SupFlags) ->
supervise(Children) ->
supervise(Children, #{}).

%% @private
supervise(Children, SupFlagsMap) ->
assert_unique_ids([Id || #{id := Id} <- Children]),
SupFlags = {
maps:get(strategy, SupFlagsMap, one_for_one),
maps:get(intensity, SupFlagsMap, 1),
maps:get(period, SupFlagsMap, 5)
},
{ok, {SupFlags, Children}}.

%% @private
Expand Down Expand Up @@ -113,7 +122,7 @@ parse_opts([{pick_node_fun, PickNode} | Opts], Acc) ->
parse_opts(Opts, Acc#{pick_node_fun := PickNode});
parse_opts([{autoeject_nodes, AutoEject} | Opts], Acc) ->
parse_opts(Opts, Acc#{autoeject_nodes := AutoEject});
parse_opts([Opt | Opts], #{opts := NOpts} = Acc) when ?is_type_prop(Opt) ->
parse_opts([Opt | Opts], #{opts := NOpts} = Acc) when ?is_ets_type(Opt) ->
parse_opts(Opts, Acc#{type := Opt, opts := [Opt | NOpts]});
parse_opts([Opt | Opts], #{opts := NOpts} = Acc) ->
parse_opts(Opts, Acc#{opts := [Opt | NOpts]}).
Expand Down
2 changes: 1 addition & 1 deletion test/dist_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
t_delete_tabs/1
]).

-include("test_common.hrl").
-include("test_helper.hrl").

-define(SLAVES, [a, b, c, d, e, f]).

Expand Down
46 changes: 32 additions & 14 deletions test/test_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
]).

-include_lib("stdlib/include/ms_transform.hrl").
-include("test_common.hrl").
-include("test_helper.hrl").

%%%===================================================================
%%% Tests Key Generator
Expand Down Expand Up @@ -447,19 +447,7 @@ t_unsupported_ops(_Config) ->
%%%===================================================================

init_shards(Scope) ->
DefaultShards = ?N_SHARDS,
{_, {2, _, set}} = shards:new(?SET, [{n_shards, 2}, {scope, Scope}, set]),
{_, {5, _, duplicate_bag}} =
shards:new(?DUPLICATE_BAG, [{n_shards, 5}, {scope, Scope}, duplicate_bag]),
{_, {DefaultShards, _, ordered_set}} =
shards:new(?ORDERED_SET, [{scope, Scope}, ordered_set]),
{_, {5, _, duplicate_bag}} = shards:new(?SHARDED_DUPLICATE_BAG, [
{n_shards, 5},
{scope, Scope},
duplicate_bag,
{pick_shard_fun, fun pick_shard/3},
{pick_node_fun, fun pick_node/3}
]),
init_shards_new(Scope),

set = shards_local:info_shard(?SET, 0, type),
duplicate_bag = shards_local:info_shard(?DUPLICATE_BAG, 0, type),
Expand All @@ -485,6 +473,36 @@ init_shards(Scope) ->
ets:give_away(?ETS_SHARDED_DUPLICATE_BAG, whereis(?SHARDED_DUPLICATE_BAG), []),
ok.

%% @private
init_shards_new(g) ->
DefaultShards = ?N_SHARDS,
{_, {{2, _, set}, _}} = shards:new(?SET, [{n_shards, 2}, {scope, g}, set]),
{_, {{5, _, duplicate_bag}, _}} =
shards:new(?DUPLICATE_BAG, [{n_shards, 5}, {scope, g}, duplicate_bag]),
{_, {{DefaultShards, _, ordered_set}, _}} =
shards:new(?ORDERED_SET, [{scope, g}, ordered_set]),
{_, {{5, _, duplicate_bag}, _}} = shards:new(?SHARDED_DUPLICATE_BAG, [
{n_shards, 5},
{scope, g},
duplicate_bag,
{pick_shard_fun, fun pick_shard/3},
{pick_node_fun, fun pick_node/3}
]);
init_shards_new(Scope) ->
DefaultShards = ?N_SHARDS,
{_, {2, _, set}} = shards:new(?SET, [{n_shards, 2}, {scope, Scope}, set]),
{_, {5, _, duplicate_bag}} =
shards:new(?DUPLICATE_BAG, [{n_shards, 5}, {scope, Scope}, duplicate_bag]),
{_, {DefaultShards, _, ordered_set}} =
shards:new(?ORDERED_SET, [{scope, Scope}, ordered_set]),
{_, {5, _, duplicate_bag}} = shards:new(?SHARDED_DUPLICATE_BAG, [
{n_shards, 5},
{scope, Scope},
duplicate_bag,
{pick_shard_fun, fun pick_shard/3},
{pick_node_fun, fun pick_node/3}
]).

cleanup_shards() ->
Mod = shards:module(?SET),
cleanup_shards_(Mod).
Expand Down
File renamed without changes.