cubdb v0.1.0 CubDB View Source
Top-level module providing the database public API.
CubDB is a pure-Elixir embedded key-value database, designed to be simple to
use. It runs locally, and is backed by a file.
Both keys and values can be any Elixir (or Erlang) term, so no serialization and de-serialization is necessary.
CubDB uses an immutable data structure that ensures robustness to data
corruption. Read and select operations are performed on immutable "snapshots",
so they are always consistent, run concurrently, and do not block write
operations, nor are blocked by them.
Link to this section Summary
Functions
Returns a specification to start this module under a supervisor.
Runs a database compaction.
Deletes the entry associated to key from the database.
Get the value associated to key from the database.
Returns a tuple indicating if key is associated to a value in the database.
Invoked when the server is started. start_link/3 or start/3 will
block until it returns.
Writes an entry in the database, associating key to value.
Selects a range of entries from the database, and optionally performs a pipeline of operations on them.
Returns the number of entries present in the database.
Starts the CubDB database without a link.
Starts the CubDB database process linked to the current process.
Link to this section Functions
child_spec(init_arg) View Source
Returns a specification to start this module under a supervisor.
See Supervisor.
compact(db)
View Source
compact(GenServer.server()) :: :ok | {:error, binary()}
compact(GenServer.server()) :: :ok | {:error, binary()}
Runs a database compaction.
As write operations are performed on a database, its file grows. Occasionally, a compaction operation can be ran to shrink the file to its optimal size. Compaction is ran in the background and does not block operations.
Only one compaction operation can run at any time, therefore if this function
is called when a compaction is already running, it returns {:error, :pending_compaction}.
compaction_file?(file_name) View Source
cubdb_file?(file_name) View Source
db_file?(file_name) View Source
delete(db, key)
View Source
delete(GenServer.server(), any()) :: :ok
delete(GenServer.server(), any()) :: :ok
Deletes the entry associated to key from the database.
If key was not present in the database, nothing is done.
get(db, key)
View Source
get(GenServer.server(), any()) :: any()
get(GenServer.server(), any()) :: any()
Get the value associated to key from the database.
If no value is associated with key, nil is returned.
has_key?(db, key)
View Source
has_key?(GenServer.server(), any()) :: {boolean(), any()}
has_key?(GenServer.server(), any()) :: {boolean(), any()}
Returns a tuple indicating if key is associated to a value in the database.
If key is associated to a value, it returns {true, value}. Otherwise, it
returns {false, nil}
init(data_dir) View Source
Invoked when the server is started. start_link/3 or start/3 will
block until it returns.
init_arg is the argument term (second argument) passed to start_link/3.
Returning {:ok, state} will cause start_link/3 to return
{:ok, pid} and the process to enter its loop.
Returning {:ok, state, timeout} is similar to {:ok, state}
except handle_info(:timeout, state) will be called after timeout
milliseconds if no messages are received within the timeout.
Returning {:ok, state, :hibernate} is similar to {:ok, state}
except the process is hibernated before entering the loop. See
c:handle_call/3 for more information on hibernation.
Returning {:ok, state, {:continue, continue}} is similar to
{:ok, state} except that immediately after entering the loop
the c:handle_continue/2 callback will be invoked with the value
continue as first argument.
Returning :ignore will cause start_link/3 to return :ignore and
the process will exit normally without entering the loop or calling
c:terminate/2. If used when part of a supervision tree the parent
supervisor will not fail to start nor immediately try to restart the
GenServer. The remainder of the supervision tree will be started
and so the GenServer should not be required by other processes.
It can be started later with Supervisor.restart_child/2 as the child
specification is saved in the parent supervisor. The main use cases for
this are:
- The
GenServeris disabled by configuration but might be enabled later. - An error occurred and it will be handled by a different mechanism than the
Supervisor. Likely this approach involves callingSupervisor.restart_child/2after a delay to attempt a restart.
Returning {:stop, reason} will cause start_link/3 to return
{:error, reason} and the process to exit with reason reason without
entering the loop or calling c:terminate/2.
Callback implementation for GenServer.init/1.
put(db, key, value)
View Source
put(GenServer.server(), any(), any()) :: :ok
put(GenServer.server(), any(), any()) :: :ok
Writes an entry in the database, associating key to value.
If key was already present, it is overwritten.
select(db, options \\ [], timeout \\ 5000)
View Source
select(GenServer.server(), Keyword.t(), timeout()) ::
{:ok, any()} | {:error, Exception.t()}
select(GenServer.server(), Keyword.t(), timeout()) :: {:ok, any()} | {:error, Exception.t()}
Selects a range of entries from the database, and optionally performs a pipeline of operations on them.
It returns {:ok, result} if successful, or {:error, exception} if an
exception is raised.
Options
The min_key and max_key the range of entriethat is selected. All entries
that have a key greater or equal than min_key and less or equal then
max_key are selected. One or both of min_key and max_key can be omitted
or set to nil, in which case the range is open-ended.
The reverse option, when set to true, causes the entries to be selected and
traversed in reverse order.
The pipe option specifies an optional list of operations performed
sequentially on the selected entries. The given order of operations is
respected. The available operations, specified as tuples, are:
{:filter, fun}filters entries for whichfunreturns a truthy value{:map, fun}maps each entry to the value returned by the functionfun{:take, n}takes the firstnentries{:drop, n}skips the firstnentries{:take_while, fun}takes entries whilefunreturns a truthy value{:drop_while, fun}skips entries whilefunreturns a truthy value
The reduce option specifies how the selected entries are aggregated. If
reduce is omitted, the entries are returned as a list. If reduce is a
function, it is used to reduce the collection of entries. If reduce is a
tuple, the first element is the starting value of the reduction, and the
second is the reducing function.
Examples
To select all entries with keys between :a and :c as a list of {key, value} we can do:
{:ok, entries} = CubDB.select(db, min_key: :a, max_key: :c)
To select the last 3 entries, we can do:
{:ok, entries} = CubDB.select(db, reverse: true, pipe: [take: 3])
If we want to obtain the sum of the first 10 positive numeric values
associated to keys from :a to :f, we can do:
{:ok, sum} = CubDB.select(db,
min_key: :a,
max_key: :f,
pipe: [
map: fn {_key, value} -> value end, # map values
filter: fn n -> is_number(n) and n > 0 end # only positive numbers
take: 10, # take only the first 10 entries in the range
],
reduce: fn n, sum -> sum + n end # reduce to the sum of selected values
)
size(db)
View Source
size(GenServer.server()) :: pos_integer()
size(GenServer.server()) :: pos_integer()
Returns the number of entries present in the database.
start(data_dir, options \\ [])
View Source
start(binary(), GenServer.options()) :: GenServer.on_start()
start(binary(), GenServer.options()) :: GenServer.on_start()
Starts the CubDB database without a link.
See start_link/2 for more informations.
start_link(data_dir, options \\ [])
View Source
start_link(binary(), GenServer.options()) :: GenServer.on_start()
start_link(binary(), GenServer.options()) :: GenServer.on_start()
Starts the CubDB database process linked to the current process.
The data_dir argument is a directory name where the database files will be
stored. Only one CubDB instance can run per directory, so if you run several
databases, they should each use their own data directory.
The options are passed to GenServer.start_link/3.