|
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- |
|
%% ex: ft=erlang ts=4 sw=4 et |
|
-module(case2). |
|
-export([main/1]). |
|
|
|
-define(TEST_FILE_PATH, "test.dat"). |
|
|
|
main([Arg1,Arg2,Arg3|_T]) -> |
|
FileSize = list_to_integer(Arg1), |
|
ReadBytes = list_to_integer(Arg2), |
|
NumRepeat = list_to_integer(Arg3), |
|
%% generate a test file |
|
Data = crypto:rand_bytes(FileSize), |
|
file:write_file(?TEST_FILE_PATH, Data), |
|
{ok, IoDev} = file:open(?TEST_FILE_PATH, [read, raw, binary]), |
|
try |
|
Ret = random_read(IoDev, FileSize, ReadBytes, NumRepeat, <<>>), |
|
io:format(user, "[info]ret size:~p~n", [size(Ret)]) |
|
catch |
|
Class:Reason -> |
|
io:format(user, "[error]class:~p reason:~p stacktrace:~p~n",[Class, Reason, erlang:get_stacktrace()]) |
|
after |
|
file:close(IoDev) |
|
end, |
|
ok; |
|
main(_) -> |
|
io:format(user, "Usage: case2 (file size) (read bytes) (# of operations)~n", []). |
|
|
|
random_read(_, _, _, 0, Acc) -> Acc; |
|
random_read(IoDev, FileSize, MaxReadBytes, N, Acc) -> |
|
Offset = random:uniform(FileSize - 1), |
|
ReadBytes = random:uniform(round(MaxReadBytes/2)) + round(MaxReadBytes/2), |
|
NewAcc = case file:pread(IoDev, Offset, ReadBytes) of |
|
{ok, Data} -> |
|
<<Acc/binary, Data/binary>>; |
|
eof -> |
|
Acc; |
|
{error, Reason} -> |
|
io:format(user, "[error] file read error:~p~n", [Reason]), |
|
exit(Reason) |
|
end, |
|
NewAcc2 = case N rem 8 of |
|
0 -> |
|
io:format(user, "[info] memory usages:~p~n", [erlang:memory()]), |
|
io:format(user, "[info] acc size:~p~n", [size(NewAcc)]), |
|
<<Clipped:128/binary, _/binary>> = NewAcc, |
|
Clipped; |
|
_ -> NewAcc |
|
end, |
|
random_read(IoDev, FileSize, MaxReadBytes, N - 1, NewAcc2). |