Skip to content

Instantly share code, notes, and snippets.

@RoadRunnr
Created April 14, 2025 13:28
Show Gist options
  • Save RoadRunnr/136cd05ab6f7090b1b7a126f40f4e181 to your computer and use it in GitHub Desktop.
Save RoadRunnr/136cd05ab6f7090b1b7a126f40f4e181 to your computer and use it in GitHub Desktop.
%% create dummy.dat with:
%% dd if=/dev/random of=dummy.dat bs=1024 count=1024
-module(test).
-compile([export_all, nowarn_export_all]).
-compile(bin_opt_info).
-include_lib("kernel/include/logger.hrl").
xor_block(<<>>, _, Acc) ->
iolist_to_binary(lists:reverse(Acc));
xor_block(<<Block:8/bytes, Next/binary>>, Xor, Acc) ->
xor_block(Next, Xor, [crypto:exor(Block, Xor)|Acc]);
xor_block(Rest, Xor, Acc) ->
<<XorL:(byte_size(Rest))/bytes, _/binary>> = Xor,
xor_block(<<>>, Xor, [crypto:exor(Rest, XorL)|Acc]).
tc(Last, Msg) ->
Now = erlang:monotonic_time(),
Duration = erlang:convert_time_unit(Now - Last, native, microsecond),
if Duration > 20_000 ->
io:format("ridiculus time consumtion in ~s: ~w µs\n", [Msg, Duration]);
true -> ok
end,
Now.
make_tab(0, L) ->
L;
make_tab(Cnt, L) ->
make_tab(Cnt - 1, [crypto:hash(sha256, <<Cnt:256>>)|L]).
test(Cnt, Size) ->
%% lets consume some memory
L = make_tab(Size, []),
HashTab = #{K => K || K <- L},
PrevTab = #{K => [K] || K <- L},
io:format("HashTab: ~w, PrevTab: ~w~n", [map_size(HashTab), map_size(PrevTab)]),
test_(Cnt, PrevTab, HashTab).
test_(0, _, _) ->
ok;
test_(Cnt, PrevTab, HashTab) ->
Offset = 2,
Size = 415743,
read_file("dummy.dat", Offset, Size, <<1,2,3,4,5,6,7,8>>),
test_(Cnt - 1, PrevTab, HashTab).
-define(BLOCK_SIZE, (32*1024)).
read_file_loop(_Fd, 0, _Xor, Acc) ->
lists:reverse(Acc);
read_file_loop(Fd, Size, Xor, Acc) ->
T1 = erlang:monotonic_time(),
ReadS = if Size > ?BLOCK_SIZE -> ?BLOCK_SIZE;
true -> Size
end,
{ok, Data} = file:read(Fd, ReadS),
tc(T1, "Read"),
T2 = erlang:monotonic_time(),
Bin = xor_block(Data, Xor, []),
tc(T2, "xor_block/3"),
read_file_loop(Fd, Size - ReadS, Xor, [Data|Acc]).
read_file(FileName, Offset, BlkSize, Xor) ->
Offs = (Offset div 8) * 8,
Size = (BlkSize + (Offset rem 8)),
{ok, Fd} = file:open(FileName, [raw, read, binary]),
file:position(Fd, {bof, Offs}),
[First|More] = read_file_loop(Fd, Size, Xor, []),
file:close(Fd),
T2 = erlang:monotonic_time(),
<<_:(Offset rem 8)/bytes, FirstSeg/binary>> = First,
tc(T2, "Match"),
T3 = erlang:monotonic_time(),
Block = list_to_binary([FirstSeg|More]),
tc(T3, "list_to_binary/1"),
Block.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment