defmodule Kdb.Registry do @table __MODULE__ @key :kdb def child_spec(_) do %{ id: __MODULE__, start: {__MODULE__, :init, []}, type: :worker, restart: :permanent, shutdown: 500 } end def init do if :ets.info(@table) == :undefined do :ets.new(@table, [ :set, :public, :named_table, read_concurrency: true, write_concurrency: true ]) end :ignore end # {:db, name} # {:bucket, dbname, bucket_name} # {:batch, name} # {:cache, name} def register(%Kdb{name: name} = kdb) do # :ets.insert(@table, {name, kdb}) :persistent_term.put({@key, name}, kdb) # Enum.each(buckets, fn bucket -> # :ets.insert(@table, {{:db, name}, bucket}) # end) end def register(%Kdb.Bucket{name: name, dbname: dbname} = bucket) do kdb = get_db(dbname) :persistent_term.put({@key, dbname}, %{ kdb | buckets: Map.put(kdb.buckets, name, bucket) }) end def register(%Kdb.Batch{} = batch) do :ets.insert(@table, {{:batch, batch.name}, batch}) end def register(%Kdb.Cache{} = cache) do :ets.insert(@table, {{:cache, cache.name}, cache}) end def unregister(%Kdb{name: name}) do :persistent_term.erase({@key, name}) end def unregister(%Kdb.Bucket{name: name, dbname: dbname}) do kdb = get_db(dbname) :persistent_term.put({@key, dbname}, %{kdb | buckets: Map.delete(kdb.buckets, name)}) end def unregister(%Kdb.Batch{} = batch) do :ets.delete(@table, {:batch, batch.name}) end def unregister(%Kdb.Cache{} = cache) do :ets.delete(@table, {:cache, cache.name}) end def unregister(name) do :ets.delete(@table, name) end def get_db(name) do :persistent_term.get({@key, name}, nil) end def get_bucket(dbname, bucket_name) do case :persistent_term.get({@key, dbname}, nil) do nil -> nil %Kdb{buckets: buckets} -> Map.get(buckets, bucket_name) end end def get_batch(name) do case :ets.lookup(@table, {:batch, name}) do [{_id, object}] -> object [] -> nil end end def get_cache(name) do case :ets.lookup(@table, {:cache, name}) do [{_id, object}] -> object [] -> nil end end end