From c543d5bff7fb23c3f44cc4817c0654117de78919 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Wed, 12 Mar 2014 20:11:10 +0100
Subject: erts: Change external format for maps
to be: 116,Arity, K1,V1,K2,V2,...,Kn,Vn
instead of: 116,Arity, K1,K2,...,Kn, V1,V2,....,Vn
We think this will be better for future internal map structures
like HAMT. Would be bad if we need to iterate twice over HAMT
in term_to_binary, one for keys and one for values.
---
lib/debugger/test/map_SUITE.erl | 9 +++++----
lib/erl_interface/doc/src/ei.xml | 18 ++++++++----------
.../ei_decode_encode_test.c | 5 +++--
.../java_src/com/ericsson/otp/erlang/OtpErlangMap.java | 4 ----
lib/jinterface/test/jinterface_SUITE_data/Maps.java | 8 ++++----
5 files changed, 20 insertions(+), 24 deletions(-)
(limited to 'lib')
diff --git a/lib/debugger/test/map_SUITE.erl b/lib/debugger/test/map_SUITE.erl
index e9f4ea1fad..741ad2dc41 100644
--- a/lib/debugger/test/map_SUITE.erl
+++ b/lib/debugger/test/map_SUITE.erl
@@ -790,16 +790,16 @@ t_map_encode_decode(Config) when is_list(Config) ->
%% literally #{ b=>2, a=>1 } in the internal order
#{ a:=1, b:=2 } =
- erlang:binary_to_term(<<131,116,0,0,0,2,100,0,1,98,100,0,1,97,97,2,97,1>>),
+ erlang:binary_to_term(<<131,116,0,0,0,2,100,0,1,98,97,2,100,0,1,97,97,1>>),
%% literally #{ "hi" => "value", a=>33, b=>55 } in the internal order
#{ a:=33, b:=55, "hi" := "value"} = erlang:binary_to_term(<<131,116,0,0,0,3,
107,0,2,104,105, % "hi" :: list()
- 100,0,1,97, % a :: atom()
- 100,0,1,98, % b :: atom()
107,0,5,118,97,108,117,101, % "value" :: list()
+ 100,0,1,97, % a :: atom()
97,33, % 33 :: integer()
+ 100,0,1,98, % b :: atom()
97,55 % 55 :: integer()
>>),
@@ -829,7 +829,8 @@ map_encode_decode_and_match([{K,V}|Pairs], EncodedPairs, M0) ->
B0 = erlang:term_to_binary(M1),
Ls = lists:sort(fun(A,B) -> erts_internal:cmp_term(A,B) < 0 end, [{K, erlang:term_to_binary(K), erlang:term_to_binary(V)}|EncodedPairs]),
%% sort Ks and Vs according to term spec, then match it
- ok = match_encoded_map(B0, length(Ls), [Kbin||{_,Kbin,_}<-Ls] ++ [Vbin||{_,_,Vbin}<-Ls]),
+ KVbins = lists:foldr(fun({_,Kbin,Vbin}, Acc) -> [Kbin,Vbin | Acc] end, [], Ls),
+ ok = match_encoded_map(B0, length(Ls), KVbins),
%% decode and match it
M1 = erlang:binary_to_term(B0),
map_encode_decode_and_match(Pairs,Ls,M1);
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index 1756ee8a7d..90495eebd6 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -422,19 +422,18 @@ ei_x_encode_empty_list(&x);
Encode a map
This function encodes a map header, with a specified arity. The next
- arity terms encoded will be the keys of the map, and the next
- arity terms after that will be the corresponding values in
- same order.
+ arity*2 terms encoded will be the keys and values of the map
+ encoded in the following order: K1, V1, K2, V2, ..., Kn, Vn.
+
E.g. to encode the map #{a => "Apple", b => "Banana"}:
ei_x_encode_map_header(&x, 2);
ei_x_encode_atom(&x, "a");
-ei_x_encode_atom(&x, "b");
ei_x_encode_string(&x, "Apple");
+ei_x_encode_atom(&x, "b");
ei_x_encode_string(&x, "Banana");
- A correctly encoded map can not have duplicate keys, but no check
- for duplicate keys is done by this function.
+ A correctly encoded map can not have duplicate keys.
@@ -664,10 +663,9 @@ ei_x_encode_string(&x, "Banana");
This function decodes a map header from the binary
format. The number of key-value pairs is returned in
- arity. Keys and values follows, first all keys and then all values,
- which makes a total of arity*2 terms.
- Keys and values are paired according to their order, the first key
- with the first value and so on. If arity is zero, it's an empty map.
+ *arity. Keys and values follow in the following order:
+ K1, V1, K2, V2, ..., Kn, Vn. This makes a total of
+ arity*2 terms. If arity is zero, it's an empty map.
A correctly encoded map does not have duplicate keys.
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
index 790d498a1d..fcf546105b 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
@@ -527,8 +527,9 @@ TESTCASE(test_ei_decode_encode)
{ /* #{atom => atom, atom => pid, port => ref }*/
struct Type* map[] = { &map_type,
- &my_atom_type, &my_atom_type, &port_type,
- &my_atom_type, &pid_type, &ref_type
+ &my_atom_type, &my_atom_type,
+ &my_atom_type, &pid_type,
+ &port_type, &ref_type
};
decode_encode(map, 7);
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
index 7c1cf84e98..03c18e55a2 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
@@ -125,8 +125,6 @@ public class OtpErlangMap extends OtpErlangObject implements Serializable,
for (int i = 0; i < arity; i++) {
keys[i] = buf.read_any();
- }
- for (int i = 0; i < arity; i++) {
values[i] = buf.read_any();
}
} else {
@@ -227,8 +225,6 @@ public class OtpErlangMap extends OtpErlangObject implements Serializable,
for (int i = 0; i < arity; i++) {
buf.write_any(keys[i]);
- }
- for (int i = 0; i < arity; i++) {
buf.write_any(values[i]);
}
}
diff --git a/lib/jinterface/test/jinterface_SUITE_data/Maps.java b/lib/jinterface/test/jinterface_SUITE_data/Maps.java
index 136a665f23..653defc621 100644
--- a/lib/jinterface/test/jinterface_SUITE_data/Maps.java
+++ b/lib/jinterface/test/jinterface_SUITE_data/Maps.java
@@ -42,16 +42,16 @@ class Maps {
runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 1, 100, 0, 1, 97, 100,
0, 1, 98 }, "#{a => b}", 2);
// make sure keys are sorted here, jinterface doesn't reorder them
- runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 2, 97, 2, 100, 0, 1, 97,
- 106, 97, 1 }, "#{2 => [],a => 1}", 3);
+ runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 2, 97, 2, 106,
+ 100, 0, 1, 97, 97, 1 }, "#{2 => [],a => 1}", 3);
runTest(new byte[] { (byte) 131, 116, 0, 0, 0, 1, 104, 1, 97, 3, 108,
0, 0, 0, 1, 100, 0, 1, 114, 106 }, "#{{3} => [r]}", 4);
try {
// #{2 => [],a => 1}
final OtpErlangMap map = new OtpErlangMap(new OtpInputStream(
- new byte[] { (byte) 131, 116, 0, 0, 0, 2, 97, 2, 100, 0, 1,
- 97, 106, 97, 1 }));
+ new byte[] { (byte) 131, 116, 0, 0, 0, 2, 97, 2, 106,
+ 100, 0, 1, 97, 97, 1 }));
if (map.arity() != 2) {
fail(5);
--
cgit v1.2.3