From 44edeae19bec364b9689f84b06da140e47401eb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 16 Jun 2014 14:47:18 +0200
Subject: erts: Add BIF erlang:get_keys/0
Returns a list of all keys in the process dictionary.
---
erts/emulator/beam/bif.tab | 11 ++++++--
erts/emulator/beam/erl_process_dict.c | 52 +++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index e68b8e6274..55ac778475 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -578,7 +578,7 @@ bif io:printable_range/0
bif os:unsetenv/1
#
-# New in R17A
+# New in 17.0
#
bif re:inspect/2
@@ -601,9 +601,16 @@ bif maps:values/1
bif erts_internal:cmp_term/2
#
-# New in 17.1.
+# New in 17.1
#
+
bif erlang:fun_info_mfa/1
+
+# New in 18.0
+#
+
+bif erlang:get_keys/0
+
#
# Obsolete
#
diff --git a/erts/emulator/beam/erl_process_dict.c b/erts/emulator/beam/erl_process_dict.c
index 23e5bf737f..3ce707efda 100644
--- a/erts/emulator/beam/erl_process_dict.c
+++ b/erts/emulator/beam/erl_process_dict.c
@@ -82,6 +82,7 @@
static void pd_hash_erase(Process *p, Eterm id, Eterm *ret);
static void pd_hash_erase_all(Process *p);
static Eterm pd_hash_get_keys(Process *p, Eterm value);
+static Eterm pd_hash_get_all_keys(Process *p, ProcDict *pd);
static Eterm pd_hash_get_all(Process *p, ProcDict *pd);
static Eterm pd_hash_put(Process *p, Eterm id, Eterm value);
@@ -275,6 +276,16 @@ BIF_RETTYPE get_1(BIF_ALIST_1)
BIF_RET(ret);
}
+BIF_RETTYPE get_keys_0(BIF_ALIST_0)
+{
+ Eterm ret;
+
+ PD_CHECK(BIF_P->dictionary);
+ ret = pd_hash_get_all_keys(BIF_P,BIF_P->dictionary);
+ PD_CHECK(BIF_P->dictionary);
+ BIF_RET(ret);
+}
+
BIF_RETTYPE get_keys_1(BIF_ALIST_1)
{
Eterm ret;
@@ -412,6 +423,47 @@ Eterm erts_pd_hash_get(Process *p, Eterm id)
return am_undefined;
}
+#define PD_GET_TKEY(Dst,Src) \
+do { \
+ ASSERT(is_tuple((Src))); \
+ ASSERT(arityval(*((Eterm*)tuple_val((Src)))) == 2); \
+ (Dst) = ((Eterm*)tuple_val((Src)))[1]; \
+} while(0)
+
+static Eterm pd_hash_get_all_keys(Process *p, ProcDict *pd) {
+ Eterm* hp;
+ Eterm res = NIL;
+ Eterm tmp, tmp2;
+ unsigned int i;
+ unsigned int num;
+
+ if (pd == NULL) {
+ return res;
+ }
+
+ num = HASH_RANGE(pd);
+ hp = HAlloc(p, pd->numElements * 2);
+
+ for (i = 0; i < num; ++i) {
+ tmp = ARRAY_GET(pd, i);
+ if (is_boxed(tmp)) {
+ PD_GET_TKEY(tmp,tmp);
+ res = CONS(hp, tmp, res);
+ hp += 2;
+ } else if (is_list(tmp)) {
+ while (tmp != NIL) {
+ tmp2 = TCAR(tmp);
+ PD_GET_TKEY(tmp2,tmp2);
+ res = CONS(hp, tmp2, res);
+ hp += 2;
+ tmp = TCDR(tmp);
+ }
+ }
+ }
+ return res;
+}
+#undef PD_GET_TKEY
+
static Eterm pd_hash_get_keys(Process *p, Eterm value)
{
Eterm *hp;
--
cgit v1.2.3
From 98a82e0df1783932ca9a09fa15dcf9bdab22b362 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 16 Jun 2014 15:44:31 +0200
Subject: kernel: Test BIF erlang:get_keys/0
---
lib/kernel/test/pdict_SUITE.erl | 33 +++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl
index 98cff0222e..a70e9b4704 100644
--- a/lib/kernel/test/pdict_SUITE.erl
+++ b/lib/kernel/test/pdict_SUITE.erl
@@ -31,7 +31,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
- simple/1, complicated/1, heavy/1, info/1]).
+ simple/1, complicated/1, heavy/1, simple_all_keys/1, info/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
-export([other_process/2]).
@@ -46,7 +46,7 @@ end_per_testcase(_Case, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [simple, complicated, heavy, info].
+ [simple, complicated, heavy, simple_all_keys, info].
groups() ->
[].
@@ -70,6 +70,7 @@ simple(suite) ->
[];
simple(Config) when is_list(Config) ->
XX = get(),
+ ok = match_keys(XX),
erase(),
L = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,
q,r,s,t,u,v,x,y,z,'A','B','C','D'],
@@ -105,6 +106,7 @@ simple(Config) when is_list(Config) ->
complicated(Config) when is_list(Config) ->
Previous = get(),
+ ok = match_keys(Previous),
Previous = erase(),
N = case ?t:is_debug() of
false -> 500000;
@@ -113,8 +115,10 @@ complicated(Config) when is_list(Config) ->
comp_1(N),
comp_2(N),
N = comp_3(lists:sort(get()), 1),
+ ok = match_keys(get()),
comp_4(get()),
[] = get(),
+ [] = erlang:get_keys(),
[put(Key, Value) || {Key,Value} <- Previous],
ok.
@@ -160,6 +164,26 @@ heavy(Config) when is_list(Config) ->
[put(Key, Value) || {Key,Value} <- XX],
ok.
+simple_all_keys(Config) when is_list(Config) ->
+ erase(),
+ ok = simple_all_keys_add_loop(1000),
+ [] = erlang:get_keys(),
+ [] = erlang:get(),
+ ok.
+
+simple_all_keys_add_loop(0) ->
+ simple_all_keys_del_loop(erlang:get_keys());
+simple_all_keys_add_loop(N) ->
+ put(gen_key(N),value),
+ ok = match_keys(get()),
+ simple_all_keys_add_loop(N-1).
+
+simple_all_keys_del_loop([]) -> ok;
+simple_all_keys_del_loop([K|Ks]) ->
+ value = erase(K),
+ ok = match_keys(get()),
+ simple_all_keys_del_loop(Ks).
+
info(doc) ->
["Tests process_info(Pid, dictionary)"];
info(suite) ->
@@ -339,3 +363,8 @@ m(A,B,Module,Line) ->
[A,B,Module,Line]),
exit({no_match,{A,B},Module,Line})
end.
+
+match_keys(All) ->
+ Ks = lists:sort([K||{K,_}<-All]),
+ Ks = lists:sort(erlang:get_keys()),
+ ok.
--
cgit v1.2.3
From 7cd4ac96cb8e8bef78c6eebfadb2e9590f88055d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 16 Jun 2014 15:53:11 +0200
Subject: erts: Add spec for erlang:get_keys/0
---
erts/preloaded/src/erlang.erl | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 7903901b81..b96a601792 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -93,7 +93,7 @@
float_to_list/1, float_to_list/2]).
-export([fun_info/2, fun_info_mfa/1, fun_to_list/1, function_exported/3]).
-export([garbage_collect/0, garbage_collect/1, garbage_collect/2]).
--export([garbage_collect_message_area/0, get/0, get/1, get_keys/1]).
+-export([garbage_collect_message_area/0, get/0, get/1, get_keys/0, get_keys/1]).
-export([get_module_info/1, get_stacktrace/0, group_leader/0]).
-export([group_leader/2, halt/0, halt/1, halt/2, hash/2, hibernate/3]).
-export([insert_element/3]).
@@ -931,6 +931,12 @@ get() ->
get(_Key) ->
erlang:nif_error(undefined).
+%% get_keys/0
+-spec get_keys() -> [Key] when
+ Key :: term().
+get_keys() ->
+ erlang:nif_error(undefined).
+
%% get_keys/1
-spec get_keys(Val) -> [Key] when
Val :: term(),
--
cgit v1.2.3
From 021c3366c2857f0f8ac040a3a37c606dc9c8d96c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 16 Jun 2014 15:54:58 +0200
Subject: stdlib: Auto-import erlang:get_keys/0
---
lib/kernel/test/pdict_SUITE.erl | 6 +++---
lib/stdlib/src/erl_internal.erl | 1 +
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl
index a70e9b4704..4b60beb9dc 100644
--- a/lib/kernel/test/pdict_SUITE.erl
+++ b/lib/kernel/test/pdict_SUITE.erl
@@ -118,7 +118,7 @@ complicated(Config) when is_list(Config) ->
ok = match_keys(get()),
comp_4(get()),
[] = get(),
- [] = erlang:get_keys(),
+ [] = get_keys(),
[put(Key, Value) || {Key,Value} <- Previous],
ok.
@@ -167,8 +167,8 @@ heavy(Config) when is_list(Config) ->
simple_all_keys(Config) when is_list(Config) ->
erase(),
ok = simple_all_keys_add_loop(1000),
- [] = erlang:get_keys(),
- [] = erlang:get(),
+ [] = get_keys(),
+ [] = get(),
ok.
simple_all_keys_add_loop(0) ->
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index e523b6b476..2bf8b86c23 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.erl
@@ -295,6 +295,7 @@ bif(garbage_collect, 1) -> true;
bif(garbage_collect, 2) -> true;
bif(get, 0) -> true;
bif(get, 1) -> true;
+bif(get_keys, 0) -> true;
bif(get_keys, 1) -> true;
bif(group_leader, 0) -> true;
bif(group_leader, 2) -> true;
--
cgit v1.2.3
From 4ec6f6875469f32bc499876605df2542a4c13532 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 16 Jun 2014 16:37:26 +0200
Subject: erts: Document erlang:get_keys/0
---
erts/doc/src/erlang.xml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 3d8ef9a97d..97fe6d2915 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -1376,6 +1376,19 @@ true
alive; otherwise the atom nocookie.
+
+
+ Return a list of all keys from the process dictionary
+
+ Returns a list of keys all keys present in the process dictionary.
+
+> put(dog, {animal,1}),
+put(cow, {animal,2}),
+put(lamb, {animal,3}),
+get_keys().
+[dog,cow,lamb]
+
+
Return a list of keys from the process dictionary
--
cgit v1.2.3
From 6ec6493dcca2724493700e7d269d2984efe30b38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Fri, 22 Aug 2014 19:06:16 +0200
Subject: Update preloaded erlang.beam
---
erts/preloaded/ebin/erlang.beam | Bin 97908 -> 98008 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index 3bf5f42a43..32ff6a3874 100644
Binary files a/erts/preloaded/ebin/erlang.beam and b/erts/preloaded/ebin/erlang.beam differ
--
cgit v1.2.3