Manages the FerricStore on-disk directory layout (spec section 2B.4).
The canonical directory structure under data_dir is:
data_dir/
data/shard_0/ ... shard_N/ (shared Bitcask per shard)
dedicated/shard_0/ ... shard_N/ (for future promoted collections)
prob/shard_0/ ... shard_N/ (probabilistic structure files)
raft/shard_0/ ... shard_N/ (Raft WAL - managed by ra)
registry/ (merge scheduler state)
hints/ (hot cache warm-up files)Backward compatibility
Before this layout was introduced, shard data was stored directly under
data_dir/shard_N/. For backward compatibility, shard_data_path/2 checks
whether the legacy data_dir/shard_N/ directory already exists. If it does,
that path is returned so that existing data is not orphaned. For fresh
installs (where no legacy directory exists), the new canonical path
data_dir/data/shard_N/ is used.
Usage
Call ensure_layout!/2 during application startup to create all placeholder
directories. Then use shard_data_path/2 wherever a per-shard Bitcask path
is needed.
Summary
Functions
Creates the full directory layout under data_dir.
Returns the Bitcask data path for a given shard index, respecting backward compatibility.
Returns the list of top-level subdirectory names that make up the layout.
Functions
@spec ensure_layout!(binary(), pos_integer()) :: :ok
Creates the full directory layout under data_dir.
For each of data/, dedicated/, prob/, and raft/,
per-shard subdirectories shard_0 through shard_{N-1} are created.
registry/ and hints/ are top-level directories without per-shard
subdirectories.
This function is idempotent -- calling it multiple times is safe.
Parameters
data_dir-- the root data directoryshard_count-- number of shards (default: 4)
Returns
:ok
Raises
Raises on filesystem errors (e.g. permission denied).
@spec shard_data_path(binary(), non_neg_integer()) :: binary()
Returns the Bitcask data path for a given shard index, respecting backward compatibility.
If the legacy path data_dir/shard_N/ already exists on disk, it is
returned to avoid orphaning existing data. Otherwise the canonical path
data_dir/data/shard_N/ is returned.
Parameters
data_dir-- the root data directoryshard_index-- zero-based shard index
Examples
# Legacy directory exists on disk:
iex> Ferricstore.DataDir.shard_data_path("/tmp/fs", 0)
"/tmp/fs/shard_0"
# Fresh install (no legacy directory):
iex> Ferricstore.DataDir.shard_data_path("/tmp/fs_new", 0)
"/tmp/fs_new/data/shard_0"
@spec top_level_dirs() :: [binary()]
Returns the list of top-level subdirectory names that make up the layout.
Useful for testing and introspection.