bloom_list v1.0.0 BloomList behaviour

A behaviour for implementing bloomfilter module.

The BloomList behaviour is a implementation of the GenServer behaviour which will keep the bloomfilter in state of GenServer. Support some bloomfilter operations:

  • initialize: initial bloomfilter through call init_bloom_data callback
  • add: add key(s) to bloomfilter, and call handle_add_single or handle_add_list
  • delete: only call handle_delete callback rather than delete key from bloomfilter

As we know, bloomfilter only can check one key must not exist, can't ensure one key must exist. So, if return true from bloomfilter through member? function, the BloomList can not return true directly to caller. Thus, BloomList will call handle_maybe_exist callback function to double check if the key really in bloomlist.

An example BloomList module:

defmodule BloomList.Test.BlackList do
  @moduledoc false

  use BloomList

  def start_link(_) do
    BloomList.start_link(__MODULE__, nil,
      name: __MODULE__,
      bloom_options: [capacity: 2000, error: 0.7]
    )
  end

  def reinit(data_list \ []) do
    BloomList.reinit_bloom_data(__MODULE__, data_list)
  end

  def add(key) do
    BloomList.add(__MODULE__, key)
  end

  def add_list(key_list) do
    BloomList.add_list(__MODULE__, key_list)
  end

  def delete(key) do
    BloomList.delete(__MODULE__, key)
  end

  def member?(key) do
    BloomList.member?(__MODULE__, key)
  end

  # callback
  def init_bloom_data(_) do
    data_list = [1, 2, 3, 4, 5]
    {data_list, %{data_list: data_list}}
  end

  # callback
  def handle_reinit_bloom_data([], _) do
    data_list = [2, 3, 4, 5, 6, 7]
    {data_list, %{data_list: data_list}}
  end

  def handle_reinit_bloom_data(data_list, _) do
    {data_list, %{data_list: data_list}}
  end

  # callback
  def handle_maybe_exist(key, %{data_list: data_list}) do
    Enum.member?(data_list, key)
  end

  # callback
  def handle_delete(key, %{data_list: data_list} = state) do
    %{state | data_list: List.delete(data_list, key)}
  end

  # callback
  def handle_add_single(key, %{data_list: data_list} = state) do
    %{state | data_list: [key | data_list]}
  end

  # callback
  def handle_add_list(key_list, %{data_list: data_list} = state) do
    %{state | data_list: key_list ++ data_list}
  end

  # __end_of_module__
end

The example above realized a blacklist module which follows a common pattern.

Link to this section Summary

Functions

Add one key to bloomlist

Add key list to bloomlist

Returns a specification to start this module under a supervisor

Delete key from bloomlist

Check the key if member bloomlist

Reinit bloom data for one bloomlist

Start a bloomlist process linked to the current process

Check the key if member bloomlist using sync mode, it will execute by GenServer process serially

Callbacks

Called when add a key list to bloomlist. The first param is the key list to add, and second one is the custom state

Called when add single key to bloomlist. The first param is the new key to add, and the second one is custom state

Called when delete one key from bloomlist. bloomfilter not supported delete operation this callback just only for the bloomlist to update custom state

Called after get true when check one key if member of bloomfilter. The first param is the key from member?/2 and the second one is the custom state

Called the the bloomlist want to reinit bloomfilter members. The first param for this function is data_list which from the second param of reinit_bloom_data/2

Called when the bloomlist first started. The params for this callback is passed from start_link/3

Link to this section Functions

Link to this function

add(bloom_name, key)
add(atom(), any()) :: :ok

Add one key to bloomlist.

Link to this function

add_list(bloom_name, key_list)
add_list(atom(), [any()]) :: :ok

Add key list to bloomlist.

Link to this function

child_spec(arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

delete(bloom_name, key)
delete(atom(), any()) :: :ok

Delete key from bloomlist.

Link to this function

member?(bloom_name, key)
member?(atom(), any()) :: boolean()

Check the key if member bloomlist.

Link to this function

reinit_bloom_data(bloom_name, data_list)
reinit_bloom_data(atom(), [any()]) :: :ok

Reinit bloom data for one bloomlist.

Link to this function

start_link(mod, args, options)
start_link(module(), any(), Keyword.t()) :: GenServer.on_start()

Start a bloomlist process linked to the current process.

This function is used to start a BloomList process in a supervision tree, which will execute GenServer.start_link/3 to start one real GenServer process.Then the init/1 callback for GenServer in this module will be executed and will keep one bloomfilter data block in its state.

When init/1 callback in this module execute, the init_bloom_data/1 function in callback module will be executed.

Link to this function

sync_member?(bloom_name, key)
sync_member?(atom(), any()) :: boolean()

Check the key if member bloomlist using sync mode, it will execute by GenServer process serially.

Link to this section Callbacks

Link to this callback

handle_add_list(list, any)
handle_add_list([any()], any()) :: any()

Called when add a key list to bloomlist. The first param is the key list to add, and second one is the custom state.

Returning the new custom state.

Link to this callback

handle_add_single(any, any)
handle_add_single(any(), any()) :: any()

Called when add single key to bloomlist. The first param is the new key to add, and the second one is custom state.

Returning the new custom state.

Link to this callback

handle_delete(any, any)
handle_delete(any(), any()) :: any()

Called when delete one key from bloomlist. bloomfilter not supported delete operation this callback just only for the bloomlist to update custom state.

Returning the new custom state.

Link to this callback

handle_maybe_exist(any, any)
handle_maybe_exist(any(), any()) :: boolean()

Called after get true when check one key if member of bloomfilter. The first param is the key from member?/2 and the second one is the custom state.

Returning the boolean value.

Link to this callback

handle_reinit_bloom_data(list, any)
handle_reinit_bloom_data([any()], any()) :: {[any()], any()}

Called the the bloomlist want to reinit bloomfilter members. The first param for this function is data_list which from the second param of reinit_bloom_data/2.

def reinit_bloom_data(bloom_name, data_list) do
  GenServer.call(bloom_name, {:reinit_bloom_data, data_list})
end

As the above function, the data_list will be passed to handle_reinit_bloom_data/2 callback as first param.

The second param is the custom state.

Returning {[any], any} is the new bloomfilter data and new custom state.

Link to this callback

init_bloom_data(any)
init_bloom_data(any()) :: {[any()], any()}

Called when the bloomlist first started. The params for this callback is passed from start_link/3.

Returning {[any], any} the first element is a list, which will be put into bloomfilter as members to inital bloomfilter. And the second element is the custom state.