mnesia_rocksdb/doc/mrdb.html

729 lines
33 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Module mrdb</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
</head>
<body bgcolor="white">
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
<hr>
<h1>Module mrdb</h1>
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Mid-level access API for Mnesia-managed rocksdb tables.
<h2><a name="description">Description</a></h2><p>Mid-level access API for Mnesia-managed rocksdb tables</p>
<p>This module implements access functions for the mnesia_rocksdb
backend plugin. The functions are designed to also support
direct access to rocksdb with little overhead. Such direct
access will maintain existing indexes, but not support
replication.</p>
<p>Each table has a metadata structure stored as a persistent
term for fast access. The structure of the metadata is as
follows:</p>
<pre> #{ name := &lt;Logical table name&gt;
, db_ref := &lt;Rocksdb database Ref&gt;
, cf_handle := &lt;Rocksdb column family handle&gt;
, activity := Ongoing batch or transaction, if any (map())
, attr_pos := #{AttrName := Pos}
, mode := &lt;Set to 'mnesia' for mnesia access flows&gt;
, properties := &lt;Mnesia table props in map format&gt;
, type := column_family | standalone
}</pre>
<p>Helper functions like <code>as_batch(Ref, fun(R) -&gt; ... end)</code> and
<code>with_iterator(Ref, fun(I) -&gt; ... end)</code> add some extra
convenience on top of the <code>rocksdb</code> API.</p>
Note that no automatic provision exists to manage concurrent
updates via mnesia AND direct access to this API. It's advisable
to use ONE primary mode of access. If replication is used,
the mnesia API will support this, but direct <code>mrdb</code> updates will
not be replicated.
<h2><a name="types">Data Types</a></h2>
<h3 class="typedecl"><a name="type-activity">activity()</a></h3>
<p><tt>activity() = <a href="#type-tx_activity">tx_activity()</a> | <a href="#type-batch_activity">batch_activity()</a></tt></p>
<h3 class="typedecl"><a name="type-activity_type">activity_type()</a></h3>
<p><tt>activity_type() = <a href="#type-mrdb_activity_type">mrdb_activity_type()</a> | <a href="#type-mnesia_activity_type">mnesia_activity_type()</a></tt></p>
<h3 class="typedecl"><a name="type-admin_tab">admin_tab()</a></h3>
<p><tt>admin_tab() = {admin, <a href="#type-alias">alias()</a>}</tt></p>
<h3 class="typedecl"><a name="type-alias">alias()</a></h3>
<p><tt>alias() = atom()</tt></p>
<h3 class="typedecl"><a name="type-attr_pos">attr_pos()</a></h3>
<p><tt>attr_pos() = #{atom() := <a href="#type-pos">pos()</a>}</tt></p>
<h3 class="typedecl"><a name="type-batch_activity">batch_activity()</a></h3>
<p><tt>batch_activity() = #{type := batch, handle := <a href="#type-batch_handle">batch_handle()</a>}</tt></p>
<h3 class="typedecl"><a name="type-batch_handle">batch_handle()</a></h3>
<p><tt>batch_handle() = <a href="/home/uwiger/ae/mnesia_rocksdb/_build/default/lib/rocksdb/doc/rocksdb.html#type-batch_handle">rocksdb:batch_handle()</a></tt></p>
<h3 class="typedecl"><a name="type-cf_handle">cf_handle()</a></h3>
<p><tt>cf_handle() = <a href="/home/uwiger/ae/mnesia_rocksdb/_build/default/lib/rocksdb/doc/rocksdb.html#type-cf_handle">rocksdb:cf_handle()</a></tt></p>
<h3 class="typedecl"><a name="type-db_handle">db_handle()</a></h3>
<p><tt>db_handle() = <a href="/home/uwiger/ae/mnesia_rocksdb/_build/default/lib/rocksdb/doc/rocksdb.html#type-db_handle">rocksdb:db_handle()</a></tt></p>
<h3 class="typedecl"><a name="type-db_ref">db_ref()</a></h3>
<p><tt>db_ref() = #{name =&gt; <a href="#type-table">table()</a>, alias =&gt; atom(), vsn =&gt; non_neg_integer(), db_ref := <a href="#type-db_handle">db_handle()</a>, cf_handle := <a href="#type-cf_handle">cf_handle()</a>, semantics := <a href="#type-semantics">semantics()</a>, encoding := <a href="#type-encoding">encoding()</a>, attr_pos := <a href="#type-attr_pos">attr_pos()</a>, type := column_family | standalone, status := open | closed | pre_existing, properties := <a href="#type-properties">properties()</a>, mode =&gt; mnesia, ix_vals_f =&gt; fun((tuple()) -&gt; [any()]), activity =&gt; <a href="#type-activity">activity()</a>, term() =&gt; term()}</tt></p>
<h3 class="typedecl"><a name="type-encoding">encoding()</a></h3>
<p><tt>encoding() = raw | sext | term | {<a href="#type-key_encoding">key_encoding()</a>, <a href="#type-val_encoding">val_encoding()</a>}</tt></p>
<h3 class="typedecl"><a name="type-error">error()</a></h3>
<p><tt>error() = {error, any()}</tt></p>
<h3 class="typedecl"><a name="type-index">index()</a></h3>
<p><tt>index() = {<a href="#type-tab_name">tab_name()</a>, index, any()}</tt></p>
<h3 class="typedecl"><a name="type-index_position">index_position()</a></h3>
<p><tt>index_position() = atom() | <a href="#type-pos">pos()</a></tt></p>
<h3 class="typedecl"><a name="type-inner">inner()</a></h3>
<p><tt>inner() = non_neg_integer()</tt></p>
<h3 class="typedecl"><a name="type-iterator_action">iterator_action()</a></h3>
<p><tt>iterator_action() = first | last | next | prev | binary() | {seek, binary()} | {seek_for_prev, binary()}</tt></p>
<h3 class="typedecl"><a name="type-itr_handle">itr_handle()</a></h3>
<p><tt>itr_handle() = <a href="/home/uwiger/ae/mnesia_rocksdb/_build/default/lib/rocksdb/doc/rocksdb.html#type-itr_handle">rocksdb:itr_handle()</a></tt></p>
<h3 class="typedecl"><a name="type-key">key()</a></h3>
<p><tt>key() = any()</tt></p>
<h3 class="typedecl"><a name="type-key_encoding">key_encoding()</a></h3>
<p><tt>key_encoding() = raw | sext | term</tt></p>
<h3 class="typedecl"><a name="type-mnesia_activity_type">mnesia_activity_type()</a></h3>
<p><tt>mnesia_activity_type() = transaction | sync_transaction | async_dirty | sync_dirty</tt></p>
<h3 class="typedecl"><a name="type-mrdb_activity_type">mrdb_activity_type()</a></h3>
<p><tt>mrdb_activity_type() = tx | {tx, <a href="#type-tx_options">tx_options()</a>} | batch</tt></p>
<h3 class="typedecl"><a name="type-mrdb_iterator">mrdb_iterator()</a></h3>
<p><tt>mrdb_iterator() = #mrdb_iter{i = <a href="#type-itr_handle">itr_handle()</a>, ref = <a href="#type-db_ref">db_ref()</a>}</tt></p>
<h3 class="typedecl"><a name="type-obj">obj()</a></h3>
<p><tt>obj() = tuple()</tt></p>
<h3 class="typedecl"><a name="type-outer">outer()</a></h3>
<p><tt>outer() = non_neg_integer()</tt></p>
<h3 class="typedecl"><a name="type-pos">pos()</a></h3>
<p><tt>pos() = non_neg_integer()</tt></p>
<h3 class="typedecl"><a name="type-properties">properties()</a></h3>
<p><tt>properties() = #{record_name := atom(), attributes := [atom()], index := [{<a href="#type-pos">pos()</a>, bag | ordered}]}</tt></p>
<h3 class="typedecl"><a name="type-read_options">read_options()</a></h3>
<p><tt>read_options() = [{verify_checksums, boolean()} | {fill_cache, boolean()} | {iterate_upper_bound, binary()} | {iterate_lower_bound, binary()} | {tailing, boolean()} | {total_order_seek, boolean()} | {prefix_same_as_start, boolean()} | {snapshot, <a href="#type-snapshot_handle">snapshot_handle()</a>}]</tt></p>
<h3 class="typedecl"><a name="type-ref_or_tab">ref_or_tab()</a></h3>
<p><tt>ref_or_tab() = <a href="#type-table">table()</a> | <a href="#type-db_ref">db_ref()</a></tt></p>
<h3 class="typedecl"><a name="type-retainer">retainer()</a></h3>
<p><tt>retainer() = {<a href="#type-tab_name">tab_name()</a>, retainer, any()}</tt></p>
<h3 class="typedecl"><a name="type-retries">retries()</a></h3>
<p><tt>retries() = <a href="#type-outer">outer()</a> | {<a href="#type-inner">inner()</a>, <a href="#type-outer">outer()</a>}</tt></p>
<h3 class="typedecl"><a name="type-semantics">semantics()</a></h3>
<p><tt>semantics() = bag | set</tt></p>
<h3 class="typedecl"><a name="type-snapshot_handle">snapshot_handle()</a></h3>
<p><tt>snapshot_handle() = <a href="/home/uwiger/ae/mnesia_rocksdb/_build/default/lib/rocksdb/doc/rocksdb.html#type-snapshot_handle">rocksdb:snapshot_handle()</a></tt></p>
<h3 class="typedecl"><a name="type-tab_name">tab_name()</a></h3>
<p><tt>tab_name() = atom()</tt></p>
<h3 class="typedecl"><a name="type-table">table()</a></h3>
<p><tt>table() = atom() | <a href="#type-admin_tab">admin_tab()</a> | <a href="#type-index">index()</a> | <a href="#type-retainer">retainer()</a></tt></p>
<h3 class="typedecl"><a name="type-tx_activity">tx_activity()</a></h3>
<p><tt>tx_activity() = #{type := tx, handle := <a href="#type-tx_handle">tx_handle()</a>, attempt := undefined | <a href="#type-retries">retries()</a>}</tt></p>
<h3 class="typedecl"><a name="type-tx_handle">tx_handle()</a></h3>
<p><tt>tx_handle() = <a href="/home/uwiger/ae/mnesia_rocksdb/_build/default/lib/rocksdb/doc/rocksdb.html#type-transaction_handle">rocksdb:transaction_handle()</a></tt></p>
<h3 class="typedecl"><a name="type-tx_options">tx_options()</a></h3>
<p><tt>tx_options() = #{retries =&gt; <a href="#type-retries">retries()</a>, no_snapshot =&gt; boolean()}</tt></p>
<h3 class="typedecl"><a name="type-val_encoding">val_encoding()</a></h3>
<p><tt>val_encoding() = {value | object, term | raw} | raw</tt></p>
<h3 class="typedecl"><a name="type-write_options">write_options()</a></h3>
<p><tt>write_options() = [{sync, boolean()} | {disable_wal, boolean()} | {ignore_missing_column_families, boolean()} | {no_slowdown, boolean()} | {low_pri, boolean()}]</tt></p>
<h2><a name="index">Function Index</a></h2>
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#abort-1">abort/1</a></td><td>Aborts an ongoing <a docgen-rel="seemfa" docgen-href="#activity/2" href="#activity-2"><code>activity/2</code></a></td></tr>
<tr><td valign="top"><a href="#activity-3">activity/3</a></td><td>Run an activity (similar to <a docgen-rel="seemfa" docgen-href="mnesia:mnesia#activity/2" href="/home/uwiger/ae/mnesia/doc/mnesia.html#activity-2"><code>//mnesia/mnesia:activity/2</code></a>).</td></tr>
<tr><td valign="top"><a href="#alias_of-1">alias_of/1</a></td><td>Returns the alias of a given table or table reference.</td></tr>
<tr><td valign="top"><a href="#as_batch-2">as_batch/2</a></td><td>Creates a <code>rocksdb</code> batch context and executes the fun <code>F</code> in it.</td></tr>
<tr><td valign="top"><a href="#as_batch-3">as_batch/3</a></td><td>as <a docgen-rel="seemfa" docgen-href="#as_batch/2" href="#as_batch-2"><code>as_batch/2</code></a>, but with the ability to pass <code>Opts</code> to <code>rocksdb:write_batch/2</code></td></tr>
<tr><td valign="top"><a href="#batch_write-2">batch_write/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#batch_write-3">batch_write/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#clear_table-1">clear_table/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#current_context-0">current_context/0</a></td><td></td></tr>
<tr><td valign="top"><a href="#delete-2">delete/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#delete-3">delete/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#delete_object-2">delete_object/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#delete_object-3">delete_object/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#ensure_ref-1">ensure_ref/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#ensure_ref-2">ensure_ref/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#first-1">first/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#first-2">first/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#fold-3">fold/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#fold-4">fold/4</a></td><td></td></tr>
<tr><td valign="top"><a href="#fold-5">fold/5</a></td><td></td></tr>
<tr><td valign="top"><a href="#get_batch-1">get_batch/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#get_ref-1">get_ref/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#index_read-3">index_read/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#insert-2">insert/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#insert-3">insert/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#iterator-1">iterator/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#iterator-2">iterator/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#iterator_close-1">iterator_close/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#iterator_move-2">iterator_move/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#last-1">last/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#last-2">last/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#match_delete-2">match_delete/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#new_tx-1">new_tx/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#new_tx-2">new_tx/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#next-2">next/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#next-3">next/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#prev-2">prev/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#prev-3">prev/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_delete-2">rdb_delete/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_delete-3">rdb_delete/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_fold-4">rdb_fold/4</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_fold-5">rdb_fold/5</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_get-2">rdb_get/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_get-3">rdb_get/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_iterator-1">rdb_iterator/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_iterator-2">rdb_iterator/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_iterator_move-2">rdb_iterator_move/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_put-3">rdb_put/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#rdb_put-4">rdb_put/4</a></td><td></td></tr>
<tr><td valign="top"><a href="#read-2">read/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#read-3">read/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#read_info-1">read_info/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#read_info-2">read_info/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#release_snapshot-1">release_snapshot/1</a></td><td>release a snapshot created by <a docgen-rel="seemfa" docgen-href="#snapshot/1" href="#snapshot-1"><code>snapshot/1</code></a>.</td></tr>
<tr><td valign="top"><a href="#select-1">select/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#select-2">select/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#select-3">select/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#snapshot-1">snapshot/1</a></td><td>Create a snapshot of the database instance associated with the
table reference, table name or alias.</td></tr>
<tr><td valign="top"><a href="#tx_commit-1">tx_commit/1</a></td><td></td></tr>
<tr><td valign="top"><a href="#tx_ref-2">tx_ref/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#update_counter-3">update_counter/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#update_counter-4">update_counter/4</a></td><td></td></tr>
<tr><td valign="top"><a href="#with_iterator-2">with_iterator/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#with_iterator-3">with_iterator/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#with_rdb_iterator-2">with_rdb_iterator/2</a></td><td></td></tr>
<tr><td valign="top"><a href="#with_rdb_iterator-3">with_rdb_iterator/3</a></td><td></td></tr>
<tr><td valign="top"><a href="#write_info-3">write_info/3</a></td><td></td></tr>
</table>
<h2><a name="functions">Function Details</a></h2>
<h3 class="function"><a name="abort-1">abort/1</a></h3>
<div class="spec">
<p><tt>abort(Reason) -&gt; any()</tt></p>
<p> </p>
</div><p>Aborts an ongoing <a docgen-rel="seemfa" docgen-href="#activity/2" href="#activity-2"><code>activity/2</code></a></p>
<h3 class="function"><a name="activity-3">activity/3</a></h3>
<div class="spec">
<p><tt>activity(Type::<a href="#type-activity_type">activity_type()</a>, Alias::<a href="#type-alias">alias()</a>, F::fun(() -&gt; Res)) -&gt; Res</tt><br></p>
<p> </p>
</div><p><p>Run an activity (similar to <a docgen-rel="seemfa" docgen-href="mnesia:mnesia#activity/2" href="/home/uwiger/ae/mnesia/doc/mnesia.html#activity-2"><code>//mnesia/mnesia:activity/2</code></a>).</p>
Supported activity types are:
<ul>
<li> <code>transaction</code> - An optimistic <code>rocksdb</code> transaction</li>
<li> <code>{tx, TxOpts}</code> - A <code>rocksdb</code> transaction with sligth modifications</li>
<li> <code>batch</code> - A <code>rocksdb</code> batch operation</li>
</ul>
<p>By default, transactions are combined with a snapshot with 1 retry.
The snapshot ensures that writes from concurrent transactions don't leak into the transaction context.
A transaction will be retried if it detects that the commit set conflicts with recent changes.
A mutex is used to ensure that only one of potentially conflicting <code>mrdb</code> transactions is run at a time.
The re-run transaction may still fail, if new transactions, or non-transaction writes interfere with
the commit set. It will then be re-run again, until the retry count is exhausted.</p>
<p>For finer-grained retries, it's possible to set <code>retries =&gt; {Inner, Outer}</code>. Setting the retries to a
single number, <code>Retries</code>, is analogous to <code>{0, Retries}`. Each outer retry requests a</code>mutex lock' by
waiting in a FIFO queue. Once it receives the lock, it will try the activity once + as many retries
as specified by <code>Inner</code>. If these fail, the activity again goes to the FIFO queue (ending up last
in line) if there are outer retries remaining. When all retries are exhaused, the activity aborts
with <code>retry_limit</code>. Note that transactions, being optimistic, do not request a lock on the first
attempt, but only on outer retries (the first retry is always an outer retry).</p>
<p>Valid <code>TxOpts</code> are <code>#{no_snapshot =&gt; boolean(), retries =&gt; retries()}</code>.</p>
To simplify code adaptation, <code>tx | transaction | sync_transaction</code> are synonyms, and
<code>batch | async_dirty | sync_dirty</code> are synonyms.</p>
<h3 class="function"><a name="alias_of-1">alias_of/1</a></h3>
<div class="spec">
<p><tt>alias_of(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>) -&gt; <a href="#type-alias">alias()</a></tt><br></p>
<p> </p>
</div><p>Returns the alias of a given table or table reference.</p>
<h3 class="function"><a name="as_batch-2">as_batch/2</a></h3>
<div class="spec">
<p><tt>as_batch(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, F::fun((<a href="#type-db_ref">db_ref()</a>) -&gt; Res)) -&gt; Res</tt><br></p>
<p> </p>
</div><p><p>Creates a <code>rocksdb</code> batch context and executes the fun <code>F</code> in it.</p>
%% Rocksdb batches aren't tied to a specific DbRef until written.
This can cause surprising problems if we're juggling multiple
rocksdb instances (as we do if we have standalone tables).
At the time of writing, all objects end up in the DbRef the batch
is written to, albeit not necessarily in the intended column family.
This will probably change, but no failure mode is really acceptable.
The code below ensures that separate batches are created for each
DbRef, under a unique reference stored in the pdict. When writing,
all batches are written separately to the corresponding DbRef,
and when releasing, all batches are released. This will not ensure
atomicity, but there is no way in rocksdb to achieve atomicity
across db instances. At least, data should end up where you expect.
</p>
<h3 class="function"><a name="as_batch-3">as_batch/3</a></h3>
<div class="spec">
<p><tt>as_batch(Tab, F, Opts) -&gt; any()</tt></p>
<p> </p>
</div><p>as <a docgen-rel="seemfa" docgen-href="#as_batch/2" href="#as_batch-2"><code>as_batch/2</code></a>, but with the ability to pass <code>Opts</code> to <code>rocksdb:write_batch/2</code></p>
<h3 class="function"><a name="batch_write-2">batch_write/2</a></h3>
<div class="spec">
<p><tt>batch_write(Tab, L) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="batch_write-3">batch_write/3</a></h3>
<div class="spec">
<p><tt>batch_write(Tab, L, Opts) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="clear_table-1">clear_table/1</a></h3>
<div class="spec">
<p><tt>clear_table(Tab) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="current_context-0">current_context/0</a></h3>
<div class="spec">
<p><tt>current_context() -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="delete-2">delete/2</a></h3>
<div class="spec">
<p><tt>delete(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Key::<a href="#type-key">key()</a>) -&gt; ok</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="delete-3">delete/3</a></h3>
<div class="spec">
<p><tt>delete(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Key::<a href="#type-key">key()</a>, Opts::<a href="#type-write_options">write_options()</a>) -&gt; ok</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="delete_object-2">delete_object/2</a></h3>
<div class="spec">
<p><tt>delete_object(Tab, Obj) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="delete_object-3">delete_object/3</a></h3>
<div class="spec">
<p><tt>delete_object(Tab, Obj, Opts) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="ensure_ref-1">ensure_ref/1</a></h3>
<div class="spec">
<p><tt>ensure_ref(R::<a href="#type-ref_or_tab">ref_or_tab()</a>) -&gt; <a href="#type-db_ref">db_ref()</a></tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="ensure_ref-2">ensure_ref/2</a></h3>
<div class="spec">
<p><tt>ensure_ref(Ref, R) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="first-1">first/1</a></h3>
<div class="spec">
<p><tt>first(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="first-2">first/2</a></h3>
<div class="spec">
<p><tt>first(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Opts::<a href="#type-read_options">read_options()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="fold-3">fold/3</a></h3>
<div class="spec">
<p><tt>fold(Tab, Fun, Acc) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="fold-4">fold/4</a></h3>
<div class="spec">
<p><tt>fold(Tab, Fun, Acc, MatchSpec) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="fold-5">fold/5</a></h3>
<div class="spec">
<p><tt>fold(Tab, Fun, Acc, MatchSpec, Limit) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="get_batch-1">get_batch/1</a></h3>
<div class="spec">
<p><tt>get_batch(X1) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="get_ref-1">get_ref/1</a></h3>
<div class="spec">
<p><tt>get_ref(Tab::<a href="#type-table">table()</a>) -&gt; <a href="#type-db_ref">db_ref()</a></tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="index_read-3">index_read/3</a></h3>
<div class="spec">
<p><tt>index_read(Tab, Val, Ix) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="insert-2">insert/2</a></h3>
<div class="spec">
<p><tt>insert(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Obj::<a href="#type-obj">obj()</a>) -&gt; ok</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="insert-3">insert/3</a></h3>
<div class="spec">
<p><tt>insert(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Obj0::<a href="#type-obj">obj()</a>, Opts::<a href="#type-write_options">write_options()</a>) -&gt; ok</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="iterator-1">iterator/1</a></h3>
<div class="spec">
<p><tt>iterator(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>) -&gt; {ok, <a href="#type-mrdb_iterator">mrdb_iterator()</a>} | {error, term()}</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="iterator-2">iterator/2</a></h3>
<div class="spec">
<p><tt>iterator(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Opts::<a href="#type-read_options">read_options()</a>) -&gt; {ok, <a href="#type-mrdb_iterator">mrdb_iterator()</a>} | {error, term()}</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="iterator_close-1">iterator_close/1</a></h3>
<div class="spec">
<p><tt>iterator_close(Mrdb_iter::<a href="#type-mrdb_iterator">mrdb_iterator()</a>) -&gt; ok</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="iterator_move-2">iterator_move/2</a></h3>
<div class="spec">
<p><tt>iterator_move(Mrdb_iter::<a href="#type-mrdb_iterator">mrdb_iterator()</a>, Dir::<a href="#type-iterator_action">iterator_action()</a>) -&gt; {ok, tuple()} | {error, any()}</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="last-1">last/1</a></h3>
<div class="spec">
<p><tt>last(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="last-2">last/2</a></h3>
<div class="spec">
<p><tt>last(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Opts::<a href="#type-read_options">read_options()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="match_delete-2">match_delete/2</a></h3>
<div class="spec">
<p><tt>match_delete(Tab, Pat) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="new_tx-1">new_tx/1</a></h3>
<div class="spec">
<p><tt>new_tx(Tab::<a href="#type-table">table()</a> | <a href="#type-db_ref">db_ref()</a>) -&gt; <a href="#type-db_ref">db_ref()</a></tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="new_tx-2">new_tx/2</a></h3>
<div class="spec">
<p><tt>new_tx(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Opts::<a href="#type-write_options">write_options()</a>) -&gt; <a href="#type-db_ref">db_ref()</a></tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="next-2">next/2</a></h3>
<div class="spec">
<p><tt>next(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, K::<a href="#type-key">key()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="next-3">next/3</a></h3>
<div class="spec">
<p><tt>next(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, K::<a href="#type-key">key()</a>, Opts::<a href="#type-read_options">read_options()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="prev-2">prev/2</a></h3>
<div class="spec">
<p><tt>prev(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, K::<a href="#type-key">key()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="prev-3">prev/3</a></h3>
<div class="spec">
<p><tt>prev(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, K::<a href="#type-key">key()</a>, Opts::<a href="#type-read_options">read_options()</a>) -&gt; <a href="#type-key">key()</a> | '$end_of_table'</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_delete-2">rdb_delete/2</a></h3>
<div class="spec">
<p><tt>rdb_delete(R, K) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_delete-3">rdb_delete/3</a></h3>
<div class="spec">
<p><tt>rdb_delete(R, K, Opts) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_fold-4">rdb_fold/4</a></h3>
<div class="spec">
<p><tt>rdb_fold(Tab, Fun, Acc, Prefix) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_fold-5">rdb_fold/5</a></h3>
<div class="spec">
<p><tt>rdb_fold(Tab, Fun, Acc, Prefix, Limit) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_get-2">rdb_get/2</a></h3>
<div class="spec">
<p><tt>rdb_get(R, K) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_get-3">rdb_get/3</a></h3>
<div class="spec">
<p><tt>rdb_get(R, K, Opts) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_iterator-1">rdb_iterator/1</a></h3>
<div class="spec">
<p><tt>rdb_iterator(R) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_iterator-2">rdb_iterator/2</a></h3>
<div class="spec">
<p><tt>rdb_iterator(R, Opts) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_iterator_move-2">rdb_iterator_move/2</a></h3>
<div class="spec">
<p><tt>rdb_iterator_move(I, Dir) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_put-3">rdb_put/3</a></h3>
<div class="spec">
<p><tt>rdb_put(R, K, V) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="rdb_put-4">rdb_put/4</a></h3>
<div class="spec">
<p><tt>rdb_put(R, K, V, Opts) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="read-2">read/2</a></h3>
<div class="spec">
<p><tt>read(Tab, Key) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="read-3">read/3</a></h3>
<div class="spec">
<p><tt>read(Tab, Key, Opts) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="read_info-1">read_info/1</a></h3>
<div class="spec">
<p><tt>read_info(Tab) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="read_info-2">read_info/2</a></h3>
<div class="spec">
<p><tt>read_info(Tab, K) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="release_snapshot-1">release_snapshot/1</a></h3>
<div class="spec">
<p><tt>release_snapshot(SHandle::<a href="#type-snapshot_handle">snapshot_handle()</a>) -&gt; ok | <a href="#type-error">error()</a></tt><br></p>
<p> </p>
</div><p>release a snapshot created by <a docgen-rel="seemfa" docgen-href="#snapshot/1" href="#snapshot-1"><code>snapshot/1</code></a>.</p>
<h3 class="function"><a name="select-1">select/1</a></h3>
<div class="spec">
<p><tt>select(Cont) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="select-2">select/2</a></h3>
<div class="spec">
<p><tt>select(Tab, Pat) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="select-3">select/3</a></h3>
<div class="spec">
<p><tt>select(Tab, Pat, Limit) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="snapshot-1">snapshot/1</a></h3>
<div class="spec">
<p><tt>snapshot(Name::<a href="#type-alias">alias()</a> | <a href="#type-ref_or_tab">ref_or_tab()</a>) -&gt; {ok, <a href="#type-snapshot_handle">snapshot_handle()</a>} | <a href="#type-error">error()</a></tt><br></p>
<p> </p>
</div><p><p>Create a snapshot of the database instance associated with the
table reference, table name or alias.</p>
Snapshots provide consistent read-only views over the entire state of the key-value store.</p>
<h3 class="function"><a name="tx_commit-1">tx_commit/1</a></h3>
<div class="spec">
<p><tt>tx_commit(TxH::<a href="#type-tx_handle">tx_handle()</a> | <a href="#type-db_ref">db_ref()</a>) -&gt; ok</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="tx_ref-2">tx_ref/2</a></h3>
<div class="spec">
<p><tt>tx_ref(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a> | <a href="#type-db_ref">db_ref()</a> | <a href="#type-db_ref">db_ref()</a>, TxH::<a href="#type-tx_handle">tx_handle()</a>) -&gt; <a href="#type-db_ref">db_ref()</a></tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="update_counter-3">update_counter/3</a></h3>
<div class="spec">
<p><tt>update_counter(Tab, C, Val) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="update_counter-4">update_counter/4</a></h3>
<div class="spec">
<p><tt>update_counter(Tab, C, Val, Opts) -&gt; any()</tt></p>
<p> </p>
</div>
<h3 class="function"><a name="with_iterator-2">with_iterator/2</a></h3>
<div class="spec">
<p><tt>with_iterator(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Fun::fun((<a href="#type-mrdb_iterator">mrdb_iterator()</a>) -&gt; Res)) -&gt; Res</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="with_iterator-3">with_iterator/3</a></h3>
<div class="spec">
<p><tt>with_iterator(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Fun::fun((<a href="#type-mrdb_iterator">mrdb_iterator()</a>) -&gt; Res), Opts::<a href="#type-read_options">read_options()</a>) -&gt; Res</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="with_rdb_iterator-2">with_rdb_iterator/2</a></h3>
<div class="spec">
<p><tt>with_rdb_iterator(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Fun::fun((<a href="#type-itr_handle">itr_handle()</a>) -&gt; Res)) -&gt; Res</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="with_rdb_iterator-3">with_rdb_iterator/3</a></h3>
<div class="spec">
<p><tt>with_rdb_iterator(Tab::<a href="#type-ref_or_tab">ref_or_tab()</a>, Fun::fun((<a href="#type-itr_handle">itr_handle()</a>) -&gt; Res), Opts::<a href="#type-read_options">read_options()</a>) -&gt; Res</tt><br></p>
<p> </p>
</div>
<h3 class="function"><a name="write_info-3">write_info/3</a></h3>
<div class="spec">
<p><tt>write_info(Tab, K, V) -&gt; any()</tt></p>
<p> </p>
</div>
<hr>
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
<p><i>Generated by EDoc</i></p>
</body>
</html>