# `SuperCache.Config`
[🔗](https://github.com/ohhi-vn/super_cache/blob/main/lib/app/config.ex#L1)

Central configuration store for SuperCache.

Acts as a GenServer-backed key-value store with an optimisation for
hot-path keys: values for `@fast_keys` are also written to `:persistent_term`
so reads are allocation-free (no GenServer hop).

## Fast keys

The following keys are served from `:persistent_term` on every read:

- `:key_pos` — tuple index used as the ETS key
- `:partition_pos` — tuple index used to select partition
- `:num_partition` — number of ETS partitions
- `:table_type` — ETS table type (`:set`, `:bag`, etc.)
- `:table_prefix` — prefix for ETS table atom names

All other keys fall back to a `GenServer.call/3` with a 5-second timeout.

## Example

    SuperCache.Config.set_config(:my_key, "value")
    SuperCache.Config.get_config(:my_key)
    # => "value"

    # Fast key — zero-cost read
    SuperCache.Config.get_config(:num_partition)
    # => 8

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `clear_config`

```elixir
@spec clear_config() :: :ok
```

Clear all configuration values and erase all `:persistent_term` entries
for hot keys.

# `delete_config`

```elixir
@spec delete_config(any()) :: :ok
```

Delete a configuration value from the GenServer state and `:persistent_term`.

Uses a synchronous call to ensure the deletion is complete before returning,
preventing race conditions with concurrent reads.

# `distributed?`

```elixir
@spec distributed?() :: boolean()
```

Returns `true` when SuperCache is running in distributed mode.

Zero-cost read from `:persistent_term` — no GenServer hop.
This function is inlined by the compiler and is the fastest way to
check cluster mode on the hot path (called by every API operation).

## Examples

    SuperCache.Config.distributed?()
    # => true  (when cluster: :distributed was set at startup)

# `get_config`

```elixir
@spec get_config(any(), any()) :: any()
```

Read a configuration value.

Hot keys (`@fast_keys`) are served from `:persistent_term` with no
GenServer hop. All other keys use `GenServer.call/3` with a 5-second
timeout.

## Examples

    SuperCache.Config.get_config(:num_partition)
    # => 8

    SuperCache.Config.get_config(:unknown_key, :default)
    # => :default

# `get_key!`

```elixir
@spec get_key!(tuple()) :: any()
```

Extract the key element from a data tuple using the configured `:key_pos`.

Raises `Config` if the tuple is too small.

## Examples

    SuperCache.Config.set_config(:key_pos, 0)
    SuperCache.Config.get_key!({:user, 1, "Alice"})
    # => :user

# `get_partition!`

```elixir
@spec get_partition!(tuple()) :: any()
```

Extract the partition element from a data tuple using the configured `:partition_pos`.

Raises `Config` if the tuple is too small.

## Examples

    SuperCache.Config.set_config(:partition_pos, 1)
    SuperCache.Config.get_partition!({:user, 1, "Alice"})
    # => 1

# `has_config?`

```elixir
@spec has_config?(any()) :: boolean()
```

Check whether a configuration key exists in the GenServer state.

Note: This always hits the GenServer, even for fast keys, because
`:persistent_term` does not distinguish between "not set" and "set to nil".

# `set_config`

```elixir
@spec set_config(any(), any()) :: :ok
```

Store a configuration value.

Hot keys are also written to `:persistent_term` for fast subsequent reads.

# `start_link`

```elixir
@spec start_link(keyword()) :: :ignore | {:error, any()} | {:ok, pid()}
```

Starts the Config GenServer.

Accepts a keyword list of initial configuration values.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
