summaryrefslogtreecommitdiff
path: root/test/permdbtest.erl
blob: e48158f46a25692ec5d9e1cc124d37bc130b00d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -pa ebin -pa ../lager/ebin -pa ../lager/deps/goldrush/ebin

-mode(compile).

gentestdata(Size) ->
    [{crypto:hash(sha256, <<E:32, 0:32>>), crypto:hash(sha256, <<E:32, 1:32>>)} || E <- lists:seq(0, Size-1)].

genemptytestdata(Size) ->
    [{crypto:hash(sha256, <<E:32, 0:32>>), noentry} || E <- lists:seq(0, Size-1)].

timeprint(Time) ->
    io_lib:format("~.2fs", [Time/1000000]).

testinit(Filename) ->
    permdb:start_link(testdb, Filename, [{write_flag, write}]).

teststop() ->
    permdb:stop(testdb).

constructdata(VSeed, Size) ->
    A = binary:copy(VSeed, Size div 32),
    B = binary:part(VSeed, 0, Size rem 32),
    <<A/binary, B/binary>>.

getvalue_loop([], _Port, _Datasize, _DB) ->
    none;
getvalue_loop([{K, VSeed}|Rest], Port, Datasize, DB) ->
    V = case VSeed of
            noentry ->
                noentry;
            _ ->
                constructdata(VSeed, Datasize)
        end,
    case permdb:getvalue(DB, K) of
        V ->
            getvalue_loop(Rest, Port, Datasize, DB);
        VOther ->
            io:format("expected: ~p got: ~p~nkey: ~p~n", [V, VOther, K]),
            exit(mismatch)
    end.

addvalue_loop([], _Port, _Datasize, _DB) ->
    none;
addvalue_loop([{K, VSeed}|Rest], Port, Datasize, DB) ->
    V = constructdata(VSeed, Datasize),
    case permdb:addvalue(DB, K, V) of
        ok ->
            addvalue_loop(Rest, Port, Datasize, DB);
        Other ->
            io:format("expected: 0 or 1 got: ~p~n", [Other]),
            exit(mismatch)
    end.

testget(_Filename, TestData, Datasize) ->
    testget(_Filename, TestData, Datasize, testdb).

testget(_Filename, TestData, Datasize, DB) ->
    getvalue_loop(TestData, none, Datasize, DB),
    ok.

testadd(_Filename, TestData, Datasize) ->
    testadd(_Filename, TestData, Datasize, testdb).

testadd(_Filename, TestData, Datasize, DB) ->
    addvalue_loop(TestData, none, Datasize, DB),
    case permdb:commit(DB) of
        <<0>> ->
            ok;
        Other ->
            io:format("commit expected: 0 got: ~p~n", [Other]),
            exit(mismatch)
    end.

stop() ->
    teststop(),
    receive
    after
        100 ->
            ok
    end.

main([]) ->
    {ok, Cwd} = file:get_cwd(),
    code:add_path(Cwd ++ "/ebin"),
    Size = 10,
    Datasize = 99,
    Filename = "testpermdb",
    file:delete(Filename),
    file:delete(Filename ++ ".idx"),
    {Time1, TestData} = timer:tc(fun () -> gentestdata(Size) end),
    EmptyTestData = genemptytestdata(Size),
    io:format("Init with ~p entries: ~s~n", [Size, timeprint(Time1)]),
    testinit(Filename),
    Testadd = fun () ->
                      {Time2, ok} = timer:tc(fun () -> testadd(Filename, TestData, Datasize) end),
                      io:format("Add ~p entries: ~s ~.1f entries/s (~.2f microseconds)~n", [Size, timeprint(Time2), Size*1000000/Time2, Time2/Size])
              end,
    Testadd(),
    Testget = fun () ->
                      {Time2, ok} = timer:tc(fun () -> testget(Filename, TestData, Datasize) end),
                      io:format("Get ~p entries: ~s ~.1f entries/s (~.2f microseconds)~n", [Size, timeprint(Time2), Size*1000000/Time2, Time2/Size])
              end,
    Testget(),
    stop(),

    testinit(Filename),
    Testget(),
    stop(),

    file:delete(Filename ++ ".idx"),
    testinit(Filename),
    Testget(),
    stop(),

    testinit(Filename),
    Testget(),
    stop(),

    {ok, File} = file:open(Filename ++ ".idx", [read, write, binary]),
    {ok, _Position} = file:position(File, {eof, -120}),
    ok = file:write(File, <<0>>),
    file:close(File),

    testinit(Filename),
    Testget(),
    stop(),

    io:format("------------------------------------------------------------~n", []),
    file:delete(Filename),
    file:delete(Filename ++ ".idx"),
    testinit(Filename),
    Testemptyget = fun () ->
                      {Time2, ok} = timer:tc(fun () -> testget(Filename, EmptyTestData, Datasize) end),
                      io:format("Get ~p entries: ~s ~.1f entries/s (~.2f microseconds)~n", [Size, timeprint(Time2), Size*1000000/Time2, Time2/Size])
              end,
    Testemptyget(),
    testadd(Filename, gentestdata(1), 99),
    testadd(Filename, gentestdata(1+2), 99),
    testadd(Filename, gentestdata(1+2+3), 99),
    testadd(Filename, gentestdata(1+2+3+4), 99),
    testget(Filename, gentestdata(1+2+3+4), 99),
    stop(),

    testinit(Filename),

    permdb:start_link(testdb_ro, Filename, [{write_flag, read}]),

    testget(Filename, gentestdata(1+2+3+4), 99),
    testadd(Filename, gentestdata(1+2+3+4+5), 99),
    testget(Filename, gentestdata(1+2+3+4+5), 99, testdb_ro),
    permdb:stop(testdb_ro),
    stop(),

    ok.