# `HRW.Skeleton`

A skeleton-based variant of HRW that gives O(log n) lookups by grouping
nodes into clusters and routing keys through a virtual tree.

Build the skeleton once with `build/2`, then pass it to each `owner/3` call.
The skeleton is plain data, not a process.

# `t`

```elixir
@type t() :: %HRW.Skeleton{
  clusters: tuple(),
  fanout: pos_integer(),
  levels: non_neg_integer()
}
```

# `build`

```elixir
@spec build(
  [term()],
  keyword()
) :: t()
```

Builds a skeleton from `nodes`.

## Options

  * `:fanout` - branching factor of the virtual tree. Defaults to `3`.
  * `:cluster_size` - target number of nodes per cluster. Defaults to `16`.

## Examples

    iex> HRW.Skeleton.build(["server1", "server2", "server3"])
    #HRW.Skeleton<3 nodes, fanout: 3>

# `owner`

```elixir
@spec owner(term(), t(), keyword()) :: term()
```

Returns the node responsible for `key` in the given skeleton.

## Options

  * `:hash_fn` - a function `term -> integer`. Defaults to `&:erlang.phash2/1`.

## Examples

    iex> skeleton = HRW.Skeleton.build(["server1", "server2", "server3"])
    iex> HRW.Skeleton.owner("192.168.0.2", skeleton)
    "server3"

---

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