Skip to content

Commit

Permalink
Quick'n'dirty $Get-$Piece optimization cache;
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomas Morstein committed Dec 30, 2012
1 parent ebacd5c commit 9504ab9
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 10 deletions.
33 changes: 30 additions & 3 deletions priv/egtm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,39 @@

%% Functions that are for some (security) reason denied
%{deny, [kill, do, call, merge, xecute]}
{deny, []}
%,
{deny, []},

%% String encoder/decoder functions
%{string_conversion, [
% {encode, {egtm_string, erl2utf} },
% {decode, {egtm_string, utf2erl} } ]}
% {decode, {egtm_string, utf2erl} } ]},

%% Dynamic Optimizer settings
{optimize, [

%% Use $Get(@Gvn@Subs) Erlang-side cache?
%% This would speed up the code where the
%% repetitive $Get on the same @Gvn@Subs
%% is performed -- such as multiple non-native
%% `getp' calls.
%% Any non-true value means to not use $Get-cache.
%% Default is false.
{get_cache, [
%{enabled, false},
{enabled, true},
{timeout, 5}
]},

%% Use native $P($G(@Gvn@Subs,Delim,Piece)) from
%% getp^%egtmapi or use standard get^%egtmapi
%% in combination with Erlang-based $Piece-emulation?
%% Any non-false value means to use native getp.
%% Default is true.
%{native_getp, true}
{native_getp, false}
]},

true %% dummy to avoid trailing commas
]}.

%% egtm metrics: histograms and counters
Expand Down
3 changes: 2 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
%% Lager must be first because of Erlang form transformations
{lager, ".*", {git, "https://github.com/basho/lager.git", "master"}},
{deepprops, ".*", {git, "https://github.com/keynslug/deepprops.git", "master"}},
{folsom, ".*", {git, "https://github.com/boundary/folsom.git", "master"}}
{folsom, ".*", {git, "https://github.com/boundary/folsom.git", "master"}},
{ecache, ".*", {git, "https://github.com/dweldon/ecache.git", "master"}}
]}.

{port_envs, [
Expand Down
63 changes: 59 additions & 4 deletions src/egtm.erl
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
%% @doc application:start callback, do not use directly!
start (_Type, _Args) ->
lager:start (),
application:start (ecache),
?report_info ("Starting up ~p on node ~p...", [?MODULE, node ()]),
egtm_admin:initdb (),
case operation_mode () of
Expand Down Expand Up @@ -125,8 +126,23 @@ get (Gvn) -> get (Gvn, []).
-spec get (Gvn::global_name (), Subs::subscripts ()) -> string ().
get (Gvn, Subs) when is_list (Subs) ->
?trace ("get", [Gvn, Subs]),
egtm_string:decode (unescape_val (perform (get,
[format_gvn (Gvn, Subs)]))).
PerformIt = fun () ->
egtm_string:decode (unescape_val (perform (get,
[format_gvn (Gvn, Subs)])))
end,
case egtm_config:param ([egtm,optimize,get_cache,enabled]) of
true ->
CKey = {Gvn, Subs},
TimeOut = egtm_config:param ([egtm,optimize,get_cache,timeout]),
case ecache:load (CKey) of
{ok, Val} ->
Val;
_ ->
X = PerformIt (), ecache:store (CKey, X, TimeOut), X
end;
_ ->
PerformIt ()
end.

%% @doc Get value of specific position in specified node
%% value delimited by specified delimiter
Expand All @@ -135,8 +151,18 @@ get (Gvn, Subs) when is_list (Subs) ->
Piece::integer (), Delim::string ()) -> string ().
getp (Gvn, Subs, Piece, Delim) when is_number (Piece) ->
?trace ("getp", [Gvn, Subs, Piece, Delim]),
egtm_string:decode (unescape_val (perform (getp,
[format_gvn (Gvn, Subs), Piece, Delim]))).

% Use native $GET($PIECE(@Gvn@Subs,Delim,Piece)) or
% just $Get(@Gvn@Subs) and emulate $Piece in Erlang?
case egtm_config:param ([egtm,optimize,native_getp]) of
false ->
% Use Erlang-side $Piece only if the native one
% is explicitly disabled:
epiece (get (Gvn, Subs), Delim, Piece);
_ ->
egtm_string:decode (unescape_val (perform (getp,
[format_gvn (Gvn, Subs), Piece, Delim])))
end.

%% @equiv getp (Gvn, Subs, Piece, Delim)
getp (Gvn, Piece, Delim) when is_number (Piece) ->
Expand All @@ -162,6 +188,7 @@ set (Gvn, Val) -> set (Gvn, [], Val).
Val::string ()) -> ok.
set (Gvn, Subs, Val) ->
?trace ("set", [Gvn, Subs, Val]),
clear_cache (Gvn, Subs),
perform (set, [format_gvn (Gvn, Subs),
escape_val (egtm_string:encode (Val))]).

Expand All @@ -173,6 +200,7 @@ set (Gvn, Subs, Val) ->
Val::string ()) -> ok.
setp (Gvn, Subs, Piece, Delim, Val) when is_number (Piece) ->
?trace ("setp", [Gvn, Subs, Piece, Delim, Val]),
clear_cache (Gvn, Subs),
perform (setp, [format_gvn (Gvn, Subs), Piece, Delim,
escape_val (egtm_string:encode (Val))]).

Expand Down Expand Up @@ -261,6 +289,7 @@ kill (Gvn) -> kill (Gvn, []).
-spec kill (Gvn::global_name (), Subs::subscripts ()) -> ok.
kill (Gvn, Subs) ->
?trace ("kill", [Gvn, Subs]),
clear_cache (Gvn, Subs, true),
perform (kill, [format_gvn (Gvn, Subs)]).

%% @equiv zkill (Gvn, [])
Expand All @@ -272,6 +301,7 @@ zkill (Gvn) -> zkill (Gvn, []).
-spec zkill (Gvn::global_name (), Subs::subscripts ()) -> ok.
zkill (Gvn, Subs) ->
?trace ("zkill", [Gvn, Subs]),
clear_cache (Gvn, Subs),
perform (zkill, [format_gvn (Gvn, Subs)]).

%% @equiv do (Gvn, [])
Expand Down Expand Up @@ -301,6 +331,7 @@ merge (SrcGvn, DstGvn) -> merge (SrcGvn, [], DstGvn, []).
DstGvn::global_name (), DstSubs::subscripts ()) -> ok.
merge (SrcGvn, SrcSubs, DstGvn, DstSubs) ->
?trace ("merge", [SrcGvn, SrcSubs, DstGvn, DstSubs]),
clear_cache (DstGvn, DstSubs),
perform (merge, [format_gvn (DstGvn, DstSubs),
format_gvn (SrcGvn, SrcSubs)]).

Expand Down Expand Up @@ -516,6 +547,30 @@ mumps_unescape ([]) -> [];
mumps_unescape ([$",$"|T]) -> [$"|mumps_unescape (T)];
mumps_unescape ([H|T]) -> [H|mumps_unescape (T)].

epiece ([], _, _) -> [];
epiece (_, _, N) when N =< 0 -> [];
epiece (S, D, N) when N > 0 andalso is_list (S) ->
DBin = list_to_binary (D),
binary_to_list (epiece_internal (binary:split (list_to_binary (S), DBin), DBin, 1, N)).

epiece_internal ([S|_], _, N, N) -> S;
epiece_internal ([_, R], D, M, N) ->
epiece_internal (binary:split (R, D), D, M+1, N);
epiece_internal (_, _, _, _) -> <<>>.

clear_cache (Gvn, Subs) -> clear_cache (Gvn, Subs, false).
clear_cache (Gvn, Subs, Flush) ->
case egtm_config:param ([egtm,optimize,get_cache,enabled]) of
true ->
CKey = {Gvn, Subs},
case Flush of
true -> ecache:flush ();
false -> ecache:delete (CKey)
end,
ok;
_ -> ok
end.


%% EUnit Tests
-ifdef (TEST).
Expand Down
7 changes: 5 additions & 2 deletions src/egtm_config.erl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ defaults () ->
[{defaults,[{piece_delim,"|"}]},
{mode, single},
{workers,[{nodes,[egtm1,egtm2,egtm3,egtm4]}]},
{deny,[kill,do,call,merge,xecute]}]},
{deny,[]},
{optimize,
[{get_cache, [{enabled, false}, {timeout, 5}]},
{native_getp, true}]}]},
{egtm_metrics, [{enabled, false}]}].

%% @doc Get a config value from `priv/egtm.conf'.
Expand All @@ -112,7 +115,7 @@ param () ->
application:set_env (module_name (), config, Conf),
Conf;
{error, Error} ->
io:format ("ConfigError: ~p~n", [Error]),
io:format ("ConfigError: ~p~n", [{config_path (), Error}]),
application:set_env (module_name (), config, {}),
{};
_ ->
Expand Down

0 comments on commit 9504ab9

Please sign in to comment.