diff options
author | Lukas Larsson <[email protected]> | 2017-10-12 16:00:50 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2017-11-20 09:57:43 +0100 |
commit | a1c796e7f6b86b4b506492ae6354382c565278d1 (patch) | |
tree | b83738b3d313a2c43bdcaf25b555a8c4602492c2 /erts/emulator/test/map_SUITE.erl | |
parent | 0149a73d15df1f80cb46752ec3829f48c38dd230 (diff) | |
download | otp-a1c796e7f6b86b4b506492ae6354382c565278d1.tar.gz otp-a1c796e7f6b86b4b506492ae6354382c565278d1.tar.bz2 otp-a1c796e7f6b86b4b506492ae6354382c565278d1.zip |
erts: Implement batching maps:iterator
This iterator implementation fetches multiple elements to
iterate over in one call to erts_internal:maps_next instead
of one at a time. This means that the memory usage will go
up for the iterator as we are buffering elements, but the
usage is still bounded.
In this implementation the max memory usage is 1000 words.
Using this approach makes the iterator as fast as using
maps:to_list, so maps:iterator/2 has been removed.
Diffstat (limited to 'erts/emulator/test/map_SUITE.erl')
-rw-r--r-- | erts/emulator/test/map_SUITE.erl | 57 |
1 files changed, 19 insertions, 38 deletions
diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl index 3cf071b590..1e70d31b16 100644 --- a/erts/emulator/test/map_SUITE.erl +++ b/erts/emulator/test/map_SUITE.erl @@ -2366,41 +2366,6 @@ t_bif_map_from_list(Config) when is_list(Config) -> {'EXIT', {badarg,_}} = (catch maps:from_list(id(42))), ok. -t_bif_erts_internal_maps_to_list(Config) when is_list(Config) -> - %% small maps - [] = erts_internal:maps_to_list(#{},-1), - [] = erts_internal:maps_to_list(#{},-2), - [] = erts_internal:maps_to_list(#{},10), - [{a,1},{b,2}] = lists:sort(erts_internal:maps_to_list(#{a=>1,b=>2}, 2)), - [{a,1},{b,2}] = lists:sort(erts_internal:maps_to_list(#{a=>1,b=>2}, -1)), - [{_,_}] = erts_internal:maps_to_list(#{a=>1,b=>2}, 1), - [{a,1},{b,2},{c,3}] = lists:sort(erts_internal:maps_to_list(#{c=>3,a=>1,b=>2},-2)), - [{a,1},{b,2},{c,3}] = lists:sort(erts_internal:maps_to_list(#{c=>3,a=>1,b=>2},3)), - [{a,1},{b,2},{c,3}] = lists:sort(erts_internal:maps_to_list(#{c=>3,a=>1,b=>2},5)), - [{_,_},{_,_}] = erts_internal:maps_to_list(#{c=>3,a=>1,b=>2},2), - [{_,_}] = erts_internal:maps_to_list(#{c=>3,a=>1,b=>2},1), - [] = erts_internal:maps_to_list(#{c=>3,a=>1,b=>2},0), - - %% big maps - M = maps:from_list([{I,ok}||I <- lists:seq(1,500)]), - [] = erts_internal:maps_to_list(M,0), - [{_,_}] = erts_internal:maps_to_list(M,1), - [{_,_},{_,_}] = erts_internal:maps_to_list(M,2), - Ls1 = erts_internal:maps_to_list(M,10), - 10 = length(Ls1), - Ls2 = erts_internal:maps_to_list(M,20), - 20 = length(Ls2), - Ls3 = erts_internal:maps_to_list(M,120), - 120 = length(Ls3), - Ls4 = erts_internal:maps_to_list(M,-1), - 500 = length(Ls4), - - %% error cases - {'EXIT', {{badmap,[{a,b},b]},_}} = (catch erts_internal:maps_to_list(id([{a,b},b]),id(1))), - {'EXIT', {badarg,_}} = (catch erts_internal:maps_to_list(id(#{}),id(a))), - {'EXIT', {badarg,_}} = (catch erts_internal:maps_to_list(id(#{1=>2}),id(<<>>))), - ok. - t_bif_map_next(Config) when is_list(Config) -> erts_debug:set_internal_state(available_internal_state, true), @@ -2420,9 +2385,25 @@ t_bif_map_next(Config) when is_list(Config) -> {'EXIT', {badarg,_}} = (catch maps:next(id(a))), {'EXIT', {badarg,_}} = (catch maps:next(id([a|FM]))), {'EXIT', {badarg,_}} = (catch maps:next(id([1|#{}]))), - {'EXIT', {badarg,_}} = (catch maps:next(id([16#FFFFFFF|FM]))), - {'EXIT', {badarg,_}} = (catch maps:next(id([16#F0F0F0F|FM]))), - {'EXIT', {badarg,_}} = (catch maps:next(id([16#1234567890ABCDEF|FM]))), + {'EXIT', {badarg,_}} = (catch maps:next(id([-1|#{}]))), + {'EXIT', {badarg,_}} = (catch maps:next(id([-1|FM]))), + {'EXIT', {badarg,_}} = (catch maps:next(id([16#FFFFFFFFFFFFFFFF|FM]))), + {'EXIT', {badarg,_}} = (catch maps:next(id([-16#FFFFFFFFFFFFFFFF|FM]))), + + %% This us a whitebox test that the error code works correctly. + %% It uses a path for a tree of depth 4 and tries to do next on + %% each of those paths. + (fun F(0) -> ok; + F(N) -> + try maps:next([N|FM]) of + none -> + F(N-1); + {_K,_V,_I} -> + F(N-1) + catch error:badarg -> + F(N-1) + end + end)(16#FFFF), ok after |