refactor!: un-export six types that no caller could reach
`TimeSlice`, `EventKind`, `KeyTable`, `CompetitorStore`, `Competitor` and the `storage` module were all public and none was obtainable from a `History` — `time_slices`, `agents` and `keys` are all private or `pub(crate)`. `TimeSlice` was the worst: `new`, `add_events`, `iteration`, `get_composition` and `get_results` were `pub` on a type you could only build standalone and never feed back into anything. Their sole consumer outside `src/` was `benches/batch.rs`, so a benchmark was dictating six public types. It is rewritten against the public API: a single-slice history's `converge` calls exactly the same per-slice sweep, so capping at one iteration measures the same code path. `N01` had zero references in the entire repository, including inside the crate; removed. `N00` and `N_INF` are EP identities (`Add` and `Mul`) and are now `pub(crate)` — a user reaching for `N_INF` as "an unknown competitor's prior" would get an improper distribution whose `mu()` silently reports 0.0. Adds the accessors their absence forced people around, from #70: `competitors()`, `competitor_count()` and `event_count()` (`size` had no accessor at all). Answering "who is best" previously meant materialising every competitor's full smoothed curve to read the last point of each. `KeyTable::keys` now iterates the dense reverse table rather than the forward `HashMap`, so `competitors()` yields insertion order rather than per-process hash order — the same hazard as #62, caught before it could reach a caller building a standings table. Two `CompetitorStore` methods (`is_empty`, `iter_mut`) had no callers anywhere and are gone; four more are now `#[cfg(test)]`, which is what they always were in practice. Worth recording a mistake: I first deleted `get_composition`/`get_results` on the strength of a "never used" warning, and the build broke — the warning came from the plain-lib target, where `#[cfg(test)]` callers in history.rs are not compiled. A dead-code warning from one target is not evidence about the others. BREAKING CHANGE: `TimeSlice`, `EventKind`, `KeyTable`, `CompetitorStore`, `Competitor`, the `storage` module, `N01`, `N00` and `N_INF` are no longer public. Refs #73, #70 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011hcFjNDmHXZF8URGLku5zZ
This commit is contained in:
@@ -546,6 +546,39 @@ impl<T: Time, D: Drift<T>, O: Observer<T>, K: Eq + Hash + Clone> History<T, D, O
|
||||
self.time_slices.len()
|
||||
}
|
||||
|
||||
/// Every competitor the history knows, in the order they were first seen.
|
||||
///
|
||||
/// Includes competitors created by [`History::register`] that have not yet
|
||||
/// appeared in an event.
|
||||
///
|
||||
/// Insertion order, not hash order: a `HashMap` walk differs between
|
||||
/// processes, which would make anything built from this — a standings
|
||||
/// table, a printed report — unreproducible.
|
||||
///
|
||||
/// ```
|
||||
/// # use trueskill_tt::History;
|
||||
/// let mut h = History::builder().build();
|
||||
/// h.record_winner(&"alice", &"bob", 1)?;
|
||||
/// let names: Vec<_> = h.competitors().copied().collect();
|
||||
/// assert_eq!(names, ["alice", "bob"]);
|
||||
/// # Ok::<(), trueskill_tt::InferenceError>(())
|
||||
/// ```
|
||||
pub fn competitors(&self) -> impl ExactSizeIterator<Item = &K> {
|
||||
self.keys.keys()
|
||||
}
|
||||
|
||||
/// How many competitors the history knows.
|
||||
#[must_use]
|
||||
pub fn competitor_count(&self) -> usize {
|
||||
self.keys.len()
|
||||
}
|
||||
|
||||
/// How many events have been ingested.
|
||||
#[must_use]
|
||||
pub fn event_count(&self) -> usize {
|
||||
self.size
|
||||
}
|
||||
|
||||
/// Learning curves for all competitors, keyed by their user-facing key.
|
||||
pub fn learning_curves(&self) -> HashMap<K, Vec<(T, Gaussian)>> {
|
||||
#[cfg(feature = "rayon")]
|
||||
|
||||
Reference in New Issue
Block a user