Segment optimisation for segmented ets backends

This commit is contained in:
Daniil Fedotov 2016-06-02 11:39:42 +01:00
parent be1bea1f99
commit 28d22cdca4
2 changed files with 33 additions and 24 deletions

View File

@ -69,16 +69,15 @@ handle_call({get_write_segment, Expiration}, _From,
[{_, Segment} | _] = NewSegments = maybe_add_segment(NewBoundary, Segments),
{reply, Segment, State#state{segments = NewSegments}};
handle_call(get_segment_tables, _From, State = #state{segments = Segments}) ->
{_,Tables} = lists:unzip(Segments),
{_, Valid} = partition_expired_segments(Segments),
{_,Tables} = lists:unzip(Valid),
{reply, Tables, State}.
handle_cast(_, State = #state{}) ->
{noreply, State}.
handle_info(gc, State = #state{ segments = Segments }) ->
{Expired, Valid} = lists:partition(
fun({Boundary, _}) -> rabbit_auth_cache:expired(Boundary) end,
Segments),
{Expired, Valid} = partition_expired_segments(Segments),
[ets:delete(Table) || {_, Table} <- Expired],
{noreply, State#state{ segments = Valid }};
handle_info(_Msg, State) ->
@ -91,6 +90,11 @@ terminate(_Reason, State = #state{gc_timer = Timer}) ->
timer:cancel(Timer),
State.
partition_expired_segments(Segments) ->
lists:partition(
fun({Boundary, _}) -> rabbit_auth_cache:expired(Boundary) end,
Segments).
maybe_add_segment(Boundary, OldSegments) ->
case OldSegments of
[{OldBoundary, _}|_] when OldBoundary > Boundary ->
@ -108,13 +112,16 @@ get_from_segments(Key) ->
lists:flatmap(
fun(undefined) -> [];
(T) ->
case ets:lookup(T, Key) of
try ets:lookup(T, Key) of
[{Key, {Exp, Val}}] ->
case rabbit_auth_cache:expired(Exp) of
true -> [];
false -> [Val]
end;
[] -> []
% ETS table can be deleted concurrently.
catch
error:badarg -> []
end
end,
Tables).

View File

@ -110,10 +110,9 @@ do_add_segment(Segment) ->
end.
get_segment_tables() ->
get_all_segment_tables().
% Now = time_compat:erlang_system_time(milli_seconds),
% MatchSpec = [{{'$1', '$2'}, [{'>', '$1', {const, Now}}], ['$_']}],
% [V || {K, V} <- ets:select(?SEGMENT_TABLE, MatchSpec), K =/= segment_size].
Now = time_compat:erlang_system_time(milli_seconds),
MatchSpec = [{{'$1', '$2'}, [{'>', '$1', {const, Now}}], ['$_']}],
[V || {K, V} <- ets:select(?SEGMENT_TABLE, MatchSpec), K =/= segment_size].
get_all_segment_tables() ->
[V || {K, V} <- ets:tab2list(?SEGMENT_TABLE), K =/= segment_size].
@ -123,13 +122,16 @@ get_from_segments(Key) ->
lists:flatmap(
fun(undefined) -> [];
(T) ->
case ets:lookup(T, Key) of
try ets:lookup(T, Key) of
[{Key, {Exp, Val}}] ->
case rabbit_auth_cache:expired(Exp) of
true -> [];
false -> [Val]
end;
[] -> []
% ETS table can be deleted concurrently.
catch
error:badarg -> []
end
end,
Tables).