Skip to main content

mnemosyne_arena/scratch/pool/
query.rs

1//! Read-only queries for [`super::ScratchPool`]: depth, capacity mirrors,
2//! slot availability, and total byte footprint.
3//!
4//! All methods here read from the `Cell` mirrors maintained outside the
5//! `UnsafeCell` slots, so they are safe to call even from inside a live
6//! `with_scratch` borrow of the same pool.
7
8use super::super::element::ScratchElement;
9use super::ScratchPool;
10
11impl<T: ScratchElement> ScratchPool<T> {
12    /// Returns the current borrow depth (0 = fully available).
13    #[inline]
14    pub fn borrow_depth(&self) -> u8 {
15        self.borrow_depth.get()
16    }
17
18    /// Returns the capacity of the first slot (primary buffer).
19    ///
20    /// Callable at any time, including from inside a live
21    /// [`Self::with_scratch`] borrow of that same slot. The figure is read from
22    /// a mirror maintained outside the slot's `UnsafeCell`, so the accessor
23    /// never derives a reference that could alias the exclusive one the borrow
24    /// holds — the reentrant call is sound rather than merely undetected, and it
25    /// neither panics nor reports a stale value.
26    ///
27    /// Every slot carries such a mirror; see [`Self::total_capacity_bytes`] for
28    /// the sum across all of them.
29    #[inline]
30    pub fn capacity(&self) -> usize {
31        self.slot_capacities[0].get()
32    }
33
34    /// Returns `true` when the pool has at least one slot available for a
35    /// new borrow (`borrow_depth < MAX_POOL_SLOTS`).
36    #[inline]
37    #[must_use]
38    pub fn is_available(&self) -> bool {
39        use super::MAX_POOL_SLOTS;
40        self.borrow_depth.get() < MAX_POOL_SLOTS as u8
41    }
42
43    /// Returns the backing capacity of slot `idx`, or `0` when `idx` is out
44    /// of range. Callable at any time including during a live borrow.
45    #[inline]
46    #[must_use]
47    pub fn slot_capacity(&self, idx: usize) -> usize {
48        self.slot_capacities.get(idx).map_or(0, |c| c.get())
49    }
50
51    /// Sum of backing capacities across all slots, in bytes.
52    #[inline]
53    pub fn total_capacity_bytes(&self) -> usize {
54        // Read from the per-slot mirrors, never through the slots
55        // themselves: a live `with_scratch` borrow holds one slot exclusively,
56        // and the mirrors are maintained outside the `UnsafeCell`s precisely so
57        // this stays a total — a borrow-time branch returning slot 0 alone
58        // would contradict the documented sum.
59        self.slot_capacities
60            .iter()
61            .map(|mirror| mirror.get().saturating_mul(core::mem::size_of::<T>()))
62            .fold(0usize, usize::saturating_add)
63    }
64}