From c8964e955c368d6414213eec7f762aa43c1f160d Mon Sep 17 00:00:00 2001 From: Kresten Krab Thorup Date: Tue, 1 May 2012 16:27:06 +0200 Subject: [PATCH] Config option {merge_strategy, fast|predictable} Both options have same log2(N) upper bound on latencies, but `fast' fluctuates. --- README.md | 13 ++++++++++--- src/hanoi_level.erl | 14 +++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 99c1dee..3e16bd8 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,16 @@ Put these values in your `app.config` in the `hanoi` section {data_root, "./data/hanoi"}, {compress, none | snappy | gzip}, {sync_strategy, none | sync | {seconds, N}}, - {page_size, 8192} - {write_buffer_size, 524288} % 512kB - {read_buffer_size, 524288} % 512kB + {page_size, 8192}, + {write_buffer_size, 524288}, % 512kB + {read_buffer_size, 524288}, % 512kB + + %% + %% The merge strategy is one of `fast' or `predictable'. + %% Both have same log2(N) worst case, but `fast' is + %% sometimes faster; yielding latency fluctuations. + %% + {merge_strategy, fast | predictable} ]}, ``` diff --git a/src/hanoi_level.erl b/src/hanoi_level.erl index 35bab1d..a146db3 100644 --- a/src/hanoi_level.erl +++ b/src/hanoi_level.erl @@ -514,7 +514,7 @@ main_loop(State = #state{ next=Next }) -> {ok, PID} = ?MODULE:open(State#state.dir, State#state.level + 1, undefined, State#state.opts, State#state.owner ), State#state.owner ! { bottom_level, State#state.level + 1 }, - State#state{ next=PID }; + State#state{ next=PID, max_level= State#state.level+1 }; true -> State end, @@ -582,10 +582,18 @@ do_step(StepFrom, PreviousWork, State) -> true -> WorkLeftHere = 0 end, + WorkUnit = ?BTREE_SIZE(?TOP_LEVEL), MaxLevel = max(State#state.max_level, State#state.level), - TotalWork = (MaxLevel-?TOP_LEVEL+1) * ?BTREE_SIZE(?TOP_LEVEL), + TotalWork = (MaxLevel-?TOP_LEVEL+1) * WorkUnit, WorkUnitsLeft = max(0, TotalWork-PreviousWork), - WorkToDoHere = min(WorkLeftHere, WorkUnitsLeft), + + case hanoi:get_opt( merge_strategy, State#state.opts, predictable) of + fast -> + WorkToDoHere = min(WorkLeftHere, WorkUnitsLeft); + predictable -> + WorkToDoHere = min(WorkLeftHere, WorkUnit) + end, + WorkIncludingHere = PreviousWork + WorkToDoHere, ?log("do_step prev:~p, do:~p of ~p ~n", [PreviousWork, WorkToDoHere, WorkLeftHere]),