-module(packkit@internal@fse). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/packkit/internal/fse.gleam"). -export([predefined_literal_length/0, predefined_match_length/0, predefined_offset/0, predefined_literal_length_log/0, predefined_match_length_log/0, predefined_offset_log/0, high_bit_position/1, build_state_table/2, predefined_literal_length_table/0, predefined_match_length_table/0, predefined_offset_table/0, state_count/1, read_backward_bits/2, read_backward_bits_padded/2, new_backward_reader/1, ll_base/1, ll_extra_bits/1, ml_base/1, ml_extra_bits/1, decode_state/3, distribution_total/1]). -export_type([state_entry/0, backward_reader/0, fse_error/0]). -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). -type state_entry() :: {state_entry, integer(), integer(), integer()}. -opaque backward_reader() :: {backward_reader, integer(), integer(), list(integer())}. -type fse_error() :: fse_empty_bitstream | fse_truncated. -file("src/packkit/internal/fse.gleam", 18). ?DOC(false). -spec predefined_literal_length() -> list(integer()). predefined_literal_length() -> [4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, -1, -1, -1, -1]. -file("src/packkit/internal/fse.gleam", 28). ?DOC(false). -spec predefined_match_length() -> list(integer()). predefined_match_length() -> [1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1]. -file("src/packkit/internal/fse.gleam", 37). ?DOC(false). -spec predefined_offset() -> list(integer()). predefined_offset() -> [1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1]. -file("src/packkit/internal/fse.gleam", 45). ?DOC(false). -spec predefined_literal_length_log() -> integer(). predefined_literal_length_log() -> 6. -file("src/packkit/internal/fse.gleam", 49). ?DOC(false). -spec predefined_match_length_log() -> integer(). predefined_match_length_log() -> 6. -file("src/packkit/internal/fse.gleam", 53). ?DOC(false). -spec predefined_offset_log() -> integer(). predefined_offset_log() -> 5. -file("src/packkit/internal/fse.gleam", 92). ?DOC(false). -spec real_counts( list(integer()), gleam@dict:dict(integer(), integer()), integer() ) -> gleam@dict:dict(integer(), integer()). real_counts(Normalized, Acc, Symbol) -> case Normalized of [] -> Acc; [N | Rest] -> Count = case N of -1 -> 1; V -> V end, real_counts(Rest, gleam@dict:insert(Acc, Symbol, Count), Symbol + 1) end. -file("src/packkit/internal/fse.gleam", 132). ?DOC(false). -spec place_less_probable( list(integer()), integer(), integer(), gleam@dict:dict(integer(), integer()) ) -> {gleam@dict:dict(integer(), integer()), integer()}. place_less_probable(Normalized, Symbol, High_cursor, Acc) -> case Normalized of [] -> {Acc, High_cursor}; [N | Rest] -> case N of -1 -> place_less_probable( Rest, Symbol + 1, High_cursor - 1, gleam@dict:insert(Acc, High_cursor, Symbol) ); _ -> place_less_probable(Rest, Symbol + 1, High_cursor, Acc) end end. -file("src/packkit/internal/fse.gleam", 229). ?DOC(false). -spec advance_cursor(integer(), integer(), integer(), integer()) -> integer(). advance_cursor(Cursor, Mask, Step, High_threshold) -> Next = erlang:'band'(Cursor + Step, Mask), case Next > High_threshold of true -> advance_cursor(Next, Mask, Step, High_threshold); false -> Next end. -file("src/packkit/internal/fse.gleam", 202). ?DOC(false). -spec place_one_symbol( integer(), integer(), integer(), gleam@dict:dict(integer(), integer()), integer(), integer(), integer() ) -> {integer(), gleam@dict:dict(integer(), integer())}. place_one_symbol( Symbol, Remaining, Cursor, Positions, Mask, Step, High_threshold ) -> case Remaining of 0 -> {Cursor, Positions}; _ -> Positions@1 = gleam@dict:insert(Positions, Cursor, Symbol), New_cursor = advance_cursor(Cursor, Mask, Step, High_threshold), place_one_symbol( Symbol, Remaining - 1, New_cursor, Positions@1, Mask, Step, High_threshold ) end. -file("src/packkit/internal/fse.gleam", 154). ?DOC(false). -spec place_normal( list(integer()), integer(), integer(), gleam@dict:dict(integer(), integer()), integer(), integer(), integer() ) -> gleam@dict:dict(integer(), integer()). place_normal(Normalized, Cursor, Symbol, Positions, Mask, Step, High_threshold) -> case Normalized of [] -> Positions; [N | Rest] -> case N of V when V =< 0 -> place_normal( Rest, Cursor, Symbol + 1, Positions, Mask, Step, High_threshold ); V@1 -> {New_cursor, Positions@1} = place_one_symbol( Symbol, V@1, Cursor, Positions, Mask, Step, High_threshold ), place_normal( Rest, New_cursor, Symbol + 1, Positions@1, Mask, Step, High_threshold ) end end. -file("src/packkit/internal/fse.gleam", 112). ?DOC(false). -spec assign_positions(list(integer()), integer(), integer()) -> gleam@dict:dict(integer(), integer()). assign_positions(Normalized, _, Table_size) -> Mask = Table_size - 1, Step = (erlang:'bsr'(Table_size, 1) + erlang:'bsr'(Table_size, 3)) + 3, High_threshold = Table_size - 1, {Positions, Next_high} = place_less_probable( Normalized, 0, High_threshold, maps:new() ), place_normal(Normalized, 0, 0, Positions, Mask, Step, Next_high). -file("src/packkit/internal/fse.gleam", 287). ?DOC(false). -spec high_bit_position(integer()) -> integer(). high_bit_position(Value) -> case Value of N when N =< 1 -> 0; _ -> 1 + high_bit_position(erlang:'bsr'(Value, 1)) end. -file("src/packkit/internal/fse.gleam", 237). ?DOC(false). -spec build_entries( gleam@dict:dict(integer(), integer()), gleam@dict:dict(integer(), integer()), gleam@dict:dict(integer(), integer()), integer(), integer(), integer(), gleam@dict:dict(integer(), state_entry()) ) -> gleam@dict:dict(integer(), state_entry()). build_entries( Positions, Counts, Symbol_next, Accuracy_log, Table_size, State_index, Acc ) -> case State_index >= Table_size of true -> Acc; false -> Symbol = case gleam_stdlib:map_get(Positions, State_index) of {ok, V} -> V; {error, _} -> 0 end, Count = case gleam_stdlib:map_get(Counts, Symbol) of {ok, V@1} -> V@1; {error, _} -> 1 end, Next_value = case gleam_stdlib:map_get(Symbol_next, Symbol) of {ok, V@2} -> V@2; {error, _} -> Count end, Nb_bits = Accuracy_log - high_bit_position(Next_value), Baseline = erlang:'bsl'(Next_value, Nb_bits) - Table_size, Entry = {state_entry, Symbol, Nb_bits, Baseline}, build_entries( Positions, Counts, gleam@dict:insert(Symbol_next, Symbol, Next_value + 1), Accuracy_log, Table_size, State_index + 1, gleam@dict:insert(Acc, State_index, Entry) ) end. -file("src/packkit/internal/fse.gleam", 71). ?DOC(false). -spec build_state_table(list(integer()), integer()) -> gleam@dict:dict(integer(), state_entry()). build_state_table(Normalized, Accuracy_log) -> Table_size = erlang:'bsl'(1, Accuracy_log), Position_dict = assign_positions(Normalized, Accuracy_log, Table_size), Symbol_counts = real_counts(Normalized, maps:new(), 0), build_entries( Position_dict, Symbol_counts, maps:new(), Accuracy_log, Table_size, 0, maps:new() ). -file("src/packkit/internal/fse.gleam", 295). ?DOC(false). -spec predefined_literal_length_table() -> gleam@dict:dict(integer(), state_entry()). predefined_literal_length_table() -> build_state_table( predefined_literal_length(), predefined_literal_length_log() ). -file("src/packkit/internal/fse.gleam", 303). ?DOC(false). -spec predefined_match_length_table() -> gleam@dict:dict(integer(), state_entry()). predefined_match_length_table() -> build_state_table(predefined_match_length(), predefined_match_length_log()). -file("src/packkit/internal/fse.gleam", 308). ?DOC(false). -spec predefined_offset_table() -> gleam@dict:dict(integer(), state_entry()). predefined_offset_table() -> build_state_table(predefined_offset(), predefined_offset_log()). -file("src/packkit/internal/fse.gleam", 313). ?DOC(false). -spec state_count(integer()) -> integer(). state_count(Accuracy_log) -> erlang:'bsl'(1, Accuracy_log). -file("src/packkit/internal/fse.gleam", 412). ?DOC(false). -spec refill_backward(backward_reader(), integer()) -> backward_reader(). refill_backward(Reader, Needed) -> case erlang:element(3, Reader) >= Needed of true -> Reader; false -> case erlang:element(4, Reader) of [Byte | Rest] -> New_buffer = erlang:'bor'( erlang:'bsl'(erlang:element(2, Reader), 8), Byte ), refill_backward( {backward_reader, New_buffer, erlang:element(3, Reader) + 8, Rest}, Needed ); [] -> Reader end end. -file("src/packkit/internal/fse.gleam", 357). ?DOC(false). -spec read_backward_bits(backward_reader(), integer()) -> {ok, {integer(), backward_reader()}} | {error, fse_error()}. read_backward_bits(Reader, Count) -> Reader@1 = refill_backward(Reader, Count), case erlang:element(3, Reader@1) >= Count of false -> {error, fse_truncated}; true -> Shift = erlang:element(3, Reader@1) - Count, Mask = erlang:'bsl'(1, Count) - 1, Value = erlang:'band'( erlang:'bsr'(erlang:element(2, Reader@1), Shift), Mask ), Leftover_mask = erlang:'bsl'(1, Shift) - 1, {ok, {Value, {backward_reader, erlang:'band'( erlang:element(2, Reader@1), Leftover_mask ), Shift, erlang:element(4, Reader@1)}}} end. -file("src/packkit/internal/fse.gleam", 387). ?DOC(false). -spec read_backward_bits_padded(backward_reader(), integer()) -> {ok, {integer(), backward_reader()}} | {error, fse_error()}. read_backward_bits_padded(Reader, Count) -> Reader@1 = refill_backward(Reader, Count), case erlang:element(3, Reader@1) >= Count of true -> read_backward_bits(Reader@1, Count); false -> case erlang:element(3, Reader@1) of 0 -> {error, fse_empty_bitstream}; Available -> Pad = Count - Available, Mask = erlang:'bsl'(1, Available) - 1, Value = begin _pipe = erlang:'band'(erlang:element(2, Reader@1), Mask), erlang:'bsl'(_pipe, Pad) end, {ok, {Value, {backward_reader, 0, 0, erlang:element(4, Reader@1)}}} end end. -file("src/packkit/internal/fse.gleam", 434). ?DOC(false). -spec bytes_to_reverse_list(bitstring(), list(integer())) -> list(integer()). bytes_to_reverse_list(Bytes, Acc) -> case Bytes of <> -> bytes_to_reverse_list(Rest, [B | Acc]); _ -> Acc end. -file("src/packkit/internal/fse.gleam", 329). ?DOC(false). -spec new_backward_reader(bitstring()) -> {ok, backward_reader()} | {error, fse_error()}. new_backward_reader(Bytes) -> Bytes_rev = bytes_to_reverse_list(Bytes, []), case Bytes_rev of [] -> {error, fse_empty_bitstream}; [Last | Rest] -> High = high_bit_position(Last), case Last =:= 0 of true -> {error, fse_empty_bitstream}; false -> Bits_below = High, Mask = erlang:'bsl'(1, Bits_below) - 1, Initial = erlang:'band'(Last, Mask), {ok, {backward_reader, Initial, Bits_below, Rest}} end end. -file("src/packkit/internal/fse.gleam", 447). ?DOC(false). -spec ll_base(integer()) -> integer(). ll_base(Code) -> case Code of N when (N >= 0) andalso (N =< 15) -> N; 16 -> 16; 17 -> 18; 18 -> 20; 19 -> 22; 20 -> 24; 21 -> 28; 22 -> 32; 23 -> 40; 24 -> 48; 25 -> 64; 26 -> 128; 27 -> 256; 28 -> 512; 29 -> 1024; 30 -> 2048; 31 -> 4096; 32 -> 8192; 33 -> 16384; 34 -> 32768; 35 -> 65536; _ -> 0 end. -file("src/packkit/internal/fse.gleam", 475). ?DOC(false). -spec ll_extra_bits(integer()) -> integer(). ll_extra_bits(Code) -> case Code of N when (N >= 0) andalso (N =< 15) -> 0; N@1 when (N@1 >= 16) andalso (N@1 =< 19) -> 1; N@2 when (N@2 >= 20) andalso (N@2 =< 21) -> 2; N@3 when (N@3 >= 22) andalso (N@3 =< 23) -> 3; 24 -> 4; 25 -> 6; 26 -> 7; 27 -> 8; 28 -> 9; 29 -> 10; 30 -> 11; 31 -> 12; 32 -> 13; 33 -> 14; 34 -> 15; 35 -> 16; _ -> 0 end. -file("src/packkit/internal/fse.gleam", 501). ?DOC(false). -spec ml_base(integer()) -> integer(). ml_base(Code) -> case Code of N when (N >= 0) andalso (N =< 31) -> 3 + N; 32 -> 35; 33 -> 37; 34 -> 39; 35 -> 41; 36 -> 43; 37 -> 47; 38 -> 51; 39 -> 59; 40 -> 67; 41 -> 83; 42 -> 99; 43 -> 131; 44 -> 259; 45 -> 515; 46 -> 1027; 47 -> 2051; 48 -> 4099; 49 -> 8195; 50 -> 16387; 51 -> 32771; 52 -> 65539; _ -> 3 end. -file("src/packkit/internal/fse.gleam", 530). ?DOC(false). -spec ml_extra_bits(integer()) -> integer(). ml_extra_bits(Code) -> case Code of N when (N >= 0) andalso (N =< 31) -> 0; N@1 when (N@1 >= 32) andalso (N@1 =< 35) -> 1; N@2 when (N@2 >= 36) andalso (N@2 =< 37) -> 2; N@3 when (N@3 >= 38) andalso (N@3 =< 39) -> 3; 40 -> 4; 41 -> 4; 42 -> 5; 43 -> 7; 44 -> 8; 45 -> 9; 46 -> 10; 47 -> 11; 48 -> 12; 49 -> 13; 50 -> 14; 51 -> 15; 52 -> 16; _ -> 0 end. -file("src/packkit/internal/fse.gleam", 556). ?DOC(false). -spec decode_state( gleam@dict:dict(integer(), state_entry()), integer(), backward_reader() ) -> {ok, {integer(), integer(), backward_reader()}} | {error, fse_error()}. decode_state(Table, State, Reader) -> Entry = case gleam_stdlib:map_get(Table, State) of {ok, E} -> E; {error, _} -> {state_entry, 0, 0, 0} end, gleam@result:'try'( read_backward_bits(Reader, erlang:element(3, Entry)), fun(_use0) -> {Extra, Reader@1} = _use0, {ok, {erlang:element(2, Entry), erlang:element(4, Entry) + Extra, Reader@1}} end ). -file("src/packkit/internal/fse.gleam", 571). ?DOC(false). -spec distribution_total(list(integer())) -> integer(). distribution_total(Normalized) -> gleam@list:fold(Normalized, 0, fun(Acc, N) -> case N of -1 -> Acc + 1; V -> Acc + V end end).