dgen_backend behaviour (DGen v0.1.0)

Copy Markdown View Source

Behaviour defining the storage backend for dgen.

A backend must implement all required callbacks to provide:

  • Transactions — serializable read-write transactions over the keyspace.
  • Key-value operations — get, set, clear, range reads, atomic adds.
  • Watches — notifications when a key changes.
  • Versionstamps — globally-ordered, unique write stamps for FIFO queuing.
  • Directory layer — tuple-key packing, range calculation, namespace isolation.

The default backend is dgen_erlfdb, which delegates to FoundationDB via the erlfdb library.

We look forward to changing the backend interface to support other systems.

Configuring the backend

Set the backend application env before starting dgen:

application:set_env(dgen, backend, my_backend).

Or in config.exs:

config :dgen, backend: MyBackend

Implementing a backend

A backend module must implement this behaviour. All watch and future operations must return {dgen_future, Ref, BackendData} tuples where Ref is a reference that will appear in a {Ref, ready} message sent to the watching process.

Types

Backends define opaque types for database handles, transaction handles, directory handles, and futures. The dgen core treats these as opaque terms and only passes them back into backend callbacks.

Summary

Functions

Runs Fun inside a transaction if Handle is a database handle, or calls Fun directly if Handle is already a transaction.

Types

db()

-type db() :: term().

dir()

-type dir() :: term().

future()

-type future() :: term().

key()

-type key() :: binary().

tenant()

-type tenant() :: {db() | tx(), dir()}.

tuple_key()

-type tuple_key() :: tuple().

tx()

-type tx() :: term().

versionstamp()

-type versionstamp() :: term().

Callbacks

add(Tx, Key, Value)

-callback add(Tx :: tx(), Key :: key(), Value :: integer()) -> ok.

clear_range(Tx, StartKey, EndKey)

-callback clear_range(Tx :: tx(), StartKey :: key(), EndKey :: key()) -> ok.

dir_create(Db, Dir, Name)

-callback dir_create(Db :: db(), Dir :: dir(), Name :: term()) -> dir().

dir_pack(Dir, TupleKey)

-callback dir_pack(Dir :: dir(), TupleKey :: tuple_key()) -> key().

dir_pack_vs(Dir, TupleKey)

-callback dir_pack_vs(Dir :: dir(), TupleKey :: tuple_key()) -> key().

dir_range(Dir, TupleKey)

-callback dir_range(Dir :: dir(), TupleKey :: tuple_key()) -> {key(), key()}.

dir_remove(Db, Dir, Name)

-callback dir_remove(Db :: db(), Dir :: dir(), Name :: term()) -> ok.

dir_unpack(Dir, PackedKey)

-callback dir_unpack(Dir :: dir(), PackedKey :: key()) -> tuple_key().

get(Tx, Key)

-callback get(Tx :: tx(), Key :: key()) -> future().

get_next_tx_id(Tx)

-callback get_next_tx_id(Tx :: tx()) -> non_neg_integer().

get_range(Tx, StartKey, EndKey, Opts)

-callback get_range(Tx :: tx(), StartKey :: key(), EndKey :: key(), Opts :: list()) -> [{key(), binary()}].

get_versionstamp(Tx)

-callback get_versionstamp(Tx :: tx()) -> future().

is_transaction(Handle)

-callback is_transaction(Handle :: db() | tx()) -> boolean().

key_strinc(Key)

-callback key_strinc(Key :: key()) -> key().

sandbox_open(Name, DirName)

(optional)
-callback sandbox_open(Name :: term(), DirName :: term()) -> tenant().

set(Tx, Key, Value)

-callback set(Tx :: tx(), Key :: key(), Value :: binary()) -> ok.

set_versionstamped_key(Tx, Key, Value)

-callback set_versionstamped_key(Tx :: tx(), Key :: key(), Value :: binary()) -> ok.

set_versionstamped_value(Tx, Key, Value)

-callback set_versionstamped_value(Tx :: tx(), Key :: key(), Value :: binary()) -> ok.

transactional(Db, Fun)

-callback transactional(Db :: db(), Fun :: fun((Tx :: tx()) -> Result)) -> Result when Result :: term().

wait(Future)

-callback wait(Future :: future()) -> term().

wait_for_all(Futures)

-callback wait_for_all(Futures :: [future()]) -> [term()].

watch(Tx, Key)

-callback watch(Tx :: tx(), Key :: key()) -> future().

watch(Tx, Key, Opts)

-callback watch(Tx :: tx(), Key :: key(), Opts :: list()) -> future().

Functions

transactional(Db, Fun)

-spec transactional(tenant(), fun((tenant()) -> Result)) -> Result when Result :: term().

Runs Fun inside a transaction if Handle is a database handle, or calls Fun directly if Handle is already a transaction.