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:
Kresten Krab Thorup 2012-04-23 22:32:51 +02:00
parent 755788ecfb
commit 9fb8a5e73f
2 changed files with 16 additions and 11 deletions

View file

@ -41,7 +41,7 @@
-include_lib("kernel/include/file.hrl").
-include_lib("include/hanoi.hrl").
-record(state, { top, nursery, dir, opt }).
-record(state, { top, nursery, dir, opt, max_level }).
%% PUBLIC API
@ -196,16 +196,17 @@ async_receive_fold_range(PID,Fun,Acc0,Ref,Range) ->
init([Dir, Opts]) ->
case file:read_file_info(Dir) of
{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);
{error, E} when E =:= enoent ->
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)
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} =
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)),
@ -250,7 +251,7 @@ open_levels(Dir,Options) ->
%% second incremental merge blocks until the previous is done
ok = hanoi_level:incremental_merge(TopLevel, 0),
{ok, TopLevel}.
{ok, TopLevel, MaxLevel}.
parse_level(FileName) ->
case re:run(FileName, "^[^\\d]+-(\\d+)\\.data$", [{capture,all_but_first,list}]) of
@ -261,6 +262,9 @@ parse_level(FileName) ->
end.
handle_info({bottom_level, N}, State) when N > State#state.max_level ->
{noreply,State#state{ max_level = N }};
handle_info(Info,State) ->
error_logger:error_msg("Unknown info ~p~n", [Info]),
{stop,bad_msg,State}.

View file

@ -42,7 +42,7 @@
-behavior(plain_fsm).
-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]).
-include_lib("kernel/include/file.hrl").
@ -50,16 +50,16 @@
-record(state, {
a, b, c, next, dir, level, inject_done_ref, merge_pid, folding = [],
step_next_ref, step_caller, step_merge_ref,
opts = []
opts = [], owner
}).
%%%%% 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,
fun() ->
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),
{ok, PID}.
@ -481,7 +481,8 @@ main_loop(State = #state{ next=Next }) ->
State1 =
if Next =:= 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 };
true ->
State