-module(packkit@internal@xxh32).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/packkit/internal/xxh32.gleam").
-export([digest/2]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-file("src/packkit/internal/xxh32.gleam", 73).
?DOC(false).
-spec add32(integer(), integer()) -> integer().
add32(A, B) ->
erlang:'band'(A + B, 16#FFFFFFFF).
-file("src/packkit/internal/xxh32.gleam", 77).
?DOC(false).
-spec shr32(integer(), integer()) -> integer().
shr32(Value, N) ->
erlang:'bsr'(erlang:'band'(Value, 16#FFFFFFFF), N).
-file("src/packkit/internal/xxh32.gleam", 81).
?DOC(false).
-spec rotl32(integer(), integer()) -> integer().
rotl32(Value, By_bits) ->
Masked = erlang:'band'(Value, 16#FFFFFFFF),
erlang:'band'(
erlang:'bor'(
erlang:'bsl'(Masked, By_bits),
erlang:'bsr'(Masked, 32 - By_bits)
),
16#FFFFFFFF
).
-file("src/packkit/internal/xxh32.gleam", 92).
?DOC(false).
-spec mul32(integer(), integer()) -> integer().
mul32(A, B) ->
A_low = erlang:'band'(A, 16#FFFF),
A_high = erlang:'bsr'(erlang:'band'(A, 16#FFFFFFFF), 16),
B_low = erlang:'band'(B, 16#FFFF),
B_high = erlang:'bsr'(erlang:'band'(B, 16#FFFFFFFF), 16),
Low_low = A_low * B_low,
Cross = erlang:'band'((A_low * B_high) + (A_high * B_low), 16#FFFF),
erlang:'band'(Low_low + erlang:'bsl'(Cross, 16), 16#FFFFFFFF).
-file("src/packkit/internal/xxh32.gleam", 64).
?DOC(false).
-spec avalanche(integer()) -> integer().
avalanche(State) ->
Xored_high = erlang:'bxor'(State, shr32(State, 15)),
Multiplied_by_p2 = mul32(Xored_high, 16#85EBCA77),
Xored_mid = erlang:'bxor'(Multiplied_by_p2, shr32(Multiplied_by_p2, 13)),
Multiplied_by_p3 = mul32(Xored_mid, 16#C2B2AE3D),
erlang:'bxor'(Multiplied_by_p3, shr32(Multiplied_by_p3, 16)).
-file("src/packkit/internal/xxh32.gleam", 50).
?DOC(false).
-spec mix_tail(bitstring(), integer()) -> integer().
mix_tail(Bytes, H) ->
case Bytes of
<<Lane:32/little, Rest/binary>> ->
Next = mul32(
rotl32(add32(H, mul32(Lane, 16#C2B2AE3D)), 17),
16#27D4EB2F
),
mix_tail(Rest, Next);
<<Byte, Rest@1/binary>> ->
Next@1 = mul32(
rotl32(add32(H, mul32(Byte, 16#165667B1)), 11),
16#9E3779B1
),
mix_tail(Rest@1, Next@1);
_ ->
H
end.
-file("src/packkit/internal/xxh32.gleam", 38).
?DOC(false).
-spec digest(bitstring(), integer()) -> integer().
digest(Bytes, Seed) ->
Total = erlang:byte_size(Bytes),
{Slice, Slice_len} = case gleam_stdlib:bit_array_slice(Bytes, 0, 15) of
{ok, Prefix} when Total >= 16 ->
{Prefix, 15};
_ ->
{Bytes, Total}
end,
Initial = add32(Seed, 16#165667B1),
With_length = add32(Initial, Slice_len),
After_tail = mix_tail(Slice, With_length),
avalanche(After_tail).