Skip to main content

fraiseql_wire/stream/memory_estimator/
mod.rs

1//! Memory estimator for buffered items
2//!
3//! Provides pluggable memory estimation strategy for buffered JSON items.
4//! Default: conservative 2KB per item estimation.
5
6/// Trait for estimating memory usage of buffered items
7///
8/// This allows customization of memory estimation if workload characteristics differ
9/// from the default conservative 2KB per item assumption.
10pub trait MemoryEstimator: Send + Sync {
11    /// Estimate total memory in bytes for given number of buffered items
12    fn estimate_bytes(&self, items_buffered: usize) -> usize;
13
14    /// Human-readable name for this estimator (for debugging/logging)
15    fn name(&self) -> &'static str;
16}
17
18/// Default conservative memory estimator: 2KB per item
19///
20/// Used by default for all streams. Suitable for typical JSON documents (1-5KB).
21/// - Underestimates small objects (< 2KB) → hits limit later (safe)
22/// - Overestimates large objects (> 2KB) → hits limit earlier (safe)
23#[derive(Debug, Clone)]
24pub struct ConservativeEstimator;
25
26impl MemoryEstimator for ConservativeEstimator {
27    fn estimate_bytes(&self, items_buffered: usize) -> usize {
28        items_buffered * 2048 // 2 KB per item
29    }
30
31    fn name(&self) -> &'static str {
32        "conservative_2kb"
33    }
34}
35
36/// Custom memory estimator using fixed bytes per item
37///
38/// Use this if your analysis shows different typical item sizes.
39/// Example: if your JSON averages 4KB, use `FixedEstimator::new(4096)`
40#[derive(Debug, Clone)]
41pub struct FixedEstimator {
42    bytes_per_item: usize,
43}
44
45impl FixedEstimator {
46    /// Create estimator with custom bytes-per-item
47    #[must_use]
48    pub const fn new(bytes_per_item: usize) -> Self {
49        Self { bytes_per_item }
50    }
51}
52
53impl MemoryEstimator for FixedEstimator {
54    fn estimate_bytes(&self, items_buffered: usize) -> usize {
55        items_buffered.saturating_mul(self.bytes_per_item)
56    }
57
58    fn name(&self) -> &'static str {
59        "fixed_custom"
60    }
61}
62
63#[cfg(test)]
64mod tests;