Packages

High performance embedded realtime database combining ETS with TTL for caching, RocksDB for persistent parallel writes, and SQLite for secondary indexing and fast lookups

Current section

Files

Jump to
kdb lib cache.ex
Raw

lib/cache.ex

defmodule Kdb.Cache do
@table_name __MODULE__
@unit_time :millisecond
# @cleanup_interval :timer.minutes(15)
@expiration_time :timer.minutes(10)
@dev Mix.env() == :dev
def child_spec(_) do
%{
id: __MODULE__,
start: {__MODULE__, :init, []},
type: :worker,
restart: :permanent,
shutdown: 500
}
end
@doc """
Inicia el módulo de hits creando la tabla ETS.
"""
def init() do
# Crear tabla ETS con nombre del módulo, pública y con concurrencia de lectura
if :ets.whereis(@table_name) == :undefined do
:ets.new(@table_name, [
:set,
:public,
:named_table,
read_concurrency: true,
write_concurrency: true
])
end
:ignore
end
@spec put(atom() | String.t(), binary()) :: boolean()
def put(type, id) do
timestamp = now() + @expiration_time
:ets.insert(@table_name, {{id, type}, timestamp})
end
# @spec retrive_by_type(atom()) :: [binary() | String.t()]
# def retrive_by_type(type) do
# # :ets.fun2ms(fn {{id, 1}, _readed_at} -> id end)
# match_spec =
# [{{{:"$1", type}, :"$2"}, [], [:"$1"]}]
# :ets.select(@table_name, match_spec)
# end
@spec delete(atom(), binary()) :: true
def delete(type, id) do
:ets.delete(@table_name, {id, type})
end
defp now do
:os.system_time(@unit_time)
end
def cleanup(older_than) do
n =
:ets.foldl(
fn {key, readed_at}, acc ->
if readed_at < older_than do
:ets.delete(@table_name, key)
acc + 1
else
acc
end
end,
0,
@table_name
)
@dev and IO.puts("Deleted #{n} entries")
n
end
end