Packages
An in-memory caching library using tuples as the core data type, with support for structs, key/value pairs, queues, and stacks. Includes experimental distributed caching.
Current section
Files
Jump to
Current section
Files
lib/storage/storage_api.ex
defmodule SuperCache.Storage do
@moduledoc false
require Logger
alias SuperCache.{EtsHolder, Config}
alias :ets, as: Ets
@doc """
Create all Ets tables.
"""
@spec start(pos_integer) :: any
def start(num) when is_integer(num) and (num > 0) do
for order <- 0..num-1 do
prefix = Config.get_config(:table_prefix)
name = String.to_atom("#{prefix}_#{order}")
EtsHolder.new_table(EtsHolder, name)
end
end
@doc """
Delete all Ets tables.
"""
@spec stop(pos_integer) :: any
def stop(num) when is_integer(num) and (num > 0) do
Logger.debug(fn -> "super_cache, storage, stop storage workers (#{num})" end)
for order <- 0..num-1 do
prefix = Config.get_config(:table_prefix)
name = String.to_atom("#{prefix}_#{order}")
Logger.debug(fn -> "super_cache, storage, remove storage #{inspect name}" end)
EtsHolder.delete_table(EtsHolder, name)
end
end
@doc """
Puts data(tuple) to a GenServer which has id is partition.
"""
@spec put([tuple] | tuple, atom | :ets.tid()) :: true
def put(term, partition) do
Ets.insert(partition, term)
end
@doc """
Gets data from GenServer (identity by partition) with key.
"""
@spec get(any, atom | :ets.tid()) :: [tuple]
def get(key, partition) do
Ets.lookup(partition, key)
end
@doc """
Update data in a partition.
element_spec is a tuple with 2 elements {pos_integer, any} or list of 2 element tuple.
If key is not existed, default value will be used.
Update element just works with set/ordered_set type.
"""
def update_element(key, partition, element_spec, default) do
Ets.update_element(partition, key, element_spec, default)
end
@doc """
Update data in a partition.
element_spec is a tuple with 2 elements {pos_integer, any} or list of 2 element tuple.
Update element just works with set/ordered_set type.
"""
def update_element(key, partition, element_spec) do
Ets.update_element(partition, key, element_spec)
end
@doc """
Update counter in a partition.
counter_spec is a tuple {pos, increment} or {pos, increment, threshold, setvalue}.
Update counter just works with set/ordered_set type.
"""
def update_counter(key, partition, counter_spec) do
Ets.update_counter(partition, key, counter_spec)
end
@doc """
Update counter in a partition.
counter_spec is a tuple {pos, increment} or {pos, increment, threshold, setvalue}.
If key is not existed, default value will be used.
Update counter just works with set/ordered_set type.
"""
def update_counter(key, partition, counter_spec, default) do
Ets.update_counter(partition, key, counter_spec, default)
end
@doc """
Gets data by pattern matching in a partition.
"""
@spec get_by_match(atom | tuple, atom | :ets.tid()) :: [list]
def get_by_match(pattern, partition) do
Logger.debug(fn -> "super_cache, storage, pattern for match: #{inspect pattern}, partition: #{partition}" end)
Ets.match(partition, pattern)
end
@doc """
Gets data by match object in a partition.
"""
@spec get_by_match_object(atom | tuple, atom | :ets.tid()) :: [tuple]
def get_by_match_object(pattern, partition) do
Logger.debug(fn -> "super_cache, storage, pattern for match: #{inspect pattern}, partition: #{partition}" end)
Ets.match_object(partition, pattern)
end
@doc """
Scans all object in a partition.
"""
@spec scan((any, any -> any), any, atom | :ets.tid()) :: any
def scan(fun, acc, partition) do
Ets.foldl(fun, acc, partition)
end
@doc """
Deletes data in a partition.
"""
@spec delete(any, atom | :ets.tid()) :: true
def delete(key, partition) do
Ets.delete(partition, key)
end
@doc """
Deletes all data in a partition.
"""
@spec delete_all(atom | :ets.tid()) :: true
def delete_all(partition) do
Ets.delete_all_objects(partition)
end
@doc """
Deletes by pattern in a partition.
"""
@spec delete_match(atom | tuple, atom | :ets.tid()) :: true
def delete_match(pattern, partition) do
Logger.debug(fn -> "super_cache, storage, pattern for match: #{inspect pattern}, partition: #{partition}" end)
Ets.match_delete(partition, pattern)
end
@doc """
Takes data in a partition.
Data is removed after taking.
"""
@spec take(any, atom | :ets.tid()) :: [tuple]
def take(key, partition) do
Ets.take(partition, key)
end
@doc """
Get size in partition.
"""
def stats(partition) do
counter = Ets.info(partition, :size)
{partition, counter}
end
end