Skip to main content

ProtectPool

Struct ProtectPool 

Source
pub struct ProtectPool {
    backing: SEXP,
    capacity: usize,
    generations: Vec<u32>,
    free_slots: Vec<usize>,
    next_slot: usize,
    len: usize,
    _nosend: PhantomData<Rc<()>>,
}
Expand description

A VECSXP-backed pool for GC protection with generational keys.

§Example

let mut pool = unsafe { ProtectPool::new(16) };

let key = unsafe { pool.insert(some_sexp) };
// SEXP is now protected from GC

let sexp = pool.get(key).unwrap();
// Use the SEXP...

unsafe { pool.release(key) };
// SEXP is no longer protected (eligible for GC)

Fields§

§backing: SEXP

The VECSXP that holds protected SEXPs. Anchored by R_PreserveObject.

§capacity: usize

Current capacity of the backing VECSXP.

§generations: Vec<u32>

Generation counter per VECSXP slot. Incremented on each release. A key is valid iff generations[key.slot] == key.generation.

§free_slots: Vec<usize>

Free VECSXP slot indices for reuse.

§next_slot: usize

Next fresh VECSXP slot index (for when free_slots is empty).

§len: usize

Number of currently protected objects.

§_nosend: PhantomData<Rc<()>>

Implementations§

Source§

impl ProtectPool

Source

pub const DEFAULT_CAPACITY: usize = 16

Initial default capacity.

Source

pub unsafe fn new(capacity: usize) -> Self

Create a new pool with the given initial capacity.

§Safety

Must be called from the R main thread.

Source

pub unsafe fn with_capacity(capacity: usize) -> Self

Create a new pool with a specific initial capacity.

§Safety

Must be called from the R main thread.

§Panics

Panics if capacity exceeds R_xlen_t::MAX or u32::MAX.

Source

pub unsafe fn insert(&mut self, sexp: SEXP) -> ProtectKey

Protect a SEXP, returning a generational key.

The SEXP will be protected from GC until release is called with the returned key. If the key is dropped without calling release, the SEXP remains protected (leak, not crash).

§Safety

Must be called from the R main thread. sexp must be a valid SEXP.

§Panics

Panics if the pool has grown beyond u32::MAX slots.

Source

pub unsafe fn release(&mut self, key: ProtectKey)

Release a previously protected SEXP.

If the key is stale (already released, or from a different pool), this is a no-op.

§Safety

Must be called from the R main thread.

Source

pub fn get(&self, key: ProtectKey) -> Option<SEXP>

Get the SEXP for a key, or None if the key is stale.

Source

pub unsafe fn replace(&mut self, key: ProtectKey, sexp: SEXP) -> bool

Overwrite the SEXP at an existing key without releasing/reinserting.

Returns true if the key was valid and the value was replaced. Returns false if the key was stale (no-op).

This is the pool equivalent of R_Reprotect — O(1), no allocation.

§Safety

Must be called from the R main thread. sexp must be a valid SEXP.

Source

pub fn contains_key(&self, key: ProtectKey) -> bool

Check if a key is currently valid (not stale).

Source

pub fn len(&self) -> usize

Number of currently protected objects.

Source

pub fn is_empty(&self) -> bool

Whether the pool is empty.

Source

pub fn capacity(&self) -> usize

Current capacity of the backing VECSXP.

Source

fn alloc_slot(&mut self) -> usize

Source

unsafe fn grow(&mut self)

Trait Implementations§

Source§

impl Drop for ProtectPool

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Protector for ProtectPool

Source§

unsafe fn protect(&mut self, sexp: SEXP) -> SEXP

Protect a SEXP from garbage collection. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.