Ferricstore.Bitcask.NIF (ferricstore v0.3.5)

Copy Markdown View Source

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

fs_error()

@type fs_error() :: {:error, {atom(), binary()}}

Functions

bloom_file_add(path, element)

@spec bloom_file_add(binary(), binary()) :: :ok | {:error, term()}

bloom_file_card(path)

@spec bloom_file_card(binary()) :: {:ok, non_neg_integer()} | {:error, term()}

bloom_file_card_async(caller_pid, correlation_id, path)

@spec bloom_file_card_async(pid(), term(), binary()) :: :ok | {:error, term()}

bloom_file_create(path, num_bits, num_hashes)

@spec bloom_file_create(binary(), non_neg_integer(), non_neg_integer()) ::
  :ok | {:error, term()}

bloom_file_exists(path, element)

@spec bloom_file_exists(binary(), binary()) :: {:ok, boolean()} | {:error, term()}

bloom_file_exists_async(caller_pid, correlation_id, path, element)

@spec bloom_file_exists_async(pid(), term(), binary(), binary()) ::
  :ok | {:error, term()}

bloom_file_info(path)

@spec bloom_file_info(binary()) ::
  {:ok, {non_neg_integer(), non_neg_integer(), non_neg_integer()}}
  | {:error, term()}

bloom_file_info_async(caller_pid, correlation_id, path)

@spec bloom_file_info_async(pid(), term(), binary()) :: :ok | {:error, term()}

bloom_file_madd(path, elements)

@spec bloom_file_madd(binary(), [binary()]) :: :ok | {:error, term()}

bloom_file_mexists(path, elements)

@spec bloom_file_mexists(binary(), [binary()]) ::
  {:ok, [boolean()]} | {:error, term()}

bloom_file_mexists_async(caller_pid, correlation_id, path, elements)

@spec bloom_file_mexists_async(pid(), term(), binary(), [binary()]) ::
  :ok | {:error, term()}

cms_file_create(path, width, depth)

@spec cms_file_create(binary(), non_neg_integer(), non_neg_integer()) ::
  :ok | {:error, term()}

cms_file_incrby(path, items)

@spec cms_file_incrby(binary(), [{binary(), non_neg_integer()}]) ::
  :ok | {:error, term()}

cms_file_info(path)

@spec cms_file_info(binary()) ::
  {:ok, {non_neg_integer(), non_neg_integer(), non_neg_integer()}}
  | {:error, term()}

cms_file_info_async(caller_pid, correlation_id, path)

@spec cms_file_info_async(pid(), term(), binary()) :: :ok | {:error, term()}

cms_file_merge(dst_path, src_paths, weights)

@spec cms_file_merge(binary(), [binary()], [number()]) :: :ok | {:error, term()}

cms_file_query(path, elements)

@spec cms_file_query(binary(), [binary()]) ::
  {:ok, [non_neg_integer()]} | {:error, term()}

cms_file_query_async(caller_pid, correlation_id, path, elements)

@spec cms_file_query_async(pid(), term(), binary(), [binary()]) ::
  :ok | {:error, term()}

cuckoo_file_add(path, element)

@spec cuckoo_file_add(binary(), binary()) :: :ok | {:error, term()}

cuckoo_file_addnx(path, element)

@spec cuckoo_file_addnx(binary(), binary()) :: {:ok, boolean()} | {:error, term()}

cuckoo_file_count(path, element)

@spec cuckoo_file_count(binary(), binary()) ::
  {:ok, non_neg_integer()} | {:error, term()}

cuckoo_file_count_async(caller_pid, correlation_id, path, element)

@spec cuckoo_file_count_async(pid(), term(), binary(), binary()) ::
  :ok | {:error, term()}

cuckoo_file_create(path, capacity, bucket_size)

@spec cuckoo_file_create(binary(), non_neg_integer(), non_neg_integer()) ::
  :ok | {:error, term()}

cuckoo_file_del(path, element)

@spec cuckoo_file_del(binary(), binary()) :: :ok | {:error, term()}

cuckoo_file_exists(path, element)

@spec cuckoo_file_exists(binary(), binary()) :: {:ok, boolean()} | {:error, term()}

cuckoo_file_exists_async(caller_pid, correlation_id, path, element)

@spec cuckoo_file_exists_async(pid(), term(), binary(), binary()) ::
  :ok | {:error, term()}

cuckoo_file_info(path)

@spec cuckoo_file_info(binary()) :: {:ok, tuple()} | {:error, term()}

cuckoo_file_info_async(caller_pid, correlation_id, path)

@spec cuckoo_file_info_async(pid(), term(), binary()) :: :ok | {:error, term()}

fs_exists(path)

@spec fs_exists(binary()) :: boolean()

Does the path exist? Follows symlinks (broken symlink → false). Never returns an error for the common kinds (missing, no-permission).

fs_is_dir(path)

@spec fs_is_dir(binary()) :: boolean()

Is the path a directory? Follows symlinks. Returns false for missing paths (matches File.dir?/1).

fs_ls(path)

@spec fs_ls(binary()) :: {:ok, [binary()]} | fs_error()

List the entries in a directory (names only, no path prefix). Yields every 256 entries to keep BEAM reductions accurate on huge directories.

fs_mkdir_p(path)

@spec fs_mkdir_p(binary()) :: :ok | fs_error()

Recursive mkdir -p. Idempotent when the directory already exists. Equivalent to File.mkdir_p/1.

fs_rename(old_path, new_path)

@spec fs_rename(binary(), binary()) :: :ok | fs_error()

Atomic rename. On POSIX, rename replaces the target atomically. Cross-device renames return {:error, {:other, _}} — caller must handle with copy+remove.

fs_rm(path)

@spec fs_rm(binary()) :: :ok | fs_error()

Remove a single file. Use fs_rm_rf_async/3 for directory trees.

fs_rm_rf_async(caller_pid, correlation_id, path)

@spec fs_rm_rf_async(pid(), term(), binary()) :: :ok | fs_error()

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.

fs_touch(path)

@spec fs_touch(binary()) :: :ok | fs_error()

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).

rust_allocated_bytes()

@spec rust_allocated_bytes() :: {:ok, non_neg_integer()} | {:error, term()}

topk_file_add_v2(path, elements)

@spec topk_file_add_v2(binary(), [binary()]) ::
  {:ok, [binary() | nil]} | {:error, term()}

topk_file_count_v2(path, elements)

@spec topk_file_count_v2(binary(), [binary()]) ::
  {:ok, [non_neg_integer()]} | {:error, term()}

topk_file_count_v2_async(caller_pid, correlation_id, path, elements)

@spec topk_file_count_v2_async(pid(), term(), binary(), [binary()]) ::
  :ok | {:error, term()}

topk_file_create_v2(path, k, width, depth, decay)

@spec topk_file_create_v2(
  binary(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer(),
  float()
) ::
  :ok | {:error, term()}

topk_file_incrby_v2(path, pairs)

@spec topk_file_incrby_v2(binary(), [{binary(), non_neg_integer()}]) ::
  {:ok, [binary() | nil]} | {:error, term()}

topk_file_info_v2(path)

@spec topk_file_info_v2(binary()) :: {:ok, tuple()} | {:error, term()}

topk_file_info_v2_async(caller_pid, correlation_id, path)

@spec topk_file_info_v2_async(pid(), term(), binary()) :: :ok | {:error, term()}

topk_file_list_v2(path)

@spec topk_file_list_v2(binary()) ::
  {:ok, [{binary(), non_neg_integer()}]} | {:error, term()}

topk_file_list_v2_async(caller_pid, correlation_id, path)

@spec topk_file_list_v2_async(pid(), term(), binary()) :: :ok | {:error, term()}

topk_file_query_v2(path, elements)

@spec topk_file_query_v2(binary(), [binary()]) ::
  {:ok, [boolean()]} | {:error, term()}

topk_file_query_v2_async(caller_pid, correlation_id, path, elements)

@spec topk_file_query_v2_async(pid(), term(), binary(), [binary()]) ::
  :ok | {:error, term()}

v2_append_batch(path, records)

@spec v2_append_batch(binary(), [{binary(), binary(), non_neg_integer()}]) ::
  {:ok, [{non_neg_integer(), non_neg_integer()}]} | {:error, term()}

v2_append_batch_async(caller_pid, correlation_id, path, records)

@spec v2_append_batch_async(pid(), term(), binary(), [
  {binary(), binary(), non_neg_integer()}
]) ::
  :ok | {:error, term()}

v2_append_batch_nosync(path, records)

@spec v2_append_batch_nosync(binary(), [{binary(), binary(), non_neg_integer()}]) ::
  {:ok, [{non_neg_integer(), non_neg_integer()}]} | {:error, term()}

v2_append_record(path, key, value, expire_at_ms)

@spec v2_append_record(binary(), binary(), binary(), non_neg_integer()) ::
  {:ok, {non_neg_integer(), non_neg_integer()}} | {:error, term()}

v2_append_tombstone(path, key)

@spec v2_append_tombstone(binary(), binary()) ::
  {:ok, non_neg_integer()} | {:error, term()}

v2_copy_records(source_path, dest_path, offsets)

@spec v2_copy_records(binary(), binary(), [non_neg_integer()]) ::
  :ok | {:error, term()}

v2_fsync(path)

@spec v2_fsync(binary()) :: :ok | {:error, term()}

v2_fsync_async(caller_pid, correlation_id, path)

@spec v2_fsync_async(pid(), term(), binary()) :: :ok | {:error, term()}

v2_fsync_dir(path)

@spec v2_fsync_dir(binary()) :: :ok | {: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.

v2_pread_at(path, offset)

@spec v2_pread_at(binary(), non_neg_integer()) :: {:ok, binary()} | {:error, term()}

v2_pread_at_async(caller_pid, correlation_id, path, offset)

@spec v2_pread_at_async(pid(), term(), binary(), non_neg_integer()) ::
  :ok | {:error, term()}

v2_pread_batch(path, locations)

@spec v2_pread_batch(binary(), [{non_neg_integer(), non_neg_integer()}]) ::
  {:ok, [binary()]} | {:error, term()}

v2_pread_batch_async(caller_pid, correlation_id, locations)

@spec v2_pread_batch_async(pid(), term(), [{binary(), non_neg_integer()}]) ::
  :ok | {:error, term()}

v2_read_hint_file(path)

@spec v2_read_hint_file(binary()) ::
  {:ok,
   [
     {binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(),
      non_neg_integer()}
   ]}
  | {:error, term()}

v2_scan_file(path)

@spec v2_scan_file(binary()) ::
  {:ok,
   [
     {binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(),
      boolean()}
   ]}
  | {:error, term()}

v2_write_hint_file(path, entries)

@spec v2_write_hint_file(binary(), [
  {binary(), non_neg_integer(), non_neg_integer(), non_neg_integer(),
   non_neg_integer()}
]) :: :ok | {:error, term()}