1%% %CopyrightBegin% 2%% 3%% Copyright Ericsson AB 2013. All Rights Reserved. 4%% 5%% Licensed under the Apache License, Version 2.0 (the "License"); 6%% you may not use this file except in compliance with the License. 7%% You may obtain a copy of the License at 8%% 9%% http://www.apache.org/licenses/LICENSE-2.0 10%% 11%% Unless required by applicable law or agreed to in writing, software 12%% distributed under the License is distributed on an "AS IS" BASIS, 13%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14%% See the License for the specific language governing permissions and 15%% limitations under the License. 16%% 17%% %CopyrightEnd% 18%% 19-module(map_galore). 20-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 21 init_per_group/2,end_per_group/2 22 ]). 23 24-export([ 25 t_build_and_match_literals/1, t_build_and_match_literals_large/1, 26 t_update_literals/1, t_update_literals_large/1, 27 t_match_and_update_literals/1, t_match_and_update_literals_large/1, 28 t_update_map_expressions/1, 29 t_update_assoc/1, t_update_assoc_large/1, 30 t_update_exact/1, t_update_exact_large/1, 31 t_guard_bifs/1, 32 t_guard_sequence/1, t_guard_sequence_large/1, 33 t_guard_update/1, t_guard_update_large/1, 34 t_guard_receive/1, t_guard_receive_large/1, 35 t_guard_fun/1, 36 t_update_deep/1, 37 t_list_comprehension/1, 38 t_map_sort_literals/1, 39 t_map_equal/1, 40 t_map_compare/1, 41 t_map_size/1, 42 t_is_map/1, 43 44 %% Specific Map BIFs 45 t_bif_map_get/1, 46 t_bif_map_find/1, 47 t_bif_map_is_key/1, 48 t_bif_map_keys/1, 49 t_bif_map_merge/1, 50 t_bif_map_new/1, 51 t_bif_map_put/1, 52 t_bif_map_remove/1, 53 t_bif_map_update/1, 54 t_bif_map_values/1, 55 t_bif_map_to_list/1, 56 t_bif_map_from_list/1, 57 58 %% erlang 59 t_erlang_hash/1, 60 t_map_encode_decode/1, 61 62 %% non specific BIF related 63 t_bif_build_and_check/1, 64 t_bif_merge_and_check/1, 65 66 %% maps module not bifs 67 t_maps_fold/1, 68 t_maps_map/1, 69 t_maps_size/1, 70 t_maps_without/1, 71 72 %% misc 73 t_erts_internal_order/1, 74 t_erts_internal_hash/1, 75 t_pdict/1, 76 t_ets/1, 77 t_dets/1, 78 t_tracing/1, 79 80 %% instruction-level tests 81 t_has_map_fields/1, 82 y_regs/1 83 ]). 84 85-include_lib("stdlib/include/ms_transform.hrl"). 86 87-define(CHECK(Cond,Term), 88 case (catch (Cond)) of 89 true -> true; 90 _ -> io:format("###### CHECK FAILED ######~nINPUT: ~p~n", [Term]), 91 exit(Term) 92 end). 93 94suite() -> []. 95 96all() -> [ 97 t_build_and_match_literals, t_build_and_match_literals_large, 98 t_update_literals, t_update_literals_large, 99 t_match_and_update_literals, t_match_and_update_literals_large, 100 t_update_map_expressions, 101 t_update_assoc, t_update_assoc_large, 102 t_update_exact, t_update_exact_large, 103 t_guard_bifs, 104 t_guard_sequence, t_guard_sequence_large, 105 t_guard_update, t_guard_update_large, 106 t_guard_receive, t_guard_receive_large, 107 t_guard_fun, t_list_comprehension, 108 t_update_deep, 109 t_map_equal, t_map_compare, 110 t_map_sort_literals, 111 112 %% Specific Map BIFs 113 t_bif_map_get,t_bif_map_find,t_bif_map_is_key, 114 t_bif_map_keys, t_bif_map_merge, t_bif_map_new, 115 t_bif_map_put, 116 t_bif_map_remove, t_bif_map_update, 117 t_bif_map_values, 118 t_bif_map_to_list, t_bif_map_from_list, 119 120 %% erlang 121 t_erlang_hash, t_map_encode_decode, 122 t_map_size, t_is_map, 123 124 %% non specific BIF related 125 t_bif_build_and_check, 126 t_bif_merge_and_check, 127 128 %% maps module 129 t_maps_fold, t_maps_map, 130 t_maps_size, t_maps_without, 131 132 133 %% Other functions 134 t_erts_internal_order, 135 t_erts_internal_hash, 136 t_pdict, 137 t_ets, 138 t_tracing, 139 140 %% instruction-level tests 141 t_has_map_fields, 142 y_regs 143 ]. 144 145groups() -> []. 146 147init_per_suite(Config) -> Config. 148end_per_suite(_Config) -> ok. 149 150init_per_group(_GroupName, Config) -> Config. 151end_per_group(_GroupName, Config) -> Config. 152 153%% tests 154 155t_build_and_match_literals(Config) when is_list(Config) -> 156 #{} = #{}, 157 #{1:=a} = #{1=>a}, 158 #{1:=a,2:=b} = #{1=>a,2=>b}, 159 #{1:=a,2:=b,3:="c"} = #{1=>a,2=>b,3=>"c"}, 160 #{1:=a,2:=b,3:="c","4":="d"} = #{1=>a,2=>b,3=>"c","4"=>"d"}, 161 #{1:=a,2:=b,3:="c","4":="d",<<"5">>:=<<"e">>} = 162 #{1=>a,2=>b,3=>"c","4"=>"d",<<"5">>=><<"e">>}, 163 #{1:=a,2:=b,3:="c","4":="d",<<"5">>:=<<"e">>,{"6",7}:="f"} = 164 #{1=>a,2=>b,3=>"c","4"=>"d",<<"5">>=><<"e">>,{"6",7}=>"f"}, 165 #{1:=a,2:=b,3:="c","4":="d",<<"5">>:=<<"e">>,{"6",7}:="f",8:=g} = 166 #{1=>a,2=>b,3=>"c","4"=>"d",<<"5">>=><<"e">>,{"6",7}=>"f",8=>g}, 167 168 #{[]:=a,42.0:=b,x:={x,y},[a,b]:=list} = 169 #{[]=>a,42.0=>b,x=>{x,y},[a,b]=>list}, 170 171 #{<<"hi all">> := 1} = #{<<"hi",32,"all">> => 1}, 172 173 #{a:=X,a:=X=3,b:=4} = #{a=>3,b=>4}, % weird but ok =) 174 175 #{ a:=#{ b:=#{c := third, b:=second}}, b:=first} = 176 #{ b=>first, a=>#{ b=>#{c => third, b=> second}}}, 177 178 M = #{ map_1=>#{ map_2=>#{value_3 => third}, value_2=> second}, value_1=>first}, 179 M = #{ map_1:=#{ map_2:=#{value_3 := third}, value_2:= second}, value_1:=first} = 180 #{ map_1=>#{ map_2=>#{value_3 => third}, value_2=> second}, value_1=>first}, 181 182 %% error case 183 %V = 32, 184 %{'EXIT',{{badmatch,_},_}} = (catch (#{<<"hi all">> => 1} = #{<<"hi",V,"all">> => 1})), 185 {'EXIT',{{badmatch,_},_}} = (catch (#{x:=3,x:=2} = #{x=>3})), 186 {'EXIT',{{badmatch,_},_}} = (catch (#{x:=2} = #{x=>3})), 187 {'EXIT',{{badmatch,_},_}} = (catch (#{x:=3} = {a,b,c})), 188 {'EXIT',{{badmatch,_},_}} = (catch (#{x:=3} = #{y=>3})), 189 {'EXIT',{{badmatch,_},_}} = (catch (#{x:=3} = #{x=>"three"})), 190 ok. 191 192t_build_and_match_literals_large(Config) when is_list(Config) -> 193 % normal non-repeating 194 M0 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 195 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 196 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 197 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 198 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 199 200 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 201 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 202 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 203 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 204 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" }, 205 206 #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M0, 207 #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M0, 208 #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M0, 209 #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M0, 210 #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M0, 211 212 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M0, 213 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M0, 214 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M0, 215 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M0, 216 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M0, 217 218 60 = map_size(M0), 219 60 = maps:size(M0), 220 221 % with repeating 222 M1 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 223 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 224 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 225 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 226 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 227 228 10=>na0,20=>nb0,30=>"nc0","40"=>"nd0",<<"50">>=>"ne0",{["00"]}=>"n10", 229 11=>na1,21=>nb1,31=>"nc1","41"=>"nd1",<<"51">>=>"ne1",{["01"]}=>"n11", 230 12=>na2,22=>nb2,32=>"nc2","42"=>"nd2",<<"52">>=>"ne2",{["02"]}=>"n12", 231 232 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 233 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 234 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 235 236 13=>na3,23=>nb3,33=>"nc3","43"=>"nd3",<<"53">>=>"ne3",{["03"]}=>"n13", 237 14=>na4,24=>nb4,34=>"nc4","44"=>"nd4",<<"54">>=>"ne4",{["04"]}=>"n14", 238 239 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 240 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" }, 241 242 #{10:=na0,20:=nb0,30:="nc0","40":="nd0",<<"50">>:="ne0",{["00"]}:="n10"} = M1, 243 #{11:=na1,21:=nb1,31:="nc1","41":="nd1",<<"51">>:="ne1",{["01"]}:="n11"} = M1, 244 #{12:=na2,22:=nb2,32:="nc2","42":="nd2",<<"52">>:="ne2",{["02"]}:="n12"} = M1, 245 #{13:=na3,23:=nb3,33:="nc3","43":="nd3",<<"53">>:="ne3",{["03"]}:="n13"} = M1, 246 #{14:=na4,24:=nb4,34:="nc4","44":="nd4",<<"54">>:="ne4",{["04"]}:="n14"} = M1, 247 248 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M1, 249 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M1, 250 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M1, 251 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M1, 252 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M1, 253 254 60 = map_size(M1), 255 60 = maps:size(M1), 256 257 % with floats 258 259 M2 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 260 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 261 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 262 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 263 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 264 265 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 266 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 267 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 268 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 269 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19", 270 271 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 272 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 273 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 274 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 275 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 276 277 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 278 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 279 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 280 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 281 19.0=>fa9,29.0=>fb9,39.0=>"fc9"}, 282 283 #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2, 284 #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2, 285 #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2, 286 #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2, 287 #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2, 288 289 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2, 290 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2, 291 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2, 292 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2, 293 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2, 294 295 #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2, 296 #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2, 297 #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2, 298 #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2, 299 #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2, 300 301 #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2, 302 #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2, 303 #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2, 304 #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2, 305 #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2, 306 307 90 = map_size(M2), 308 90 = maps:size(M2), 309 310 % with bignums 311 M3 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 312 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 313 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 314 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 315 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 316 317 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 318 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 319 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 320 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 321 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19", 322 323 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 324 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 325 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 326 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 327 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 328 329 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 330 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 331 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 332 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 333 19.0=>fa9,29.0=>fb9,39.0=>"fc9", 334 335 36893488147419103232=>big1, 73786976294838206464=>big2, 336 147573952589676412928=>big3, 18446744073709551616=>big4, 337 4294967296=>big5, 8589934592=>big6, 338 4294967295=>big7, 67108863=>big8 339 }, 340 341 #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3, 342 #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3, 343 #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3, 344 #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3, 345 #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3, 346 347 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3, 348 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3, 349 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3, 350 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3, 351 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3, 352 353 #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3, 354 #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3, 355 #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3, 356 #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3, 357 #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3, 358 359 #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3, 360 #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3, 361 #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3, 362 #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3, 363 #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3, 364 365 #{36893488147419103232:=big1,67108863:=big8,"45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3, 366 #{147573952589676412928:=big3,8589934592:=big6,"46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3, 367 #{4294967296:=big5,18446744073709551616:=big4,"47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3, 368 #{4294967295:=big7,73786976294838206464:=big2,"48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3, 369 370 98 = map_size(M3), 371 98 = maps:size(M3), 372 373 %% with maps 374 375 M4 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 376 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 377 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 378 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 379 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 380 381 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 382 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 383 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 384 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 385 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19", 386 387 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 388 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 389 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 390 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 391 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 392 393 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 394 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 395 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 396 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 397 19.0=>fa9,29.0=>fb9,39.0=>"fc9", 398 399 #{ one => small, map => key } => "small map key 1", 400 #{ second => small, map => key } => "small map key 2", 401 #{ third => small, map => key } => "small map key 3", 402 403 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 404 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 405 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 406 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 407 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 408 409 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 410 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 411 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 412 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 413 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1", 414 415 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 416 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 417 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 418 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 419 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 420 421 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 422 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 423 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 424 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 425 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }, 426 427 #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M4, 428 #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M4, 429 #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M4, 430 #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M4, 431 #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M4, 432 433 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M4, 434 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M4, 435 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M4, 436 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M4, 437 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M4, 438 439 #{ #{ one => small, map => key } := "small map key 1", 440 #{ second => small, map => key } := "small map key 2", 441 #{ third => small, map => key } := "small map key 3" } = M4, 442 443 #{ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 444 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 445 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 446 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 447 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 448 449 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 450 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 451 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 452 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 453 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1", 454 455 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 456 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 457 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 458 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 459 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 460 461 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 462 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 463 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 464 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 465 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 2" } = M4, 466 467 468 #{ 15:=V1,25:=b5,35:=V2,"45":="d5",<<"55">>:=V3,{["05"]}:="15", 469 #{ one => small, map => key } := "small map key 1", 470 #{ second => small, map => key } := V4, 471 #{ third => small, map => key } := "small map key 3", 472 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 473 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 474 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 475 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 476 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 477 478 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 479 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 480 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 481 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 482 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := V5 } = M4, 483 484 a5 = V1, 485 "c5" = V2, 486 "e5" = V3, 487 "small map key 2" = V4, 488 "large map key 1" = V5, 489 490 95 = map_size(M4), 491 95 = maps:size(M4), 492 493 % call for value 494 495 M5 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 496 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 497 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 498 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 499 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 500 501 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 502 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 503 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 504 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 505 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19", 506 507 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 508 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 509 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 510 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 511 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 512 513 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 514 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 515 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 516 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 517 19.0=>fa9,29.0=>fb9,39.0=>"fc9", 518 519 #{ one => small, map => key } => "small map key 1", 520 #{ second => small, map => key } => "small map key 2", 521 #{ third => small, map => key } => "small map key 3", 522 523 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 524 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 525 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 526 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 527 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 528 529 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 530 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 531 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 532 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 533 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1", 534 535 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 536 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 537 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 538 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 539 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 540 541 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 542 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 543 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 544 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 545 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }, 546 547 #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M5, 548 #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M5, 549 #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M5, 550 #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M5, 551 #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M5, 552 553 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M5, 554 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M5, 555 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M5, 556 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M5, 557 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M5, 558 559 #{ #{ one => small, map => key } := "small map key 1", 560 #{ second => small, map => key } := "small map key 2", 561 #{ third => small, map => key } := "small map key 3" } = M5, 562 563 #{ #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 564 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 565 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 566 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 567 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 568 569 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 570 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 571 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 572 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 573 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1", 574 575 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 576 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 577 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 578 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 579 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 580 581 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 582 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 583 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 584 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 585 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 2" } = M5, 586 587 95 = map_size(M5), 588 95 = maps:size(M5), 589 590 %% remember 591 592 #{10:=a0,20:=b0,30:="c0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M0, 593 #{11:=a1,21:=b1,31:="c1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M0, 594 #{12:=a2,22:=b2,32:="c2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M0, 595 #{13:=a3,23:=b3,33:="c3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M0, 596 #{14:=a4,24:=b4,34:="c4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M0, 597 598 #{10:=na0,20:=nb0,30:="nc0","40":="nd0",<<"50">>:="ne0",{["00"]}:="n10"} = M1, 599 #{11:=na1,21:=nb1,31:="nc1","41":="nd1",<<"51">>:="ne1",{["01"]}:="n11"} = M1, 600 #{12:=na2,22:=nb2,32:="nc2","42":="nd2",<<"52">>:="ne2",{["02"]}:="n12"} = M1, 601 #{13:=na3,23:=nb3,33:="nc3","43":="nd3",<<"53">>:="ne3",{["03"]}:="n13"} = M1, 602 #{14:=na4,24:=nb4,34:="nc4","44":="nd4",<<"54">>:="ne4",{["04"]}:="n14"} = M1, 603 604 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M1, 605 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M1, 606 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M1, 607 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M1, 608 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M1, 609 610 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M2, 611 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M2, 612 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M2, 613 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M2, 614 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M2, 615 616 #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M2, 617 #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M2, 618 #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M2, 619 #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M2, 620 #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M2, 621 622 #{15:=a5,25:=b5,35:="c5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3, 623 #{16:=a6,26:=b6,36:="c6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3, 624 #{17:=a7,27:=b7,37:="c7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3, 625 #{18:=a8,28:=b8,38:="c8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3, 626 #{19:=a9,29:=b9,39:="c9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3, 627 628 #{10.0:=fa0,20.0:=fb0,30.0:="fc0","40":="d0",<<"50">>:="e0",{["00"]}:="10"} = M3, 629 #{11.0:=fa1,21.0:=fb1,31.0:="fc1","41":="d1",<<"51">>:="e1",{["01"]}:="11"} = M3, 630 #{12.0:=fa2,22.0:=fb2,32.0:="fc2","42":="d2",<<"52">>:="e2",{["02"]}:="12"} = M3, 631 #{13.0:=fa3,23.0:=fb3,33.0:="fc3","43":="d3",<<"53">>:="e3",{["03"]}:="13"} = M3, 632 #{14.0:=fa4,24.0:=fb4,34.0:="fc4","44":="d4",<<"54">>:="e4",{["04"]}:="14"} = M3, 633 634 #{15.0:=fa5,25.0:=fb5,35.0:="fc5","45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3, 635 #{16.0:=fa6,26.0:=fb6,36.0:="fc6","46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3, 636 #{17.0:=fa7,27.0:=fb7,37.0:="fc7","47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3, 637 #{18.0:=fa8,28.0:=fb8,38.0:="fc8","48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3, 638 #{19.0:=fa9,29.0:=fb9,39.0:="fc9","49":="d9",<<"59">>:="e9",{["09"]}:="19"} = M3, 639 640 #{36893488147419103232:=big1,67108863:=big8,"45":="d5",<<"55">>:="e5",{["05"]}:="15"} = M3, 641 #{147573952589676412928:=big3,8589934592:=big6,"46":="d6",<<"56">>:="e6",{["06"]}:="16"} = M3, 642 #{4294967296:=big5,18446744073709551616:=big4,"47":="d7",<<"57">>:="e7",{["07"]}:="17"} = M3, 643 #{4294967295:=big7,73786976294838206464:=big2,"48":="d8",<<"58">>:="e8",{["08"]}:="18"} = M3, 644 645 ok. 646 647 648t_map_size(Config) when is_list(Config) -> 649 0 = map_size(#{}), 650 1 = map_size(#{a=>1}), 651 1 = map_size(#{a=>"wat"}), 652 2 = map_size(#{a=>1, b=>2}), 653 3 = map_size(#{a=>1, b=>2, b=>"3","33"=><<"n">>}), 654 655 true = map_is_size(#{a=>1}, 1), 656 true = map_is_size(#{a=>1, a=>2}, 1), 657 M = #{ "a" => 1, "b" => 2}, 658 true = map_is_size(M, 2), 659 false = map_is_size(M, 3), 660 true = map_is_size(M#{ "a" => 2}, 2), 661 false = map_is_size(M#{ "c" => 2}, 2), 662 663 Ks = [build_key(fun(K) -> <<1,K:32,1>> end,I)||I<-lists:seq(1,100)], 664 ok = build_and_check_size(Ks,0,#{}), 665 666 %% try deep collisions 667 %% statistically we get another subtree at 50k -> 100k elements 668 %% Try to be nice and don't use too much memory in the testcase, 669 670 N = 500000, 671 Is = lists:seq(1,N), 672 N = map_size(maps:from_list([{I,I}||I<-Is])), 673 N = map_size(maps:from_list([{<<I:32>>,I}||I<-Is])), 674 N = map_size(maps:from_list([{integer_to_list(I),I}||I<-Is])), 675 N = map_size(maps:from_list([{float(I),I}||I<-Is])), 676 677 %% Error cases. 678 do_badmap(fun(T) -> 679 {'EXIT',{{badmap,T},_}} = 680 (catch map_size(T)) 681 end), 682 ok. 683 684build_and_check_size([K|Ks],N,M0) -> 685 N = map_size(M0), 686 M1 = M0#{ K => K }, 687 build_and_check_size(Ks,N + 1,M1); 688build_and_check_size([],N,M) -> 689 N = map_size(M), 690 ok. 691 692map_is_size(M,N) when map_size(M) =:= N -> true; 693map_is_size(_,_) -> false. 694 695t_is_map(Config) when is_list(Config) -> 696 true = is_map(#{}), 697 true = is_map(#{a=>1}), 698 false = is_map({a,b}), 699 false = is_map(x), 700 if is_map(#{}) -> ok end, 701 if is_map(#{b=>1}) -> ok end, 702 if not is_map([1,2,3]) -> ok end, 703 if not is_map(x) -> ok end, 704 ok. 705 706% test map updates without matching 707t_update_literals_large(Config) when is_list(Config) -> 708 Map = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 709 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 710 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 711 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 712 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 713 714 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 715 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 716 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 717 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 718 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19", 719 720 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 721 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 722 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 723 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 724 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 725 726 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 727 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 728 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 729 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 730 19.0=>fa9,29.0=>fb9,39.0=>"fc9", 731 732 #{ one => small, map => key } => "small map key 1", 733 #{ second => small, map => key } => "small map key 2", 734 #{ third => small, map => key } => "small map key 3", 735 736 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 737 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 738 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 739 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 740 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 741 742 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 743 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 744 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 745 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 746 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1", 747 748 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 749 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 750 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 751 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 752 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 753 754 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 755 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 756 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 757 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 758 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }, 759 760 #{x:="d",q:="4"} = loop_update_literals_x_q(Map, [ 761 {"a","1"},{"b","2"},{"c","3"},{"d","4"} 762 ]), 763 ok. 764 765t_update_literals(Config) when is_list(Config) -> 766 Map = #{x=>1,y=>2,z=>3,q=>4}, 767 #{x:="d",q:="4"} = loop_update_literals_x_q(Map, [ 768 {"a","1"},{"b","2"},{"c","3"},{"d","4"} 769 ]), 770 ok. 771 772 773loop_update_literals_x_q(Map, []) -> Map; 774loop_update_literals_x_q(Map, [{X,Q}|Vs]) -> 775 loop_update_literals_x_q(Map#{q=>Q,x=>X},Vs). 776 777% test map updates with matching 778t_match_and_update_literals(Config) when is_list(Config) -> 779 Map = #{ x=>0,y=>"untouched",z=>"also untouched",q=>1, 780 #{ "one" => small, map => key } => "small map key 1" }, 781 #{x:=16,q:=21,y:="untouched",z:="also untouched"} = loop_match_and_update_literals_x_q(Map, [ 782 {1,2},{3,4},{5,6},{7,8} 783 ]), 784 M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 785 4 => number, 18446744073709551629 => wat}, 786 M1 = #{}, 787 M2 = M1#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 788 4 => number, 18446744073709551629 => wat}, 789 M0 = M2, 790 791 #{ 4 := another_number, int := 3 } = M2#{ 4 => another_number }, 792 ok. 793 794t_match_and_update_literals_large(Config) when is_list(Config) -> 795 Map = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 796 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 797 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 798 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 799 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 800 801 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 802 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 803 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 804 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 805 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19", 806 807 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 808 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 809 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 810 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 811 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 812 813 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 814 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 815 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 816 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 817 19.0=>fa9,29.0=>fb9,39.0=>"fc9", 818 819 x=>0,y=>"untouched",z=>"also untouched",q=>1, 820 821 #{ "one" => small, map => key } => "small map key 1", 822 #{ second => small, map => key } => "small map key 2", 823 #{ third => small, map => key } => "small map key 3", 824 825 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 826 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 827 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 828 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 829 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 830 831 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 832 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 833 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 834 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 835 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1", 836 837 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 838 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 839 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 840 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 841 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 842 843 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 844 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 845 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 846 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 847 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }, 848 849 #{x:=16,q:=21,y:="untouched",z:="also untouched"} = loop_match_and_update_literals_x_q(Map, [ 850 {1,2},{3,4},{5,6},{7,8} 851 ]), 852 M0 = Map#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 853 4 => number, 18446744073709551629 => wat}, 854 M1 = Map#{}, 855 M2 = M1#{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 856 4 => number, 18446744073709551629 => wat}, 857 M0 = M2, 858 859 #{ 4 := another_number, int := 3 } = M2#{ 4 => another_number }, 860 ok. 861 862 863loop_match_and_update_literals_x_q(Map, []) -> Map; 864loop_match_and_update_literals_x_q(#{ q:=Q0, x:=X0, 865 #{ "one" => small, map => key } := "small map key 1" } = Map, [{X,Q}|Vs]) -> 866 loop_match_and_update_literals_x_q(Map#{q=>Q0+Q,x=>X0+X},Vs). 867 868 869t_update_map_expressions(Config) when is_list(Config) -> 870 M = maps:new(), 871 #{ a := 1 } = M#{a => 1}, 872 873 #{ b := 2 } = (maps:new())#{ b => 2 }, 874 875 #{ a :=42, b:=42, c:=42 } = (maps:from_list([{a,1},{b,2},{c,3}]))#{ a := 42, b := 42, c := 42 }, 876 #{ "a" :=1, "b":=42, "c":=42 } = (maps:from_list([{"a",1},{"b",2}]))#{ "b" := 42, "c" => 42 }, 877 Ks = lists:seq($a,$z), 878 #{ "aa" := {$a,$a}, "ac":=41, "dc":=42 } = 879 (maps:from_list([{[K1,K2],{K1,K2}}|| K1 <- Ks, K2 <- Ks]))#{ "ac" := 41, "dc" => 42 }, 880 881 %% Error cases. 882 do_badmap(fun(T) -> 883 {'EXIT',{{badmap,T},_}} = 884 (catch (T)#{a:=42,b=>2}) 885 end), 886 ok. 887 888t_update_assoc(Config) when is_list(Config) -> 889 M0 = #{1=>a,2=>b,3.0=>c,4=>d,5=>e}, 890 891 M1 = M0#{1=>42,2=>100,4=>[a,b,c]}, 892 #{1:=42,2:=100,3.0:=c,4:=[a,b,c],5:=e} = M1, 893 #{1:=42,2:=b,4:=d,5:=e,2.0:=100,3.0:=c,4.0:=[a,b,c]} = M0#{1.0=>float,1:=42,2.0=>wrong,2.0=>100,4.0=>[a,b,c]}, 894 895 M2 = M0#{3.0=>new}, 896 #{1:=a,2:=b,3.0:=new,4:=d,5:=e} = M2, 897 M2 = M0#{3.0:=wrong,3.0=>new}, 898 899 %% Errors cases. 900 do_badmap(fun(T) -> 901 {'EXIT',{{badmap,T},_}} = 902 (catch T#{nonexisting=>val}) 903 end), 904 ok. 905 906 907t_update_assoc_large(Config) when is_list(Config) -> 908 M0 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 909 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 910 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 911 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 912 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 913 914 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 915 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 916 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 917 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 918 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19", 919 920 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 921 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 922 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 923 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 924 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 925 926 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 927 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 928 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 929 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 930 19.0=>fa9,29.0=>fb9,39.0=>"fc9", 931 932 #{ one => small, map => key } => "small map key 1", 933 #{ second => small, map => key } => "small map key 2", 934 #{ third => small, map => key } => "small map key 3", 935 936 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 937 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 938 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 939 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 940 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 941 942 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 943 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 944 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 945 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 946 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1", 947 948 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 949 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 950 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 951 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 952 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 953 954 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 955 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 956 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 957 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 958 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }, 959 960 961 M1 = M0#{1=>42,2=>100,4=>[a,b,c]}, 962 #{1:=42,2:=100,10.0:=fa0,4:=[a,b,c],25:=b5} = M1, 963 #{ 10:=43, 24:=b4, 15:=a5, 35:="c5", 2.0:=100, 13.0:=fa3, 4.0:=[a,b,c]} = 964 M0#{1.0=>float,10:=43,2.0=>wrong,2.0=>100,4.0=>[a,b,c]}, 965 966 M2 = M0#{13.0=>new}, 967 #{10:=a0,20:=b0,13.0:=new,"40":="d0",<<"50">>:="e0"} = M2, 968 M2 = M0#{13.0:=wrong,13.0=>new}, 969 970 ok. 971 972t_update_exact(Config) when is_list(Config) -> 973 M0 = #{1=>a,2=>b,3.0=>c,4=>d,5=>e}, 974 975 M1 = M0#{1:=42,2:=100,4:=[a,b,c]}, 976 #{1:=42,2:=100,3.0:=c,4:=[a,b,c],5:=e} = M1, 977 M1 = M0#{1:=wrong,1=>42,2=>wrong,2:=100,4:=[a,b,c]}, 978 979 M2 = M0#{3.0:=new}, 980 #{1:=a,2:=b,3.0:=new,4:=d,5:=e} = M2, 981 M2 = M0#{3.0=>wrong,3.0:=new}, 982 true = M2 =/= M0#{3=>right,3.0:=new}, 983 #{ 3 := right, 3.0 := new } = M0#{3=>right,3.0:=new}, 984 985 M3 = #{ 1 => val}, 986 #{1 := update2,1.0 := new_val4} = M3#{ 987 1.0 => new_val1, 1 := update, 1=> update3, 988 1 := update2, 1.0 := new_val2, 1.0 => new_val3, 989 1.0 => new_val4 }, 990 991 %% Errors cases. 992 do_badmap(fun(T) -> 993 {'EXIT',{{badmap,T},_}} = 994 (catch T#{nonexisting=>val}) 995 end), 996 Empty = #{}, 997 {'EXIT',{{badkey,nonexisting},_}} = (catch Empty#{nonexisting:=val}), 998 {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}), 999 {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}), 1000 {'EXIT',{{badkey,42},_}} = (catch M0#{42.0:=v,42:=v2}), 1001 {'EXIT',{{badkey,42.0},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}), 1002 1003 ok. 1004 1005t_update_exact_large(Config) when is_list(Config) -> 1006 M0 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 1007 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 1008 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 1009 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 1010 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 1011 1012 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 1013 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 1014 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 1015 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 1016 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19", 1017 1018 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 1019 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 1020 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 1021 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 1022 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 1023 1024 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 1025 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 1026 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 1027 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 1028 19.0=>fa9,29.0=>fb9,39.0=>"fc9", 1029 1030 #{ one => small, map => key } => "small map key 1", 1031 #{ second => small, map => key } => "small map key 2", 1032 #{ third => small, map => key } => "small map key 3", 1033 1034 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 1035 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 1036 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 1037 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 1038 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 1039 1040 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 1041 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 1042 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 1043 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 1044 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1", 1045 1046 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 1047 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 1048 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 1049 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 1050 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 1051 1052 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 1053 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 1054 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 1055 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 1056 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }, 1057 1058 1059 M1 = M0#{10:=42,<<"55">>:=100,10.0:=[a,b,c]}, 1060 #{ 10:=42,<<"55">>:=100,{["05"]}:="15",10.0:=[a,b,c], 1061 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 1062 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 1063 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 1064 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 1065 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 1066 1067 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 1068 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 1069 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 1070 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 1071 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } := "large map key 1" } = M1, 1072 1073 M1 = M0#{10:=wrong,10=>42,<<"55">>=>wrong,<<"55">>:=100,10.0:=[a,b,c]}, 1074 1075 M2 = M0#{13.0:=new}, 1076 #{10:=a0,20:=b0,13.0:=new} = M2, 1077 M2 = M0#{13.0=>wrong,13.0:=new}, 1078 1079 %% Errors cases. 1080 {'EXIT',{{badkey,nonexisting},_}} = (catch M0#{nonexisting:=val}), 1081 {'EXIT',{{badkey,1.0},_}} = (catch M0#{1.0:=v,1.0=>v2}), 1082 {'EXIT',{{badkey,42},_}} = (catch M0#{42.0:=v,42:=v2}), 1083 {'EXIT',{{badkey,42.0},_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}), 1084 1085 ok. 1086 1087t_update_deep(Config) when is_list(Config) -> 1088 N = 250000, 1089 M0 = maps:from_list([{integer_to_list(I),a}||I<-lists:seq(1,N)]), 1090 #{ "1" := a, "10" := a, "100" := a, "1000" := a, "10000" := a } = M0, 1091 1092 M1 = M0#{ "1" := b, "10" := b, "100" := b, "1000" := b, "10000" := b }, 1093 #{ "1" := a, "10" := a, "100" := a, "1000" := a, "10000" := a } = M0, 1094 #{ "1" := b, "10" := b, "100" := b, "1000" := b, "10000" := b } = M1, 1095 1096 M2 = M0#{ "1" => c, "10" => c, "100" => c, "1000" => c, "10000" => c }, 1097 #{ "1" := a, "10" := a, "100" := a, "1000" := a, "10000" := a } = M0, 1098 #{ "1" := b, "10" := b, "100" := b, "1000" := b, "10000" := b } = M1, 1099 #{ "1" := c, "10" := c, "100" := c, "1000" := c, "10000" := c } = M2, 1100 1101 M3 = M2#{ "n1" => d, "n10" => d, "n100" => d, "n1000" => d, "n10000" => d }, 1102 #{ "1" := a, "10" := a, "100" := a, "1000" := a, "10000" := a } = M0, 1103 #{ "1" := b, "10" := b, "100" := b, "1000" := b, "10000" := b } = M1, 1104 #{ "1" := c, "10" := c, "100" := c, "1000" := c, "10000" := c } = M2, 1105 #{ "1" := c, "10" := c, "100" := c, "1000" := c, "10000" := c } = M3, 1106 #{ "n1" := d, "n10" := d, "n100" := d, "n1000" := d, "n10000" := d } = M3, 1107 ok. 1108 1109t_guard_bifs(Config) when is_list(Config) -> 1110 true = map_guard_head(#{a=>1}), 1111 false = map_guard_head([]), 1112 true = map_guard_body(#{a=>1}), 1113 false = map_guard_body({}), 1114 true = map_guard_pattern(#{a=>1, <<"hi">> => "hi" }), 1115 false = map_guard_pattern("list"), 1116 ok. 1117 1118map_guard_head(M) when is_map(M) -> true; 1119map_guard_head(_) -> false. 1120 1121map_guard_body(M) -> is_map(M). 1122 1123map_guard_pattern(#{}) -> true; 1124map_guard_pattern(_) -> false. 1125 1126t_guard_sequence(Config) when is_list(Config) -> 1127 {1, "a"} = map_guard_sequence_1(#{seq=>1,val=>"a"}), 1128 {2, "b"} = map_guard_sequence_1(#{seq=>2,val=>"b"}), 1129 {3, "c"} = map_guard_sequence_1(#{seq=>3,val=>"c"}), 1130 {4, "d"} = map_guard_sequence_1(#{seq=>4,val=>"d"}), 1131 {5, "e"} = map_guard_sequence_1(#{seq=>5,val=>"e"}), 1132 1133 {1,M1} = map_guard_sequence_2(M1 = #{a=>3}), 1134 {2,M2} = map_guard_sequence_2(M2 = #{a=>4, b=>4}), 1135 {3,gg,M3} = map_guard_sequence_2(M3 = #{a=>gg, b=>4}), 1136 {4,sc,sc,M4} = map_guard_sequence_2(M4 = #{a=>sc, b=>3, c=>sc2}), 1137 {5,kk,kk,M5} = map_guard_sequence_2(M5 = #{a=>kk, b=>other, c=>sc2}), 1138 1139 %% error case 1140 {'EXIT',{function_clause,_}} = (catch map_guard_sequence_1(#{seq=>6,val=>"e"})), 1141 {'EXIT',{function_clause,_}} = (catch map_guard_sequence_2(#{b=>5})), 1142 ok. 1143 1144t_guard_sequence_large(Config) when is_list(Config) -> 1145 M0 = #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00",03]}=>"10", 1146 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01",03]}=>"11", 1147 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02",03]}=>"12", 1148 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03",03]}=>"13", 1149 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04",03]}=>"14", 1150 1151 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05",03]}=>"15", 1152 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06",03]}=>"16", 1153 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07",03]}=>"17", 1154 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08",03]}=>"18", 1155 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09",03]}=>"19", 1156 1157 10.0=>fa0,20.0=>fb0,30.0=>"fc0", 1158 11.0=>fa1,21.0=>fb1,31.0=>"fc1", 1159 12.0=>fa2,22.0=>fb2,32.0=>"fc2", 1160 13.0=>fa3,23.0=>fb3,33.0=>"fc3", 1161 14.0=>fa4,24.0=>fb4,34.0=>"fc4", 1162 1163 15.0=>fa5,25.0=>fb5,35.0=>"fc5", 1164 16.0=>fa6,26.0=>fb6,36.0=>"fc6", 1165 17.0=>fa7,27.0=>fb7,37.0=>"fc7", 1166 18.0=>fa8,28.0=>fb8,38.0=>"fc8", 1167 19.0=>fa9,29.0=>fb9,39.0=>"fc9", 1168 1169 #{ one => small, map => key } => "small map key 1", 1170 #{ second => small, map => key } => "small map key 2", 1171 #{ third => small, map => key } => "small map key 3", 1172 1173 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 1174 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 1175 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 1176 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 1177 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 1178 1179 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 1180 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 1181 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 1182 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 1183 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1", 1184 1185 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 1186 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 1187 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 1188 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 1189 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 1190 1191 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 1192 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 1193 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 1194 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 1195 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }, 1196 1197 {1, "a"} = map_guard_sequence_1(M0#{seq=>1,val=>"a"}), 1198 {2, "b"} = map_guard_sequence_1(M0#{seq=>2,val=>"b"}), 1199 {3, "c"} = map_guard_sequence_1(M0#{seq=>3,val=>"c"}), 1200 {4, "d"} = map_guard_sequence_1(M0#{seq=>4,val=>"d"}), 1201 {5, "e"} = map_guard_sequence_1(M0#{seq=>5,val=>"e"}), 1202 1203 {1,M1} = map_guard_sequence_2(M1 = M0#{a=>3}), 1204 {2,M2} = map_guard_sequence_2(M2 = M0#{a=>4, b=>4}), 1205 {3,gg,M3} = map_guard_sequence_2(M3 = M0#{a=>gg, b=>4}), 1206 {4,sc,sc,M4} = map_guard_sequence_2(M4 = M0#{a=>sc, b=>3, c=>sc2}), 1207 {5,kk,kk,M5} = map_guard_sequence_2(M5 = M0#{a=>kk, b=>other, c=>sc2}), 1208 1209 {'EXIT',{function_clause,_}} = (catch map_guard_sequence_1(M0#{seq=>6,val=>"e"})), 1210 {'EXIT',{function_clause,_}} = (catch map_guard_sequence_2(M0#{b=>5})), 1211 ok. 1212 1213 1214map_guard_sequence_1(#{seq:=1=Seq, val:=Val}) -> {Seq,Val}; 1215map_guard_sequence_1(#{seq:=2=Seq, val:=Val}) -> {Seq,Val}; 1216map_guard_sequence_1(#{seq:=3=Seq, val:=Val}) -> {Seq,Val}; 1217map_guard_sequence_1(#{seq:=4=Seq, val:=Val}) -> {Seq,Val}; 1218map_guard_sequence_1(#{seq:=5=Seq, val:=Val}) -> {Seq,Val}. 1219 1220map_guard_sequence_2(#{ a:=3 }=M) -> {1, M}; 1221map_guard_sequence_2(#{ a:=4 }=M) -> {2, M}; 1222map_guard_sequence_2(#{ a:=X, a:=X, b:=4 }=M) -> {3,X,M}; 1223map_guard_sequence_2(#{ a:=X, a:=Y, b:=3 }=M) when X =:= Y -> {4,X,Y,M}; 1224map_guard_sequence_2(#{ a:=X, a:=Y }=M) when X =:= Y -> {5,X,Y,M}. 1225 1226 1227t_guard_update(Config) when is_list(Config) -> 1228 error = map_guard_update(#{},#{}), 1229 first = map_guard_update(#{}, #{x=>first}), 1230 second = map_guard_update(#{y=>old}, #{x=>second,y=>old}), 1231 ok. 1232 1233t_guard_update_large(Config) when is_list(Config) -> 1234 M0 = #{ 70=>a0,80=>b0,90=>"c0","40"=>"d0",<<"50">>=>"e0",{["00",03]}=>"10", 1235 71=>a1,81=>b1,91=>"c1","41"=>"d1",<<"51">>=>"e1",{["01",03]}=>"11", 1236 72=>a2,82=>b2,92=>"c2","42"=>"d2",<<"52">>=>"e2",{["02",03]}=>"12", 1237 73=>a3,83=>b3,93=>"c3","43"=>"d3",<<"53">>=>"e3",{["03",03]}=>"13", 1238 74=>a4,84=>b4,94=>"c4","44"=>"d4",<<"54">>=>"e4",{["04",03]}=>"14", 1239 1240 75=>a5,85=>b5,95=>"c5","45"=>"d5",<<"55">>=>"e5",{["05",03]}=>"15", 1241 76=>a6,86=>b6,96=>"c6","46"=>"d6",<<"56">>=>"e6",{["06",03]}=>"16", 1242 77=>a7,87=>b7,97=>"c7","47"=>"d7",<<"57">>=>"e7",{["07",03]}=>"17", 1243 78=>a8,88=>b8,98=>"c8","48"=>"d8",<<"58">>=>"e8",{["08",03]}=>"18", 1244 79=>a9,89=>b9,99=>"c9","49"=>"d9",<<"59">>=>"e9",{["09",03]}=>"19", 1245 1246 70.0=>fa0,80.0=>fb0,90.0=>"fc0", 1247 71.0=>fa1,81.0=>fb1,91.0=>"fc1", 1248 72.0=>fa2,82.0=>fb2,92.0=>"fc2", 1249 73.0=>fa3,83.0=>fb3,93.0=>"fc3", 1250 74.0=>fa4,84.0=>fb4,94.0=>"fc4", 1251 1252 75.0=>fa5,85.0=>fb5,95.0=>"fc5", 1253 76.0=>fa6,86.0=>fb6,96.0=>"fc6", 1254 77.0=>fa7,87.0=>fb7,97.0=>"fc7", 1255 78.0=>fa8,88.0=>fb8,98.0=>"fc8", 1256 79.0=>fa9,89.0=>fb9,99.0=>"fc9", 1257 1258 #{ one => small, map => key } => "small map key 1", 1259 #{ second => small, map => key } => "small map key 2", 1260 #{ third => small, map => key } => "small map key 3", 1261 1262 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 1263 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 1264 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 1265 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 1266 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 1267 1268 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 1269 16=>a6,26=>b6,36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 1270 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 1271 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 1272 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 1", 1273 1274 #{ 10=>a0,20=>b0,30=>"c0","40"=>"d0",<<"50">>=>"e0",{["00"]}=>"10", 1275 11=>a1,21=>b1,31=>"c1","41"=>"d1",<<"51">>=>"e1",{["01"]}=>"11", 1276 12=>a2,22=>b2,32=>"c2","42"=>"d2",<<"52">>=>"e2",{["02"]}=>"12", 1277 13=>a3,23=>b3,33=>"c3","43"=>"d3",<<"53">>=>"e3",{["03"]}=>"13", 1278 14=>a4,24=>b4,34=>"c4","44"=>"d4",<<"54">>=>"e4",{["04"]}=>"14", 1279 1280 15=>a5,25=>b5,35=>"c5","45"=>"d5",<<"55">>=>"e5",{["05"]}=>"15", 1281 k16=>a6,k26=>b6,k36=>"c6","46"=>"d6",<<"56">>=>"e6",{["06"]}=>"16", 1282 17=>a7,27=>b7,37=>"c7","47"=>"d7",<<"57">>=>"e7",{["07"]}=>"17", 1283 18=>a8,28=>b8,38=>"c8","48"=>"d8",<<"58">>=>"e8",{["08"]}=>"18", 1284 19=>a9,29=>b9,39=>"c9","49"=>"d9",<<"59">>=>"e9",{["09"]}=>"19" } => "large map key 2" }, 1285 1286 1287 error = map_guard_update(M0#{},M0#{}), 1288 first = map_guard_update(M0#{},M0#{x=>first}), 1289 second = map_guard_update(M0#{y=>old}, M0#{x=>second,y=>old}), 1290 ok. 1291 1292 1293map_guard_update(M1, M2) when M1#{x=>first} =:= M2 -> first; 1294map_guard_update(M1, M2) when M1#{x=>second} =:= M2 -> second; 1295map_guard_update(_, _) -> error. 1296 1297t_guard_receive(Config) when is_list(Config) -> 1298 M0 = #{ id => 0 }, 1299 Pid = spawn_link(fun() -> guard_receive_loop() end), 1300 Big = 36893488147419103229, 1301 B1 = <<"some text">>, 1302 B2 = <<"was appended">>, 1303 B3 = <<B1/binary, B2/binary>>, 1304 1305 #{id:=1, res:=Big} = M1 = call(Pid, M0#{op=>sub,in=>{1 bsl 65, 3}}), 1306 #{id:=2, res:=26} = M2 = call(Pid, M1#{op=>idiv,in=>{53,2}}), 1307 #{id:=3, res:=832} = M3 = call(Pid, M2#{op=>imul,in=>{26,32}}), 1308 #{id:=4, res:=4} = M4 = call(Pid, M3#{op=>add,in=>{1,3}}), 1309 #{id:=5, res:=Big} = M5 = call(Pid, M4#{op=>sub,in=>{1 bsl 65, 3}}), 1310 #{id:=6, res:=B3} = M6 = call(Pid, M5#{op=>"append",in=>{B1,B2}}), 1311 #{id:=7, res:=4} = _ = call(Pid, M6#{op=>add,in=>{1,3}}), 1312 1313 1314 %% update old maps and check id update 1315 #{id:=2, res:=B3} = call(Pid, M1#{op=>"append",in=>{B1,B2}}), 1316 #{id:=5, res:=99} = call(Pid, M4#{op=>add,in=>{33, 66}}), 1317 1318 %% cleanup 1319 done = call(Pid, done), 1320 ok. 1321 1322-define(t_guard_receive_large_procs, 1500). 1323 1324t_guard_receive_large(Config) when is_list(Config) -> 1325 M = lists:foldl(fun(_,#{procs := Ps } = M) -> 1326 M#{ procs := Ps#{ spawn_link(fun() -> grecv_loop() end) => 0 }} 1327 end, #{procs => #{}, done => 0}, lists:seq(1,?t_guard_receive_large_procs)), 1328 lists:foreach(fun(Pid) -> 1329 Pid ! {self(), hello} 1330 end, maps:keys(maps:get(procs,M))), 1331 ok = guard_receive_large_loop(M), 1332 ok. 1333 1334guard_receive_large_loop(#{done := ?t_guard_receive_large_procs}) -> 1335 ok; 1336guard_receive_large_loop(M) -> 1337 receive 1338 #{pid := Pid, msg := hello} -> 1339 case M of 1340 #{done := Count, procs := #{Pid := 150}} -> 1341 Pid ! {self(), done}, 1342 guard_receive_large_loop(M#{done := Count + 1}); 1343 #{procs := #{Pid := Count} = Ps} -> 1344 Pid ! {self(), hello}, 1345 guard_receive_large_loop(M#{procs := Ps#{Pid := Count + 1}}) 1346 end 1347 end. 1348 1349grecv_loop() -> 1350 receive 1351 {_, done} -> 1352 ok; 1353 {Pid, hello} -> 1354 Pid ! #{pid=>self(), msg=>hello}, 1355 grecv_loop() 1356 end. 1357 1358call(Pid, M) -> 1359 Pid ! {self(), M}, receive {Pid, Res} -> Res end. 1360 1361guard_receive_loop() -> 1362 receive 1363 {Pid, #{ id:=Id, op:="append", in:={X,Y}}=M} when is_binary(X), is_binary(Y) -> 1364 Pid ! {self(), M#{ id=>Id+1, res=><<X/binary,Y/binary>>}}, 1365 guard_receive_loop(); 1366 {Pid, #{ id:=Id, op:=add, in:={X,Y}}} -> 1367 Pid ! {self(), #{ id=>Id+1, res=>X+Y}}, 1368 guard_receive_loop(); 1369 {Pid, #{ id:=Id, op:=sub, in:={X,Y}}=M} -> 1370 Pid ! {self(), M#{ id=>Id+1, res=>X-Y}}, 1371 guard_receive_loop(); 1372 {Pid, #{ id:=Id, op:=idiv, in:={X,Y}}=M} -> 1373 Pid ! {self(), M#{ id=>Id+1, res=>X div Y}}, 1374 guard_receive_loop(); 1375 {Pid, #{ id:=Id, op:=imul, in:={X,Y}}=M} -> 1376 Pid ! {self(), M#{ id=>Id+1, res=>X * Y}}, 1377 guard_receive_loop(); 1378 {Pid, done} -> 1379 Pid ! {self(), done}; 1380 {Pid, Other} -> 1381 Pid ! {error, Other}, 1382 guard_receive_loop() 1383 end. 1384 1385 1386t_list_comprehension(Config) when is_list(Config) -> 1387 [#{k:=1},#{k:=2},#{k:=3}] = [#{k=>I} || I <- [1,2,3]], 1388 1389 Ks = lists:seq($a,$z), 1390 Ms = [#{[K1,K2]=>{K1,K2}} || K1 <- Ks, K2 <- Ks], 1391 [#{"aa" := {$a,$a}},#{"ab":={$a,$b}}|_] = Ms, 1392 [#{"zz" := {$z,$z}},#{"zy":={$z,$y}}|_] = lists:reverse(Ms), 1393 ok. 1394 1395t_guard_fun(Config) when is_list(Config) -> 1396 F1 = fun 1397 (#{s:=v,v:=V}) -> {v,V}; 1398 (#{s:=t,v:={V,V}}) -> {t,V}; 1399 (#{s:=l,v:=[V,V]}) -> {l,V} 1400 end, 1401 1402 F2 = fun 1403 (#{s:=T,v:={V,V}}) -> {T,V}; 1404 (#{s:=T,v:=[V,V]}) -> {T,V}; 1405 (#{s:=T,v:=V}) -> {T,V} 1406 end, 1407 V = <<"hi">>, 1408 1409 {v,V} = F1(#{s=>v,v=>V}), 1410 {t,V} = F1(#{s=>t,v=>{V,V}}), 1411 {l,V} = F1(#{s=>l,v=>[V,V]}), 1412 1413 {v,V} = F2(#{s=>v,v=>V}), 1414 {t,V} = F2(#{s=>t,v=>{V,V}}), 1415 {l,V} = F2(#{s=>l,v=>[V,V]}), 1416 1417 %% error case 1418 {'EXIT', {function_clause,[{?MODULE,_,[#{s:=none,v:=none}],_}|_]}} = (catch F1(#{s=>none,v=>none})), 1419 ok. 1420 1421 1422t_map_sort_literals(Config) when is_list(Config) -> 1423 % test relation 1424 1425 %% size order 1426 true = #{ a => 1, b => 2} < #{ a => 1, b => 1, c => 1}, 1427 true = #{ b => 1, a => 1} < #{ c => 1, a => 1, b => 1}, 1428 false = #{ c => 1, b => 1, a => 1} < #{ c => 1, a => 1}, 1429 1430 %% key order 1431 true = #{ a => 1 } < #{ b => 1}, 1432 false = #{ b => 1 } < #{ a => 1}, 1433 true = #{ a => 1, b => 1, c => 1 } < #{ b => 1, c => 1, d => 1}, 1434 true = #{ b => 1, c => 1, d => 1 } > #{ a => 1, b => 1, c => 1}, 1435 true = #{ c => 1, b => 1, a => 1 } < #{ b => 1, c => 1, d => 1}, 1436 true = #{ "a" => 1 } < #{ <<"a">> => 1}, 1437 false = #{ <<"a">> => 1 } < #{ "a" => 1}, 1438 true = #{ 1 => 1 } < #{ 1.0 => 1}, 1439 false = #{ 1.0 => 1 } < #{ 1 => 1}, 1440 1441 %% value order 1442 true = #{ a => 1 } < #{ a => 2}, 1443 false = #{ a => 2 } < #{ a => 1}, 1444 false = #{ a => 2, b => 1 } < #{ a => 1, b => 3}, 1445 true = #{ a => 1, b => 1 } < #{ a => 1, b => 3}, 1446 false = #{ a => 1 } < #{ a => 1.0}, 1447 false = #{ a => 1.0 } < #{ a => 1}, 1448 1449 true = #{ "a" => "hi", b => 134 } == #{ b => 134,"a" => "hi"}, 1450 1451 %% large maps 1452 1453 M = maps:from_list([{I,I}||I <- lists:seq(1,500)]), 1454 1455 %% size order 1456 true = M#{ a => 1, b => 2} < M#{ a => 1, b => 1, c => 1}, 1457 true = M#{ b => 1, a => 1} < M#{ c => 1, a => 1, b => 1}, 1458 false = M#{ c => 1, b => 1, a => 1} < M#{ c => 1, a => 1}, 1459 1460 %% key order 1461 true = M#{ a => 1 } < M#{ b => 1}, 1462 false = M#{ b => 1 } < M#{ a => 1}, 1463 true = M#{ a => 1, b => 1, c => 1 } < M#{ b => 1, c => 1, d => 1}, 1464 true = M#{ b => 1, c => 1, d => 1 } > M#{ a => 1, b => 1, c => 1}, 1465 true = M#{ c => 1, b => 1, a => 1 } < M#{ b => 1, c => 1, d => 1}, 1466 true = M#{ "a" => 1 } < M#{ <<"a">> => 1}, 1467 false = M#{ <<"a">> => 1 } < #{ "a" => 1}, 1468 true = M#{ 1 => 1 } < maps:remove(1,M#{ 1.0 => 1}), 1469 false = M#{ 1.0 => 1 } < M#{ 1 => 1}, 1470 1471 %% value order 1472 true = M#{ a => 1 } < M#{ a => 2}, 1473 false = M#{ a => 2 } < M#{ a => 1}, 1474 false = M#{ a => 2, b => 1 } < M#{ a => 1, b => 3}, 1475 true = M#{ a => 1, b => 1 } < M#{ a => 1, b => 3}, 1476 false = M#{ a => 1 } < M#{ a => 1.0}, 1477 false = M#{ a => 1.0 } < M#{ a => 1}, 1478 1479 true = M#{ "a" => "hi", b => 134 } == M#{ b => 134,"a" => "hi"}, 1480 1481 %% lists:sort 1482 1483 SortVs = [#{"a"=>1},#{a=>2},#{1=>3},#{<<"a">>=>4}], 1484 [#{1:=ok},#{a:=ok},#{"a":=ok},#{<<"a">>:=ok}] = lists:sort([#{"a"=>ok},#{a=>ok},#{1=>ok},#{<<"a">>=>ok}]), 1485 [#{1:=3},#{a:=2},#{"a":=1},#{<<"a">>:=4}] = lists:sort(SortVs), 1486 [#{1:=3},#{a:=2},#{"a":=1},#{<<"a">>:=4}] = lists:sort(lists:reverse(SortVs)), 1487 ok. 1488 1489t_map_equal(Config) when is_list(Config) -> 1490 true = #{} =:= #{}, 1491 false = #{} =:= #{a=>1}, 1492 false = #{a=>1} =:= #{}, 1493 true = #{ "a" => "hi", b => 134 } =:= #{ b => 134,"a" => "hi"}, 1494 1495 false = #{ a => 1 } =:= #{ a => 2}, 1496 false = #{ a => 2 } =:= #{ a => 1}, 1497 false = #{ a => 2, b => 1 } =:= #{ a => 1, b => 3}, 1498 false = #{ a => 1, b => 1 } =:= #{ a => 1, b => 3}, 1499 1500 true = #{ a => 1 } =:= #{ a => 1}, 1501 true = #{ "a" => 2 } =:= #{ "a" => 2}, 1502 true = #{ "a" => 2, b => 3 } =:= #{ "a" => 2, b => 3}, 1503 true = #{ a => 1, b => 3, c => <<"wat">> } =:= #{ a => 1, b => 3, c=><<"wat">>}, 1504 ok. 1505 1506 1507t_map_compare(Config) when is_list(Config) -> 1508 Seed = {erlang:monotonic_time(), 1509 erlang:time_offset(), 1510 erlang:unique_integer()}, 1511 io:format("seed = ~p\n", [Seed]), 1512 random:seed(Seed), 1513 repeat(100, fun(_) -> float_int_compare() end, []), 1514 repeat(100, fun(_) -> recursive_compare() end, []), 1515 ok. 1516 1517float_int_compare() -> 1518 Terms = numeric_keys(3), 1519 %%io:format("Keys to use: ~p\n", [Terms]), 1520 Pairs = lists:map(fun(K) -> list_to_tuple([{K,V} || V <- Terms]) end, Terms), 1521 lists:foreach(fun(Size) -> 1522 MapGen = fun() -> map_gen(list_to_tuple(Pairs), Size) end, 1523 repeat(100, fun do_compare/1, [MapGen, MapGen]) 1524 end, 1525 lists:seq(1,length(Terms))), 1526 ok. 1527 1528numeric_keys(N) -> 1529 lists:foldl(fun(_,Acc) -> 1530 Int = random:uniform(N*4) - N*2, 1531 Float = float(Int), 1532 [Int, Float, Float * 0.99, Float * 1.01 | Acc] 1533 end, 1534 [], 1535 lists:seq(1,N)). 1536 1537 1538repeat(0, _, _) -> 1539 ok; 1540repeat(N, Fun, Arg) -> 1541 Fun(Arg), 1542 repeat(N-1, Fun, Arg). 1543 1544copy_term(T) -> 1545 Papa = self(), 1546 P = spawn_link(fun() -> receive Msg -> Papa ! Msg end end), 1547 P ! T, 1548 receive R -> R end. 1549 1550do_compare([Gen1, Gen2]) -> 1551 M1 = Gen1(), 1552 M2 = Gen2(), 1553 %%io:format("Maps to compare: ~p AND ~p\n", [M1, M2]), 1554 C = (M1 < M2), 1555 Erlang = maps_lessthan(M1, M2), 1556 C = Erlang, 1557 ?CHECK(M1==M1, M1), 1558 1559 %% Change one key from int to float (or vice versa) and check compare 1560 ML1 = maps:to_list(M1), 1561 {K1,V1} = lists:nth(random:uniform(length(ML1)), ML1), 1562 case K1 of 1563 I when is_integer(I) -> 1564 case maps:find(float(I),M1) of 1565 error -> 1566 M1f = maps:remove(I, maps:put(float(I), V1, M1)), 1567 ?CHECK(M1f > M1, [M1f, M1]); 1568 _ -> ok 1569 end; 1570 1571 F when is_float(F), round(F) == F -> 1572 case maps:find(round(F),M1) of 1573 error -> 1574 M1i = maps:remove(F, maps:put(round(F), V1, M1)), 1575 ?CHECK(M1i < M1, [M1i, M1]); 1576 _ -> ok 1577 end; 1578 1579 _ -> ok % skip floats with decimals 1580 end, 1581 1582 ?CHECK(M2 == M2, [M2]). 1583 1584 1585maps_lessthan(M1, M2) -> 1586 case {maps:size(M1),maps:size(M2)} of 1587 {_S,_S} -> 1588 {K1,V1} = lists:unzip(term_sort(maps:to_list(M1))), 1589 {K2,V2} = lists:unzip(term_sort(maps:to_list(M2))), 1590 1591 case erts_internal:cmp_term(K1,K2) of 1592 -1 -> true; 1593 0 -> (V1 < V2); 1594 1 -> false 1595 end; 1596 1597 {S1, S2} -> 1598 S1 < S2 1599 end. 1600 1601term_sort(L) -> 1602 lists:sort(fun(A,B) -> erts_internal:cmp_term(A,B) =< 0 end, 1603 L). 1604 1605 1606cmp(T1, T2, Exact) when is_tuple(T1) and is_tuple(T2) -> 1607 case {size(T1),size(T2)} of 1608 {_S,_S} -> cmp(tuple_to_list(T1), tuple_to_list(T2), Exact); 1609 {S1,S2} when S1 < S2 -> -1; 1610 {S1,S2} when S1 > S2 -> 1 1611 end; 1612 1613cmp([H1|T1], [H2|T2], Exact) -> 1614 case cmp(H1,H2, Exact) of 1615 0 -> cmp(T1,T2, Exact); 1616 C -> C 1617 end; 1618 1619cmp(M1, M2, Exact) when is_map(M1) andalso is_map(M2) -> 1620 cmp_maps(M1,M2,Exact); 1621cmp(M1, M2, Exact) -> 1622 cmp_others(M1, M2, Exact). 1623 1624cmp_maps(M1, M2, Exact) -> 1625 case {maps:size(M1),maps:size(M2)} of 1626 {_S,_S} -> 1627 {K1,V1} = lists:unzip(term_sort(maps:to_list(M1))), 1628 {K2,V2} = lists:unzip(term_sort(maps:to_list(M2))), 1629 1630 case cmp(K1, K2, true) of 1631 0 -> cmp(V1, V2, Exact); 1632 C -> C 1633 end; 1634 1635 {S1,S2} when S1 < S2 -> -1; 1636 {S1,S2} when S1 > S2 -> 1 1637 end. 1638 1639cmp_others(I, F, true) when is_integer(I), is_float(F) -> 1640 -1; 1641cmp_others(F, I, true) when is_float(F), is_integer(I) -> 1642 1; 1643cmp_others(T1, T2, _) -> 1644 case {T1<T2, T1==T2} of 1645 {true,false} -> -1; 1646 {false,true} -> 0; 1647 {false,false} -> 1 1648 end. 1649 1650map_gen(Pairs, Size) -> 1651 {_,L} = lists:foldl(fun(_, {Keys, Acc}) -> 1652 KI = random:uniform(size(Keys)), 1653 K = element(KI,Keys), 1654 KV = element(random:uniform(size(K)), K), 1655 {erlang:delete_element(KI,Keys), [KV | Acc]} 1656 end, 1657 {Pairs, []}, 1658 lists:seq(1,Size)), 1659 1660 maps:from_list(L). 1661 1662 1663recursive_compare() -> 1664 Leafs = {atom, 17, 16.9, 17.1, [], self(), spawn(fun() -> ok end), make_ref(), make_ref()}, 1665 {A, B} = term_gen_recursive(Leafs, 0, 0), 1666 %%io:format("Recursive term A = ~p\n", [A]), 1667 %%io:format("Recursive term B = ~p\n", [B]), 1668 1669 ?CHECK({true,false} =:= case do_cmp(A, B, false) of 1670 -1 -> {A<B, A>=B}; 1671 0 -> {A==B, A/=B}; 1672 1 -> {A>B, A=<B} 1673 end, 1674 {A,B}), 1675 A2 = copy_term(A), 1676 ?CHECK(A == A2, {A,A2}), 1677 ?CHECK(0 =:= cmp(A, A2, false), {A,A2}), 1678 1679 B2 = copy_term(B), 1680 ?CHECK(B == B2, {B,B2}), 1681 ?CHECK(0 =:= cmp(B, B2, false), {B,B2}), 1682 ok. 1683 1684do_cmp(A, B, Exact) -> 1685 C = cmp(A, B, Exact), 1686 C. 1687 1688%% Generate two terms {A,B} that may only differ 1689%% at float vs integer types. 1690term_gen_recursive(Leafs, Flags, Depth) -> 1691 MaxDepth = 10, 1692 Rnd = case {Flags, Depth} of 1693 {_, MaxDepth} -> % Only leafs 1694 random:uniform(size(Leafs)) + 3; 1695 {0, 0} -> % Only containers 1696 random:uniform(3); 1697 {0,_} -> % Anything 1698 random:uniform(size(Leafs)+3) 1699 end, 1700 case Rnd of 1701 1 -> % Make map 1702 Size = random:uniform(size(Leafs)), 1703 lists:foldl(fun(_, {Acc1,Acc2}) -> 1704 {K1,K2} = term_gen_recursive(Leafs, Flags, 1705 Depth+1), 1706 {V1,V2} = term_gen_recursive(Leafs, Flags, Depth+1), 1707 {maps:put(K1,V1, Acc1), maps:put(K2,V2, Acc2)} 1708 end, 1709 {maps:new(), maps:new()}, 1710 lists:seq(1,Size)); 1711 2 -> % Make cons 1712 {Car1,Car2} = term_gen_recursive(Leafs, Flags, Depth+1), 1713 {Cdr1,Cdr2} = term_gen_recursive(Leafs, Flags, Depth+1), 1714 {[Car1 | Cdr1], [Car2 | Cdr2]}; 1715 3 -> % Make tuple 1716 Size = random:uniform(size(Leafs)), 1717 L = lists:map(fun(_) -> term_gen_recursive(Leafs, Flags, Depth+1) end, 1718 lists:seq(1,Size)), 1719 {L1, L2} = lists:unzip(L), 1720 {list_to_tuple(L1), list_to_tuple(L2)}; 1721 1722 N -> % Make leaf 1723 case element(N-3, Leafs) of 1724 I when is_integer(I) -> 1725 case random:uniform(4) of 1726 1 -> {I, float(I)}; 1727 2 -> {float(I), I}; 1728 _ -> {I,I} 1729 end; 1730 T -> {T,T} 1731 end 1732 end. 1733 1734%% BIFs 1735t_bif_map_get(Config) when is_list(Config) -> 1736 %% small map 1737 1 = maps:get(a, #{ a=> 1}), 1738 2 = maps:get(b, #{ a=> 1, b => 2}), 1739 "hi" = maps:get("hello", #{ a=>1, "hello" => "hi"}), 1740 "tuple hi" = maps:get({1,1.0}, #{ a=>a, {1,1.0} => "tuple hi"}), 1741 1742 M0 = #{ k1=>"v1", <<"k2">> => <<"v3">> }, 1743 "v4" = maps:get(<<"k2">>, M0#{<<"k2">> => "v4"}), 1744 1745 %% large map 1746 M1 = maps:from_list([{I,I}||I<-lists:seq(1,100)] ++ 1747 [{a,1},{b,2},{"hello","hi"},{{1,1.0},"tuple hi"}, 1748 {k1,"v1"},{<<"k2">>,"v3"}]), 1749 1 = maps:get(a, M1), 1750 2 = maps:get(b, M1), 1751 "hi" = maps:get("hello", M1), 1752 "tuple hi" = maps:get({1,1.0}, M1), 1753 "v3" = maps:get(<<"k2">>, M1), 1754 1755 %% error cases 1756 do_badmap(fun(T) -> 1757 {'EXIT',{{badmap,T},[{maps,get,_,_}|_]}} = 1758 (catch maps:get(a, T)) 1759 end), 1760 1761 {'EXIT',{{badkey,{1,1}},[{maps,get,_,_}|_]}} = 1762 (catch maps:get({1,1}, #{{1,1.0} => "tuple"})), 1763 {'EXIT',{{badkey,a},[{maps,get,_,_}|_]}} = (catch maps:get(a, #{})), 1764 {'EXIT',{{badkey,a},[{maps,get,_,_}|_]}} = 1765 (catch maps:get(a, #{b=>1, c=>2})), 1766 ok. 1767 1768t_bif_map_find(Config) when is_list(Config) -> 1769 %% small map 1770 {ok, 1} = maps:find(a, #{ a=> 1}), 1771 {ok, 2} = maps:find(b, #{ a=> 1, b => 2}), 1772 {ok, "int"} = maps:find(1, #{ 1 => "int"}), 1773 {ok, "float"} = maps:find(1.0, #{ 1.0=> "float"}), 1774 1775 {ok, "hi"} = maps:find("hello", #{ a=>1, "hello" => "hi"}), 1776 {ok, "tuple hi"} = maps:find({1,1.0}, #{ a=>a, {1,1.0} => "tuple hi"}), 1777 1778 M0 = #{ k1=>"v1", <<"k2">> => <<"v3">> }, 1779 {ok, "v4"} = maps:find(<<"k2">>, M0#{ <<"k2">> => "v4" }), 1780 1781 %% large map 1782 M1 = maps:from_list([{I,I}||I<-lists:seq(1,100)] ++ 1783 [{a,1},{b,2},{"hello","hi"},{{1,1.0},"tuple hi"}, 1784 {k1,"v1"},{<<"k2">>,"v3"}]), 1785 {ok, 1} = maps:find(a, M1), 1786 {ok, 2} = maps:find(b, M1), 1787 {ok, "hi"} = maps:find("hello", M1), 1788 {ok, "tuple hi"} = maps:find({1,1.0}, M1), 1789 {ok, "v3"} = maps:find(<<"k2">>, M1), 1790 1791 %% error case 1792 error = maps:find(a,#{}), 1793 error = maps:find(a,#{b=>1, c=>2}), 1794 error = maps:find(1.0, #{ 1 => "int"}), 1795 error = maps:find(1, #{ 1.0 => "float"}), 1796 error = maps:find({1.0,1}, #{ a=>a, {1,1.0} => "tuple hi"}), % reverse types in tuple key 1797 1798 do_badmap(fun(T) -> 1799 {'EXIT',{{badmap,T},[{maps,find,_,_}|_]}} = 1800 (catch maps:find(a, T)) 1801 end), 1802 ok. 1803 1804 1805t_bif_map_is_key(Config) when is_list(Config) -> 1806 M1 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 4 => number}, 1807 1808 true = maps:is_key("hi", M1), 1809 true = maps:is_key(int, M1), 1810 true = maps:is_key(<<"key">>, M1), 1811 true = maps:is_key(4, M1), 1812 1813 false = maps:is_key(5, M1), 1814 false = maps:is_key(<<"key2">>, M1), 1815 false = maps:is_key("h", M1), 1816 false = maps:is_key("hello", M1), 1817 false = maps:is_key(atom, M1), 1818 false = maps:is_key(any, #{}), 1819 1820 false = maps:is_key("hi", maps:remove("hi", M1)), 1821 true = maps:is_key("hi", M1), 1822 true = maps:is_key(1, maps:put(1, "number", M1)), 1823 false = maps:is_key(1.0, maps:put(1, "number", M1)), 1824 1825 %% error case 1826 do_badmap(fun(T) -> 1827 {'EXIT',{{badmap,T},[{maps,is_key,_,_}|_]}} = 1828 (catch maps:is_key(a, T)) 1829 end), 1830 ok. 1831 1832t_bif_map_keys(Config) when is_list(Config) -> 1833 [] = maps:keys(#{}), 1834 1835 [1,2,3,4,5] = lists:sort(maps:keys(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e})), 1836 [1,2,3,4,5] = lists:sort(maps:keys(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c})), 1837 1838 % values in key order: [4,int,"hi",<<"key">>] 1839 M1 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 4 => number}, 1840 [4,int,"hi",<<"key">>] = lists:sort(maps:keys(M1)), 1841 1842 %% error case 1843 do_badmap(fun(T) -> 1844 {'EXIT',{{badmap,T},[{maps,keys,_,_}|_]}} = 1845 (catch maps:keys(T)) 1846 end), 1847 ok. 1848 1849t_bif_map_new(Config) when is_list(Config) -> 1850 #{} = maps:new(), 1851 0 = erlang:map_size(maps:new()), 1852 ok. 1853 1854t_bif_map_merge(Config) when is_list(Config) -> 1855 0 = erlang:map_size(maps:merge(#{},#{})), 1856 1857 M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 1858 4 => number, 18446744073709551629 => wat}, 1859 1860 #{ "hi" := "hello", int := 3, <<"key">> := <<"value">>, 1861 4 := number, 18446744073709551629 := wat} = maps:merge(#{}, M0), 1862 1863 #{ "hi" := "hello", int := 3, <<"key">> := <<"value">>, 1864 4 := number, 18446744073709551629 := wat} = maps:merge(M0, #{}), 1865 1866 M1 = #{ "hi" => "hello again", float => 3.3, {1,2} => "tuple", 4 => integer }, 1867 1868 #{4 := number, 18446744073709551629 := wat, float := 3.3, int := 3, 1869 {1,2} := "tuple", "hi" := "hello", <<"key">> := <<"value">>} = maps:merge(M1,M0), 1870 1871 #{4 := integer, 18446744073709551629 := wat, float := 3.3, int := 3, 1872 {1,2} := "tuple", "hi" := "hello again", <<"key">> := <<"value">>} = maps:merge(M0,M1), 1873 1874 %% try deep collisions 1875 N = 150000, 1876 Is = lists:seq(1,N), 1877 M2 = maps:from_list([{I,I}||I<-Is]), 1878 150000 = maps:size(M2), 1879 M3 = maps:from_list([{<<I:32>>,I}||I<-Is]), 1880 150000 = maps:size(M3), 1881 M4 = maps:merge(M2,M3), 1882 300000 = maps:size(M4), 1883 M5 = maps:from_list([{integer_to_list(I),I}||I<-Is]), 1884 150000 = maps:size(M5), 1885 M6 = maps:merge(M4,M5), 1886 450000 = maps:size(M6), 1887 M7 = maps:from_list([{float(I),I}||I<-Is]), 1888 150000 = maps:size(M7), 1889 M8 = maps:merge(M7,M6), 1890 600000 = maps:size(M8), 1891 1892 #{ 1 := 1, "1" := 1, <<1:32>> := 1 } = M8, 1893 #{ 10 := 10, "10" := 10, <<10:32>> := 10 } = M8, 1894 #{ 100 := 100, "100" := 100, <<100:32>> := 100 } = M8, 1895 #{ 1000 := 1000, "1000" := 1000, <<1000:32>> := 1000 } = M8, 1896 #{ 10000 := 10000, "10000" := 10000, <<10000:32>> := 10000 } = M8, 1897 #{ 100000 := 100000, "100000" := 100000, <<100000:32>> := 100000 } = M8, 1898 1899 %% overlapping 1900 M8 = maps:merge(M2,M8), 1901 M8 = maps:merge(M3,M8), 1902 M8 = maps:merge(M4,M8), 1903 M8 = maps:merge(M5,M8), 1904 M8 = maps:merge(M6,M8), 1905 M8 = maps:merge(M7,M8), 1906 M8 = maps:merge(M8,M8), 1907 1908 %% maps:merge/2 and mixed 1909 1910 Ks1 = [764492191,2361333849], %% deep collision 1911 Ks2 = lists:seq(1,33), 1912 M9 = maps:from_list([{K,K}||K <- Ks1]), 1913 M10 = maps:from_list([{K,K}||K <- Ks2]), 1914 M11 = maps:merge(M9,M10), 1915 ok = check_keys_exist(Ks1 ++ Ks2, M11), 1916 1917 %% error case 1918 do_badmap(fun(T) -> 1919 {'EXIT',{{badmap,T},[{maps,merge,_,_}|_]}} = 1920 (catch maps:merge(#{}, T)), 1921 {'EXIT',{{badmap,T},[{maps,merge,_,_}|_]}} = 1922 (catch maps:merge(T, #{})), 1923 {'EXIT',{{badmap,T},[{maps,merge,_,_}|_]}} = 1924 (catch maps:merge(T, T)) 1925 end), 1926 ok. 1927 1928 1929t_bif_map_put(Config) when is_list(Config) -> 1930 M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 1931 4 => number, 18446744073709551629 => wat}, 1932 1933 M1 = #{ "hi" := "hello"} = maps:put("hi", "hello", #{}), 1934 1935 true = is_members(["hi"],maps:keys(M1)), 1936 true = is_members(["hello"],maps:values(M1)), 1937 1938 M2 = #{ int := 3 } = maps:put(int, 3, M1), 1939 1940 true = is_members([int,"hi"],maps:keys(M2)), 1941 true = is_members([3,"hello"],maps:values(M2)), 1942 1943 M3 = #{ <<"key">> := <<"value">> } = maps:put(<<"key">>, <<"value">>, M2), 1944 1945 true = is_members([int,"hi",<<"key">>],maps:keys(M3)), 1946 true = is_members([3,"hello",<<"value">>],maps:values(M3)), 1947 1948 M4 = #{ 18446744073709551629 := wat } = maps:put(18446744073709551629, wat, M3), 1949 1950 true = is_members([18446744073709551629,int,"hi",<<"key">>],maps:keys(M4)), 1951 true = is_members([wat,3,"hello",<<"value">>],maps:values(M4)), 1952 1953 M0 = #{ 4 := number } = M5 = maps:put(4, number, M4), 1954 1955 true = is_members([4,18446744073709551629,int,"hi",<<"key">>],maps:keys(M5)), 1956 true = is_members([number,wat,3,"hello",<<"value">>],maps:values(M5)), 1957 1958 M6 = #{ <<"key">> := <<"other value">> } = maps:put(<<"key">>, <<"other value">>, M5), 1959 1960 true = is_members([4,18446744073709551629,int,"hi",<<"key">>],maps:keys(M6)), 1961 true = is_members([number,wat,3,"hello",<<"other value">>],maps:values(M6)), 1962 1963 %% error case 1964 do_badmap(fun(T) -> 1965 {'EXIT',{{badmap,T},[{maps,put,_,_}|_]}} = 1966 (catch maps:put(1, a, T)) 1967 end), 1968 ok. 1969 1970is_members(Ks,Ls) when length(Ks) =/= length(Ls) -> false; 1971is_members(Ks,Ls) -> is_members_do(Ks,Ls). 1972 1973is_members_do([],[]) -> true; 1974is_members_do([],_) -> false; 1975is_members_do([K|Ks],Ls) -> 1976 is_members_do(Ks, lists:delete(K,Ls)). 1977 1978t_bif_map_remove(Config) when is_list(Config) -> 1979 0 = erlang:map_size(maps:remove(some_key, #{})), 1980 1981 M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 1982 4 => number, 18446744073709551629 => wat}, 1983 1984 M1 = maps:remove("hi", M0), 1985 true = is_members([4,18446744073709551629,int,<<"key">>],maps:keys(M1)), 1986 true = is_members([number,wat,3,<<"value">>],maps:values(M1)), 1987 1988 M2 = maps:remove(int, M1), 1989 true = is_members([4,18446744073709551629,<<"key">>],maps:keys(M2)), 1990 true = is_members([number,wat,<<"value">>],maps:values(M2)), 1991 1992 M3 = maps:remove(<<"key">>, M2), 1993 true = is_members([4,18446744073709551629],maps:keys(M3)), 1994 true = is_members([number,wat],maps:values(M3)), 1995 1996 M4 = maps:remove(18446744073709551629, M3), 1997 true = is_members([4],maps:keys(M4)), 1998 true = is_members([number],maps:values(M4)), 1999 2000 M5 = maps:remove(4, M4), 2001 [] = maps:keys(M5), 2002 [] = maps:values(M5), 2003 2004 M0 = maps:remove(5,M0), 2005 M0 = maps:remove("hi there",M0), 2006 2007 #{ "hi" := "hello", int := 3, 4 := number} = maps:remove(18446744073709551629,maps:remove(<<"key">>,M0)), 2008 2009 %% error case 2010 do_badmap(fun(T) -> 2011 {'EXIT',{{badmap,T},[{maps,remove,_,_}|_]}} = 2012 (catch maps:remove(a, T)) 2013 end), 2014 ok. 2015 2016t_bif_map_update(Config) when is_list(Config) -> 2017 M0 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 2018 4 => number, 18446744073709551629 => wat}, 2019 2020 #{ "hi" := "hello again", int := 3, <<"key">> := <<"value">>, 2021 4 := number, 18446744073709551629 := wat} = maps:update("hi", "hello again", M0), 2022 2023 #{ "hi" := "hello", int := 1337, <<"key">> := <<"value">>, 2024 4 := number, 18446744073709551629 := wat} = maps:update(int, 1337, M0), 2025 2026 #{ "hi" := "hello", int := 3, <<"key">> := <<"new value">>, 2027 4 := number, 18446744073709551629 := wat} = maps:update(<<"key">>, <<"new value">>, M0), 2028 2029 #{ "hi" := "hello", int := 3, <<"key">> := <<"value">>, 2030 4 := integer, 18446744073709551629 := wat} = maps:update(4, integer, M0), 2031 2032 #{ "hi" := "hello", int := 3, <<"key">> := <<"value">>, 2033 4 := number, 18446744073709551629 := wazzup} = maps:update(18446744073709551629, wazzup, M0), 2034 2035 %% error case 2036 do_badmap(fun(T) -> 2037 {'EXIT',{{badmap,T},[{maps,update,_,_}|_]}} = 2038 (catch maps:update(1, none, T)) 2039 end), 2040 ok. 2041 2042 2043 2044t_bif_map_values(Config) when is_list(Config) -> 2045 2046 [] = maps:values(#{}), 2047 [1] = maps:values(#{a=>1}), 2048 2049 true = is_members([a,b,c,d,e],maps:values(#{ 1 => a, 2 => b, 3 => c, 4 => d, 5 => e})), 2050 true = is_members([a,b,c,d,e],maps:values(#{ 4 => d, 5 => e, 1 => a, 2 => b, 3 => c})), 2051 2052 M1 = #{ "hi" => "hello", int => 3, <<"key">> => <<"value">>, 4 => number}, 2053 M2 = M1#{ "hi" => "hello2", <<"key">> => <<"value2">> }, 2054 true = is_members([number,3,"hello2",<<"value2">>],maps:values(M2)), 2055 true = is_members([number,3,"hello",<<"value">>],maps:values(M1)), 2056 2057 Vs = lists:seq(1000,20000), 2058 M3 = maps:from_list([{K,K}||K<-Vs]), 2059 M4 = maps:merge(M1,M3), 2060 M5 = maps:merge(M2,M3), 2061 true = is_members(Vs,maps:values(M3)), 2062 true = is_members([number,3,"hello",<<"value">>]++Vs,maps:values(M4)), 2063 true = is_members([number,3,"hello2",<<"value2">>]++Vs,maps:values(M5)), 2064 2065 %% error case 2066 do_badmap(fun(T) -> 2067 {'EXIT',{{badmap,T},[{maps,values,_,_}|_]}} = 2068 (catch maps:values(T)) 2069 end), 2070 ok. 2071 2072t_erlang_hash(Config) when is_list(Config) -> 2073 ok = t_bif_erlang_phash2(), 2074 ok = t_bif_erlang_phash(), 2075 ok. 2076 2077t_bif_erlang_phash2() -> 2078 2079 39679005 = erlang:phash2(#{}), 2080 33667975 = erlang:phash2(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 }), % 78942764 2081 95332690 = erlang:phash2(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} }), % 37338230 2082 108954384 = erlang:phash2(#{ 1 => a }), % 14363616 2083 59617982 = erlang:phash2(#{ a => 1 }), % 51612236 2084 2085 42770201 = erlang:phash2(#{{} => <<>>}), % 37468437 2086 71687700 = erlang:phash2(#{<<>> => {}}), % 44049159 2087 2088 M0 = #{ a => 1, "key" => <<"value">> }, 2089 M1 = maps:remove("key",M0), 2090 M2 = M1#{ "key" => <<"value">> }, 2091 2092 70249457 = erlang:phash2(M0), % 118679416 2093 59617982 = erlang:phash2(M1), % 51612236 2094 70249457 = erlang:phash2(M2), % 118679416 2095 ok. 2096 2097t_bif_erlang_phash() -> 2098 Sz = 1 bsl 32, 2099 1113425985 = erlang:phash(#{},Sz), % 268440612 2100 1510068139 = erlang:phash(#{ a => 1, "a" => 2, <<"a">> => 3, {a,b} => 4 },Sz), % 1196461908 2101 3182345590 = erlang:phash(#{ 1 => a, 2 => "a", 3 => <<"a">>, 4 => {a,b} },Sz), % 3944426064 2102 2927531828 = erlang:phash(#{ 1 => a },Sz), % 1394238263 2103 1670235874 = erlang:phash(#{ a => 1 },Sz), % 4066388227 2104 2105 3935089469 = erlang:phash(#{{} => <<>>},Sz), % 1578050717 2106 71692856 = erlang:phash(#{<<>> => {}},Sz), % 1578050717 2107 2108 M0 = #{ a => 1, "key" => <<"value">> }, 2109 M1 = maps:remove("key",M0), 2110 M2 = M1#{ "key" => <<"value">> }, 2111 2112 2620391445 = erlang:phash(M0,Sz), % 3590546636 2113 1670235874 = erlang:phash(M1,Sz), % 4066388227 2114 2620391445 = erlang:phash(M2,Sz), % 3590546636 2115 ok. 2116 2117t_map_encode_decode(Config) when is_list(Config) -> 2118 <<131,116,0,0,0,0>> = erlang:term_to_binary(#{}), 2119 Pairs = [ 2120 {a,b},{"key","values"},{<<"key">>,<<"value">>}, 2121 {1,b},{[atom,1],{<<"wat">>,1,2,3}}, 2122 {aa,"values"}, 2123 {1 bsl 64 + (1 bsl 50 - 1), sc1}, 2124 {99, sc2}, 2125 {1 bsl 65 + (1 bsl 51 - 1), sc3}, 2126 {88, sc4}, 2127 {1 bsl 66 + (1 bsl 52 - 1), sc5}, 2128 {77, sc6}, 2129 {1 bsl 67 + (1 bsl 53 - 1), sc3}, 2130 {75, sc6}, {-10,sc8}, 2131 {<<>>, sc9}, {3.14158, sc10}, 2132 {[3.14158], sc11}, {more_atoms, sc12}, 2133 {{more_tuples}, sc13}, {self(), sc14}, 2134 {{},{}},{[],[]} 2135 ], 2136 ok = map_encode_decode_and_match(Pairs,[],#{}), 2137 2138 %% check sorting 2139 2140 %% literally #{ b=>2, a=>1 } in the internal order 2141 #{ a:=1, b:=2 } = 2142 erlang:binary_to_term(<<131,116,0,0,0,2,100,0,1,98,97,2,100,0,1,97,97,1>>), 2143 2144 2145 %% literally #{ "hi" => "value", a=>33, b=>55 } in the internal order 2146 #{ a:=33, b:=55, "hi" := "value"} = erlang:binary_to_term(<<131,116,0,0,0,3, 2147 107,0,2,104,105, % "hi" :: list() 2148 107,0,5,118,97,108,117,101, % "value" :: list() 2149 100,0,1,97, % a :: atom() 2150 97,33, % 33 :: integer() 2151 100,0,1,98, % b :: atom() 2152 97,55 % 55 :: integer() 2153 >>), 2154 2155 %% Maps of different sizes 2156 lists:foldl(fun(Key, M0) -> 2157 M1 = M0#{Key => Key}, 2158 case Key rem 17 of 2159 0 -> 2160 M1 = binary_to_term(term_to_binary(M1)); 2161 _ -> 2162 ok 2163 end, 2164 M1 2165 end, 2166 #{}, 2167 lists:seq(1,10000)), 2168 2169 %% many maps in same binary 2170 MapList = lists:foldl(fun(K, [M|_]=Acc) -> [M#{K => K} | Acc] end, 2171 [#{}], 2172 lists:seq(1,100)), 2173 MapList = binary_to_term(term_to_binary(MapList)), 2174 MapListR = lists:reverse(MapList), 2175 MapListR = binary_to_term(term_to_binary(MapListR)), 2176 2177 %% error cases 2178 %% template: <<131,116,0,0,0,2,100,0,1,97,100,0,1,98,97,1,97,1>> 2179 %% which is: #{ a=>1, b=>1 } 2180 2181 %% uniqueness violation 2182 %% literally #{ a=>1, "hi"=>"value", a=>2 } 2183 {'EXIT',{badarg,[{_,_,_,_}|_]}} = (catch 2184 erlang:binary_to_term(<<131,116,0,0,0,3, 2185 100,0,1,97, 2186 97,1, 2187 107,0,2,104,105, 2188 107,0,5,118,97,108,117,101, 2189 100,0,1,97, 2190 97,2>>)), 2191 2192 %% bad size (too large) 2193 {'EXIT',{badarg,[{_,_,_,_}|_]}} = (catch 2194 erlang:binary_to_term(<<131,116,0,0,0,12,100,0,1,97,97,1,100,0,1,98,97,1>>)), 2195 2196 %% bad size (too small) .. should fail just truncate it .. weird. 2197 %% possibly change external format so truncated will be #{a:=1} 2198 #{ a:=b } = 2199 erlang:binary_to_term(<<131,116,0,0,0,1,100,0,1,97,100,0,1,98,97,1,97,1>>), 2200 2201 ok. 2202 2203map_encode_decode_and_match([{K,V}|Pairs], EncodedPairs, M0) -> 2204 M1 = maps:put(K,V,M0), 2205 B0 = erlang:term_to_binary(M1), 2206 Ls = [{erlang:term_to_binary(K), erlang:term_to_binary(V)}|EncodedPairs], 2207 ok = match_encoded_map(B0, length(Ls), Ls), 2208 %% decode and match it 2209 M1 = erlang:binary_to_term(B0), 2210 map_encode_decode_and_match(Pairs,Ls,M1); 2211map_encode_decode_and_match([],_,_) -> ok. 2212 2213match_encoded_map(<<131,116,Size:32,Encoded/binary>>,Size,Items) -> 2214 match_encoded_map_stripped_size(Encoded,Items,Items); 2215match_encoded_map(_,_,_) -> no_match_size. 2216 2217match_encoded_map_stripped_size(<<>>,_,_) -> ok; 2218match_encoded_map_stripped_size(B0,[{<<131,K/binary>>,<<131,V/binary>>}|Items],Ls) -> 2219 Ksz = byte_size(K), 2220 Vsz = byte_size(V), 2221 case B0 of 2222 <<K:Ksz/binary,V:Vsz/binary,B1/binary>> -> 2223 match_encoded_map_stripped_size(B1,Ls,Ls); 2224 _ -> 2225 match_encoded_map_stripped_size(B0,Items,Ls) 2226 end; 2227match_encoded_map_stripped_size(_,[],_) -> fail. 2228 2229 2230t_bif_map_to_list(Config) when is_list(Config) -> 2231 [] = maps:to_list(#{}), 2232 [{a,1},{b,2}] = lists:sort(maps:to_list(#{a=>1,b=>2})), 2233 [{a,1},{b,2},{c,3}] = lists:sort(maps:to_list(#{c=>3,a=>1,b=>2})), 2234 [{a,1},{b,2},{g,3}] = lists:sort(maps:to_list(#{g=>3,a=>1,b=>2})), 2235 [{a,1},{b,2},{g,3},{"c",4}] = lists:sort(maps:to_list(#{g=>3,a=>1,b=>2,"c"=>4})), 2236 [{3,v2},{hi,v4},{{hi,3},v5},{"hi",v3},{<<"hi">>,v1}] = 2237 lists:sort(maps:to_list(#{<<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5})), 2238 2239 [{3,v7},{hi,v9},{{hi,3},v10},{"hi",v8},{<<"hi">>,v6}] = 2240 lists:sort(maps:to_list(#{<<"hi">>=>v1,3=>v2,"hi"=>v3,hi=>v4,{hi,3}=>v5, 2241 <<"hi">>=>v6,3=>v7,"hi"=>v8,hi=>v9,{hi,3}=>v10})), 2242 2243 %% error cases 2244 do_badmap(fun(T) -> 2245 {'EXIT', {{badmap,T},_}} = 2246 (catch maps:to_list(T)) 2247 end), 2248 ok. 2249 2250 2251t_bif_map_from_list(Config) when is_list(Config) -> 2252 #{} = maps:from_list([]), 2253 A = maps:from_list([]), 2254 0 = erlang:map_size(A), 2255 2256 #{a:=1,b:=2} = maps:from_list([{a,1},{b,2}]), 2257 #{c:=3,a:=1,b:=2} = maps:from_list([{a,1},{b,2},{c,3}]), 2258 #{g:=3,a:=1,b:=2} = maps:from_list([{a,1},{b,2},{g,3}]), 2259 2260 #{a:=2} = maps:from_list([{a,1},{a,3},{a,2}]), 2261 2262 #{ <<"hi">>:=v1,3:=v3,"hi":=v6,hi:=v4,{hi,3}:=v5} = 2263 maps:from_list([{3,v3},{"hi",v6},{hi,v4},{{hi,3},v5},{<<"hi">>,v1}]), 2264 2265 #{<<"hi">>:=v6,3:=v8,"hi":=v11,hi:=v9,{hi,3}:=v10} = 2266 maps:from_list([ {{hi,3},v3}, {"hi",v0},{3,v1}, {<<"hi">>,v4}, {hi,v2}, 2267 {<<"hi">>,v6}, {{hi,3},v10},{"hi",v11}, {hi,v9}, {3,v8}]), 2268 2269 %% repeated keys (large -> small) 2270 Ps1 = [{a,I}|| I <- lists:seq(1,32)], 2271 Ps2 = [{a,I}|| I <- lists:seq(33,64)], 2272 2273 M = maps:from_list(Ps1 ++ [{b,1},{c,1}] ++ Ps2), 2274 #{ a := 64, b := 1, c := 1 } = M, 2275 2276 %% error cases 2277 {'EXIT', {badarg,_}} = (catch maps:from_list([{a,b},b])), 2278 {'EXIT', {badarg,_}} = (catch maps:from_list([{a,b},{b,b,3}])), 2279 {'EXIT', {badarg,_}} = (catch maps:from_list([{a,b},<<>>])), 2280 {'EXIT', {badarg,_}} = (catch maps:from_list([{a,b}|{b,a}])), 2281 {'EXIT', {badarg,_}} = (catch maps:from_list(a)), 2282 {'EXIT', {badarg,_}} = (catch maps:from_list(42)), 2283 ok. 2284 2285t_bif_build_and_check(Config) when is_list(Config) -> 2286 ok = check_build_and_remove(750,[ 2287 fun(K) -> [K,K] end, 2288 fun(K) -> [float(K),K] end, 2289 fun(K) -> K end, 2290 fun(K) -> {1,K} end, 2291 fun(K) -> {K} end, 2292 fun(K) -> [K|K] end, 2293 fun(K) -> [K,1,2,3,4] end, 2294 fun(K) -> {K,atom} end, 2295 fun(K) -> float(K) end, 2296 fun(K) -> integer_to_list(K) end, 2297 fun(K) -> list_to_atom(integer_to_list(K)) end, 2298 fun(K) -> [K,{K,[K,{K,[K]}]}] end, 2299 fun(K) -> <<K:32>> end 2300 ]), 2301 2302 ok. 2303 2304check_build_and_remove(_,[]) -> ok; 2305check_build_and_remove(N,[F|Fs]) -> 2306 {M,Ks} = build_and_check(N, maps:new(), F, []), 2307 ok = remove_and_check(Ks,M), 2308 check_build_and_remove(N,Fs). 2309 2310build_and_check(0, M0, _, Ks) -> {M0, Ks}; 2311build_and_check(N, M0, F, Ks) -> 2312 K = build_key(F,N), 2313 M1 = maps:put(K,K,M0), 2314 ok = check_keys_exist([I||{I,_} <- [{K,M1}|Ks]], M1), 2315 M2 = maps:update(K,v,M1), 2316 v = maps:get(K,M2), 2317 build_and_check(N-1,M1,F,[{K,M1}|Ks]). 2318 2319remove_and_check([],_) -> ok; 2320remove_and_check([{K,Mc}|Ks], M0) -> 2321 K = maps:get(K,M0), 2322 true = maps:is_key(K,M0), 2323 true = Mc =:= M0, 2324 true = M0 == Mc, 2325 M1 = maps:remove(K,M0), 2326 false = M1 =:= Mc, 2327 false = Mc == M1, 2328 false = maps:is_key(K,M1), 2329 true = maps:is_key(K,M0), 2330 ok = check_keys_exist([I||{I,_} <- Ks],M1), 2331 error = maps:find(K,M1), 2332 remove_and_check(Ks, M1). 2333 2334build_key(F,N) when N rem 3 =:= 0 -> F(N); 2335build_key(F,N) when N rem 3 =:= 1 -> K = F(N), {K,K}; 2336build_key(F,N) when N rem 3 =:= 2 -> K = F(N), [K,K]. 2337 2338check_keys_exist([], _) -> ok; 2339check_keys_exist([K|Ks],M) -> 2340 true = maps:is_key(K,M), 2341 check_keys_exist(Ks,M). 2342 2343t_bif_merge_and_check(Config) when is_list(Config) -> 2344 2345 io:format("rand:export_seed() -> ~p\n",[rand:export_seed()]), 2346 2347 %% simple disjunct ones 2348 %% make sure all keys are unique 2349 Kss = [[a,b,c,d], 2350 [1,2,3,4], 2351 [], 2352 ["hi"], 2353 [e], 2354 [build_key(fun(K) -> {small,K} end, I) || I <- lists:seq(1,32)], 2355 lists:seq(5, 28), 2356 lists:seq(29, 59), 2357 [build_key(fun(K) -> integer_to_list(K) end, I) || I <- lists:seq(2000,10000)], 2358 [build_key(fun(K) -> <<K:32>> end, I) || I <- lists:seq(1,80)], 2359 [build_key(fun(K) -> {<<K:32>>} end, I) || I <- lists:seq(100,1000)]], 2360 2361 2362 KsMs = build_keys_map_pairs(Kss), 2363 Cs = [{CKs1,CM1,CKs2,CM2} || {CKs1,CM1} <- KsMs, {CKs2,CM2} <- KsMs], 2364 ok = merge_and_check_combo(Cs), 2365 2366 %% overlapping ones 2367 2368 KVs1 = [{a,1},{b,2},{c,3}], 2369 KVs2 = [{b,3},{c,4},{d,5}], 2370 KVs = [{I,I} || I <- lists:seq(1,32)], 2371 KVs3 = KVs1 ++ KVs, 2372 KVs4 = KVs2 ++ KVs, 2373 2374 M1 = maps:from_list(KVs1), 2375 M2 = maps:from_list(KVs2), 2376 M3 = maps:from_list(KVs3), 2377 M4 = maps:from_list(KVs4), 2378 2379 M12 = maps:merge(M1,M2), 2380 ok = check_key_values(KVs2 ++ [{a,1}], M12), 2381 M21 = maps:merge(M2,M1), 2382 ok = check_key_values(KVs1 ++ [{d,5}], M21), 2383 2384 M34 = maps:merge(M3,M4), 2385 ok = check_key_values(KVs4 ++ [{a,1}], M34), 2386 M43 = maps:merge(M4,M3), 2387 ok = check_key_values(KVs3 ++ [{d,5}], M43), 2388 2389 M14 = maps:merge(M1,M4), 2390 ok = check_key_values(KVs4 ++ [{a,1}], M14), 2391 M41 = maps:merge(M4,M1), 2392 ok = check_key_values(KVs1 ++ [{d,5}] ++ KVs, M41), 2393 2394 [begin Ma = random_map(SzA, a), 2395 Mb = random_map(SzB, b), 2396 ok = merge_maps(Ma, Mb) 2397 end || SzA <- [3,10,20,100,200,1000], SzB <- [3,10,20,100,200,1000]], 2398 2399 ok. 2400 2401% Generate random map with an average of Sz number of pairs: K -> {V,K} 2402random_map(Sz, V) -> 2403 random_map_insert(#{}, 0, V, Sz*2). 2404 2405random_map_insert(M0, K0, _, Sz) when K0 > Sz -> 2406 M0; 2407random_map_insert(M0, K0, V, Sz) -> 2408 Key = K0 + rand:uniform(3), 2409 random_map_insert(M0#{Key => {V,Key}}, Key, V, Sz). 2410 2411 2412merge_maps(A, B) -> 2413 AB = maps:merge(A, B), 2414 %%io:format("A=~p\nB=~p\n",[A,B]), 2415 maps_foreach(fun(K,VB) -> VB = maps:get(K, AB) 2416 end, B), 2417 maps_foreach(fun(K,VA) -> 2418 case {maps:get(K, AB),maps:find(K, B)} of 2419 {VA, error} -> ok; 2420 {VB, {ok, VB}} -> ok 2421 end 2422 end, A), 2423 2424 maps_foreach(fun(K,V) -> 2425 case {maps:find(K, A),maps:find(K, B)} of 2426 {{ok, V}, error} -> ok; 2427 {error, {ok, V}} -> ok; 2428 {{ok,_}, {ok, V}} -> ok 2429 end 2430 end, AB), 2431 ok. 2432 2433maps_foreach(Fun, Map) -> 2434 maps:fold(fun(K,V,_) -> Fun(K,V) end, void, Map). 2435 2436 2437check_key_values([],_) -> ok; 2438check_key_values([{K,V}|KVs],M) -> 2439 V = maps:get(K,M), 2440 check_key_values(KVs,M). 2441 2442merge_and_check_combo([]) -> ok; 2443merge_and_check_combo([{Ks1,M1,Ks2,M2}|Cs]) -> 2444 M12 = maps:merge(M1,M2), 2445 ok = check_keys_exist(Ks1 ++ Ks2, M12), 2446 M21 = maps:merge(M2,M1), 2447 ok = check_keys_exist(Ks1 ++ Ks2, M21), 2448 2449 true = M12 =:= M21, 2450 M12 = M21, 2451 2452 merge_and_check_combo(Cs). 2453 2454build_keys_map_pairs([]) -> []; 2455build_keys_map_pairs([Ks|Kss]) -> 2456 M = maps:from_list(keys_to_pairs(Ks)), 2457 ok = check_keys_exist(Ks, M), 2458 [{Ks,M}|build_keys_map_pairs(Kss)]. 2459 2460keys_to_pairs(Ks) -> [{K,K} || K <- Ks]. 2461 2462 2463%% Maps module, not BIFs 2464t_maps_fold(_Config) -> 2465 Vs = lists:seq(1,100), 2466 M = maps:from_list([{{k,I},{v,I}}||I<-Vs]), 2467 2468 %% fold 2469 5050 = maps:fold(fun({k,_},{v,V},A) -> V + A end, 0, M), 2470 2471 ok. 2472 2473t_maps_map(_Config) -> 2474 Vs = lists:seq(1,100), 2475 M1 = maps:from_list([{I,I}||I<-Vs]), 2476 M2 = maps:from_list([{I,{token,I}}||I<-Vs]), 2477 2478 M2 = maps:map(fun(_K,V) -> {token,V} end, M1), 2479 ok. 2480 2481t_maps_size(_Config) -> 2482 Vs = lists:seq(1,100), 2483 lists:foldl(fun(I,M) -> 2484 M1 = maps:put(I,I,M), 2485 I = maps:size(M1), 2486 M1 2487 end, #{}, Vs), 2488 ok. 2489 2490 2491t_maps_without(_Config) -> 2492 Ki = [11,22,33,44,55,66,77,88,99], 2493 M0 = maps:from_list([{{k,I},{v,I}}||I<-lists:seq(1,100)]), 2494 M1 = maps:from_list([{{k,I},{v,I}}||I<-lists:seq(1,100) -- Ki]), 2495 M1 = maps:without([{k,I}||I <- Ki],M0), 2496 ok. 2497 2498t_erts_internal_order(_Config) when is_list(_Config) -> 2499 M = #{0 => 0,2147483648 => 0}, 2500 true = M =:= binary_to_term(term_to_binary(M)), 2501 2502 F1 = fun(_, _) -> 0 end, 2503 F2 = fun(_, _) -> 1 end, 2504 M0 = maps:from_list( [{-2147483649, 0}, {0,0}, {97, 0}, {false, 0}, {flower, 0}, {F1, 0}, {F2, 0}, {<<>>, 0}]), 2505 M1 = maps:merge(M0, #{0 => 1}), 2506 8 = maps:size(M1), 2507 1 = maps:get(0,M1), 2508 ok. 2509 2510t_erts_internal_hash(_Config) when is_list(_Config) -> 2511 K1 = 0.0, 2512 K2 = 0.0/-1, 2513 M = maps:from_list([{I,I}||I<-lists:seq(1,32)]), 2514 2515 M1 = M#{ K1 => a, K2 => b }, 2516 b = maps:get(K2,M1), 2517 2518 M2 = M#{ K2 => a, K1 => b }, 2519 b = maps:get(K1,M2), 2520 2521 %% test previously faulty hash list optimization 2522 2523 M3 = M#{[0] => a, [0,0] => b, [0,0,0] => c, [0,0,0,0] => d}, 2524 a = maps:get([0],M3), 2525 b = maps:get([0,0],M3), 2526 c = maps:get([0,0,0],M3), 2527 d = maps:get([0,0,0,0],M3), 2528 2529 M4 = M#{{[0]} => a, {[0,0]} => b, {[0,0,0]} => c, {[0,0,0,0]} => d}, 2530 a = maps:get({[0]},M4), 2531 b = maps:get({[0,0]},M4), 2532 c = maps:get({[0,0,0]},M4), 2533 d = maps:get({[0,0,0,0]},M4), 2534 2535 M5 = M3#{[0,0,0] => e, [0,0,0,0] => f, [0,0,0,0,0] => g, 2536 [0,0,0,0,0,0] => h, [0,0,0,0,0,0,0] => i, 2537 [0,0,0,0,0,0,0,0] => j, [0,0,0,0,0,0,0,0,0] => k}, 2538 2539 a = maps:get([0],M5), 2540 b = maps:get([0,0],M5), 2541 e = maps:get([0,0,0],M5), 2542 f = maps:get([0,0,0,0],M5), 2543 g = maps:get([0,0,0,0,0],M5), 2544 h = maps:get([0,0,0,0,0,0],M5), 2545 i = maps:get([0,0,0,0,0,0,0],M5), 2546 j = maps:get([0,0,0,0,0,0,0,0],M5), 2547 k = maps:get([0,0,0,0,0,0,0,0,0],M5), 2548 2549 M6 = M4#{{[0,0,0]} => e, {[0,0,0,0]} => f, {[0,0,0,0,0]} => g, 2550 {[0,0,0,0,0,0]} => h, {[0,0,0,0,0,0,0]} => i, 2551 {[0,0,0,0,0,0,0,0]} => j, {[0,0,0,0,0,0,0,0,0]} => k}, 2552 2553 a = maps:get({[0]},M6), 2554 b = maps:get({[0,0]},M6), 2555 e = maps:get({[0,0,0]},M6), 2556 f = maps:get({[0,0,0,0]},M6), 2557 g = maps:get({[0,0,0,0,0]},M6), 2558 h = maps:get({[0,0,0,0,0,0]},M6), 2559 i = maps:get({[0,0,0,0,0,0,0]},M6), 2560 j = maps:get({[0,0,0,0,0,0,0,0]},M6), 2561 k = maps:get({[0,0,0,0,0,0,0,0,0]},M6), 2562 2563 M7 = maps:merge(M5,M6), 2564 2565 a = maps:get([0],M7), 2566 b = maps:get([0,0],M7), 2567 e = maps:get([0,0,0],M7), 2568 f = maps:get([0,0,0,0],M7), 2569 g = maps:get([0,0,0,0,0],M7), 2570 h = maps:get([0,0,0,0,0,0],M7), 2571 i = maps:get([0,0,0,0,0,0,0],M7), 2572 j = maps:get([0,0,0,0,0,0,0,0],M7), 2573 k = maps:get([0,0,0,0,0,0,0,0,0],M7), 2574 a = maps:get({[0]},M7), 2575 b = maps:get({[0,0]},M7), 2576 e = maps:get({[0,0,0]},M7), 2577 f = maps:get({[0,0,0,0]},M7), 2578 g = maps:get({[0,0,0,0,0]},M7), 2579 h = maps:get({[0,0,0,0,0,0]},M7), 2580 i = maps:get({[0,0,0,0,0,0,0]},M7), 2581 j = maps:get({[0,0,0,0,0,0,0,0]},M7), 2582 k = maps:get({[0,0,0,0,0,0,0,0,0]},M7), 2583 ok. 2584 2585t_pdict(_Config) -> 2586 2587 put(#{ a => b, b => a},#{ c => d}), 2588 put(get(#{ a => b, b => a}),1), 2589 1 = get(#{ c => d}), 2590 #{ c := d } = get(#{ a => b, b => a}). 2591 2592t_ets(_Config) -> 2593 2594 Tid = ets:new(map_table,[]), 2595 2596 [ets:insert(Tid,{maps:from_list([{I,-I}]),I}) || I <- lists:seq(1,100)], 2597 2598 2599 [{#{ 2 := -2},2}] = ets:lookup(Tid,#{ 2 => -2 }), 2600 2601 %% Test equal 2602 [3,4] = lists:sort( 2603 ets:select(Tid,[{{'$1','$2'}, 2604 [{'or',{'==','$1',#{ 3 => -3 }}, 2605 {'==','$1',#{ 4 => -4 }}}], 2606 ['$2']}])), 2607 %% Test match 2608 [30,50] = lists:sort( 2609 ets:select(Tid, 2610 [{{#{ 30 => -30}, '$1'},[],['$1']}, 2611 {{#{ 50 => -50}, '$1'},[],['$1']}] 2612 )), 2613 2614 ets:insert(Tid,{#{ a => b, b => c, c => a},transitivity}), 2615 2616 %% Test equal with map of different size 2617 [] = ets:select(Tid,[{{'$1','_'},[{'==','$1',#{ b => c }}],['$_']}]), 2618 2619 %% Test match with map of different size 2620 %[{#{ a := b },_}] = ets:select(Tid,[{{#{ b => c },'_'},[],['$_']}]), 2621 2622 %%% Test match with don't care value 2623 %[{#{ a := b },_}] = ets:select(Tid,[{{#{ b => '_' },'_'},[],['$_']}]), 2624 2625 %% Test is_map bif 2626 101 = length(ets:select(Tid,[{'$1',[{is_map,{element,1,'$1'}}],['$1']}])), 2627 ets:insert(Tid,{not_a_map,2}), 2628 101 = length(ets:select(Tid,[{'$1',[{is_map,{element,1,'$1'}}],['$1']}])), 2629 ets:insert(Tid,{{nope,a,tuple},2}), 2630 101 = length(ets:select(Tid,[{'$1',[{is_map,{element,1,'$1'}}],['$1']}])), 2631 2632 %% Test map_size bif 2633 [3] = ets:select(Tid,[{{'$1','_'},[{'==',{map_size,'$1'},3}], 2634 [{map_size,'$1'}]}]), 2635 2636 true = ets:delete(Tid,#{50 => -50}), 2637 [] = ets:lookup(Tid,#{50 => -50}), 2638 2639 ets:delete(Tid), 2640 ok. 2641 2642t_dets(_Config) -> 2643 ok. 2644 2645t_tracing(_Config) -> 2646 2647 dbg:stop_clear(), 2648 {ok,Tracer} = dbg:tracer(process,{fun trace_collector/2, self()}), 2649 dbg:p(self(),c), 2650 2651 %% Test basic map call 2652 {ok,_} = dbg:tpl(?MODULE,id,x), 2653 #{ a => b }, 2654 {trace,_,call,{?MODULE,id,[#{ a := b }]}} = getmsg(Tracer), 2655 {trace,_,return_from,{?MODULE,id,1},#{ a := b }} = getmsg(Tracer), 2656 dbg:ctpl(), 2657 2658 %% Test equals in argument list 2659 {ok,_} = dbg:tpl(?MODULE,id,[{['$1'],[{'==','$1',#{ b => c}}], 2660 [{return_trace}]}]), 2661 #{ a => b }, 2662 #{ b => c }, 2663 {trace,_,call,{?MODULE,id,[#{ b := c }]}} = getmsg(Tracer), 2664 {trace,_,return_from,{?MODULE,id,1},#{ b := c }} = getmsg(Tracer), 2665 dbg:ctpl(), 2666 2667 %% Test match in head 2668 {ok,_} = dbg:tpl(?MODULE,id,[{[#{b => c}],[],[]}]), 2669 #{ a => b }, 2670 #{ b => c }, 2671 {trace,_,call,{?MODULE,id,[#{ b := c }]}} = getmsg(Tracer), 2672 dbg:ctpl(), 2673 2674 % Test map guard bifs 2675 {ok,_} = dbg:tpl(?MODULE,id,[{['$1'],[{is_map,{element,1,'$1'}}],[]}]), 2676 #{ a => b }, 2677 {1,2}, 2678 {#{ a => b},2}, 2679 {trace,_,call,{?MODULE,id,[{#{ a := b },2}]}} = getmsg(Tracer), 2680 dbg:ctpl(), 2681 2682 {ok,_} = dbg:tpl(?MODULE,id,[{['$1'],[{'==',{map_size,{element,1,'$1'}},2}],[]}]), 2683 #{ a => b }, 2684 {1,2}, 2685 {#{ a => b},2}, 2686 {#{ a => b, b => c},atom}, 2687 {trace,_,call,{?MODULE,id,[{#{ a := b, b := c },atom}]}} = getmsg(Tracer), 2688 dbg:ctpl(), 2689 2690 %MS = dbg:fun2ms(fun([A]) when A == #{ a => b} -> ok end), 2691 %dbg:tpl(?MODULE,id,MS), 2692 %#{ a => b }, 2693 %#{ b => c }, 2694 %{trace,_,call,{?MODULE,id,[#{ a := b }]}} = getmsg(Tracer), 2695 %dbg:ctpl(), 2696 2697 %% Check to extra messages 2698 timeout = getmsg(Tracer), 2699 2700 dbg:stop_clear(), 2701 ok. 2702 2703getmsg(_Tracer) -> 2704 receive V -> V after 100 -> timeout end. 2705 2706trace_collector(Msg,Parent) -> 2707 io:format("~p~n",[Msg]), 2708 Parent ! Msg, 2709 Parent. 2710 2711t_has_map_fields(Config) when is_list(Config) -> 2712 true = has_map_fields_1(#{one=>1}), 2713 true = has_map_fields_1(#{one=>1,two=>2}), 2714 false = has_map_fields_1(#{two=>2}), 2715 false = has_map_fields_1(#{}), 2716 2717 true = has_map_fields_2(#{c=>1,b=>2,a=>3}), 2718 true = has_map_fields_2(#{c=>1,b=>2,a=>3,x=>42}), 2719 false = has_map_fields_2(#{b=>2,c=>1}), 2720 false = has_map_fields_2(#{x=>y}), 2721 false = has_map_fields_2(#{}), 2722 2723 true = has_map_fields_3(#{c=>1,b=>2,a=>3}), 2724 true = has_map_fields_3(#{c=>1,b=>2,a=>3,[]=>42}), 2725 true = has_map_fields_3(#{b=>2,a=>3,[]=>42,42.0=>43}), 2726 true = has_map_fields_3(#{a=>3,[]=>42,42.0=>43}), 2727 true = has_map_fields_3(#{[]=>42,42.0=>43}), 2728 false = has_map_fields_3(#{b=>2,c=>1}), 2729 false = has_map_fields_3(#{[]=>y}), 2730 false = has_map_fields_3(#{42.0=>x,a=>99}), 2731 false = has_map_fields_3(#{}), 2732 2733 ok. 2734 2735has_map_fields_1(#{one:=_}) -> true; 2736has_map_fields_1(#{}) -> false. 2737 2738has_map_fields_2(#{a:=_,b:=_,c:=_}) -> true; 2739has_map_fields_2(#{}) -> false. 2740 2741has_map_fields_3(#{a:=_,b:=_}) -> true; 2742has_map_fields_3(#{[]:=_,42.0:=_}) -> true; 2743has_map_fields_3(#{}) -> false. 2744 2745y_regs(Config) when is_list(Config) -> 2746 Val = [length(Config)], 2747 Map0 = y_regs_update(#{}, Val), 2748 Map2 = y_regs_update(Map0, Val), 2749 2750 Map3 = maps:from_list([{I,I*I} || I <- lists:seq(1, 100)]), 2751 Map4 = y_regs_update(Map3, Val), 2752 2753 true = is_map(Map2) andalso is_map(Map4), 2754 2755 ok. 2756 2757y_regs_update(Map0, Val0) -> 2758 Val1 = {t,Val0}, 2759 K1 = {key,1}, 2760 K2 = {key,2}, 2761 Map1 = Map0#{K1=>K1, 2762 a=>Val0,b=>Val0,c=>Val0,d=>Val0,e=>Val0, 2763 f=>Val0,g=>Val0,h=>Val0,i=>Val0,j=>Val0, 2764 k=>Val0,l=>Val0,m=>Val0,n=>Val0,o=>Val0, 2765 p=>Val0,q=>Val0,r=>Val0,s=>Val0,t=>Val0, 2766 u=>Val0,v=>Val0,w=>Val0,x=>Val0,y=>Val0, 2767 z=>Val0, 2768 aa=>Val0,ab=>Val0,ac=>Val0,ad=>Val0,ae=>Val0, 2769 af=>Val0,ag=>Val0,ah=>Val0,ai=>Val0,aj=>Val0, 2770 ak=>Val0,al=>Val0,am=>Val0,an=>Val0,ao=>Val0, 2771 ap=>Val0,aq=>Val0,ar=>Val0,as=>Val0,at=>Val0, 2772 au=>Val0,av=>Val0,aw=>Val0,ax=>Val0,ay=>Val0, 2773 az=>Val0, 2774 K2=>[a,b,c]}, 2775 Map2 = Map1#{K1=>K1, 2776 a:=Val1,b:=Val1,c:=Val1,d:=Val1,e:=Val1, 2777 f:=Val1,g:=Val1,h:=Val1,i:=Val1,j:=Val1, 2778 k:=Val1,l:=Val1,m:=Val1,n:=Val1,o:=Val1, 2779 p:=Val1,q:=Val1,r:=Val1,s:=Val1,t:=Val1, 2780 u:=Val1,v:=Val1,w:=Val1,x:=Val1,y:=Val1, 2781 z:=Val1, 2782 aa:=Val1,ab:=Val1,ac:=Val1,ad:=Val1,ae:=Val1, 2783 af:=Val1,ag:=Val1,ah:=Val1,ai:=Val1,aj:=Val1, 2784 ak:=Val1,al:=Val1,am:=Val1,an:=Val1,ao:=Val1, 2785 ap:=Val1,aq:=Val1,ar:=Val1,as:=Val1,at:=Val1, 2786 au:=Val1,av:=Val1,aw:=Val1,ax:=Val1,ay:=Val1, 2787 az:=Val1, 2788 K2=>[a,b,c]}, 2789 2790 %% Traverse the maps to validate them. 2791 _ = erlang:phash2({Map1,Map2}, 100000), 2792 2793 _ = {K1,K2,Val0,Val1}, %Force use of Y registers. 2794 Map2. 2795 2796do_badmap(Test) -> 2797 Terms = [Test,fun erlang:abs/1,make_ref(),self(),0.0/-1, 2798 <<0:1024>>,<<1:1>>,<<>>,<<1,2,3>>, 2799 [],{a,b,c},[a,b],atom,10.0,42,(1 bsl 65) + 3], 2800 [Test(T) || T <- Terms]. 2801