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}