base2histogram 0.1.1

A Rust histogram library using base-2 logarithmic bucketing for fast percentile estimation
Documentation
# base2histogram

`base2histogram` is a Rust histogram library for fast percentile estimation with
base-2 logarithmic bucketing.

It is designed for latency and metrics workloads where:

- recording should be `O(1)`,
- memory usage should stay bounded,
- percentile queries should be cheap,
- and large `u64` values should still be representable without resizing.

## Features

- Fixed-size histogram over the full `u64` range.
- Base-2 logarithmic buckets with bounded relative error.
- Cheap percentile queries such as `P50`, `P99`, and `P99.9`.
- Optional multi-slot mode for sliding-window style aggregation.
- No external runtime or allocator tricks required.

## Bucket Model

The default configuration uses 3 significant bits to define a bucket:

- values `0..=7` are represented exactly,
- values `8..=15` are grouped with step size `2`,
- values `16..=31` are grouped with step size `4`,
- larger values keep doubling the bucket width with the magnitude.

This keeps relative error bounded while covering the entire `u64` range in a
small, fixed number of buckets.

## Usage

```rust
use base2histogram::Histogram;

let mut hist = Histogram::<()>::new();

hist.record(5);
hist.record(8);
hist.record(13);
hist.record_n(21, 3);

assert_eq!(hist.total(), 6);

let p50 = hist.percentile(0.50);
let p99 = hist.percentile(0.99);

assert!(p50 <= p99);
```

`percentile()` returns the minimum value of the bucket that contains the target
percentile. This is intentional: the histogram stores bucketed counts, not raw
samples.

## Sliding Window

Use `with_slots()` plus `advance()` when metrics should be aggregated over a
bounded set of recent windows:

```rust
use base2histogram::Histogram;

let mut hist = Histogram::<&'static str>::with_slots(2);

hist.record_n(10, 2);
hist.advance("warm");
hist.record_n(100, 3);

assert_eq!(hist.total(), 5);

hist.advance("steady");

// The oldest slot is evicted once the slot limit is reached.
assert_eq!(hist.total(), 3);
```

## Common Stats

```rust
use base2histogram::Histogram;

let mut hist = Histogram::<()>::new();
hist.record_n(20, 80);
hist.record_n(80, 20);

let stats = hist.percentile_stats();

assert_eq!(stats.samples, 100);
assert_eq!(stats.p50, 20);
assert_eq!(stats.p90, 80);
```

## Development

Common local commands:

```bash
make check
make test
make lint
make doc
```

## License

Licensed under Apache-2.0. See [LICENSE](./LICENSE).