Skip to content

Commit

Permalink
[#1] – Implement shards:rename/2 (for local and distributed shards).
Browse files Browse the repository at this point in the history
  • Loading branch information
cabol committed Feb 22, 2017
1 parent 6b5f05d commit c777b9e
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 57 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
language: erlang
otp_release:
- 19.0
- 19.2
- 18.3
- 18.2.1
- 18.1
- 18.0
before_script:
- epmd -daemon
Expand Down
1 change: 0 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@

{dialyzer, [
{warnings, [
race_conditions,
no_return,
unmatched_returns,
error_handling
Expand Down
13 changes: 13 additions & 0 deletions src/shards.erl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
new/2,
next/2,
prev/2,
rename/2,
safe_fixtable/2,
select/2, select/3, select/1,
select_count/2,
Expand Down Expand Up @@ -479,6 +480,18 @@ next(Tab, Key1) ->
prev(Tab, Key1) ->
call(Tab, prev, [Tab, Key1]).

%% @doc
%% Wrapper to `shards_local:rename/3' and `shards_dist:rename/3'.
%%
%% @see shards_local:rename/3.
%% @see shards_dist:rename/3.
%% @end
-spec rename(Tab, Name) -> Name | no_return() when
Tab :: atom(),
Name :: atom().
rename(Tab, Name) ->
call(Tab, rename, [Tab, Name]).

%% @doc
%% Wrapper to `shards_local:safe_fixtable/2' and `shards_dist:safe_fixtable/2'.
%%
Expand Down
20 changes: 17 additions & 3 deletions src/shards_dist.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
delete/1, delete/3,
delete_all_objects/2,
delete_object/3,
new/2,
insert/3,
insert_new/3,
lookup/3,
Expand All @@ -26,6 +25,8 @@
match_delete/3,
match_object/3,
member/3,
new/2,
rename/3,
select/3,
select_count/3,
select_delete/3,
Expand Down Expand Up @@ -70,7 +71,7 @@ join(Tab, Nodes) ->

%% @private
join_(Tab) ->
pg2:join(Tab, whereis(Tab)).
pg2:join(Tab, shards_local:get_pid(Tab)).

-spec leave(Tab, Nodes) -> LeavedNodes when
Tab :: atom(),
Expand Down Expand Up @@ -198,7 +199,7 @@ lookup_element(Tab, Key, Pos, State) ->
(_) -> true
end, mapred(Tab, Map, nil, State, r)),
case Filter of
[] -> exit({badarg, erlang:get_stacktrace()});
[] -> error(badarg);
_ -> lists:append(Filter)
end;
Node ->
Expand Down Expand Up @@ -265,6 +266,19 @@ new(Name, Options, Nodes) ->
_ = join(Name, AllNodes),
Name.

-spec rename(Tab, Name, State) -> Name | no_return() when
Tab :: atom(),
Name :: atom(),
State :: shards_state:state().
rename(Tab, Name, State) ->
Map = {?SHARDS, rename, [Tab, Name, State]},
_ = mapred(Tab, nil, Map, nil, State, r),
Nodes = get_nodes(Tab),
ok = pg2:delete(Tab),
ok = pg2:create(Name),
Nodes = join(Name, Nodes),
Name.

-spec select(Tab, MatchSpec, State) -> [Match] when
Tab :: atom(),
MatchSpec :: ets:match_spec(),
Expand Down
65 changes: 58 additions & 7 deletions src/shards_local.erl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
new/2,
next/2, next/3,
prev/2, prev/3,
rename/2, rename/3,
safe_fixtable/2, safe_fixtable/3,
select/2, select/3, select/4, select/1,
select_count/2, select_count/3,
Expand All @@ -108,7 +109,8 @@
-export([
shard_name/2,
pick/3,
list/2
list/2,
get_pid/1
]).

%%%===================================================================
Expand Down Expand Up @@ -218,7 +220,7 @@ all() ->
%% @end
-spec delete(Tab :: atom()) -> true.
delete(Tab) ->
ok = shards_sup:terminate_child(shards_sup, whereis(Tab)),
ok = shards_sup:terminate_child(shards_sup, get_pid(Tab)),
true.

%% @equiv delete(Tab, Key, shards_state:new())
Expand Down Expand Up @@ -297,8 +299,8 @@ file2tab(Filenames, Options) ->
{ok, Info} ->
{name, ShardTabName} = lists:keyfind(name, 1, Info),
{ShardTabName, FN};
{error, Reason} ->
throw({error, Reason})
{error, _} = Error ->
throw(Error)
end
end || FN <- Filenames],
Tab = name_from_shard(First),
Expand Down Expand Up @@ -638,7 +640,7 @@ lookup_element(Tab, Key, Pos, State) ->
(_) -> true
end, mapred(Tab, {LookupElem, [Key, Pos]}, State)),
case Filter of
[] -> exit({badarg, erlang:get_stacktrace()});
[] -> error(badarg);
_ -> lists:append(Filter)
end;
Shard ->
Expand Down Expand Up @@ -849,8 +851,11 @@ member(Tab, Key, State) ->
Options :: [option()].
new(Name, Options) ->
case shards_sup:start_child([Name, Options]) of
{ok, _} -> Name;
_ -> throw(badarg)
{ok, Pid} ->
true = register(Name, Pid),
Name;
_ ->
error(badarg)
end.

%% @equiv next(Tab, Key1, shards_state:new())
Expand Down Expand Up @@ -916,6 +921,39 @@ prev(Tab, Key1, State) ->
next(Tab, Key1, State)
end.

%% @equiv rename(Tab, Name, shards_state:new())
rename(Tab, Name) ->
rename(Tab, Name, shards_state:new()).

%% @doc
%% Equivalent to `ets:rename/2'.
%%
%% Renames the table name and all its associated shard tables.
%% If something unexpected occurs during the process, an exception
%% will be thrown.
%%
%% @see ets:rename/2.
%% @end
-spec rename(Tab, Name, State) -> Name | no_return() when
Tab :: atom(),
Name :: atom(),
State :: shards_state:state().
rename(Tab, Name, State) ->
_ = lists:foreach(fun(Shard) ->
ShardName = shard_name(Tab, Shard),
NewShardName = shard_name(Name, Shard),
NewShardName = do_rename(ShardName, NewShardName)
end, lists:seq(0, shards_state:n_shards(State) - 1)),
do_rename(Tab, Name).

%% @private
do_rename(OldName, NewName) ->
NewName = ets:rename(OldName, NewName),
Pid = get_pid(OldName),
true = unregister(OldName),
true = register(NewName, Pid),
NewName.

%% @equiv safe_fixtable(Tab, Fix, shards_state:new())
safe_fixtable(Tab, Fix) ->
safe_fixtable(Tab, Fix, shards_state:new()).
Expand Down Expand Up @@ -1340,6 +1378,19 @@ list(TabName, NumShards) ->
Shards = lists:seq(0, NumShards - 1),
[shard_name(TabName, Shard) || Shard <- Shards].

%% @doc
%% Returns the PID associated to the table `Tab'.
%% <ul>
%% <li>`TabName': Table name.</li>
%% </ul>
%% @end
-spec get_pid(Tab :: atom()) -> pid() | no_return().
get_pid(Tab) ->
case whereis(Tab) of
undefined -> error(badarg);
Pid -> Pid
end.

%%%===================================================================
%%% Internal functions
%%%===================================================================
Expand Down
4 changes: 2 additions & 2 deletions src/shards_owner_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@
Options :: [term()],
Response :: supervisor:startlink_ret().
start_link(Name, Options) ->
supervisor:start_link({local, Name}, ?MODULE, [Name, Options]).
supervisor:start_link(?MODULE, [Name, Options]).

%%%===================================================================
%%% Supervisor callbacks
%%%===================================================================

%% @hidden
init([Name, Options]) ->
% ETS table to hold state info.
% ETS table to store state info.
Name = ets:new(Name, [
set,
named_table,
Expand Down
4 changes: 3 additions & 1 deletion test/dist_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
-mixin([
{test_helper, [
t_basic_ops/1,
t_update_ops/1
t_update_ops/1,
t_rename/1
]}
]).

Expand Down Expand Up @@ -48,6 +49,7 @@ groups() ->
t_update_ops,
t_match_ops,
t_select_ops,
t_rename,
t_eject_node_on_failure,
t_delete_and_auto_setup_tab
]}].
Expand Down
5 changes: 5 additions & 0 deletions test/local_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
t_fold_ops/1,
t_info_ops/1,
t_tab2list_tab2file_file2tab/1,
t_rename/1,
t_equivalent_ops/1
]}
]).
Expand Down Expand Up @@ -79,6 +80,10 @@ t_shard_restarted_when_down(_Config) ->
tab1 = shards:new(tab1, []),
tab2 = shards:new(tab2, [{restart_strategy, one_for_all}]),

try shards_local:get_pid(wrong)
catch _:badarg -> ok
end,

% insert some values
true = shards:insert(tab1, [{1, 1}, {2, 2}, {3, 3}]),
true = shards:insert(tab2, [{1, 1}, {2, 2}, {3, 3}]),
Expand Down
Loading

0 comments on commit c777b9e

Please sign in to comment.