Current section
Files
Jump to
Current section
Files
lib/cache.ex
defmodule Kdb.Cache do
@table_name __MODULE__
@unit_time :millisecond
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(database :: atom(), bucket_name :: atom(), key :: binary(), ttl :: integer()) ::
boolean()
def put(dbname, bucket, id, ttl) do
timestamp = now() + ttl
:ets.insert(@table_name, {{id, bucket, dbname}, timestamp})
end
@spec delete(atom(), atom(), binary()) :: true
def delete(dbname, bucket, id) do
:ets.delete(@table_name, {id, bucket, dbname})
end
defp now do
:os.system_time(@unit_time)
end
@spec cleanup(older_than :: integer()) :: integer()
def cleanup(older_than) do
n =
:ets.foldl(
fn
{key = {id, bucket_name, dbname}, readed_at}, acc when readed_at < older_than ->
kdb = Kdb.get(dbname)
tid = Map.get(kdb.buckets, bucket_name).t
:ets.delete(tid, id)
:ets.delete(@table_name, key)
acc + 1
_, acc ->
acc
end,
0,
@table_name
)
n
end
@callback init() :: :ignore
@callback put(database :: atom(), bucket :: atom(), id :: binary(), ttl :: integer()) ::
boolean()
@callback delete(database :: atom(), bucket :: atom(), id :: binary()) :: any()
@callback cleanup(older_than :: integer()) :: integer()
end