Rustler NIF bindings for Bitcask record I/O, hint files, and mmap-backed probabilistic data structure file operations.
Summary
Functions
Does the path exist? Follows symlinks (broken symlink → false). Never returns an error for the common kinds (missing, no-permission).
Is the path a directory? Follows symlinks. Returns false for
missing paths (matches File.dir?/1).
List the entries in a directory (names only, no path prefix). Yields every 256 entries to keep BEAM reductions accurate on huge directories.
Recursive mkdir -p. Idempotent when the directory already exists.
Equivalent to File.mkdir_p/1.
Atomic rename. On POSIX, rename replaces the target atomically.
Cross-device renames return {:error, {:other, _}} — caller must
handle with copy+remove.
Remove a single file. Use fs_rm_rf_async/3 for directory trees.
Async recursive remove. Runs on the Tokio blocking pool; sends
{:tokio_complete, correlation_id, :ok} or
{:tokio_complete, correlation_id, :error, {kind, msg}} to the
caller on completion. Idempotent: removing a non-existent path sends
:ok.
Creates an empty file if it does not exist. Idempotent on an existing
file (does not truncate). Equivalent to File.touch!/1 without the
timestamp update (matches our callers' usage).
Fsyncs a directory so that recent File.rename/2, File.rm/1,
File.touch!/1, or File.create/1 operations on files inside it are
durable. Use after any namespace mutation that must survive a kernel
panic — rotation, compaction rename, hint-file creation, prob-file
create/delete, shard init.
Types
@type append_op() :: {:put, binary(), binary(), non_neg_integer()} | {:delete, binary()}
@type append_op_location() :: {:put, non_neg_integer(), non_neg_integer()} | {:delete, non_neg_integer(), non_neg_integer()}
@type flow_index_resource() :: reference()
@type flow_record_claim_history_entry() :: {binary(), binary(), non_neg_integer(), non_neg_integer(), binary(), binary(), non_neg_integer() | nil, non_neg_integer() | nil, boolean()}
@type flow_record_claim_history_plan() :: {binary(), flow_index_claim_entry(), binary(), non_neg_integer() | nil, flow_record_claim_history_entry()}
@type flow_record_claim_plan() :: {binary(), flow_index_claim_entry(), binary(), non_neg_integer() | nil}
@type pread_batch_result() :: [pread_batch_value()]
Functions
@spec bloom_file_card(binary()) :: {:ok, non_neg_integer()} | {:error, term()}
@spec bloom_file_create(binary(), non_neg_integer(), non_neg_integer()) :: :ok | {:error, term()}
@spec bloom_file_info(binary()) :: {:ok, {non_neg_integer(), non_neg_integer(), non_neg_integer()}} | {:error, term()}
@spec cms_file_create(binary(), non_neg_integer(), non_neg_integer()) :: :ok | {:error, term()}
@spec cms_file_incrby(binary(), [{binary(), non_neg_integer()}]) :: :ok | {:error, term()}
@spec cms_file_info(binary()) :: {:ok, {non_neg_integer(), non_neg_integer(), non_neg_integer()}} | {:error, term()}
@spec cms_file_query(binary(), [binary()]) :: {:ok, [non_neg_integer()]} | {:error, term()}
@spec cuckoo_file_count(binary(), binary()) :: {:ok, non_neg_integer()} | {:error, term()}
@spec cuckoo_file_create(binary(), non_neg_integer(), non_neg_integer()) :: :ok | {:error, term()}
@spec flow_history_encode( binary(), non_neg_integer() | nil, non_neg_integer() | nil, binary() | nil, binary() | nil, binary() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() ) :: binary()
@spec flow_index_apply_claim_entries(flow_index_resource(), [flow_index_claim_entry()]) :: :ok
@spec flow_index_claim_due_candidates( flow_index_resource(), [binary()], float(), non_neg_integer(), non_neg_integer() ) :: [{binary(), [{binary(), float()}]}]
@spec flow_index_count_all(flow_index_resource(), binary()) :: non_neg_integer()
@spec flow_index_count_keys(flow_index_resource()) :: [binary()]
@spec flow_index_count_many(flow_index_resource(), [binary()]) :: [non_neg_integer()]
@spec flow_index_delete_count(flow_index_resource(), binary()) :: :ok
@spec flow_index_delete_entries(flow_index_resource(), [{binary(), binary()}]) :: :ok
@spec flow_index_delete_members(flow_index_resource(), binary(), [binary()]) :: :ok
@spec flow_index_due_count_keys(flow_index_resource()) :: [binary()]
@spec flow_index_due_keys_present(flow_index_resource(), [binary()], float()) :: [ binary() ]
@spec flow_index_move_entries(flow_index_resource(), [ {binary(), binary(), binary(), float()} ]) :: :ok
@spec flow_index_new() :: flow_index_resource()
@spec flow_index_put_entries(flow_index_resource(), [{binary(), binary(), float()}]) :: :ok
@spec flow_index_put_new_entries(flow_index_resource(), [ {binary(), binary(), float()} ]) :: :ok
@spec flow_index_range_slice( flow_index_resource(), binary(), non_neg_integer(), float(), non_neg_integer(), float(), boolean(), non_neg_integer(), integer() ) :: [{binary(), float()}]
@spec flow_index_restore_count(flow_index_resource(), binary(), integer()) :: :ok
@spec flow_index_rollback_claim_entries(flow_index_resource(), [ flow_index_claim_entry() ]) :: :ok
@spec flow_index_score_of(flow_index_resource(), binary(), binary()) :: {:ok, float()} | :miss
@spec flow_index_take_due( flow_index_resource(), binary(), float(), non_neg_integer() ) :: [{binary(), float()}]
flow_record_encode(id, type, state, version, attempts, fencing_token, created_at_ms, updated_at_ms, next_run_at_ms, priority, ttl_ms, history_hot_max_events, history_max_events, retention_ttl_ms, terminal_retention_until_ms, partition_key, payload_ref, parent_flow_id, parent_partition_key, root_flow_id, correlation_id, result_ref, error_ref, lease_owner, lease_token, lease_deadline_ms, run_state, rewound_to_event_id, child_groups_encoded)
@spec flow_record_encode( binary() | nil, binary() | nil, binary() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, non_neg_integer() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, binary() | nil, non_neg_integer() | nil, binary() | nil, binary() | nil, binary() ) :: binary()
@spec flow_record_plan_claims( [{binary(), float()}], [binary() | nil], binary(), binary(), binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(), binary(), binary(), binary(), binary(), binary(), binary(), binary() ) :: {:ok, [flow_record_claim_plan()], [binary()], non_neg_integer()} | :fallback
@spec flow_record_plan_claims_with_history( [{binary(), float()}], [binary() | nil], binary(), binary(), binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(), binary(), binary(), binary(), binary(), binary(), binary(), binary(), binary() ) :: {:ok, [flow_record_claim_history_plan()], [binary()], non_neg_integer()} | :fallback
Does the path exist? Follows symlinks (broken symlink → false). Never returns an error for the common kinds (missing, no-permission).
Is the path a directory? Follows symlinks. Returns false for
missing paths (matches File.dir?/1).
List the entries in a directory (names only, no path prefix). Yields every 256 entries to keep BEAM reductions accurate on huge directories.
Recursive mkdir -p. Idempotent when the directory already exists.
Equivalent to File.mkdir_p/1.
Atomic rename. On POSIX, rename replaces the target atomically.
Cross-device renames return {:error, {:other, _}} — caller must
handle with copy+remove.
Remove a single file. Use fs_rm_rf_async/3 for directory trees.
Async recursive remove. Runs on the Tokio blocking pool; sends
{:tokio_complete, correlation_id, :ok} or
{:tokio_complete, correlation_id, :error, {kind, msg}} to the
caller on completion. Idempotent: removing a non-existent path sends
:ok.
Creates an empty file if it does not exist. Idempotent on an existing
file (does not truncate). Equivalent to File.touch!/1 without the
timestamp update (matches our callers' usage).
@spec io_uring_available() :: boolean()
@spec lmdb_clear(binary(), non_neg_integer()) :: :ok | {:error, term()}
@spec lmdb_delete(binary(), binary(), non_neg_integer()) :: :ok | {:error, term()}
@spec lmdb_get(binary(), binary(), non_neg_integer()) :: {:ok, binary()} | :not_found | {:error, term()}
@spec lmdb_get_many(binary(), [binary()], non_neg_integer()) :: {:ok, [{:ok, binary()} | :not_found]} | {:error, term()}
@spec lmdb_prefix_count(binary(), binary(), non_neg_integer()) :: {:ok, non_neg_integer()} | {:error, term()}
@spec lmdb_prefix_entries(binary(), binary(), non_neg_integer(), non_neg_integer()) :: {:ok, [{binary(), binary()}]} | {:error, term()}
@spec lmdb_prefix_entries_after( binary(), binary(), binary(), non_neg_integer(), non_neg_integer() ) :: {:ok, [{binary(), binary()}]} | {:error, term()}
@spec lmdb_prefix_entries_reverse( binary(), binary(), non_neg_integer(), non_neg_integer() ) :: {:ok, [{binary(), binary()}]} | {:error, term()}
@spec lmdb_prefix_entries_reverse_before( binary(), binary(), binary(), non_neg_integer(), non_neg_integer() ) :: {:ok, [{binary(), binary()}]} | {:error, term()}
@spec lmdb_put(binary(), binary(), binary(), non_neg_integer()) :: :ok | {:error, term()}
@spec lmdb_release_all() :: {:ok, non_neg_integer()} | {:busy, non_neg_integer()} | {:error, term()}
@spec lmdb_write_batch(binary(), [lmdb_op()], non_neg_integer()) :: :ok | {:error, term()}
@spec lmdb_write_batch_with_originals(binary(), [lmdb_op()], non_neg_integer()) :: {:ok, [lmdb_original()]} | {:error, term()}
@spec rust_allocated_bytes() :: {:ok, non_neg_integer()} | {:error, term()}
@spec topk_file_count_v2(binary(), [binary()]) :: {:ok, [non_neg_integer()]} | {:error, term()}
@spec topk_file_create_v2( binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(), float() ) :: :ok | {:error, term()}
@spec topk_file_incrby_v2(binary(), [{binary(), non_neg_integer()}]) :: {:ok, [binary() | nil]} | {:error, term()}
@spec topk_file_list_v2(binary()) :: {:ok, [{binary(), non_neg_integer()}]} | {:error, term()}
@spec v2_append_batch(binary(), [{binary(), binary(), non_neg_integer()}]) :: {:ok, [{non_neg_integer(), non_neg_integer()}]} | {:error, term()}
@spec v2_append_batch_nosync(binary(), [{binary(), binary(), non_neg_integer()}]) :: {:ok, [{non_neg_integer(), non_neg_integer()}]} | {:error, term()}
@spec v2_append_ops_batch_nosync(binary(), [append_op()]) :: {:ok, [append_op_location()]} | {:error, term()}
@spec v2_append_record(binary(), binary(), binary(), non_neg_integer()) :: {:ok, {non_neg_integer(), non_neg_integer()}} | {:error, term()}
@spec v2_append_tombstone(binary(), binary()) :: {:ok, {non_neg_integer(), non_neg_integer()}} | {:error, term()}
@spec v2_available_disk_space(binary()) :: {:ok, non_neg_integer()} | {:error, term()}
@spec v2_copy_records(binary(), binary(), [non_neg_integer()]) :: {:ok, [{non_neg_integer(), non_neg_integer()}]} | {:error, term()}
@spec v2_copy_records_preserve_tombstones(binary(), binary(), [non_neg_integer()], [ non_neg_integer() ]) :: {:ok, [{non_neg_integer(), non_neg_integer()}]} | {:error, term()}
Fsyncs a directory so that recent File.rename/2, File.rm/1,
File.touch!/1, or File.create/1 operations on files inside it are
durable. Use after any namespace mutation that must survive a kernel
panic — rotation, compaction rename, hint-file creation, prob-file
create/delete, shard init.
Returns :ok on success or {:error, reason} where reason is a
short string suitable for logging.
POSIX: file-data fsync does NOT make the filename durable; only a directory fsync does.
@spec v2_pread_at(binary(), non_neg_integer()) :: {:ok, binary()} | {:error, term()}
@spec v2_pread_at_async(pid(), term(), binary(), non_neg_integer()) :: :ok | {:error, term()}
@spec v2_pread_batch(binary(), [non_neg_integer()]) :: {:ok, [binary() | nil]} | {:error, term()}
@spec v2_pread_batch_async(pid(), term(), [{binary(), non_neg_integer()}]) :: :ok | {:error, term()}
@spec v2_pread_batch_grouped_async( pid(), term(), [{binary(), [{non_neg_integer(), non_neg_integer()}]}] ) :: :ok | {:error, term()}
@spec v2_pread_batch_grouped_key_async( pid(), term(), [{binary(), [{non_neg_integer(), non_neg_integer(), binary()}]}] ) :: :ok | {:error, term()}
@spec v2_pread_batch_path_async(pid(), term(), binary(), [non_neg_integer()]) :: :ok | {:error, term()}
@spec v2_read_hint_file(binary()) :: {:ok, [ {binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer()} ]} | {:error, term()}
@spec v2_scan_file(binary()) :: {:ok, [ {binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(), boolean()} ]} | {:error, term()}
@spec v2_scan_file_from_offset(binary(), non_neg_integer()) :: {:ok, [ {binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(), boolean()} ]} | {:error, term()}
@spec v2_scan_file_page(binary(), non_neg_integer(), pos_integer()) :: {:ok, [ {binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(), boolean()} ], non_neg_integer(), boolean()} | {:error, term()}
@spec v2_scan_tombstones(binary()) :: {:ok, [{binary(), non_neg_integer(), non_neg_integer(), non_neg_integer()}]} | {:error, term()}
@spec v2_validate_value_ref(binary(), non_neg_integer(), binary(), non_neg_integer()) :: {:ok, {non_neg_integer(), non_neg_integer()}} | :mismatch | {:error, term()}
@spec v2_write_hint_file(binary(), [ {binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer()} ]) :: :ok | {:error, term()}