Packages

Guava like bloom filter library

Current section

Files

Jump to
gloomex lib bitarray.ex
Raw

lib/bitarray.ex

defmodule Gloomex.BitArray do
@moduledoc """
This module implements a bit array using Erlang's `:array` module.
"""
use Bitwise
@type t :: :array.array(term)
@long_size 64
# long only shifts by last 6 bits (0x3F)
@long_shift_mask 0x3F
@long_addressable_bits 6
@doc """
Returns a new bitarray of size `n`.
"""
@spec new(pos_integer) :: t
def new(n) do
:array.new(ceil(n / @long_size), default: 0)
end
@doc """
Updates a bitarray
"""
@spec set(t(), non_neg_integer) :: t()
def set(a, i) do
if get(a, i) do
a
else
long_index = i >>> @long_addressable_bits
mask = 1 <<< (i &&& @long_shift_mask)
{_set, a} = try_exchange(a, long_index, mask)
a
end
end
defp try_exchange(a, long_index, mask) do
old_value = :array.get(long_index, a)
new_value = old_value ||| mask
if old_value == new_value do
{false, a}
else
{true, :array.set(long_index, new_value, a)}
end
end
@doc """
Returns `true` if the bitarray has the `i`th bit set,
otherwise returns `false`.
"""
@spec get(t(), non_neg_integer) :: boolean
def get(a, i) do
case :array.get(i >>> @long_addressable_bits, a) &&& 1 <<< (i &&& @long_shift_mask) do
0 -> false
_ -> true
end
end
@doc """
Amount of bits used by the atomic array
"""
def bit_size(a) do
:array.size(a) * @long_size
end
end