Refactor step #1, know current max_level
This refactoring just adds the stat to the master gen_server of a Hanoi instance to know the current number of levels. Until now, we've only held a reference to the current top level.
This commit is contained in:
parent
755788ecfb
commit
9fb8a5e73f
2 changed files with 16 additions and 11 deletions
|
@ -41,7 +41,7 @@
|
||||||
-include_lib("kernel/include/file.hrl").
|
-include_lib("kernel/include/file.hrl").
|
||||||
-include_lib("include/hanoi.hrl").
|
-include_lib("include/hanoi.hrl").
|
||||||
|
|
||||||
-record(state, { top, nursery, dir, opt }).
|
-record(state, { top, nursery, dir, opt, max_level }).
|
||||||
|
|
||||||
|
|
||||||
%% PUBLIC API
|
%% PUBLIC API
|
||||||
|
@ -196,16 +196,17 @@ async_receive_fold_range(PID,Fun,Acc0,Ref,Range) ->
|
||||||
init([Dir, Opts]) ->
|
init([Dir, Opts]) ->
|
||||||
case file:read_file_info(Dir) of
|
case file:read_file_info(Dir) of
|
||||||
{ok, #file_info{ type=directory }} ->
|
{ok, #file_info{ type=directory }} ->
|
||||||
{ok, TopLevel} = open_levels(Dir,Opts),
|
{ok, TopLevel, MaxLevel} = open_levels(Dir,Opts),
|
||||||
{ok, Nursery} = hanoi_nursery:recover(Dir, TopLevel);
|
{ok, Nursery} = hanoi_nursery:recover(Dir, TopLevel);
|
||||||
|
|
||||||
{error, E} when E =:= enoent ->
|
{error, E} when E =:= enoent ->
|
||||||
ok = file:make_dir(Dir),
|
ok = file:make_dir(Dir),
|
||||||
{ok, TopLevel} = hanoi_level:open(Dir, ?TOP_LEVEL, undefined, Opts),
|
{ok, TopLevel} = hanoi_level:open(Dir, ?TOP_LEVEL, undefined, Opts, self()),
|
||||||
|
MaxLevel = ?TOP_LEVEL,
|
||||||
{ok, Nursery} = hanoi_nursery:new(Dir)
|
{ok, Nursery} = hanoi_nursery:new(Dir)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
{ok, #state{ top=TopLevel, dir=Dir, nursery=Nursery, opt=Opts }}.
|
{ok, #state{ top=TopLevel, dir=Dir, nursery=Nursery, opt=Opts, max_level=MaxLevel }}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,7 +234,7 @@ open_levels(Dir,Options) ->
|
||||||
|
|
||||||
{TopLevel, MaxMerge} =
|
{TopLevel, MaxMerge} =
|
||||||
lists:foldl( fun(LevelNo, {Prev, Max}) ->
|
lists:foldl( fun(LevelNo, {Prev, Max}) ->
|
||||||
{ok, Level} = hanoi_level:open(Dir,LevelNo,Prev,Options),
|
{ok, Level} = hanoi_level:open(Dir,LevelNo,Prev,Options,self()),
|
||||||
|
|
||||||
NextMax = max(Max, hanoi_level:unmerged_count(Level)),
|
NextMax = max(Max, hanoi_level:unmerged_count(Level)),
|
||||||
|
|
||||||
|
@ -250,7 +251,7 @@ open_levels(Dir,Options) ->
|
||||||
%% second incremental merge blocks until the previous is done
|
%% second incremental merge blocks until the previous is done
|
||||||
ok = hanoi_level:incremental_merge(TopLevel, 0),
|
ok = hanoi_level:incremental_merge(TopLevel, 0),
|
||||||
|
|
||||||
{ok, TopLevel}.
|
{ok, TopLevel, MaxLevel}.
|
||||||
|
|
||||||
parse_level(FileName) ->
|
parse_level(FileName) ->
|
||||||
case re:run(FileName, "^[^\\d]+-(\\d+)\\.data$", [{capture,all_but_first,list}]) of
|
case re:run(FileName, "^[^\\d]+-(\\d+)\\.data$", [{capture,all_but_first,list}]) of
|
||||||
|
@ -261,6 +262,9 @@ parse_level(FileName) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
handle_info({bottom_level, N}, State) when N > State#state.max_level ->
|
||||||
|
{noreply,State#state{ max_level = N }};
|
||||||
|
|
||||||
handle_info(Info,State) ->
|
handle_info(Info,State) ->
|
||||||
error_logger:error_msg("Unknown info ~p~n", [Info]),
|
error_logger:error_msg("Unknown info ~p~n", [Info]),
|
||||||
{stop,bad_msg,State}.
|
{stop,bad_msg,State}.
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
-behavior(plain_fsm).
|
-behavior(plain_fsm).
|
||||||
-export([data_vsn/0, code_change/3]).
|
-export([data_vsn/0, code_change/3]).
|
||||||
|
|
||||||
-export([open/4, lookup/2, inject/2, close/1, snapshot_range/3, blocking_range/3,
|
-export([open/5, lookup/2, inject/2, close/1, snapshot_range/3, blocking_range/3,
|
||||||
incremental_merge/2, unmerged_count/1]).
|
incremental_merge/2, unmerged_count/1]).
|
||||||
|
|
||||||
-include_lib("kernel/include/file.hrl").
|
-include_lib("kernel/include/file.hrl").
|
||||||
|
@ -50,16 +50,16 @@
|
||||||
-record(state, {
|
-record(state, {
|
||||||
a, b, c, next, dir, level, inject_done_ref, merge_pid, folding = [],
|
a, b, c, next, dir, level, inject_done_ref, merge_pid, folding = [],
|
||||||
step_next_ref, step_caller, step_merge_ref,
|
step_next_ref, step_caller, step_merge_ref,
|
||||||
opts = []
|
opts = [], owner
|
||||||
}).
|
}).
|
||||||
|
|
||||||
%%%%% PUBLIC OPERATIONS
|
%%%%% PUBLIC OPERATIONS
|
||||||
|
|
||||||
open(Dir,Level,Next,Opts) when Level>0 ->
|
open(Dir,Level,Next,Opts,Owner) when Level>0 ->
|
||||||
PID = plain_fsm:spawn_link(?MODULE,
|
PID = plain_fsm:spawn_link(?MODULE,
|
||||||
fun() ->
|
fun() ->
|
||||||
process_flag(trap_exit,true),
|
process_flag(trap_exit,true),
|
||||||
initialize(#state{dir=Dir,level=Level,next=Next,opts=Opts})
|
initialize(#state{dir=Dir,level=Level,next=Next,opts=Opts,owner=Owner})
|
||||||
end),
|
end),
|
||||||
{ok, PID}.
|
{ok, PID}.
|
||||||
|
|
||||||
|
@ -481,7 +481,8 @@ main_loop(State = #state{ next=Next }) ->
|
||||||
State1 =
|
State1 =
|
||||||
if Next =:= undefined ->
|
if Next =:= undefined ->
|
||||||
{ok, PID} = ?MODULE:open(State#state.dir, State#state.level + 1, undefined,
|
{ok, PID} = ?MODULE:open(State#state.dir, State#state.level + 1, undefined,
|
||||||
State#state.opts ),
|
State#state.opts, State#state.owner ),
|
||||||
|
State#state.owner ! { bottom_level, State#state.level + 1 },
|
||||||
State#state{ next=PID };
|
State#state{ next=PID };
|
||||||
true ->
|
true ->
|
||||||
State
|
State
|
||||||
|
|
Loading…
Reference in a new issue