   @doc """
   Creates a new empty dict.
   """
-  @spec new :: Dict.t
+  @spec new :: Dict.t()
   def new do
     %HashDict{}
   end


  defp do_update(node, key, initial, fun, hash) do
    index = key_mask(hash)
    case elem(node, index) do
      [] ->
        {put_elem(node, index, [key | initial.()]), 1}
      [^key | value] ->
        {put_elem(node, index, [key | fun.(value)]), 0}
      [k | v] ->
        n = put_elem(@node_template, key_mask(key_shift(hash)), [key | initial.()])
        {put_elem(node, index, {k, v, n}), 1}
      {^key, value, n} ->
        {put_elem(node, index, {key, fun.(value), n}), 0}
      {k, v, n} ->
        {n, counter} = do_update(n, key, initial, fun, key_shift(hash))
        {put_elem(node, index, {k, v, n}), counter}


  defp do_fetch(node, key, hash) do
    index = key_mask(hash)

    case elem(node, index) do
      [^key | v] -> {:ok, v}
      {^key, v, _} -> {:ok, v}
      {_, _, n} -> do_fetch(n, key, key_shift(hash))
      _ -> :error
    end
  end

  defp do_put(node, key, value, hash) do
    index = key_mask(hash)

    case elem(node, index) do
      [] ->
        {put_elem(node, index, [key | value]), 1}

      [^key | _] ->
        {put_elem(node, index, [key | value]), 0}

      [k | v] ->
        n = put_elem(@node_template, key_mask(key_shift(hash)), [key | value])
        {put_elem(node, index, {k, v, n}), 1}

      {^key, _, n} ->
        {put_elem(node, index, {key, value, n}), 0}

      {k, v, n} ->
        {n, counter} = do_put(n, key, value, key_shift(hash))
        {put_elem(node, index, {k, v, n}), counter}
