1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! Forest aggregate root.
//!
//! - [`point_store::PointStore`] — a refcounted ring buffer that
//! holds the canonical copy of every point currently referenced by
//! any tree. Trees see it through the
//! [`crate::tree::PointAccessor`] trait.
//! - [`random_cut_forest::RandomCutForest`] — orchestrates `N`
//! `(RandomCutTree, ReservoirSampler)` pairs sharing the
//! [`point_store::PointStore`].
//! - [`ForestSnapshot`] — minimal read-only health + capacity view,
//! exposed so downstream crates (`anomstream-triage`, any external
//! calibrator / SOC dashboard) can consume forest state without
//! reaching into the reservoir-level internals.
pub use PointStore;
pub use RandomCutForest;
/// Read-only snapshot view of a forest's capacity + health.
///
/// Lives in `anomstream-core` so any consumer — including the
/// downstream `anomstream-triage` crate that hosts SAGE, Platt,
/// `AlertClusterer`, `FeedbackStore` — can introspect a forest
/// (`RandomCutForest` or `ThresholdedForest`) without needing
/// access to the reservoir internals (`point_store()`, `trees()`).
///
/// The contract is intentionally tiny; calibration / triage
/// pipelines typically need only sizing + progress information,
/// not tree-level data.
///
/// Implemented by:
/// - [`RandomCutForest<D>`]
/// - [`crate::thresholded::ThresholdedForest<D>`] (delegates to
/// its inner forest)
///
/// # Examples
///
/// ```
/// use anomstream_core::{ForestBuilder, ForestSnapshot};
///
/// let forest = ForestBuilder::<4>::new()
/// .num_trees(50)
/// .sample_size(64)
/// .seed(42)
/// .build()
/// .unwrap();
/// assert_eq!(forest.snapshot_num_trees(), 50);
/// assert_eq!(forest.snapshot_dimension(), 4);
/// assert_eq!(forest.snapshot_updates_seen(), 0);
/// ```