barrel_db_server (barrel_docdb v1.1.1)

View Source

barrel_db_server - Individual database server process

Manages a single database instance. Each database has its own gen_server process that handles all operations for that database. Opens both a document store (regular RocksDB) and an attachment store (RocksDB with BlobDB enabled).

Summary

Functions

Checkpoint both stores into a branch's directories, minting the fork instant inside the writer: every write applied before this call is in the checkpoint and every later one has a larger HLC. Blocks the writer for the memtable flush + hard links.

Delete a document

Delete a local document

Get revisions difference (for replication) Returns {ok, Missing, PossibleAncestors}

Fold over all documents

Fold over all documents with options

Fold over local documents with a given prefix

Get the attachment store reference

Get conflicts for a document Returns list of conflicting revision IDs (excluding the winner)

Get a document When raw_body => true in Opts, returns {ok, CborBin, Meta} for zero-copy responses

Get multiple documents (batch read)

Get a local document

Get the document store reference

Handle synchronous calls

Handle asynchronous casts

Handle other messages The periodic compaction/retention/ttl work runs in a monitored worker so it never blocks the writer loop (a long compaction used to make concurrent writes time out). The periodic timer is re-armed when the worker finishes.

Get database info

Initialize the database server

Acknowledge processed outbox entries by their exact HLC keys. Deleting a key that was already replaced by a newer write is a no-op, so acks never lose work (see barrel_outbox).

Put a document (create or update)

Put multiple documents (batch write)

Put a local document (not replicated)

Put a document with explicit revision history (for replication) Returns {ok, DocId, RevId} on success.

Resolve a conflict by choosing a winning revision or providing a merged doc Resolution can be: - {choose, Rev} - keep this revision as winner, delete other branches - {merge, Doc} - create new revision merging all conflicts

Store a computed embedding as the document's embedding column. CAS on the expected revision: embeddings are derived data, so this never bumps the revision or emits a change; a conflict means a newer write exists (which re-drives the computing indexer anyway).

Start the database server

Stop the database server

Run a retention sweep now. Prunes history entries, superseded version bodies and expired tombstones older than the retention window, then advances the history floor. No-op when retention is infinite (retention_period 0).

Run one doc TTL sweep pass now (test and ops hook). Returns the number of docs tombstoned.

Clean up when terminating

Types

att_info/0

-type att_info() ::
          #{name := binary(),
            content_type := binary(),
            length := non_neg_integer(),
            digest := binary(),
            chunked => boolean(),
            chunk_size => pos_integer(),
            chunk_count => pos_integer()}.

change/0

-type change() :: map().

db_config/0

-type db_config() :: #{path => string(), store => module(), atom() => term()}.

db_name/0

-type db_name() :: binary().

db_ref/0

-type db_ref() :: pid() | atom().

doc/0

-type doc() :: #{binary() => term()}.

doc_info/0

-type doc_info() :: #{id := docid(), rev := revid(), deleted := boolean(), revtree := revtree()}.

docid/0

-type docid() :: binary().

endpoint/0

-type endpoint() :: db_name() | {node(), db_name()} | {module(), term()}.

rep_options/0

-type rep_options() ::
          #{continuous => boolean(),
            since => seq_string(),
            filter => fun((doc()) -> boolean()),
            atom() => term()}.

rev_info/0

-type rev_info() ::
          #{id := revid(),
            parent := revid() | undefined,
            deleted := boolean(),
            attachments => #{binary() => att_info()}}.

revid/0

-type revid() :: binary().

revtree/0

-type revtree() :: #{revid() => rev_info()}.

seq/0

-type seq() :: barrel_hlc:timestamp().

seq_string/0

-type seq_string() :: binary().

view_name/0

-type view_name() :: binary().

view_result/0

-type view_result() :: #{key := term(), value := term(), id := docid()}.

Functions

checkpoint_to(Pid, DocsPath, AttPath)

-spec checkpoint_to(pid(), string(), string()) -> {ok, barrel_hlc:timestamp()} | {error, term()}.

Checkpoint both stores into a branch's directories, minting the fork instant inside the writer: every write applied before this call is in the checkpoint and every later one has a larger HLC. Blocks the writer for the memtable flush + hard links.

delete_doc(Pid, DocId, Opts)

-spec delete_doc(pid(), binary(), map()) -> {ok, map()} | {error, term()}.

Delete a document

delete_local_doc(Pid, DocId)

-spec delete_local_doc(pid(), binary()) -> ok | {error, not_found}.

Delete a local document

diff_versions(Pid, TokenMap)

-spec diff_versions(pid(), #{binary() => binary()}) ->
                       {ok, #{binary() => missing | have}} | {error, term()}.

Get revisions difference (for replication) Returns {ok, Missing, PossibleAncestors}

fold_docs(Pid, Fun, Acc)

-spec fold_docs(pid(), fun(), term()) -> {ok, term()}.

Fold over all documents

fold_docs(Pid, Fun, Acc, Opts)

-spec fold_docs(pid(), fun(), term(), map()) -> {ok, term()}.

Fold over all documents with options

fold_local_docs(Pid, Prefix, Fun, Acc)

-spec fold_local_docs(pid(), binary(), fun((binary(), map(), term()) -> term()), term()) ->
                         {ok, term()} | {error, term()}.

Fold over local documents with a given prefix

get_att_ref(Pid)

-spec get_att_ref(pid()) -> {ok, barrel_att_store:att_ref()} | {error, term()}.

Get the attachment store reference

get_conflicts(Pid, DocId)

-spec get_conflicts(pid(), binary()) -> {ok, [binary()]} | {error, term()}.

Get conflicts for a document Returns list of conflicting revision IDs (excluding the winner)

get_doc(Pid, DocId, Opts)

-spec get_doc(pid(), binary(), map()) ->
                 {ok, map()} | {ok, binary(), map()} | {error, not_found} | {error, term()}.

Get a document When raw_body => true in Opts, returns {ok, CborBin, Meta} for zero-copy responses

get_docs(Pid, DocIds, Opts)

-spec get_docs(pid(), [binary()], map()) -> [{ok, map()} | {error, not_found} | {error, term()}].

Get multiple documents (batch read)

get_local_doc(Pid, DocId)

-spec get_local_doc(pid(), binary()) -> {ok, map()} | {error, not_found}.

Get a local document

get_store_ref(Pid)

-spec get_store_ref(pid()) -> {ok, barrel_store_rocksdb:db_ref()} | {error, term()}.

Get the document store reference

handle_call(Request, From, State)

Handle synchronous calls

handle_cast(Msg, State)

Handle asynchronous casts

handle_info(Info, State)

Handle other messages The periodic compaction/retention/ttl work runs in a monitored worker so it never blocks the writer loop (a long compaction used to make concurrent writes time out). The periodic timer is re-armed when the worker finishes.

info(Pid)

-spec info(pid()) -> {ok, map()} | {error, term()}.

Get database info

init(_)

Initialize the database server

outbox_ack(Pid, Tag, Hlcs)

-spec outbox_ack(pid(), barrel_outbox:tag(), [barrel_hlc:timestamp()]) -> ok | {error, term()}.

Acknowledge processed outbox entries by their exact HLC keys. Deleting a key that was already replaced by a newer write is a no-op, so acks never lose work (see barrel_outbox).

put_doc(Pid, Doc, Opts)

-spec put_doc(pid(), map(), map()) -> {ok, map()} | {error, term()}.

Put a document (create or update)

put_docs(Pid, Docs, Opts)

-spec put_docs(pid(), [map()], map()) -> [{ok, map()} | {error, term()}].

Put multiple documents (batch write)

put_local_doc(Pid, DocId, Doc)

-spec put_local_doc(pid(), binary(), map()) -> ok | {error, term()}.

Put a local document (not replicated)

put_version(Pid, Doc, VersionToken, VVBin, Deleted)

-spec put_version(pid(), map(), binary(), binary(), boolean()) ->
                     {ok, binary(), binary()} | {error, term()}.

Put a document with explicit revision history (for replication) Returns {ok, DocId, RevId} on success.

resolve_conflict(Pid, DocId, BaseRev, Resolution)

-spec resolve_conflict(pid(), binary(), binary(), {choose, binary()} | {merge, map()}) ->
                          {ok, map()} | {error, term()}.

Resolve a conflict by choosing a winning revision or providing a merged doc Resolution can be: - {choose, Rev} - keep this revision as winner, delete other branches - {merge, Doc} - create new revision merging all conflicts

set_doc_embedding(Pid, DocId, ExpectedRev, Vector)

-spec set_doc_embedding(pid(), binary(), binary(), [number()]) ->
                           ok | {error, conflict | not_found | term()}.

Store a computed embedding as the document's embedding column. CAS on the expected revision: embeddings are derived data, so this never bumps the revision or emits a change; a conflict means a newer write exists (which re-drives the computing indexer anyway).

start_link(Name, Config)

-spec start_link(binary(), map()) -> {ok, pid()} | {error, term()}.

Start the database server

stop(Pid)

-spec stop(pid()) -> ok.

Stop the database server

sweep_retention(Pid)

-spec sweep_retention(pid()) -> {ok, map()} | {error, term()}.

Run a retention sweep now. Prunes history entries, superseded version bodies and expired tombstones older than the retention window, then advances the history floor. No-op when retention is infinite (retention_period 0).

sweep_ttl(Pid)

-spec sweep_ttl(pid()) -> {ok, non_neg_integer()}.

Run one doc TTL sweep pass now (test and ops hook). Returns the number of docs tombstoned.

terminate(Reason, State)

Clean up when terminating