A simple ETS-based key-value store with the ability to watch changes.
Usage
You can start the bucket process under a supervisor:
children = [
{Rkv, bucket: :my_bucket}
]
Supervisor.start_link(children, strategy: :one_for_one)Or start it directly:
Rkv.start_link(bucket: :my_bucket)Then you can use the bucket:
Rkv.put(:my_bucket, "foo", "bar")
Rkv.get(:my_bucket, "foo")
#=> "bar"Buckets
A bucket's data lives only as long as the process that owns it. If that process restarts, the bucket comes back empty, so treat a bucket as a cache rather than a store.
Bucket names are global to the application. Pick one unlikely to clash if you
use Rkv inside a library.
Watching changes
A notification tells you that a key changed, not what it changed to, so read the key when one arrives. A key that changes often may change again before you read it, so you see the latest value rather than every step along the way.
Watching a key and its bucket at the same time delivers two messages, one for each subscription.
Summary
Functions
Returns all key/value pairs.
Returns all active buckets.
Returns a specification to start this module under a supervisor.
Returns the :ets_options a bucket is created with by default.
Deletes the key from the bucket.
Returns the underlying ETS table.
Returns true if the key exists in the bucket, otherwise false.
Fetches the value for the key.
Returns the value by key.
Puts the key into the bucket.
Puts the key into the bucket only if the key does not exist.
Starts the Rkv bucket.
Unsubscribes the caller from all updates.
Unsubscribes the caller from key updates.
Subscribes the caller to all updates.
Subscribes the caller to key updates.
Types
Functions
Returns all key/value pairs.
The order is not defined.
Examples
iex> Rkv.put(:my_bucket, "foo", "bar")
iex> Rkv.all(:my_bucket)
[{"foo", "bar"}]
@spec buckets() :: [bucket()]
Returns all active buckets.
@spec child_spec([option()]) :: Supervisor.child_spec()
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec default_ets_options() :: list()
Returns the :ets_options a bucket is created with by default.
Add to it to keep the defaults:
{Rkv, bucket: :my_bucket, ets_options: Rkv.default_ets_options() ++ [:compressed]}
Deletes the key from the bucket.
Examples
iex> Rkv.put(:my_bucket, "foo", "bar")
iex> Rkv.delete(:my_bucket, "foo")
:ok
iex> Rkv.get(:my_bucket, "foo")
nil
@spec ets(bucket()) :: :ets.table()
Returns the underlying ETS table.
Returns true if the key exists in the bucket, otherwise false.
Examples
iex> Rkv.put(:my_bucket, "foo", "bar")
iex> Rkv.exists?(:my_bucket, "foo")
true
iex> Rkv.exists?(:my_bucket, "missing")
false
Fetches the value for the key.
Returns {:ok, value} if the key exists, otherwise :error.
Examples
iex> Rkv.put(:my_bucket, "foo", "bar")
iex> Rkv.fetch(:my_bucket, "foo")
{:ok, "bar"}
iex> Rkv.fetch(:my_bucket, "missing")
:error
Returns the value by key.
Returns default if the key does not exist.
Examples
iex> Rkv.put(:my_bucket, "foo", "bar")
iex> Rkv.get(:my_bucket, "foo")
"bar"
iex> Rkv.get(:my_bucket, "missing")
nil
iex> Rkv.get(:my_bucket, "missing", :default)
:default
Puts the key into the bucket.
If the key already exists, the value is updated.
Examples
iex> Rkv.put(:my_bucket, "foo", "bar")
:ok
Puts the key into the bucket only if the key does not exist.
Returns :ok if successful, or {:error, :already_exists} if the key already exists.
Examples
iex> Rkv.put_new(:my_bucket, "foo", "bar")
:ok
iex> Rkv.put_new(:my_bucket, "foo", "baz")
{:error, :already_exists}
@spec start_link([option()]) :: GenServer.on_start()
Starts the Rkv bucket.
The opts keyword list must contain the :bucket key, which is used to
register the process.
Options
:bucket- the name of the bucket (required):ets_options- options for:ets.new/2(optional). Replacesdefault_ets_options/0instead of merging with it. The table must be:setor:ordered_set, and:public.
@spec unwatch_all(bucket()) :: :ok
Unsubscribes the caller from all updates.
Examples
iex> Rkv.unwatch_all(:my_bucket)
:ok
Unsubscribes the caller from key updates.
Examples
iex> Rkv.unwatch_key(:my_bucket, "foo")
:ok
Subscribes the caller to all updates.
The caller will receive:
{:updated, bucket, key}when any key is updated{:deleted, bucket, key}when any key is deleted
Examples
iex> Rkv.watch_all(:my_bucket)
:ok
Subscribes the caller to key updates.
The caller will receive:
{:updated, bucket, key}when the key is updated{:deleted, bucket, key}when the key is deleted
Examples
iex> Rkv.watch_key(:my_bucket, "foo")
:ok