mnesia_meter.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 463 行 · 第 1/2 页

ERL
463
字号
%% ``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 via the world wide web 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.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%%% Getting started:%%%% 1 Start one or more distributed Erlang nodes%% 2a Connect the nodes, e.g. with net_adm:ping/1%% 3a Run mnesia_meter:go()%% 3b Run mnesia_meter:go(ReplicaType)%% 3c Run mnesia_meter:go(ReplicaType, Nodes)-module(mnesia_meter).-author('hakan@erix.ericsson.se').-export([         go/0,          go/1,          go/2,         repeat_meter/2        ]).-record(person, {name,        %% atomic, unique key                 data,        %% compound structure                 married_to,  %% name of partner or undefined                 children}).  %% list of children-record(meter, {desc, init, meter, micros}).-record(result, {desc, list}).-define(TIMES, 1000).go() ->    go(ram_copies).go(ReplicaType) ->    go(ReplicaType, [node() | nodes()]).go(ReplicaType, Nodes) ->    {ok, FunOverhead} = tc(fun(_) -> {atomic, ok} end, ?TIMES),    Size = size(term_to_binary(#person{})),    io:format("A fun apply costs ~p micro seconds. Record size is ~p bytes.~n",              [FunOverhead, Size]),    Res = go(ReplicaType, Nodes, [], FunOverhead, []),    NewRes = rearrange(Res, []),    DescHeader = lists:flatten(io_lib:format("~w on ~w", [ReplicaType, Nodes])),    ItemHeader = lists:seq(1, length(Nodes)),    Header = #result{desc = DescHeader, list = ItemHeader},    SepList = ['--------' || _ <- Nodes],    Separator = #result{desc = "", list = SepList},    display([Separator, Header, Separator | NewRes] ++ [Separator]).go(ReplicaType, [], Config, FunOverhead, Acc) ->    Acc;go(ReplicaType, [H | T], OldNodes, FunOverhead, Acc) ->    Nodes = [H | OldNodes],    Config = [{ReplicaType, Nodes}],    Res = run(Nodes, Config, FunOverhead),    go(ReplicaType, T, Nodes, FunOverhead, [{ReplicaType, Nodes, Res} | Acc]).rearrange([{ReplicaType, Nodes, Meters} | Tail], Acc) ->    Acc2 = [add_meter(M, Acc) || M <- Meters],    rearrange(Tail, Acc2);rearrange([], Acc) ->    Acc.add_meter(M, Acc) ->    case lists:keysearch(M#meter.desc, #result.desc, Acc) of        {value, R} ->            R#result{list = [M#meter.micros | R#result.list]};        false ->            #result{desc = M#meter.desc, list = [M#meter.micros]}    end.display(Res) ->    MaxDesc = lists:max([length(R#result.desc) || R <- Res]),    Format = lists:concat(["! ~-", MaxDesc, "s"]),    display(Res, Format, MaxDesc).display([R | Res], Format, MaxDesc) ->    case R#result.desc of	"" ->	    io:format(Format, [lists:duplicate(MaxDesc, "-")]);	Desc ->	    io:format(Format, [Desc])    end,    display_items(R#result.list, R#result.desc),    io:format(" !~n", []),    display(Res, Format, MaxDesc);display([], _Format, _MaxDesc) ->    ok.    display_items([Item | Items], "") ->    io:format(" ! ~s", [lists:duplicate(10, $-)]),    display_items(Items, "");display_items([Micros | Items], Desc) ->    io:format(" ! ~10w", [Micros]),    display_items(Items, Desc);display_items([], _Desc) ->    ok.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%meters() ->    [#meter{desc = "transaction update two records with read and write",             init = fun write_records/2,            meter = fun update_records/1},      #meter{desc = "transaction update two records with wread and write",             init = fun write_records/2,            meter = fun w_update_records/1},      #meter{desc = "transaction update two records with read and s_write",             init = fun s_write_records/2,            meter = fun s_update_records/1},      #meter{desc = "sync_dirty  update two records with read and write",             init = fun sync_dirty_write_records/2,            meter = fun sync_dirty_update_records/1},      #meter{desc = "async_dirty update two records with read and write",             init = fun async_dirty_write_records/2,            meter = fun async_dirty_update_records/1},      #meter{desc = "plain fun   update two records with dirty_read and dirty_write",             init = fun dirty_write_records/2,            meter = fun dirty_update_records/1},      #meter{desc = "ets         update two records with read and write (local only)",             init = fun ets_opt_write_records/2,            meter = fun ets_update_records/1},      #meter{desc = "plain fun   update two records with ets:lookup and ets:insert (local only)",             init = fun bif_opt_write_records/2,            meter = fun bif_update_records/1},      #meter{desc = "plain fun   update two records with dets:lookup and dets:insert (local only)",             init = fun dets_opt_write_records/2,            meter = fun dets_update_records/1},           #meter{desc = "transaction write two records with write",             init = fun write_records/2,            meter = fun(X) -> write_records(X, 0-X) end},      #meter{desc = "transaction write two records with s_write",             init = fun s_write_records/2,            meter = fun(X) -> s_write_records(X, 0-X) end},      #meter{desc = "sync_dirty  write two records with write",             init = fun sync_dirty_write_records/2,            meter = fun(X) -> sync_dirty_write_records(X, 0-X) end},      #meter{desc = "async_dirty write two records with write",             init = fun async_dirty_write_records/2,            meter = fun(X) -> async_dirty_write_records(X, 0-X) end},      #meter{desc = "plain fun   write two records with dirty_write",             init = fun dirty_write_records/2,            meter = fun(X) -> dirty_write_records(X, 0-X) end},      #meter{desc = "ets         write two records with write (local only)",             init = fun ets_opt_write_records/2,            meter = fun(X) -> ets_write_records(X, 0-X) end},      #meter{desc = "plain fun   write two records with ets:insert (local only)",             init = fun bif_opt_write_records/2,            meter = fun(X) -> bif_write_records(X, 0-X) end},      #meter{desc = "plain fun   write two records with dets:insert (local only)",             init = fun dets_opt_write_records/2,            meter = fun(X) -> dets_write_records(X, 0-X) end},           #meter{desc = "transaction read two records with read",             init = fun write_records/2,            meter = fun(X) -> read_records(X, 0-X) end},      #meter{desc = "sync_dirty  read two records with read",             init = fun sync_dirty_write_records/2,            meter = fun(X) -> sync_dirty_read_records(X, 0-X) end},      #meter{desc = "async_dirty read two records with read",             init = fun async_dirty_write_records/2,            meter = fun(X) -> async_dirty_read_records(X, 0-X) end},      #meter{desc = "plain fun   read two records with dirty_read",             init = fun dirty_write_records/2,            meter = fun(X) -> dirty_read_records(X, 0-X) end},      #meter{desc = "ets         read two records with read",             init = fun ets_opt_write_records/2,            meter = fun(X) -> ets_read_records(X, 0-X) end},     #meter{desc = "plain fun   read two records with ets:lookup",             init = fun bif_opt_write_records/2,            meter = fun(X) -> bif_read_records(X, 0-X) end},     #meter{desc = "plain fun   read two records with dets:lookup",             init = fun dets_opt_write_records/2,            meter = fun(X) -> dets_read_records(X, 0-X) end}    ].update_fun(Name) ->    fun() ->            case mnesia:read({person, Name}) of                [] ->                     mnesia:abort(no_such_person);                [Pers] ->                    [Partner] = mnesia:read({person, Pers#person.married_to}),                     mnesia:write(Pers#person{married_to = undefined}),                     mnesia:write(Partner#person{married_to = undefined})            end    end.    update_records(Name) ->  mnesia:transaction(update_fun(Name)).sync_dirty_update_records(Name) ->  {atomic, mnesia:sync_dirty(update_fun(Name))}.async_dirty_update_records(Name) ->  {atomic, mnesia:async_dirty(update_fun(Name))}.ets_update_records(Name) ->  {atomic, mnesia:ets(update_fun(Name))}.w_update_records(Name) ->    F = fun() ->                case mnesia:wread({person, Name}) of                    [] ->                         mnesia:abort(no_such_person);                    [Pers] ->                        [Partner] = mnesia:wread({person, Pers#person.married_to}),                         mnesia:write(Pers#person{married_to = undefined}),                         mnesia:write(Partner#person{married_to = undefined})                end        end,     mnesia:transaction(F).s_update_records(Name) ->    F = fun() ->

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?