Skip to content

Commit 615eebc

Browse files
authored
Merge pull request #29 from uwiger/uw-maps
Uw maps
2 parents 4381bd9 + fa67ab7 commit 615eebc

File tree

4 files changed

+58
-3
lines changed

4 files changed

+58
-3
lines changed

README.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ in the global Erlang term ordering. The number type is divided into several
7272
subtypes, to facilitate a reasonably efficient representation:
7373

7474

75-
<table border="1"><tr align="left"><th>Type</th><th>Description</th><th>Tag</th></tr><tr><td>negbig</td><td>Negative bignum</td><td>8</td></tr><tr><td>neg4</td><td>Negative 31-bit integer</td><td>9</td></tr><tr><td>pos4</td><td>Positive 31-bit integer</td><td>10</td></tr><tr><td>posbig</td><td>Positive bignum</td><td>11</td></tr><tr><td>atom</td><td>Obj of type atom()</td><td>12</td></tr><tr><td>reference</td><td>Obj of type reference()</td><td>13</td></tr><tr><td>port</td><td>Obj of type port()</td><td>14</td></tr><tr><td>pid</td><td>Obj of type pid()</td><td>15</td></tr><tr><td>tuple</td><td>Obj of type tuple()</td><td>16</td></tr><tr><td>list</td><td>Obj of type list()</td><td>17</td></tr><tr><td>binary</td><td>Obj of type binary()</td><td>18</td></tr><tr><td>bin_tail</td><td>Improper-tail marker followed by binary or bitstring</td><td>19</td></tr>
75+
<table border="1"><tr align="left"><th>Type</th><th>Description</th><th>Tag</th></tr><tr><td>negbig</td><td>Negative bignum</td><td>8</td></tr><tr><td>neg4</td><td>Negative 31-bit integer</td><td>9</td></tr><tr><td>pos4</td><td>Positive 31-bit integer</td><td>10</td></tr><tr><td>posbig</td><td>Positive bignum</td><td>11</td></tr><tr><td>atom</td><td>Obj of type atom()</td><td>12</td></tr><tr><td>reference</td><td>Obj of type reference()</td><td>13</td></tr><tr><td>port</td><td>Obj of type port()</td><td>14</td></tr><tr><td>pid</td><td>Obj of type pid()</td><td>15</td></tr><tr><td>tuple</td><td>Obj of type tuple()</td><td>16</td></tr><tr><td>list</td><td>Obj of type map()</td><td>17, 1</td></tr><tr><td>list</td><td>Obj of type list()</td><td>17</td></tr><tr><td>binary</td><td>Obj of type binary()</td><td>18</td></tr><tr><td>bin_tail</td><td>Improper-tail marker followed by binary or bitstring</td><td>19</td></tr>
7676
</table>
7777

7878

@@ -289,9 +289,18 @@ encode_pid(P) ->
289289
```
290290

291291

292+
## 2.11 Maps ##
293+
294+
The encoding of maps is currently experimental.
295+
Maps sort between tuples and lists. Since the smallest list is represented
296+
by `<<17, 2>>`, maps encoding starts with `<<17, 1>>` (introducing a new tag
297+
would break backwards compatibility), followed by the size of the map (4 bytes),
298+
and each Key-Value pair in the map.
299+
292300

293301
## Modules ##
294302

295303

296304
<table width="100%" border="0" summary="list of modules">
297-
<tr><td><a href="http://github.com/uwiger/sext/blob/master/doc/sext.md" class="module">sext</a></td></tr></table>
305+
<tr><td><a href="http://github.com/uwiger/sext/blob/uw-maps/doc/sext.md" class="module">sext</a></td></tr></table>
306+

doc/README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ in the global Erlang term ordering. The number type is divided into several
7474
subtypes, to facilitate a reasonably efficient representation:
7575

7676

77-
<table border="1"><tr align="left"><th>Type</th><th>Description</th><th>Tag</th></tr><tr><td>negbig</td><td>Negative bignum</td><td>8</td></tr><tr><td>neg4</td><td>Negative 31-bit integer</td><td>9</td></tr><tr><td>pos4</td><td>Positive 31-bit integer</td><td>10</td></tr><tr><td>posbig</td><td>Positive bignum</td><td>11</td></tr><tr><td>atom</td><td>Obj of type atom()</td><td>12</td></tr><tr><td>reference</td><td>Obj of type reference()</td><td>13</td></tr><tr><td>port</td><td>Obj of type port()</td><td>14</td></tr><tr><td>pid</td><td>Obj of type pid()</td><td>15</td></tr><tr><td>tuple</td><td>Obj of type tuple()</td><td>16</td></tr><tr><td>list</td><td>Obj of type list()</td><td>17</td></tr><tr><td>binary</td><td>Obj of type binary()</td><td>18</td></tr><tr><td>bin_tail</td><td>Improper-tail marker followed by binary or bitstring</td><td>19</td></tr>
77+
<table border="1"><tr align="left"><th>Type</th><th>Description</th><th>Tag</th></tr><tr><td>negbig</td><td>Negative bignum</td><td>8</td></tr><tr><td>neg4</td><td>Negative 31-bit integer</td><td>9</td></tr><tr><td>pos4</td><td>Positive 31-bit integer</td><td>10</td></tr><tr><td>posbig</td><td>Positive bignum</td><td>11</td></tr><tr><td>atom</td><td>Obj of type atom()</td><td>12</td></tr><tr><td>reference</td><td>Obj of type reference()</td><td>13</td></tr><tr><td>port</td><td>Obj of type port()</td><td>14</td></tr><tr><td>pid</td><td>Obj of type pid()</td><td>15</td></tr><tr><td>tuple</td><td>Obj of type tuple()</td><td>16</td></tr><tr><td>list</td><td>Obj of type map()</td><td>17, 1</td></tr><tr><td>list</td><td>Obj of type list()</td><td>17</td></tr><tr><td>binary</td><td>Obj of type binary()</td><td>18</td></tr><tr><td>bin_tail</td><td>Improper-tail marker followed by binary or bitstring</td><td>19</td></tr>
7878
</table>
7979

8080

@@ -291,6 +291,14 @@ encode_pid(P) ->
291291
```
292292

293293

294+
## 2.11 Maps ##
295+
296+
The encoding of maps is currently experimental.
297+
Maps sort between tuples and lists. Since the smallest list is represented
298+
by `<<17, 2>>`, maps encoding starts with `<<17, 1>>` (introducing a new tag
299+
would break backwards compatibility), followed by the size of the map (4 bytes),
300+
and each Key-Value pair in the map.
301+
294302

295303
## Modules ##
296304

doc/overview.edoc

+14
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ subtypes, to facilitate a reasonably efficient representation:
114114
<td>Obj of type tuple()</td>
115115
<td>16</td>
116116
</tr>
117+
<tr>
118+
<td>list</td>
119+
<td>Obj of type map()</td>
120+
<td>17, 1</td>
121+
</tr>
117122
<tr>
118123
<td>list</td>
119124
<td>Obj of type list()</td>
@@ -308,4 +313,13 @@ The encoding of ports is perhaps best described by the code:
308313
NameEnc = encode_bin_elems(Name),
309314
<<?pid, NameEnc/binary, Rest/binary>>.]]></pre>
310315

316+
<h2>2.11 Maps</h2>
317+
318+
The encoding of maps is currently experimental.
319+
320+
Maps sort between tuples and lists. Since the smallest list is represented
321+
by `<<17, 2>>', maps encoding starts with `<<17, 1>>' (introducing a new tag
322+
would break backwards compatibility), followed by the size of the map (4 bytes),
323+
and each Key-Value pair in the map.
324+
311325
@end

src/sext.erl

+24
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ encode(X) -> encode(X, false).
9090
%% Use only as transition support. This function will be deprecated in time.
9191
%% @end
9292
encode(X, Legacy) when is_tuple(X) -> encode_tuple(X, Legacy);
93+
encode(X, Legacy) when is_map(X) -> encode_map(X, Legacy);
9394
encode(X, Legacy) when is_list(X) -> encode_list(X, Legacy);
9495
encode(X, _) when is_pid(X) -> encode_pid(X);
9596
encode(X, _) when is_port(X) -> encode_port(X);
@@ -274,6 +275,15 @@ encode_list(L, Legacy) ->
274275
prefix_list(L) ->
275276
prefix_list_elems(L, <<?list>>).
276277

278+
encode_map(M, Legacy) ->
279+
Sz = map_size(M),
280+
maps:fold(
281+
fun(K,V,Acc) ->
282+
<<Acc/binary, (encode(K, Legacy))/binary,
283+
(encode(V, Legacy))/binary>>
284+
end, <<?list, 1:8, Sz:32>>, M).
285+
286+
277287
encode_binary(B) ->
278288
Enc = encode_bin_elems(B),
279289
<<?binary:8, Enc/binary>>.
@@ -650,6 +660,9 @@ decode_next(<<?pid, Rest/binary>>) -> decode_pid(Rest);
650660
decode_next(<<?port, Rest/binary>>) -> decode_port(Rest);
651661
decode_next(<<?reference,Rest/binary>>) -> decode_ref(Rest);
652662
decode_next(<<?tuple,Sz:32, Rest/binary>>) -> decode_tuple(Sz,Rest);
663+
%% decode_next(<<?nil, Rest/binary>>) -> {[], Rest};
664+
%% decode_next(<<?old_list, Rest/binary>>) -> decode_list(Rest);
665+
decode_next(<<?list, 1, Rest/binary>>) -> decode_map(Rest);
653666
decode_next(<<?list, Rest/binary>>) -> decode_list(Rest);
654667
decode_next(<<?negbig, Rest/binary>>) -> decode_neg_big(Rest);
655668
decode_next(<<?posbig, Rest/binary>>) -> decode_pos_big(Rest);
@@ -753,6 +766,17 @@ partial_decode_list(<<X,_/binary>> = Next, Acc) when ?is_sext(X) ->
753766
partial_decode_list(Rest, Acc) ->
754767
{partial, lists:reverse(Acc) ++ '_', Rest}.
755768

769+
decode_map(<<Sz:32, Rest/binary>>) ->
770+
decode_map(Sz, Rest, #{}).
771+
772+
decode_map(0, Rest, M) ->
773+
{M, Rest};
774+
decode_map(N, Bin, M) ->
775+
{K, Bin1} = decode_next(Bin),
776+
{V, Bin2} = decode_next(Bin1),
777+
decode_map(N-1, Bin2, maps:put(K, V, M)).
778+
779+
756780
decode_list(Elems) ->
757781
decode_list(Elems, []).
758782

0 commit comments

Comments
 (0)