diff --git a/src/bdberl.erl b/src/bdberl.erl
index 86384fa..2beb41b 100644
--- a/src/bdberl.erl
+++ b/src/bdberl.erl
@@ -73,6 +73,55 @@ open(Name, Type) ->
%% @doc
%% Open a database file.
%%
+%% This function opens the database represented by the `Name' parameter
+%% for both reading and writing. The `Type' parameter specifies the
+%% database file format. The currently supported file formats (or access
+%% methods) are `btree' and `hash'. The `btree' format is a
+%% representation of a sorted, balanced tree structure. The `hash'
+%% format is an extensible, dynamic hashing scheme.
+%%
+%% Calling open is a relatively expensive operation, and maintaining a
+%% set of open databases will normally be preferable to repeatedly
+%% opening and closing the database for each new query.
+%%
+%% This function returns `{ok, Db}' on success. `Db' is a handle that
+%% must be used when performing operations on this database. If open
+%% fails, the close function is called automatically to discard the `Db'
+%% handle.
+%%
+%% === Options ===
+%%
+%% The `Opts' parameter takes a list of flags that will modify the
+%% behavior of bdberl when accessing this file. The following flags are
+%% recognized:
+%%
+%%
+%% - create
+%% - Create the database if it does not exist.
+%% - exclusive
+%% - Return an error if the database already exists. Only
+%% meaningful when used with `create'.
+%% - multiversion
+%% - Open the database with support for multiversion concurrency
+%% protocol.
+%% - no_mmap
+%% - Do not map this database into process memory.
+%% - readonly
+%% - Open the database for reading only. Any attempt to modify items
+%% in the database will fail.
+%% - read_uncommitted
+%% - Support transactional read operations with degree 1
+%% isolation. Read operations on the database may request the
+%% return of modified but not yet committed data.
+%% - truncate
+%% - Physically truncate the underlying file, discarding all
+%% previous databases it might have held.
+%%
+%%
+%% Additionally, the driver supports the `auto_commit' and `threaded'
+%% flags which are always enabled. Specifying either flag in `Opts' is
+%% safe, but does not alter the behavior of bdberl.
+%%
%% @spec open(Name, Type, Opts) -> {ok, Db} | {error, Error}
%% where
%% Name = string()
@@ -103,7 +152,7 @@ open(Name, Type, Opts) ->
%%--------------------------------------------------------------------
%% @doc
-%% Close a database file.
+%% Close a database file with default options.
%%
%% @spec close(Db) -> ok | {error, Error}
%% where
@@ -123,6 +172,30 @@ close(Db) ->
%% @doc
%% Close a database file.
%%
+%% This function flushes any cached database information to disk, closes
+%% any open cursors, frees any allocated resources, and closes any
+%% underlying files.
+%%
+%% The `Db' handle should not be closed while any other handle that refers
+%% to it is not yet closed; for example, database handles must not be
+%% closed while cursor handles into the database remain open, or
+%% transactions that include operations on the database have not yet
+%% been committed or aborted.
+%%
+%% Because key/data pairs are cached in memory, failing to sync the file
+%% with the `close' function may result in inconsistent or lost
+%% information.
+%%
+%% The `Db' handle may not be accessed again after this function is
+%% called, regardless of its return.
+%%
+%% === Options ===
+%%
+%%
+%% - no_sync
+%% - Do not flush cached information to disk.
+%%
+%%
%% @spec close(Db, Opts) -> ok | {error, Error}
%% where
%% Db = integer()
@@ -146,7 +219,7 @@ close(Db, Opts) ->
%%--------------------------------------------------------------------
%% @doc
-%% Begin a transaction.
+%% Begin a transaction with default options.
%%
%% @spec txn_begin() -> ok | {error, Error}
%%
@@ -164,6 +237,80 @@ txn_begin() ->
%% @doc
%% Begin a transaction.
%%
+%% This function creates a new transaction in the environment. Calling
+%% the `abort' or `commit' functions will end the transaction.
+%%
+%% Transactions may only span threads if they do so serially; that is,
+%% each transaction must be active in only a single thread of control at
+%% a time. This restriction holds for parents of nested transactions as
+%% well; no two children may be concurrently active in more than one
+%% thread of control at any one time.
+%%
+%% Cursors may not span transactions; that is, each cursor must be
+%% opened and closed within a single transaction.
+%%
+%% A parent transaction may not issue any Berkeley DB operations --
+%% except for `txn_begin', `abort' and `commit' -- while it has active
+%% child transactions (child transactions that have not yet been
+%% committed or aborted).
+%%
+%% === Options ===
+%%
+%%
+%% - read_committed
+%% - This transaction will have degree 2 isolation. This provides
+%% for cursor stability but not repeatable reads. Data items which
+%% have been previously read by this transaction may be deleted or
+%% modified by other transactions before this transaction
+%% completes.
+%% - read_uncommitted
+%% - This transaction will have degree 1 isolation. Read operations
+%% performed by the transaction may read modified but not yet
+%% committed data. Silently ignored if the `read_uncommitted'
+%% option was not specified when the underlying database was
+%% opened.
+%% - txn_no_sync
+%% - Do not synchronously flush the log when this transaction
+%% commits. This means the transaction will exhibit the ACI
+%% (atomicity, consistency, and isolation) properties, but not D
+%% (durability); that is, database integrity will be maintained
+%% but it is possible that this transaction may be undone during
+%% recovery.
+%% - txn_no_wait
+%% - If a lock is unavailable for any Berkeley DB operation
+%% performed in the context of this transaction, cause the
+%% operation to return `deadlock' or `lock_not_granted'.
+%% - txn_snapshot
+%% - This transaction will execute with snapshot isolation. For
+%% databases with the `multiversion' flag set, data values will be
+%% read as they are when the transaction begins, without taking
+%% read locks. Silently ignored for operations on databases with
+%% `multiversion' not set on the underlying database (read locks
+%% are acquired). The error `deadlock' will be returned from
+%% update operations if a snapshot transaction attempts to update
+%% data which was modified after the snapshot transaction read it.
+%%
+%% - txn_sync
+%% - Synchronously flush the log when this transaction commits.
+%% This means the transaction will exhibit all of the ACID
+%% (atomicity, consistency, isolation, and durability)
+%% properties. This behavior is the default.
+%% - txn_wait
+%% - If a lock is unavailable for any operation performed in the
+%% context of this transaction, wait for the lock. This behavior
+%% is the default.
+%% - txn_write_nosync
+%% - Write, but do not synchronously flush, the log when this
+%% transaction commits. This means the transaction will exhibit
+%% the ACI (atomicity, consistency, and isolation) properties,
+%% but not D (durability); that is, database integrity will be
+%% maintained, but if the system fails, it is possible some
+%% number of the most recently committed transactions may be
+%% undone during recovery. The number of transactions at risk is
+%% governed by how often the system flushes dirty buffers to disk
+%% and how often the log is flushed or checkpointed.
+%%
+%%
%% @spec txn_begin(Opts) -> ok | {error, Error}
%% where
%% Opts = [atom()]
@@ -184,7 +331,7 @@ txn_begin(Opts) ->
%%--------------------------------------------------------------------
%% @doc
-%% Commit a transaction.
+%% Commit a transaction with default options.
%%
%% @spec txn_commit() -> ok | {error, Error}
%%
@@ -202,6 +349,35 @@ txn_commit() ->
%% @doc
%% Commit a transaction.
%%
+%% This function ends the transaction. In the case of nested
+%% transactions, if the transaction is a parent transaction, committing
+%% the parent transaction causes all unresolved children of the parent
+%% to be committed. In the case of nested transactions, if the
+%% transaction is a child transaction, its locks are not released, but
+%% are acquired by its parent. Although the commit of the child
+%% transaction will succeed, the actual resolution of the child
+%% transaction is postponed until the parent transaction is committed or
+%% aborted; that is, if its parent transaction commits, it will be
+%% committed; and if its parent transaction aborts, it will be aborted.
+%%
+%% All cursors opened within the transaction must be closed before the
+%% transaction is committed.
+%%
+%% === Options ===
+%%
+%%
+%% - txn_no_sync
+%% - Do not synchronously flush the log. This means the transaction
+%% will exhibit the ACI (atomicity, consistency, and isolation)
+%% properties, but not D (durability); that is, database integrity
+%% will be maintained but it is possible that this transaction may
+%% be undone during recovery.
+%% - txn_sync
+%% - Synchronously flush the log. This means the transaction will
+%% exhibit all of the ACID (atomicity, consistency, isolation,
+%% and durability) properties. This behavior is the default.
+%%
+%%
%% @spec txn_commit(Opts) -> ok | {error, Error}
%% where
%% Opts = [atom()]
@@ -229,6 +405,18 @@ txn_commit(Opts) ->
%% @doc
%% Abort a transaction.
%%
+%% This function causes an abnormal termination of the transaction. The
+%% log is played backward, and any necessary undo operations are
+%% performed. Before this function returns, any locks held by the
+%% transaction will have been released.
+%%
+%% In the case of nested transactions, aborting a parent transaction
+%% causes all children (unresolved or not) of the parent transaction to
+%% be aborted.
+%%
+%% All cursors opened within the transaction must be closed before the
+%% transaction is aborted.
+%%
%% @spec txn_abort() -> ok | {error, Error}
%%
%% @end
@@ -274,6 +462,16 @@ transaction(Fun) ->
%% @doc
%% Execute a fun inside of a transaction.
%%
+%% This function executes a user-supplied function inside the scope of a
+%% transaction. If the function returns normally, then the transaction
+%% is committed and the value returned by the function is returned. If
+%% the function returns the value `abort' then the transaction will be
+%% aborted.
+%%
+%% If the transaction deadlocks on commit, the function will be executed
+%% again until the commit succeeds or the number of retries exceeds the
+%% value of the `Retries' parameter.
+%%
%% @spec transaction(Fun, Retries) -> {ok, Value} | {error, Error}
%% where
%% Fun = function()
@@ -345,6 +543,32 @@ put(Db, Key, Value) ->
%% @doc
%% Store a value in a database file.
%%
+%% This function stores key/data pairs in the database. The default
+%% behavior is to enter the new key/data pair, replacing any previously
+%% existing key if duplicates are disallowed, or adding a duplicate data
+%% item if duplicates are allowed. If the database supports duplicates,
+%% this function adds the new data value at the end of the duplicate
+%% set. If the database supports sorted duplicates, the new data value
+%% is inserted at the correct sorted location.
+%%
+%% === Options ===
+%%
+%%
+%% - no_duplicate
+%% - enter the new key/data pair only if it does not already appear
+%% in the database. This option may only be specified if the
+%% underlying database has been configured to support sorted
+%% duplicates. The `put' function will return `key_exist' if
+%% this option is set and the key/data pair already appears in the
+%% database.
+%% - no_overwrite
+%% - Enter the new key/data pair only if the key does not already
+%% appear in the database. The `put' function call with this
+%% option set will fail if the key already exists in the database,
+%% even if the database supports duplicates. In this case the
+%% `put' function will return `key_exist'.
+%%
+%%
%% @spec put(Db, Key, Value, Opts) -> ok | {error, Error}
%% where
%% Db = integer()
@@ -363,7 +587,7 @@ put(Db, Key, Value, Opts) ->
%%--------------------------------------------------------------------
%% @doc
-%% Store a value in a database file.
+%% Store a value in a database file raising an exception on failure.
%%
%% @spec put_r(Db, Key, Value) -> ok
%% where
@@ -385,7 +609,12 @@ put_r(Db, Key, Value) ->
%%--------------------------------------------------------------------
%% @doc
-%% Store a value in a database file.
+%% Store a value in a database file raising an exception on failure.
+%%
+%% This function is the same as put/4 except that it raises an exception
+%% on failure instead of returning an error tuple.
+%%
+%% @see put/4
%%
%% @spec put_r(Db, Key, Value, Opts) -> ok
%% where
@@ -409,7 +638,7 @@ put_r(Db, Key, Value, Opts) ->
%%--------------------------------------------------------------------
%% @doc
-%% Store a value in a database file.
+%% Store a value in a database file and commit the transaction.
%%
%% @spec put_commit(Db, Key, Value) -> ok | {error, Error}
%% where
@@ -430,7 +659,11 @@ put_commit(Db, Key, Value) ->
%%--------------------------------------------------------------------
%% @doc
-%% Store a value in a database file.
+%% Store a value in a database file and commit the transaction.
+%%
+%% This function is logically the equicalent of calling `put' followed
+%% by `txn_commit' except that it is implemented with the driver and is
+%% therefore more efficient.
%%
%% @spec put_commit(Db, Key, Value, Opts) -> ok | {error, Error}
%% where
@@ -450,7 +683,7 @@ put_commit(Db, Key, Value, Opts) ->
%%--------------------------------------------------------------------
%% @doc
-%% Store a value in a database file.
+%% Store a value in a database file and commit the transaction.
%%
%% @spec put_commit_r(Db, Key, Value) -> ok
%% where
@@ -472,7 +705,12 @@ put_commit_r(Db, Key, Value) ->
%%--------------------------------------------------------------------
%% @doc
-%% Store a value in a database file.
+%% Store a value in a database file and commit the transaction.
+%%
+%% This function is the same as put_commit/4 except that it raises an
+%% exception on failure instead of returning an error tuple.
+%%
+%% @see put_commit/4
%%
%% @spec put_commit_r(Db, Key, Value, Opts) -> ok
%% where
@@ -518,6 +756,38 @@ get(Db, Key) ->
%% @doc
%% Retrieve a value based on key.
%%
+%% This function retrieves key/data pairs from the database. In the
+%% presence of duplicate key values, this function will return the first
+%% data item for the designated key. Duplicates are sorted by insert
+%% order, except where this order has been overridden by cursor
+%% operations. Retrieval of duplicates requires the use of cursor
+%% operations.
+%%
+%% This function will return `not_found' if the specified key is not in
+%% the database.
+%%
+%% === Options ===
+%%
+%%
+%% - read_committed
+%% - Configure a transactional get operation to have degree 2
+%% isolation (the read is not repeatable).
+%% - read_uncommitted
+%% - Configure a transactional get operation to have degree 1
+%% isolation, reading modified but not yet committed data.
+%% Silently ignored if the `read_uncommitted' flag was not
+%% specified when the underlying database was opened.
+%% - rmw
+%% - Acquire write locks instead of read locks when doing the read,
+%% if locking is configured. Setting this flag can eliminate
+%% deadlock during a read-modify-write cycle by acquiring the
+%% write lock during the read part of the cycle so that another
+%% thread of control acquiring a read lock for the same item, in
+%% its own read-modify-write cycle, will not result in deadlock.
+%% This option is meaningful only in the presence of transactions.
+%%
+%%
+%%
%% @spec get(Db, Key, Opts) -> not_found | {ok, Value} | {error, Error}
%% where
%% Db = integer()
@@ -572,6 +842,11 @@ get_r(Db, Key) ->
%% @doc
%% Retrieve a value based on key.
%%
+%% This function is the same as get/3 except that it raises an
+%% exception on failure instead of returning an error tuple.
+%%
+%% @see get/3
+%%
%% @spec get_r(Db, Key, Opts) -> not_found | {ok, Value}
%% where
%% Db = integer()
@@ -618,6 +893,12 @@ update(Db, Key, Fun) ->
%% @doc
%% Updates the value of a key by executing a fun.
%%
+%% This function updates a key/value pair by calling the provided
+%% function and passing in the key and value as they are
+%% currently. Additional arguments can be provided to the function by
+%% passing them in the `Args' parameter. The entire operation is
+%% executed within the scope of a new transaction.
+%%
%% @spec update(Db, Key, Fun, Args) -> {ok, Value} | {error, Error}
%% where
%% Db = integer()
@@ -650,6 +931,9 @@ update(Db, Key, Fun, Args) ->
%% @doc
%% Truncates all of the open databases.
%%
+%% This function is equivalent to calling truncate/1 for every open
+%% database.
+%%
%% @spec truncate() -> ok | {error, Error}
%%
%% @end
@@ -664,6 +948,11 @@ truncate() ->
%% @doc
%% Truncates a database.
%%
+%% This function empties the database, discarding all records it
+%% contains.
+%%
+%% It is an error to call this function on a database with open cursors.
+%%
%% @spec truncate(Db) -> ok | {error, Error}
%% where
%% Db = integer()
@@ -691,7 +980,11 @@ truncate(Db) ->
%% @doc
%% Opens a cursor on a database.
%%
-%% @spec cursor_open(Db) -> {ok, Db} | {error, Error}
+%% This function creates a database cursor. Cursors may span threads,
+%% but only serially, that is, the application must serialize access to
+%% the cursor handle.
+%%
+%% @spec cursor_open(Db) -> ok | {error, Error}
%% where
%% Db = integer()
%%
@@ -712,7 +1005,19 @@ cursor_open(Db) ->
%%--------------------------------------------------------------------
%% @doc
-%% Returns the next cursor value.
+%% Retrieves key/data pairs from the database.
+%%
+%% The cursor is moved to the next key/data pair of the database, and
+%% that pair is returned. In the presence of duplicate key values, the
+%% value of the key may not change.
+%%
+%% Modifications to the database during a sequential scan will be
+%% reflected in the scan; that is, records inserted behind a cursor will
+%% not be returned while records inserted in front of a cursor will be
+%% returned.
+%%
+%% If this function fails for any reason, the state of the cursor will
+%% be unchanged.
%%
%% @spec cursor_next() -> not_found | {ok, Key, Value} | {error, Error}
%%
@@ -726,7 +1031,19 @@ cursor_next() ->
%%--------------------------------------------------------------------
%% @doc
-%% Returns the previous cursor value.
+%% Retrieves key/data pairs from the database.
+%%
+%% The cursor is moved to the previous key/data pair of the database,
+%% and that pair is returned. In the presence of duplicate key values,
+%% the value of the key may not change.
+%%
+%% Modifications to the database during a sequential scan will be
+%% reflected in the scan; that is, records inserted behind a cursor will
+%% not be returned while records inserted in front of a cursor will be
+%% returned.
+%%
+%% If this function fails for any reason, the state of the cursor will
+%% be unchanged.
%%
%% @spec cursor_prev() -> not_found | {ok, Key, Value} | {error, Error}
%%
@@ -740,7 +1057,17 @@ cursor_prev() ->
%%--------------------------------------------------------------------
%% @doc
-%% Returns the current cursor value.
+%% Retrieves key/data pairs from the database.
+%%
+%% Returns the key/data pair to which the cursor refers.
+%%
+%% Modifications to the database during a sequential scan will be
+%% reflected in the scan; that is, records inserted behind a cursor will
+%% not be returned while records inserted in front of a cursor will be
+%% returned.
+%%
+%% If this function fails for any reason, the state of the cursor will
+%% be unchanged.
%%
%% @spec cursor_current() -> not_found | {ok, Key, Value} | {error, Error}
%%
@@ -756,6 +1083,16 @@ cursor_current() ->
%% @doc
%% Closes the cursor.
%%
+%% This function discards the cursor.
+%%
+%% It is possible for this function to return `deadlock', signaling that
+%% any enclosing transaction should be aborted. If the application is
+%% already intending to abort the transaction, this error should be
+%% ignored, and the application should proceed.
+%%
+%% After this function has been called, regardless of its return, the
+%% cursor handle may not be used again.
+%%
%% @spec cursor_close() -> ok | {error, Error}
%%
%% @end
@@ -776,6 +1113,15 @@ cursor_close() ->
%% @doc
%% Delete a database file.
%%
+%% This function removes the database specified by the filename
+%% parameter.
+%%
+%% Applications should never remove databases with open handles. For
+%% example, some architectures do not permit the removal of files with
+%% open system handles. On these architectures, attempts to remove
+%% databases currently in use by any thread of control in the system may
+%% fail.
+%%
%% @spec delete_database(Filename) -> ok | {error, Error}
%% where
%% Filename = string()
@@ -836,6 +1182,9 @@ get_data_dirs() ->
%% @doc
%% Returns the size of the in-memory cache.
%%
+%% The cache size is returned as a three element tuple representing the
+%% number of gigabytes and megabytes and the number of caches.
+%%
%% @spec get_cache_size() -> {ok, Gbytes, Mbytes, NumCaches} | {error, Error}
%% where
%% Gbytes = integer()