Skip to content

Commit 81330c3

Browse files
committed
WIP (Further optimization by macthing on index limit at the tail)
1 parent f22686b commit 81330c3

File tree

1 file changed

+61
-13
lines changed

1 file changed

+61
-13
lines changed

lib/msgpax/unpacker.ex

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ defmodule Msgpax.Unpacker do
2828
unpack(buffer, [], options, [:root], 0, 1)
2929
end
3030

31-
defp unpack(<<buffer::bits>>, result, options, [kind, index, length | outer], count, count) do
32-
unpack(buffer, build_collection(result, count, kind), options, outer, index + 1, length)
33-
end
34-
3531
primitives = %{
3632
[quote(do: [0xC0])] => quote(do: nil),
3733
[quote(do: [0xC2])] => quote(do: false),
@@ -61,7 +57,13 @@ defmodule Msgpax.Unpacker do
6157
}
6258
for {formats, value} <- primitives, format <- formats do
6359
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, count) when index < count do
64-
unpack(rest, [unquote(value) | result], options, outer, index + 1, count)
60+
result = [unquote(value) | result]
61+
case index + 1 do
62+
^count ->
63+
unpack_continue(rest, options, outer, result, count)
64+
index ->
65+
unpack(rest, result, options, outer, index, count)
66+
end
6567
end
6668
end
6769

@@ -72,7 +74,19 @@ defmodule Msgpax.Unpacker do
7274
]
7375
for format <- lists do
7476
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, count) when index < count do
75-
unpack(rest, result, options, [:list, index, count | outer], 0, unquote(quote(do: length)))
77+
case unquote(quote(do: length)) do
78+
0 ->
79+
result = [[] | result]
80+
case index + 1 do
81+
^count ->
82+
unpack_continue(rest, options, outer, result, count)
83+
index ->
84+
unpack(rest, result, options, outer, index, count)
85+
end
86+
87+
length ->
88+
unpack(rest, result, options, [:list, index, count | outer], 0, length)
89+
end
7690
end
7791
end
7892

@@ -83,7 +97,19 @@ defmodule Msgpax.Unpacker do
8397
]
8498
for format <- maps do
8599
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, count) when index < count do
86-
unpack(rest, result, options, [:map, index, count | outer], 0, unquote(quote(do: length)) * 2)
100+
case unquote(quote(do: length)) do
101+
0 ->
102+
result = [%{} | result]
103+
case index + 1 do
104+
^count ->
105+
unpack_continue(rest, options, outer, result, count)
106+
index ->
107+
unpack(rest, result, options, outer, index, count)
108+
end
109+
110+
length ->
111+
unpack(rest, result, options, [:map, index, count | outer], 0, length * 2)
112+
end
87113
end
88114
end
89115

@@ -95,7 +121,13 @@ defmodule Msgpax.Unpacker do
95121
for format <- binaries do
96122
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, count) when index < count do
97123
value = unpack_binary(unquote(quote(do: content)), options)
98-
unpack(rest, [value | result], options, outer, index + 1, count)
124+
result = [value | result]
125+
case index + 1 do
126+
^count ->
127+
unpack_continue(rest, options, outer, result, count)
128+
index ->
129+
unpack(rest, result, options, outer, index, count)
130+
end
99131
end
100132
end
101133

@@ -112,14 +144,16 @@ defmodule Msgpax.Unpacker do
112144
for format <- extensions do
113145
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, count) when index < count do
114146
value = unpack_ext(unquote(quote(do: type)), unquote(quote(do: content)), options)
115-
unpack(rest, [value | result], options, outer, index + 1, count)
147+
result = [value | result]
148+
case index + 1 do
149+
^count ->
150+
unpack_continue(rest, options, outer, result, count)
151+
index ->
152+
unpack(rest, result, options, outer, index, count)
153+
end
116154
end
117155
end
118156

119-
defp unpack(<<buffer::bits>>, [value], _options, [:root], count, count) do
120-
{value, buffer}
121-
end
122-
123157
defp unpack(<<byte, _::bits>>, _result, _options, _outer, _index, _count) do
124158
throw {:bad_format, byte}
125159
end
@@ -128,6 +162,20 @@ defmodule Msgpax.Unpacker do
128162
throw :incomplete
129163
end
130164

165+
defp unpack_continue(<<buffer::bits>>, options, [kind, index, length | outer], result, count) do
166+
result = build_collection(result, count, kind)
167+
case index + 1 do
168+
^length ->
169+
unpack_continue(buffer, options, outer, result, length)
170+
index ->
171+
unpack(buffer, result, options, outer, index, length)
172+
end
173+
end
174+
175+
defp unpack_continue(<<buffer::bits>>, _options, [:root], [value], 1) do
176+
{value, buffer}
177+
end
178+
131179
defp unpack_binary(content, %{binary: true}) do
132180
Msgpax.Bin.new(content)
133181
end

0 commit comments

Comments
 (0)