Skip to main content

src/packkit@internal@xxh32.erl

-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).