Skip to content

Commit 97ee6b0

Browse files
authored
Optimize valid32? and hex_valid32? (#14436)
1 parent 7c9e350 commit 97ee6b0

File tree

1 file changed

+81
-73
lines changed

1 file changed

+81
-73
lines changed

Diff for: lib/elixir/lib/base.ex

+81-73
Original file line numberDiff line numberDiff line change
@@ -1268,14 +1268,10 @@ defmodule Base do
12681268
pad? = Keyword.get(opts, :padding, true)
12691269

12701270
case Keyword.get(opts, :case, :upper) do
1271-
:upper -> validate32upper!(string, pad?)
1272-
:lower -> validate32lower!(string, pad?)
1273-
:mixed -> validate32mixed!(string, pad?)
1271+
:upper -> validate32upper?(string, pad?)
1272+
:lower -> validate32lower?(string, pad?)
1273+
:mixed -> validate32mixed?(string, pad?)
12741274
end
1275-
1276-
true
1277-
rescue
1278-
ArgumentError -> false
12791275
end
12801276

12811277
@doc """
@@ -1406,14 +1402,10 @@ defmodule Base do
14061402
pad? = Keyword.get(opts, :padding, true)
14071403

14081404
case Keyword.get(opts, :case, :upper) do
1409-
:upper -> validate32hexupper!(string, pad?)
1410-
:lower -> validate32hexlower!(string, pad?)
1411-
:mixed -> validate32hexmixed!(string, pad?)
1405+
:upper -> validate32hexupper?(string, pad?)
1406+
:lower -> validate32hexlower?(string, pad?)
1407+
:mixed -> validate32hexmixed?(string, pad?)
14121408
end
1413-
1414-
true
1415-
rescue
1416-
ArgumentError -> false
14171409
end
14181410

14191411
upper = Enum.with_index(b32_alphabet)
@@ -1428,96 +1420,112 @@ defmodule Base do
14281420
hexmixed: to_mixed_dec.(hexupper)
14291421
] do
14301422
decode_name = :"decode32#{base}!"
1431-
validate_name = :"validate32#{base}!"
1423+
validate_name = :"validate32#{base}?"
1424+
validate_main_name = :"validate_main32#{validate_name}?"
1425+
valid_char_name = :"valid_char32#{base}?"
14321426
{min, decoded} = to_decode_list.(alphabet)
14331427

1434-
defp unquote(validate_name)(<<>>, _pad?) do
1435-
:ok
1428+
defp unquote(validate_main_name)(<<>>), do: true
1429+
1430+
defp unquote(validate_main_name)(
1431+
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, c8::8, rest::binary>>
1432+
) do
1433+
unquote(valid_char_name)(c1) and
1434+
unquote(valid_char_name)(c2) and
1435+
unquote(valid_char_name)(c3) and
1436+
unquote(valid_char_name)(c4) and
1437+
unquote(valid_char_name)(c5) and
1438+
unquote(valid_char_name)(c6) and
1439+
unquote(valid_char_name)(c7) and
1440+
unquote(valid_char_name)(c8) and
1441+
unquote(validate_main_name)(rest)
14361442
end
14371443

1444+
defp unquote(validate_name)(<<>>, _pad?), do: true
1445+
14381446
defp unquote(validate_name)(string, pad?) do
14391447
segs = div(byte_size(string) + 7, 8) - 1
14401448
<<main::size(^segs)-binary-unit(64), rest::binary>> = string
1441-
1442-
for <<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, c8::8 <- main>> do
1443-
unquote(decode_name)(c1)
1444-
unquote(decode_name)(c2)
1445-
unquote(decode_name)(c3)
1446-
unquote(decode_name)(c4)
1447-
unquote(decode_name)(c5)
1448-
unquote(decode_name)(c6)
1449-
unquote(decode_name)(c7)
1450-
unquote(decode_name)(c8)
1451-
end
1449+
main_valid? = unquote(validate_main_name)(main)
14521450

14531451
case rest do
1452+
_ when not main_valid? ->
1453+
false
1454+
14541455
<<c1::8, c2::8, ?=, ?=, ?=, ?=, ?=, ?=>> ->
1455-
unquote(decode_name)(c1)
1456-
unquote(decode_name)(c2)
1456+
unquote(valid_char_name)(c1) and
1457+
unquote(valid_char_name)(c2)
14571458

14581459
<<c1::8, c2::8, c3::8, c4::8, ?=, ?=, ?=, ?=>> ->
1459-
unquote(decode_name)(c1)
1460-
unquote(decode_name)(c2)
1461-
unquote(decode_name)(c3)
1462-
unquote(decode_name)(c4)
1460+
unquote(valid_char_name)(c1) and
1461+
unquote(valid_char_name)(c2) and
1462+
unquote(valid_char_name)(c3) and
1463+
unquote(valid_char_name)(c4)
14631464

14641465
<<c1::8, c2::8, c3::8, c4::8, c5::8, ?=, ?=, ?=>> ->
1465-
unquote(decode_name)(c1)
1466-
unquote(decode_name)(c2)
1467-
unquote(decode_name)(c3)
1468-
unquote(decode_name)(c4)
1469-
unquote(decode_name)(c5)
1466+
unquote(valid_char_name)(c1) and
1467+
unquote(valid_char_name)(c2) and
1468+
unquote(valid_char_name)(c3) and
1469+
unquote(valid_char_name)(c4) and
1470+
unquote(valid_char_name)(c5)
14701471

14711472
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, ?=>> ->
1472-
unquote(decode_name)(c1)
1473-
unquote(decode_name)(c2)
1474-
unquote(decode_name)(c3)
1475-
unquote(decode_name)(c4)
1476-
unquote(decode_name)(c5)
1477-
unquote(decode_name)(c6)
1478-
unquote(decode_name)(c7)
1473+
unquote(valid_char_name)(c1) and
1474+
unquote(valid_char_name)(c2) and
1475+
unquote(valid_char_name)(c3) and
1476+
unquote(valid_char_name)(c4) and
1477+
unquote(valid_char_name)(c5) and
1478+
unquote(valid_char_name)(c6) and
1479+
unquote(valid_char_name)(c7)
14791480

14801481
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, c8::8>> ->
1481-
unquote(decode_name)(c1)
1482-
unquote(decode_name)(c2)
1483-
unquote(decode_name)(c3)
1484-
unquote(decode_name)(c4)
1485-
unquote(decode_name)(c5)
1486-
unquote(decode_name)(c6)
1487-
unquote(decode_name)(c7)
1488-
unquote(decode_name)(c8)
1482+
unquote(valid_char_name)(c1) and
1483+
unquote(valid_char_name)(c2) and
1484+
unquote(valid_char_name)(c3) and
1485+
unquote(valid_char_name)(c4) and
1486+
unquote(valid_char_name)(c5) and
1487+
unquote(valid_char_name)(c6) and
1488+
unquote(valid_char_name)(c7) and
1489+
unquote(valid_char_name)(c8)
14891490

14901491
<<c1::8, c2::8>> when not pad? ->
1491-
unquote(decode_name)(c1)
1492-
unquote(decode_name)(c2)
1492+
unquote(valid_char_name)(c1) and
1493+
unquote(valid_char_name)(c2)
14931494

14941495
<<c1::8, c2::8, c3::8, c4::8>> when not pad? ->
1495-
unquote(decode_name)(c1)
1496-
unquote(decode_name)(c2)
1497-
unquote(decode_name)(c3)
1498-
unquote(decode_name)(c4)
1496+
unquote(valid_char_name)(c1) and
1497+
unquote(valid_char_name)(c2) and
1498+
unquote(valid_char_name)(c3) and
1499+
unquote(valid_char_name)(c4)
14991500

15001501
<<c1::8, c2::8, c3::8, c4::8, c5::8>> when not pad? ->
1501-
unquote(decode_name)(c1)
1502-
unquote(decode_name)(c2)
1503-
unquote(decode_name)(c3)
1504-
unquote(decode_name)(c4)
1505-
unquote(decode_name)(c5)
1502+
unquote(valid_char_name)(c1) and
1503+
unquote(valid_char_name)(c2) and
1504+
unquote(valid_char_name)(c3) and
1505+
unquote(valid_char_name)(c4) and
1506+
unquote(valid_char_name)(c5)
15061507

15071508
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8>> when not pad? ->
1508-
unquote(decode_name)(c1)
1509-
unquote(decode_name)(c2)
1510-
unquote(decode_name)(c3)
1511-
unquote(decode_name)(c4)
1512-
unquote(decode_name)(c5)
1513-
unquote(decode_name)(c6)
1514-
unquote(decode_name)(c7)
1509+
unquote(valid_char_name)(c1) and
1510+
unquote(valid_char_name)(c2) and
1511+
unquote(valid_char_name)(c3) and
1512+
unquote(valid_char_name)(c4) and
1513+
unquote(valid_char_name)(c5) and
1514+
unquote(valid_char_name)(c6) and
1515+
unquote(valid_char_name)(c7)
15151516

15161517
_ ->
1517-
raise ArgumentError, "incorrect padding"
1518+
false
15181519
end
15191520
end
15201521

1522+
@compile {:inline, [{valid_char_name, 1}]}
1523+
defp unquote(valid_char_name)(char)
1524+
when elem({unquote_splicing(decoded)}, char - unquote(min)) != nil,
1525+
do: true
1526+
1527+
defp unquote(valid_char_name)(_char), do: false
1528+
15211529
defp unquote(decode_name)(char) do
15221530
index = char - unquote(min)
15231531

0 commit comments

Comments
 (0)