diff options
Diffstat (limited to 'lib/mnesia/test/mnesia_dbn_meters.erl')
-rw-r--r-- | lib/mnesia/test/mnesia_dbn_meters.erl | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/lib/mnesia/test/mnesia_dbn_meters.erl b/lib/mnesia/test/mnesia_dbn_meters.erl new file mode 100644 index 0000000000..feaf90ee75 --- /dev/null +++ b/lib/mnesia/test/mnesia_dbn_meters.erl @@ -0,0 +1,242 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% + +-module(mnesia_dbn_meters). +-export([ + start/0, + local_start/0, + distr_start/1, + start/3 + ]). + +-record(simple,{key,val=0}). +-define(key,1). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Configuration and start + +start() -> + local_start(), + distr_start(nodes()). + +local_start() -> + start(one_ram_only,[node()],some_meters()), + start(one_disc_only,[node()],some_meters()). + +distr_start([]) -> + local_only; +distr_start(OtherNodes) when is_list(OtherNodes) -> + start(ram_and_ram,[node()|OtherNodes],some_meters()), + start(disc_and_disc,[node()|OtherNodes],some_meters()). + +start(Config,Nodes,Meters) -> + Attrs = record_info(fields,simple), + Schema = [{name,simple},{type,set},{attributes,Attrs}] ++ config(Config,Nodes), + L = '====================', + io:format("~n~p dbn_meters: ~p ~p~nSchema = ~p.~n~n",[L,Config,L,Schema]), + ok = mnesia:delete_schema(Nodes), + ok = mnesia:create_schema(Nodes), + rpc:multicall(Nodes, mnesia, start, []), + {atomic,_} = mnesia:create_table(Schema), + lists:foreach(fun report_meter/1,Meters), + {atomic, ok} = mnesia:delete_table(simple), + rpc:multicall(Nodes, mnesia, stop, []), + ok. + +config(one_ram_only,[Single|_]) -> + [{ram_copies,[Single]}]; +config(ram_and_ram,[Master|[Slave|_]]) -> + [{ram_copies,[Master,Slave]}]; +config(one_disc_only,[Single|_]) -> + [{disc_copies,[Single]}]; +config(disc_and_disc,[Master|[Slave|_]]) -> + [{disc_copies,[Master,Slave]}]; +config(Config,Nodes) -> + io:format("<ERROR> Config ~p not supported or too few nodes ~p given~n",[Config,Nodes]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% The various DBN meters +some_meters() -> + [create, + open_safe_read, + open_dirty_read, + get_int, + open_update, + put_int, + put_int_and_copy, + dirty_put_int_and_copy, + start_trans, + commit_one_update, + delete, + dirty_delete + ]. + +report_meter(Meter) -> + Times = 100, + Micros = repeat_meter(Meter,{atomic,{0,ignore}},Times) div Times, + io:format("\t~-30w ~-10w micro seconds (mean of ~p repetitions)~n",[Meter,Micros,Times]). + +repeat_meter(_Meter,{atomic,{Micros,_Result}},0) -> + Micros; +repeat_meter(Meter,{atomic,{Micros,_Result}},Times) when Times > 0 -> + repeat_meter(Meter,catch meter(Meter),Times-1) + Micros; +repeat_meter(Meter,{aborted,Reason},Times) when Times > 0 -> + io:format("<ERROR>\t~-20w\t,aborted, because ~p~n",[Meter,Reason]), + 0; +repeat_meter(Meter,{'EXIT',Reason},Times) when Times > 0 -> + io:format("<ERROR>\t~-20w\tcrashed, because ~p~n",[Meter,Reason]), + 0. + +meter(create) -> + Key = 1, + mnesia:transaction(fun() -> mnesia:delete({simple,Key}) end), + Fun = fun() -> + BeforeT = erlang:now(), + R = mnesia:write(#simple{key=Key}), + AfterT = erlang:now(), + elapsed_time(BeforeT,AfterT,R) + end, + mnesia:transaction(Fun); + +meter(open_safe_read) -> + Key = 2, + mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end), + Fun = fun() -> + BeforeT = erlang:now(), + R = mnesia:read({simple,Key}), + AfterT = erlang:now(), + elapsed_time(BeforeT,AfterT,R) + end, + mnesia:transaction(Fun); + +meter(open_dirty_read) -> + Key = 21, + mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end), + Fun = fun() -> + BeforeT = erlang:now(), + R = mnesia:dirty_read({simple,Key}), + AfterT = erlang:now(), + elapsed_time(BeforeT,AfterT,R) + end, + mnesia:transaction(Fun); + +meter(get_int) -> + Key = 3, + mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end), + Fun = fun() -> + [Simple] = mnesia:read({simple,Key}), + BeforeT = erlang:now(), + Int = Simple#simple.val, + AfterT = erlang:now(), + elapsed_time(BeforeT,AfterT,Int) + end, + mnesia:transaction(Fun); + +meter(open_update) -> + Key = 3, + mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end), + Fun = fun() -> + BeforeT = erlang:now(), + R = mnesia:wread({simple,Key}), + AfterT = erlang:now(), + elapsed_time(BeforeT,AfterT,R) + end, + mnesia:transaction(Fun); + +meter(put_int) -> + Key = 4, + mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end), + Fun = fun() -> + [Simple] = mnesia:wread({simple,Key}), + BeforeT = erlang:now(), + R = Simple#simple{val=7}, + AfterT = erlang:now(), + elapsed_time(BeforeT,AfterT,R) + end, + mnesia:transaction(Fun); + +meter(put_int_and_copy) -> + Key = 5, + mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end), + Fun = fun() -> + [Simple] = mnesia:wread({simple,Key}), + BeforeT = erlang:now(), + Simple2 = Simple#simple{val=17}, + R = mnesia:write(Simple2), + AfterT = erlang:now(), + elapsed_time(BeforeT,AfterT,R) + end, + mnesia:transaction(Fun); + +meter(dirty_put_int_and_copy) -> + Key = 55, + mnesia:dirty_write(#simple{key=Key}), + [Simple] = mnesia:dirty_read({simple,Key}), + BeforeT = erlang:now(), + Simple2 = Simple#simple{val=17}, + R = mnesia:dirty_write(Simple2), + AfterT = erlang:now(), + {atomic,elapsed_time(BeforeT,AfterT,R)}; + +meter(start_trans) -> + BeforeT = erlang:now(), + {atomic,AfterT} = mnesia:transaction(fun() -> erlang:now() end), + {atomic,elapsed_time(BeforeT,AfterT,ok)}; + +meter(commit_one_update) -> + Key = 6, + mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end), + Fun = fun() -> + [Simple] = mnesia:wread({simple,Key}), + Simple2 = Simple#simple{val=27}, + _R = mnesia:write(Simple2), + erlang:now() + end, + {atomic,BeforeT} = mnesia:transaction(Fun), + AfterT = erlang:now(), + {atomic,elapsed_time(BeforeT,AfterT,ok)}; + +meter(delete) -> + Key = 7, + mnesia:transaction(fun() -> mnesia:write(#simple{key=Key}) end), + Fun = fun() -> + BeforeT = erlang:now(), + R = mnesia:delete({simple,Key}), + AfterT = erlang:now(), + elapsed_time(BeforeT,AfterT,R) + end, + mnesia:transaction(Fun); + +meter(dirty_delete) -> + Key = 75, + mnesia:dirty_write(#simple{key=Key}), + BeforeT = erlang:now(), + R = mnesia:dirty_delete({simple,Key}), + AfterT = erlang:now(), + {atomic, elapsed_time(BeforeT,AfterT,R)}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Calculate the elapsed time +elapsed_time(BeforeT,AfterT,Result) -> + {(element(1,AfterT)*1000000000000 + +element(2,AfterT)*1000000+element(3,AfterT)) - + (element(1,BeforeT)*1000000000000 + +element(2,BeforeT)*1000000+element(3,BeforeT)),Result}. |