Skip to main content

motion_core/asset/
pool.rs

1//! Project-local decoded resource accounting and identity.
2
3use super::*;
4
5/// Explicit project cache and logical allowance; clones share identity and accounting.
6/// Each new Assets owner starts isolated unless with_pool supplies a shared pool.
7/// Decoded Arc values can outlive all owners/handles and are not then pool-accounted.
8#[derive(Clone, Default)]
9pub struct ResourcePool(pub(super) Arc<Pool>);
10
11pub(super) struct Pool {
12    pub(super) bytes: AtomicUsize,
13    pub(super) entries: Mutex<BTreeMap<CacheKey, Weak<Erased>>>,
14    pub(super) max_bytes: usize,
15    pub(super) max_entries: usize,
16}
17
18impl Default for Pool {
19    fn default() -> Self {
20        Self {
21            bytes: AtomicUsize::new(0),
22            entries: Mutex::new(BTreeMap::new()),
23            max_bytes: MAX_CACHE_BYTES,
24            max_entries: MAX_ENTRIES,
25        }
26    }
27}
28
29impl ResourcePool {
30    /// Creates an isolated 256 MiB / 4096-entry logical project pool.
31    pub fn new() -> Self {
32        Self::default()
33    }
34
35    /// Uses a positive payload allowance and 1..=4096 cached entries.
36    pub fn with_limits(limits: crate::CacheLimits) -> crate::Result<Self> {
37        let (max_bytes, max_entries) = (limits.bytes, limits.entries);
38        if max_bytes == 0 || !(1..=MAX_ENTRIES).contains(&max_entries) {
39            return Err(io::Error::new(
40                io::ErrorKind::InvalidInput,
41                "Resource limits require positive bytes and 1..=4096 entries",
42            )
43            .into());
44        }
45        Ok(Self(Arc::new(Pool {
46            max_bytes,
47            max_entries,
48            ..Pool::default()
49        })))
50    }
51
52    /// Configured logical payload allowance.
53    pub fn max_bytes(&self) -> usize {
54        self.0.max_bytes
55    }
56
57    /// Configured cached-entry allowance.
58    pub fn max_entries(&self) -> usize {
59        self.0.max_entries
60    }
61
62    /// Logical payload retained by this project, not process RSS.
63    pub fn retained_bytes(&self) -> usize {
64        self.0.bytes.load(Ordering::Acquire)
65    }
66
67    /// Whether two owners charge the same project pool.
68    pub fn same_pool(&self, other: &Self) -> bool {
69        Arc::ptr_eq(&self.0, &other.0)
70    }
71}