Probabilistic data structures for Elixir, backed by Erlang's :atomics:
Talan.BloomFilter— membership and cardinality estimationTalan.CountingBloomFilter— membership, frequency, and cardinality estimation with deletionTalan.LinearCounter— cardinality estimationTalan.Stream.uniq/2— bounded-memory stream deduplication
The data structures are mutable and support concurrent access. See the documentation for API details and concurrency semantics.
Talan requires Elixir 1.14 and OTP 25 or later.
def deps do
[
{:talan, "~> 1.0"}
]
endfilter = Talan.BloomFilter.new(1_000)
:ok = Talan.BloomFilter.put(filter, "Barna")
true = Talan.BloomFilter.member?(filter, "Barna")filter = Talan.CountingBloomFilter.new(1_000)
:ok = Talan.CountingBloomFilter.put(filter, "hat")
:ok = Talan.CountingBloomFilter.put(filter, "hat")
2 = Talan.CountingBloomFilter.count(filter, "hat")
:ok = Talan.CountingBloomFilter.delete(filter, "hat")
1 = Talan.CountingBloomFilter.count(filter, "hat")put/2 and delete/2 return {:error, :value_out_of_bounds} when a packed
counter would overflow or underflow.
counter = Talan.LinearCounter.new(10_000)
:ok = Talan.LinearCounter.put(counter, "Barna")
1 = Talan.LinearCounter.cardinality(counter)filter = Talan.BloomFilter.new(10_000, hash_functions: [fn value -> value end])
[1, 2, 3] =
[1, 2, 1, 3]
|> Talan.Stream.uniq(filter)
|> Enum.to_list()Bloom filter false positives can cause Talan.Stream.uniq/2 to reject unique values. The
function mutates its filter, so re-enumerating the stream can produce different results.