atomic-log 0.2.0

A segmented, zero-copy rolling log for one writer and many readers.
Documentation
# atomic-log

`atomic-log` is a Rust library for sharing a recent rolling window of values from one
writer to many readers with very little coordination.

It is built for in-process streaming workloads where readers care more about a stable,
recent view than about guaranteed delivery of every historical update. The log is
append-only, segmented, zero-copy on the read side, and uses atomics for publication.

## At a glance

- Single writer, many readers
- Low-coordination publication and atomics-only observation on the read path
- No reader registration
- Generic over `T`
- Fixed-size segmented storage
- Zero-copy snapshots backed by stable segment allocations
- Automatic reclamation of old segments
- Reclaimable write access after a writer is dropped
- Flat iteration and per-segment chunk iteration

## When to use it

`atomic-log` is a good fit when:

- one thread publishes and many threads observe
- readers mainly care about the latest retained state
- stale history may be dropped
- readers should not block the writer
- zero-copy reads are valuable
- bounded retention matters more than full replay

Typical examples:

- market data
- telemetry
- service health and status propagation
- real-time monitoring
- replicated in-memory state views

## When not to use it

Do not use `atomic-log` when:

- every message must be delivered
- readers must never miss an update
- commands or events must be processed exactly once
- multiple writers need to append concurrently without external synchronization
- data must survive restarts

For those cases, a channel, queue, or durable log is usually the right tool.

## Model

The writer appends values into a fixed-capacity head segment. When that segment fills, a
new head segment is allocated and published. Readers build `Snapshot<T>` values from the
current head and iterate over immutable published prefixes of the retained segments.
The log owns the retained segment chain; a `Writer<T>` is an exclusive append capability
that can be dropped and later reacquired from the log.

Snapshots are stable:

- readers only observe fully published values
- published values are never mutated again
- holding a snapshot keeps its backing segments alive
- readers access `&T` directly from segment storage without copying
- dropping a writer does not discard retained history

Refreshing a snapshot replaces it with a newer captured view. If a reader falls behind
beyond the retained history, continuity across refreshes may be lost.

## Retention semantics

The constructor takes:

- `retained_capacity`: target logical retention in elements
- `segment_capacity`: fixed elements per segment

The current implementation retains whole segments, not exact element counts, so the
visible live window is rounded to segment boundaries and may exceed `retained_capacity`.
That tradeoff keeps publication and reclamation simple while preserving stable zero-copy
snapshots.

## Example

```rust
use atomic_log::AtomicLog;

let (mut writer, log) = AtomicLog::new_claimed(8, 4);

for value in 0..6 {
    writer.append(value);
}

let mut snapshot = log.snapshot();
assert_eq!(
    snapshot.iter().copied().collect::<Vec<_>>(),
    vec![0, 1, 2, 3, 4, 5]
);

writer.append(6);
writer.append(7);
snapshot.refresh();

assert_eq!(
    snapshot.iter().copied().collect::<Vec<_>>(),
    vec![0, 1, 2, 3, 4, 5, 6, 7]
);

let chunks: Vec<_> = snapshot
    .chunks()
    .map(|chunk| (chunk.sequence(), chunk.values().len()))
    .collect();

assert_eq!(chunks, vec![(0, 4), (1, 4)]);
```

## API summary

- `AtomicLog::new(retained_capacity, segment_capacity)` creates an unclaimed log
- `AtomicLog::new_claimed(retained_capacity, segment_capacity)` creates a writer and read handle
- `AtomicLog::try_claim_writer()` recreates a writer if no writer currently exists
- `Writer::append(value)` publishes one value
- `AtomicLog::snapshot()` captures a stable read view
- `Snapshot::refresh()` updates an existing snapshot in place
- `Snapshot::iter()` yields `&T`
- `Snapshot::chunks()` yields per-segment slices plus sequence numbers

## License

Licensed under either of:

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT]LICENSE-MIT or <http://opensource.org/licenses/MIT>)

at your option.

## Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for
inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual
licensed as above, without any additional terms or conditions.