-module(db_test). -export([scan_vals/2,dict/2,orddict/2,rbdict/2,gb_trees/2]). -export([rt/3]). -import(lists, [reverse/2,seq/2,seq/3,sort/1]). -define(KEY(N), N). %%-define(KEY(N), {foo,bar,N}). -define(RLOOP(F1, F2), F1(Reps, Ks, D) when Reps > 1 -> F2(Ks, D), F1(Reps-1, Ks, D); F1(1, Ks, D) -> F2(Ks, D)). -define(STORE(F1, F2), F1([K|Ks], D0) -> D1 = F2(?KEY(K), stuff, D0), F1(Ks, D1); F1([], D) -> D). -define(FETCH(F1, F2), F1([K|Ks], D) -> F2(?KEY(K), D), F1(Ks, D); F1([], D) -> D). scan_vals(0, N) -> [ X || {_,X} <- sort([ {random:uniform(N),X} || X <- seq(1, N) ]) ]; scan_vals(1, N) -> seq(1, N); %Straight sweep scan_vals(2, N) -> %Middle out M = N div 2, interlace(seq(M, 1, -1), seq(M+1, N, 1)); scan_vals(3, N) -> %Half and half M = N div 2, interlace(seq(1, M, 1), seq(M+1, N, 1)); scan_vals(4, N) -> %Double sweep seq(1, N, 2) ++ seq(2, N, 2). ?RLOOP(null, null1). ?FETCH(null1, nullop). nullop(_, _) -> ok. interlace([H1|T1], [H2|T2]) -> [H1,H2|interlace(T1, T2)]; interlace([], L2) -> L2; interlace(L1, []) -> L1. dict(Reps, Ks) -> %% Initial setup D0 = dict:new(), Nreps = (10000000 div length(Ks)) + 1, %Long timing {_,_} = statistics(runtime), %% Null sweep null(Nreps, Ks, D0), {_,Tn} = statistics(runtime), %% Initial store D1 = d_sto(Reps, Ks, D0), {_,Ti} = statistics(runtime), %% Fetching values D2 = d_fet(Reps, Ks, D1), {_,Tf} = statistics(runtime), %% Updating table D3 = d_sto(Reps, Ks, D1), {_,Tu} = statistics(runtime), {Tn/Nreps,Ti/Reps,Tf/Reps,Tu/Reps}. ?RLOOP(d_sto, d_sto1). ?STORE(d_sto1, dict:store). ?RLOOP(d_fet, d_fet1). ?FETCH(d_fet1, dict:fetch). orddict(Reps, Ks) -> D0 = orddict:new(), {_,_} = statistics(runtime), %% Null sweep null(Reps, Ks, D0), {_,Tn} = statistics(runtime), %% Initial store D1 = o_sto(Reps, Ks, D0), {_,Ti} = statistics(runtime), %% Fetching values D2 = o_fet(Reps, Ks, D1), {_,Tf} = statistics(runtime), %% Updating table D3 = o_sto(Reps, Ks, D1), {_,Tu} = statistics(runtime), {Tn/Reps,Ti/Reps,Tf/Reps,Tu/Reps}. ?RLOOP(o_sto, o_sto1). ?STORE(o_sto1, orddict:store). ?RLOOP(o_fet, o_fet1). ?FETCH(o_fet1, orddict:fetch). rbdict(Reps, Ks) -> D0 = rbdict:new(), {_,_} = statistics(runtime), %% Null sweep null(Reps, Ks, D0), {_,Tn} = statistics(runtime), %% Initial store D1 = r_sto(Reps, Ks, D0), {_,Ti} = statistics(runtime), %% Fetching values D2 = r_fet(Reps, Ks, D1), {_,Tf} = statistics(runtime), %% Updating table D3 = r_sto(Reps, Ks, D1), {_,Tu} = statistics(runtime), {Tn/Reps,Ti/Reps,Tf/Reps,Tu/Reps}. ?RLOOP(r_sto, r_sto1). ?STORE(r_sto1, rbdict:store). ?RLOOP(r_fet, r_fet1). ?FETCH(r_fet1, rbdict:fetch). gb_trees(Reps, Ks) -> D0 = gb_trees:empty(), {_,_} = statistics(runtime), %% Null sweep null(Reps, Ks, D0), {_,Tn} = statistics(runtime), %% Initial store D1 = g_ins(Reps, Ks, D0), {_,Ti} = statistics(runtime), D2 = g_ent(Reps, Ks, D0), {_,Te1} = statistics(runtime), %% Fetching values D3 = g_get(Reps, Ks, D1), {_,Tf} = statistics(runtime), %% Updating table D4 = g_upd(Reps, Ks, D1), {_,Tu} = statistics(runtime), D5 = g_ent(Reps, Ks, D1), {_,Te2} = statistics(runtime), {Tn/Reps,Ti/Reps,Te1/Reps,Tf/Reps,Tu/Reps,Te2/Reps}. ?RLOOP(g_ins, g_ins1). ?STORE(g_ins1, gb_trees:insert). ?RLOOP(g_ent, g_ent1). ?STORE(g_ent1, gb_trees:enter). ?RLOOP(g_upd, g_upd1). ?STORE(g_upd1, gb_trees:update). ?RLOOP(g_get, g_get1). ?FETCH(g_get1, gb_trees:get). rt(C, Reps, N) -> {Rds,Rrs,Rgs} = rt1(C, Reps, N), Fd = fun ({Null,Sto,Fet,Upd}, {Nulla,Stoa,Feta,Upda}) -> {Null+Nulla,Sto+Stoa,Fet+Feta,Upd+Upda} end, Fr = fun ({Null,Sto,Fet,Upd}, {Nulla,Stoa,Feta,Upda}) -> {Null+Nulla,Sto+Stoa,Fet+Feta,Upd+Upda} end, Fg = fun ({Null,Ins,Ent1,Fet,Upd,Ent2}, {Nulla,Insa,Ent1a,Feta,Upda,Ent2a}) -> {Null+Nulla,Ins+Insa,Ent1+Ent1a,Fet+Feta,Upd+Upda,Ent2+Ent2a} end, Rd = lists:foldl(Fd, {0,0,0,0}, Rds), Rr = lists:foldl(Fr, {0,0,0,0}, Rrs), Rg = lists:foldl(Fg, {0,0,0,0,0,0}, Rgs), {Rds,avd(C, Rd, N),Rrs,avr(C, Rr, N),Rgs,avg(C, Rg, N)}. rt1(C, Reps, N) when C > 0 -> L = scan_vals(0, N), {Rd,Rr,Rg} = rt1(Reps, L), {Rds,Rrs,Rgs} = rt1(C-1, Reps, N), {[Rd|Rds],[Rr|Rrs],[Rg|Rgs]}; rt1(0, _, _) -> {[],[],[]}. rt1(Reps, L) -> Rd = dict(Reps, L), Rr = rbdict(Reps, L), Rg = gb_trees(Reps, L), {Rd,Rr,Rg}. avd(C, {Null,S,F,U}, N) -> {(S-Null)/C,(F-Null)/C,(U-Null)/C}. avr(C, {Null,S,F,U}, N) -> {(S-Null)/C,(F-Null)/C,(U-Null)/C}. avg(C, {Null,I,E1,F,U,E2}, N) -> {(I-Null)/C,(E1-Null)/C,(F-Null)/C,(U-Null)/C,(E2-Null)/C}.