barrel_att_store_blob (barrel_docdb v1.1.1)
View SourceBlobDB storage backend for attachments
Uses a separate RocksDB instance with BlobDB enabled for storing attachment binary data. This avoids compaction issues from mixing small documents with large blobs.
Large attachments (>= chunk_threshold) are stored as chunks for streaming support. Small attachments are stored as single values.
This is the default attachment backend, selected by barrel_att_store when no other backend is configured.
Summary
Functions
Abort a put stream and clean up any written chunks
Feed entries since an HLC (exclusive). See barrel_att_feed.
Hard-link snapshot into Path (timeline forks); the target must not exist.
Close the attachment store
Close a stream (currently a no-op, but included for API completeness)
Delete an attachment Handles both single-value and chunked attachments.
Delete with options (origin_hlc for replicated deletes: the last-write-wins guard applies, and a tombstone lands even when the attachment was never seen locally).
Delete all attachments for a document
Finish a put stream: verify the digest, run the LWW guard, and commit metadata + feed row in one batch. Nothing is visible until this batch lands (chunks without metadata are unreadable), so a digest mismatch or a lost LWW race leaves nothing committed.
Fold over all attachments for a document
Retrieve an attachment Automatically handles both single-value and chunked attachments.
Get attachment info/metadata without reading the data
Open a stream for reading an attachment
Open an attachment store with BlobDB enabled
Store an attachment (async by default) Small attachments are stored as single values. Large attachments (>= chunk_threshold) are stored as chunks.
Store an attachment with options Options: - sync: boolean() - if true, sync to disk before returning (default: false) Options: - sync: sync to disk before returning - content_type: override the name-derived content type (replication preserves the source's) - origin_hlc: replicated write; the last-write-wins guard may answer {ok, ignored} - expected_digest: verify the data against a digest before committing anything
Open a stream for writing an attachment Returns a stream handle that can be used with write_chunk/2 and finish_stream/1
Read the next chunk from a stream
Maintenance escape hatch: synthesize feed rows for attachments written before the feed existed (format-break stance: they do not sync otherwise). Rebuilt entries carry the MINIMUM origin so any real write, local or remote, wins the LWW race against them; two rebuilt replicas converge by digest tie-break. Safe to re-run.
Write data to a put stream Data is buffered and written in chunks
Types
-type att_info() :: #{name := binary(), content_type := binary(), length := non_neg_integer(), digest := binary(), chunked => boolean(), chunk_size => pos_integer(), chunk_count => pos_integer()}.
-type att_ref() :: #{ref := rocksdb:db_handle(), path := string(), chunk_threshold => pos_integer(), chunk_size => pos_integer(), env => rocksdb:env_handle()}.
-type att_stream() :: #{att_ref := att_ref(), db_name := binary(), doc_id := binary(), att_name := binary(), info := att_info(), chunk_index := non_neg_integer(), chunk_count := non_neg_integer()}.
-type change() :: map().
-type db_name() :: binary().
-type docid() :: binary().
-type revid() :: binary().
-type seq() :: barrel_hlc:timestamp().
-type seq_string() :: binary().
-type view_name() :: binary().
Functions
-spec abort_stream(map()) -> ok.
Abort a put stream and clean up any written chunks
-spec att_changes(att_ref(), db_name(), barrel_hlc:timestamp() | first, map()) -> {ok, [barrel_att_feed:entry()], barrel_hlc:timestamp() | first}.
Feed entries since an HLC (exclusive). See barrel_att_feed.
-spec att_floor(att_ref(), db_name()) -> barrel_hlc:timestamp() | undefined.
Hard-link snapshot into Path (timeline forks); the target must not exist.
-spec close(att_ref()) -> ok.
Close the attachment store
-spec close_stream(att_stream()) -> ok.
Close a stream (currently a no-op, but included for API completeness)
Delete an attachment Handles both single-value and chunked attachments.
Delete with options (origin_hlc for replicated deletes: the last-write-wins guard applies, and a tombstone lands even when the attachment was never seen locally).
Delete all attachments for a document
Finish a put stream: verify the digest, run the LWW guard, and commit metadata + feed row in one batch. Nothing is visible until this batch lands (chunks without metadata are unreadable), so a digest mismatch or a lost LWW race leaves nothing committed.
Fold over all attachments for a document
Retrieve an attachment Automatically handles both single-value and chunked attachments.
Get attachment info/metadata without reading the data
Open a stream for reading an attachment
Open an attachment store with BlobDB enabled
Store an attachment (async by default) Small attachments are stored as single values. Large attachments (>= chunk_threshold) are stored as chunks.
-spec put(att_ref(), db_name(), docid(), binary(), binary(), map()) -> {ok, att_info()} | {ok, ignored} | {error, term()}.
Store an attachment with options Options: - sync: boolean() - if true, sync to disk before returning (default: false) Options: - sync: sync to disk before returning - content_type: override the name-derived content type (replication preserves the source's) - origin_hlc: replicated write; the last-write-wins guard may answer {ok, ignored} - expected_digest: verify the data against a digest before committing anything
-spec put_stream(att_ref(), db_name(), docid(), binary(), binary()) -> {ok, map()} | {error, term()}.
Open a stream for writing an attachment Returns a stream handle that can be used with write_chunk/2 and finish_stream/1
-spec read_chunk(att_stream()) -> {ok, binary(), att_stream()} | eof | {error, term()}.
Read the next chunk from a stream
-spec rebuild_feed(att_ref(), db_name()) -> {ok, #{rows := non_neg_integer()}}.
Maintenance escape hatch: synthesize feed rows for attachments written before the feed existed (format-break stance: they do not sync otherwise). Rebuilt entries carry the MINIMUM origin so any real write, local or remote, wins the LWW race against them; two rebuilt replicas converge by digest tie-break. Safe to re-run.
-spec sweep_att_feed(att_ref(), db_name(), barrel_hlc:timestamp()) -> {ok, #{tombstones_swept := non_neg_integer()}}.
Write data to a put stream Data is buffered and written in chunks