<commit_before>-module(clj_hash_collision).

-include("clojerl.hrl").

-export([ get_entry/3
        , create_entry/4
        , without_entry/3
        ]).

-spec get_entry(map(), integer(), any()) -> ?NIL | {any(), any()}.
get_entry(Map, Hash, Key) ->
  case maps:get(Hash, Map, ?NIL) of
    ?NIL -> ?NIL;
    {K, V} -> {K, V};
    KVs -> find_entry(KVs, Key)
  end.

-spec find_entry([{any(), any()}], any()) -> ?NIL | {any(), any()}.
find_entry([], _) ->
  ?NIL;
find_entry([{K, V} | Rest], Key) ->
  case clj_rt:equiv(K, Key) of
    true  -> {K, V};
    false -> find_entry(Rest, Key)
  end.

-spec create_entry(map(), integer(), any(), any()) ->
  {any(), any()} | [{any(), any()}].
create_entry(Map, Hash, Key, Value) ->
  case maps:get(Hash, Map, ?NIL) of
    ?NIL -> {Key, Value};
    {K, V} ->
      case clj_rt:equiv(Key, K) of
        true  -> {K, Value};
        false -> [{K, V}, {Key, Value}]
      end;
    KVs ->
      assoc_entry(KVs, Key, Value, [])
  end.

-spec assoc_entry([{any(), any()}], any(), any(), [{any(), any()}]) ->
  [{any(), any()}].
assoc_entry([], Key, Value, Acc) ->
  [{Key, Value} | Acc];
assoc_entry([{K, V} | Rest], Key, Value, Acc) ->
  case clj_rt:equiv(K, Key) of
    true  -> Acc ++ [{K, Value} | Rest];
    false -> assoc_entry(Rest, Key, Value, [{K, V} | Acc])
  end.

-spec without_entry(map(), integer(), any()) -> map().
without_entry(Map, Hash, Key) ->
  case maps:get(Hash, Map, ?NIL) of
    ?NIL   -> Map;
    {_, _} -> maps:remove(Hash, Map);
    KVs0   ->
      KVs1 = remove_entry(KVs0, Key, []),
      Map#{Hash => KVs1}
  end.

-spec remove_entry([{any(), any()}], integer(), any()) -> [{any(), any()}].
remove_entry([], _Key, Acc) ->
  Acc;
remove_entry([{K, V} | Rest], Key, Acc) ->
  case clj_rt:equiv(K, Key) of
    true  -> Acc ++ Rest;
    false -> remove_entry(Rest, Key, [{K, V} | Acc])
  end.<commit_msg>[#557] Remove collision entry when empty<commit_after>-module(clj_hash_collision).

-include("clojerl.hrl").

-export([ get_entry/3
        , create_entry/4
        , without_entry/3
        ]).

-spec get_entry(map(), integer(), any()) -> ?NIL | {any(), any()}.
get_entry(Map, Hash, Key) ->
  case maps:get(Hash, Map, ?NIL) of
    ?NIL -> ?NIL;
    {K, V} -> {K, V};
    KVs -> find_entry(KVs, Key)
  end.

-spec find_entry([{any(), any()}], any()) -> ?NIL | {any(), any()}.
find_entry([], _) ->
  ?NIL;
find_entry([{K, V} | Rest], Key) ->
  case clj_rt:equiv(K, Key) of
    true  -> {K, V};
    false -> find_entry(Rest, Key)
  end.

-spec create_entry(map(), integer(), any(), any()) ->
  {any(), any()} | [{any(), any()}].
create_entry(Map, Hash, Key, Value) ->
  case maps:get(Hash, Map, ?NIL) of
    ?NIL -> {Key, Value};
    {K, V} ->
      case clj_rt:equiv(Key, K) of
        true  -> {K, Value};
        false -> [{K, V}, {Key, Value}]
      end;
    KVs ->
      assoc_entry(KVs, Key, Value, [])
  end.

-spec assoc_entry([{any(), any()}], any(), any(), [{any(), any()}]) ->
  [{any(), any()}].
assoc_entry([], Key, Value, Acc) ->
  [{Key, Value} | Acc];
assoc_entry([{K, V} | Rest], Key, Value, Acc) ->
  case clj_rt:equiv(K, Key) of
    true  -> Acc ++ [{K, Value} | Rest];
    false -> assoc_entry(Rest, Key, Value, [{K, V} | Acc])
  end.

-spec without_entry(map(), integer(), any()) -> map().
without_entry(Map, Hash, Key) ->
  case maps:get(Hash, Map, ?NIL) of
    ?NIL   -> Map;
    {_, _} -> maps:remove(Hash, Map);
    KVs0   ->
      case remove_entry(KVs0, Key, []) of
        []   -> maps:remove(Hash, Map);
        KVs1 -> Map#{Hash => KVs1}
      end
  end.

-spec remove_entry([{any(), any()}], integer(), any()) -> [{any(), any()}].
remove_entry([], _Key, Acc) ->
  Acc;
remove_entry([{K, V} | Rest], Key, Acc) ->
  case clj_rt:equiv(K, Key) of
    true  -> Acc ++ Rest;
    false -> remove_entry(Rest, Key, [{K, V} | Acc])
  end.
{'fraction_non_alphanumeric': 0.24510060099294487, 'fraction_numerical': 0.004442121766396656, 'mean_word_length': 2.839518555667001, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7034343', 'n_tokens_mistral': 1552, 'n_tokens_neox': 1544, 'n_words': 387}