From 513a322941d208d9dcdc4c39db2966ae4c707fe7 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Tue, 19 Sep 2017 14:37:59 +0200 Subject: erts: Implement map iterator using a stack This version does not work great as the subtrees created are not proper hash maps. Also it is not all that performant as the extra allocations to keep the stack there is expensive. --- lib/stdlib/src/maps.erl | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/stdlib/src/maps.erl b/lib/stdlib/src/maps.erl index 7ed32a3988..0da12cf8e2 100644 --- a/lib/stdlib/src/maps.erl +++ b/lib/stdlib/src/maps.erl @@ -32,7 +32,7 @@ new/0, put/3, remove/2, take/2, to_list/1, update/3, values/1]). --opaque iterator() :: [{term(), term()}]. +-opaque iterator() :: [{term(), term()}] | [[pos_integer() | map()]]. -export_type([iterator/0]). @@ -279,7 +279,10 @@ size(Val) -> Iterator :: iterator(). iterator(Map) when is_map(Map) -> - maps:to_list(Map); + case maps:size(Map) < 42 of + true -> maps:to_list(Map); + false -> [[1 | Map]] + end; iterator(M) -> erlang:error(error_type(M),[M]). @@ -289,6 +292,12 @@ iterator(M) -> V :: term(), NextIterator :: iterator(). next([]) -> none; +next([[Index | Map] | St]) -> + case erts_internal:map_get_index(Index, Map) of + SubMap when is_map(SubMap) -> next([[1 | SubMap], [Index+1|Map] | St]); + [K|V] -> {K,V,[[Index+1 | Map] | St]}; + none -> next(St) + end; next([{K, V} | I]) -> {K, V, I}. -- cgit v1.2.3