Packages

Read only data store for Elixir: fast, concurrently, for large data & hot reloadable.

Current section

Files

Jump to
mnemonics lib mnemonics.ex
Raw

lib/mnemonics.ex

defmodule Mnemonics do
@moduledoc """
Read only data store for Elixir: fast, concurrently, for large data & hot reloadable.
iex> Example.create_example_ets :mnemonics_example
iex> defmodule MnemonicsExample do
iex> use Mnemonics, table_name: :mnemonics_example
iex> end
iex> MnemonicsExample.load 1
:ok
iex> :ets.lookup MnemonicsExample.table_name(1), 1
[{1, %Mnemonics.Example{id: 1, name: "1"}}]
"""
defmacro __using__(table_name: table_name) do
quote location: :keep do
@doc """
Load an ETS table from file.
opts:
* `timeout:` Timeout ms (default 5000).
"""
@spec load(pos_integer, keyword) :: :ok | {:error, term}
def load(version, opts \\ []),
do:
GenServer.call(
Mnemonics.Repo,
{:load_table, __MODULE__, unquote(table_name), version},
opts[:timeout] || 5000
)
@doc """
Take version snapshot of the table.
"""
@spec snap(Mnemonics.Snap.t()) :: Mnemonics.Snap.t()
def snap(snap), do: snap(snap, table().version)
@spec snap(Mnemonics.Snap.t(), pos_integer) :: Mnemonics.Snap.t()
def snap(snap, version), do: Mnemonics.Snap.snap(snap, unquote(table_name), version)
@doc """
Get a table of some version.
"""
@spec table :: Mnemonics.Memory.t()
def table do
memories =
for memory <- Mnemonics.Repo.tables(),
memory.table_name == unquote(table_name),
do: memory
Enum.max_by(memories, & &1.version)
end
@spec table(Mnemonics.Snap.t()) :: Mnemonics.Memory.t()
def table(%Mnemonics.Snap{} = snap), do: table(snap.versions[unquote(table_name)])
@spec table(pos_integer) :: Mnemonics.Memory.t()
def table(version) do
memory =
Enum.find(Mnemonics.Repo.tables(), fn memory ->
memory.table_name == unquote(table_name) and memory.version == version
end)
memory
end
@doc """
Get a table reference of some version.
"""
@spec table_name :: :ets.tid()
def table_name, do: table().tid
@spec table_name(Mnemonics.Snap.t()) :: :ets.tid()
def table_name(%Mnemonics.Snap{} = snap), do: table(snap).tid
@spec table_name(pos_integer) :: :ets.tid()
def table_name(version), do: table(version).tid
end
end
end