PhoenixKit.Modules.Storage.KeyLayout (phoenix_kit v2.60.2)

Copy Markdown View Source

How deep a storage profile fans its keys out (StorageProfile.key_levels, V216).

A file's folder is <prefix>/<md5>, with levels two-character hash folders between them:

0   lib-1a2b3c/22e8b90781bab72967f9d5410b4299f9/…
1   lib-1a2b3c/22/22e8b90781bab72967f9d5410b4299f9/…        (the layout so far)
2   lib-1a2b3c/22/e8/22e8b90781bab72967f9d5410b4299f9/…
3   lib-1a2b3c/22/e8/b9/22e8b90781bab72967f9d5410b4299f9/…

Each hash folder has 256 possible names, and MD5 spreads files evenly over them, so n files leave about n / 256^levels file folders in each folder at the deepest level. That number is what a local disk feels (listing, backups, rsync); an object store has no folders and does not care. The layout applies to new uploads: a file's folder is stored on its row, so nothing already uploaded moves.

Summary

Functions

The number of files at which levels stops being comfortable.

The layout every profile had before it could be chosen (V216).

The layouts a profile may choose: the number of hash folders.

The folder of a file: prefix, levels hash folders, then the MD5.

About how many file folders the busiest folder holds once a library has files files, under levels.

How a folder of per_folder entries fares: :comfortable, :slow or :too_many.

The library sizes the Storage profiles tab compares.

One row per library size: {files, per_folder, rating} under levels.

Whether levels is a layout.

Functions

comfortable_up_to(levels)

@spec comfortable_up_to(0..3) :: pos_integer()

The number of files at which levels stops being comfortable.

default()

@spec default() :: 1

The layout every profile had before it could be chosen (V216).

levels()

@spec levels() :: [0..3]

The layouts a profile may choose: the number of hash folders.

path(prefix, md5, levels)

@spec path(String.t(), String.t(), non_neg_integer()) :: String.t()

The folder of a file: prefix, levels hash folders, then the MD5.

iex> PhoenixKit.Modules.Storage.KeyLayout.path("lib-1a2b", "22e8b907", 0)
"lib-1a2b/22e8b907"
iex> PhoenixKit.Modules.Storage.KeyLayout.path("lib-1a2b", "22e8b907", 1)
"lib-1a2b/22/22e8b907"
iex> PhoenixKit.Modules.Storage.KeyLayout.path("lib-1a2b", "22e8b907", 2)
"lib-1a2b/22/e8/22e8b907"

per_folder(files, levels)

@spec per_folder(non_neg_integer(), 0..3) :: non_neg_integer()

About how many file folders the busiest folder holds once a library has files files, under levels.

iex> PhoenixKit.Modules.Storage.KeyLayout.per_folder(1_000_000, 1)
3907
iex> PhoenixKit.Modules.Storage.KeyLayout.per_folder(1_000_000, 0)
1000000

rating(per_folder)

@spec rating(non_neg_integer()) :: :comfortable | :slow | :too_many

How a folder of per_folder entries fares: :comfortable, :slow or :too_many.

sizes()

@spec sizes() :: [pos_integer()]

The library sizes the Storage profiles tab compares.

table(levels)

@spec table(0..3) :: [{pos_integer(), non_neg_integer(), atom()}]

One row per library size: {files, per_folder, rating} under levels.

valid?(levels)

@spec valid?(term()) :: boolean()

Whether levels is a layout.